bookmarks-lifecycle
Allows the MCP server to scan and import bookmarks from the Arc browser.
Allows the MCP server to scan and import bookmarks from the Brave browser.
Allows the MCP server to scan and import bookmarks from the Firefox browser.
Allows the MCP server to scan and import bookmarks from the Safari browser.
Allows the MCP server to scan and import bookmarks from the Vivaldi browser.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@bookmarks-lifecyclewhat's in my bookmark queue today?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
bookmarks-lifecycle
Give your saved bookmarks a lifecycle.
Saving is easy. Almost nothing you save ever gets decided about — it just accumulates. This is a local MCP server that puts every bookmark on a clock: 24 hours to decide, or 30 days to keep watching, or keep it for good. Nothing is ever deleted — a bookmark that times out without a decision just leaves your attention, not your disk, and every change (including ones an AI made) can be undone.
Aggregates via bookmarks-mcp. Writes only its own local state file, atomically. No accounts, no cloud, no network calls.The model
Five states:
State | Meaning | Counts down? |
| Aggregated, not yet up for a decision | no |
| The 24-hour layer — today's actual to-do list | yes |
| The 30-day layer — "give it more time" | yes |
| Decided: keep this for good | no |
| Timed out or let go — fully recoverable, never deleted | no |
aggregate → inbox
│ drip (up to N/day, oldest first)
▼
pending ──you decide──→ watching / kept / lapsed
│
└──24h, no decision────────────→ lapsed
▲
watching ──30d, no decision───────────┘
└──you decide──→ kept
lapsed ──restore──→ pending (clock resets)
any state ──undo (by history event)──→ whatever it was right before that eventFrom pending you can go to any of the three outcomes. From watching, a
decision can only be keep — that matches the model above; to back out of a
watch or a drop, use undo rather than re-deciding an item that's
already moved on.
Bookmarks don't all land in pending the moment you aggregate them — a
one-time import of 3,000 old bookmarks would otherwise all time out on the
same day and the mechanism would mean nothing. They drip in at a daily
rate instead (default 15/day, oldest first — by real save date when the
source provides one). This is computed lazily whenever you call a tool, not
by a background timer, and it does not accumulate across a long absence:
however many days you've been away, one call promotes at most one day's
quota. A 3,000-bookmark backlog at 15/day realistically takes months of
daily visits to clear — that's an honest tradeoff of "no reminders, nothing
runs unless you ask", not a claim that this replaces a habit-forming app.
Related MCP server: linkwarden-mcp
Install
No account, no API key, no configuration — it works the moment it's installed.
Claude Code:
claude mcp add -s user bookmarks-lifecycle -- npx -y bookmarks-lifecycleClaude Desktop / Cursor / any MCP client (mcpServers JSON):
{
"mcpServers": {
"bookmarks-lifecycle": {
"command": "npx",
"args": ["-y", "bookmarks-lifecycle"]
}
}
}To run from source instead (for development), clone parse-bookmarks,
bookmarks-mcp, and this repo as sibling directories, run npm install in
bookmarks-mcp and then in bookmarks-lifecycle, and point your client at
node /absolute/path/to/bookmarks-lifecycle/src/index.js.
Use -s user. Without it the scope defaults to local, which registers the
server only for the directory you ran the command in — you'd have to be inside
that folder for your assistant to see it. Your bookmarks have nothing to do with
which code project you happen to be sitting in, so register it once for your
whole account.
Config file locations (for the JSON form above):
Claude Desktop:
~/Library/Application Support/Claude/claude_desktop_config.json(macOS)Cursor:
~/.cursor/mcp.json(or per-project.cursor/mcp.json)
Verifying it's connected: ask your assistant to call the stats tool, or
check your client's MCP/server log — a successful initialize handshake and
a tools/list containing intake, today, decide, list_layer, restore, undo, stats means it's up.
After changing any environment variable below, fully restart your MCP client's connection to this server (quit/reopen Claude Desktop, or restart the Cursor MCP process) — it reads them once at startup.
First run
If you're on macOS and want Safari bookmarks included, the app hosting this
server (Claude Desktop, your terminal, Cursor) needs Full Disk Access
(System Settings → Privacy & Security → Full Disk Access) — ~/Library/Safari
is protected. Without it, intake's response will show "sourceStatus": "permission_denied" and a warnings entry explaining exactly that; it will
NOT silently look like an empty result. Chromium browsers and Firefox need
nothing extra.
Call intake first — nothing shows up in today until you do. Then today
gives you the day's actual queue. If both intake and today come back
completely empty and sourceStatus says "ok", that's an honest "you have
no bookmarks in the sources this scanned" — check sourceStatus before
assuming something's broken:
| Meaning |
| No supported browser was even detected on this machine |
| At least one source failed to read (commonly Safari without Full Disk Access) |
| Every source scanned successfully and genuinely has 0 bookmarks |
| Scanned successfully and found something |
no_sources even though you can see bookmarks in your browser? This detects
Chromium browsers (Chrome, Edge, Brave, Arc, Vivaldi, Chromium) only in their
standard per-OS install locations. If your browser uses a custom profile or
data directory (a separate work profile, a portable install, a renamed user
data folder, …), it won't be found automatically:
Open
chrome://versionin that browser (edge://version,brave://version, etc. — the same page exists in every Chromium browser) and copy the value next to Profile Path.In your MCP client's config for this server, add an environment variable
CHROMIUM_BOOKMARKS_PATHset to that path with/Bookmarksappended, e.g."/Users/you/Library/Application Support/BraveSoftware/Brave-Browser/Custom/Bookmarks". Comma-separate multiple paths if you have more than one profile to include.Fully restart the MCP client's connection to this server (see Configuration below).
This doesn't apply to Safari — see the Full Disk Access note above instead.
Talking to it
You never call these tools yourself — your assistant does. You just talk. If
you'd rather be walked through it, run the clean_up_my_bookmarks prompt
once (in Claude Code: /mcp; in Claude Desktop: the prompts menu) and it will
set you up and do one round with you.
Otherwise, plain sentences are enough:
Say something like | What happens |
"Pull in my browser bookmarks" |
|
"What should I look at today?" |
|
"Keep the first one, drop the last two" |
|
"Actually, undo that" |
|
"What did I let go of?" |
|
"Bring that one back" |
|
"How much is left?" |
|
Two things worth knowing on day one:
Nothing reminds you. There is no background process and no notification. The queue only moves when you ask — which also means it can never surprise you.
An empty result explains itself. Every response carries a
nextSteptelling your assistant what to suggest, so "0 items" never has to be guessed at: it will say whether you simply haven't scanned yet, whether today's batch is done, or whether a source failed to read.
Tools
Tool | What it does |
| Scan bookmark sources, merge new ones into |
| The |
| Judge one or more items: |
| See any single layer, paginated (default 50/page), including |
| Bring a |
| Revert an item to what it was right before one of its own history events — works for |
| Counts per layer, today's decision count, how much is waiting in |
Every read tool (today/list_layer/stats) may still write to disk on
the call you make: expiry and drip are computed lazily, so even "just
looking" can move items between layers as a side effect. It only writes
when something actually changed — a call that finds nothing due and nothing
to drip touches nothing.
Plus two prompts:
Prompt | When |
| First time. Explains the decision-clock mechanism, runs |
| Every day after that. |
Both intake and today also return a nextStep object (code + why) so
your assistant knows what to suggest next instead of inferring it from an
empty list. It is operational guidance only — never promotion.
Honesty about authorization
This server cannot verify that a tool call attributed to "user" actually
came from you confirming something. Every parameter it receives — including
actorClaim: "user" — comes from the AI, over the same channel as everything
else. There is no separate, trusted channel this code can check. An earlier
version of this README claimed "AI can't act without your say-so" as a
server-enforced guarantee; that was tested and shown to be false — an AI
that simply omits the field, or claims "user", goes through unchallenged.
We're not going to repeat that claim.
What's actually true:
Whether an AI needs your click-through before it can call a mutating tool depends on your MCP client's own tool-approval settings — Claude Desktop and Cursor both have per-tool or per-session approval prompts. That's the real gate, and it lives in your client, not in this server.
actorClaim: "ai"is rejected unless you've explicitly setBOOKMARKS_LIFECYCLE_AUTO_DECIDE=true— but a caller can just omit the field (recorded as"mcp-client") or claim"user"instead, so don't treat this as a security boundary either.What this server actually guarantees is reversibility. Every mutation — including ones made under
autoDecide, including expiry, including drip — is undoable.restorereverseslapsed → pending.undoreverses any state change, includingkeptandwatching, by history event, with apreviewmode to check first. If an AI does something you didn't want, the fix isundo, not a promise that it couldn't have happened.historyrecordsby: "user" | "ai" | "mcp-client" | "drip" | "expiry" | "system"on every change. The first two are claims, not verified identity — treat them as a hint for your own review, not evidence.
Configuration
All via environment variables in your MCP client config — none require touching this package's code. Restart your MCP client's connection after changing any of these.
Variable | Default | What |
|
| Hours in the |
|
| Days in the |
|
| Max |
|
| Whether |
|
| Where |
What gets stored
One file: ~/.bookmarks-lifecycle/state.json. Plain JSON, human-readable.
Writes are atomic (temp file → fsync → rename, never a partial write left
behind mid-crash) and the previous generation is kept as state.json.bak
before each overwrite.
Per bookmark: id, url, title, the browser source(s) it's known from (a URL
saved in two browsers keeps both), when it was actually added according to
the browser (addedAt, used for oldest-first ordering — null if the
source didn't provide one, never fabricated), current lifecycle state, when
it entered that state, a full history of every transition (each with a
stable eventId, when, who/what did it, and an optional note), and a
sourceGone flag for bookmarks no longer found in any source that was
successfully re-scanned (their record stays — nothing here is ever
auto-deleted; a source that merely failed to read never counts as
evidence something's gone).
Only identifiers and your own judgments are stored — never the page content
itself. The file has an internal version; if a future version of this tool
writes a shape this version doesn't understand, this version refuses to
touch the file rather than guess.
Concurrent access: if two MCP clients (say, Claude Desktop and Cursor)
run this server against the same state file at once, a lock file
(state.json.lock) serializes them — the second one waits briefly rather
than silently overwriting the first one's changes.
Time zone
stats's "today" (for decidedToday) uses the local calendar day on the
machine running this server. Because this server only ever runs on your own
machine (it reads local browser files directly — there's no remote/hosted
deployment of it), that's the same clock you're living by, so this is
intentional, not a bug to fix. The 24h/30d layer durations are strict
elapsed-time windows, not calendar-day counts — a daylight-saving transition
shifts wall-clock time without changing how long 24 hours actually is.
Guarantees
Never touches a browser bookmark file. Reading is entirely delegated to
bookmarks-mcp, which is itself read-only. The only files this package ever writes are its ownstate.json,state.json.bak, and a transient lock file.No lifecycle record is ever deleted, and every state change is reversible — see Honesty about authorization for exactly what that does and doesn't protect against.
No network calls, no telemetry, no accounts.
Design boundaries
No background process, no cron, no push notifications. Everything here is computed lazily, the instant you call a tool — that's what makes "no daemon" possible. The honest tradeoff: if you don't come ask, the queue just quietly lapses. Nobody reminds you.
No UI. This stays an MCP tool, not an app.
Bring your own AI. This server does no inference and charges nothing — the AI judging your bookmarks is whatever you've already connected it to. What this project provides is the state machine and the prompt, not a model.
Who makes this
Built by the team behind Burn 451 — the 24h / 30-day mechanic here is modeled on Burn's. The difference: this tool only runs when you ask it to, right where you're already working. If you want the same idea running automatically, reminding you daily, and reachable from your phone, that's what Burn is — this project stays useful on its own either way.
License
MIT
Available Tools
7 toolsdecideJudge one or more pending/watching itemsA
MUTATING TOOL. Never call until the user has explicitly confirmed the exact item ids and action in the current turn, unless the MCP host has a trusted autonomous-approval mode enabled — silence, "looks good", or an earlier preference is not confirmation. Moves items to kept (keep permanently), watching (give it 30 more days), or lapsed (remove from the attention queue — this never deletes the browser bookmark or the lifecycle record, and is fully undoable via undo). From pending: keep/watch/drop all allowed. From watching: only keep (use undo to reverse a watch/drop decision instead of re-deciding an item that's already moved on). Anything else comes back as not-decidable. This call may first persist lazy expiry/drip housekeeping (see README) even if you only meant to read.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | One or more item ids, from today/list_layer output. Max 25 per call. | |
| note | No | Why — stored on the item and in its history, if given (this field is optional; omitting it is fine) | |
| action | Yes | keep -> kept, watch -> watching (30d), drop -> lapsed | |
| actorClaim | No | Attribution claim only — this is NOT proof of user consent. This server has no way to verify who is really behind a call; omit this field unless you have a specific reason to claim "user" or "ai" (omitted calls are recorded as "mcp-client" in history). "ai" is rejected unless the user has set BOOKMARKS_LIFECYCLE_AUTO_DECIDE=true — and even then, real protection against unwanted changes comes from every mutation being undoable via `undo`, not from this field. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It openly declares itself a mutating tool, requires explicit consent, warns of potential housekeeping writes even on read intent, and explains that `drop` never deletes bookmarks or lifecycle records and is fully undoable. It also discloses the `actorClaim` caveat (not proof of consent, cannot be verified, `ai` rejected unless env var set).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense yet highly efficient. It opens with a bold 'MUTATING TOOL' warning and packs consent requirements, state transitions, side effects, error behavior, and attribution caveats into five purposeful sentences. No filler; every clause contributes critical information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex mutation tool with no annotations and no output schema, the description covers prerequisites, allowed transitions, error responses, reversal path via `undo`, housekeeping side effects, and consent/attribution limitations. It even points to the README for deeper details, making it fully actionable for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, so the baseline is high. The description adds behavioral nuance beyond the schema: it clarifies the side effects of `drop`, the 30-day window for `watch`, and the consent limitations of `actorClaim`. While it doesn't restate each parameter, it enriches understanding of how those values operate in context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: it moves items to `kept`, `watching`, or `lapsed` states, and the title specifies 'pending/watching items'. It distinguishes from siblings by defining the state machine explicitly and referencing `undo` as the reversal tool, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use and when-not-to-use guidance: it must only be called after explicit user confirmation of exact item IDs and action, unless trusted autonomous-approval mode is enabled. It also specifies state-dependent rules (from `pending` all actions allowed, from `watching` only `keep`) and directs readers to `undo` for reversing decisions, clearly separating this tool from alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
intakePull in newly saved bookmarksA
Scan browser bookmarks (via bookmarks-mcp) and merge them into the lifecycle: new URLs land in inbox with their real save date persisted; already-tracked ones get reconciled (sources, title). Never deletes a record — a URL missing from every source that was successfully scanned gets sourceGone: true, not removed. A source that failed to read (e.g. Safari without Full Disk Access) is never treated as confirming a URL is gone. Check sourceStatus in the response before assuming an empty result means nothing was found. This call may first persist lazy expiry/drip housekeeping (see README) even if you only meant to read.
| Name | Required | Description | Default |
|---|---|---|---|
| source | No | Filter by browser ("chrome", "safari", "firefox", …) or a source id from bookmarks-mcp's list_sources. Omit for all. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and excels. It discloses critical behaviors: never deletes records (sourceGone instead), treats failed source reads as non-confirmatory, advises checking sourceStatus in the response, and warns about lazy expiry/drip housekeeping side effects. This goes far beyond a basic summary and gives the agent a clear picture of consequences and edge cases.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose in the first sentence, then methodically explains behavior and caveats. Every sentence conveys useful information—there is no fluff or repetition. Despite its length, it remains tightly structured and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description does a solid job of indicating response expectations by mentioning sourceStatus and explaining sourceGone behavior. It also flags the housekeeping side effect for context. However, it does not fully enumerate the response structure or all return values, so it leaves some room for improvement, especially for a tool with this level of complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has one optional 'source' parameter with a thorough description covering browser names and source IDs, totaling 100% schema coverage. The tool description adds no additional parameter semantics beyond the schema, so the baseline of 3 is appropriate—the schema already does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action: 'Scan browser bookmarks (via bookmarks-mcp) and merge them into the lifecycle.' It identifies the resource (browser bookmarks) and the process (new URLs to inbox, existing ones reconciled). While it doesn't explicitly name siblings, the function is unique and unambiguously distinct from list_layer, today, decide, stats, restore, and undo.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage: it's for pulling in newly saved bookmarks and syncing them into the lifecycle. It provides clear context about when the tool is appropriate (when there are new bookmark URLs to merge) and what to expect. However, it does not explicitly state 'use this when X' or 'don't use this when Y', nor does it name alternative tools, so it stops short of the highest mark.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_layerList one layer (paginated)A
See what's in one layer — including lapsed, to answer 'what did I let go of'. Paginated: default limit 50, raise it only if you actually need more in one call (a large unpaginated layer can be megabytes of JSON, which will crowd out everything else in your context). sourceGone: true on an item means it's no longer found in any browser source that was successfully scanned (the record itself is never deleted). This call may first persist lazy expiry/drip housekeeping (see README) even if you only meant to read.
| Name | Required | Description | Default |
|---|---|---|---|
| layer | Yes | ||
| limit | No | ||
| offset | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses several important behaviors: the potentially large response size (megabytes), the meaning of sourceGone:true (record never deleted), and the side effect that the call may persist lazy expiry/drip housekeeping even on a read. This is strong transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, front-loaded with the core purpose. Each sentence adds essential context: purpose, pagination behavior, sourceGone semantics, and side-effect warning. No waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no annotations and no output schema, the description covers most important operational details: purpose, pagination limits, a field semantic, and a side effect. It lacks an explicit description of the response shape, but that is not critical for a listing tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains the limit parameter's default and advises against raising it unnecessarily, and it mentions the lapsed layer value. However, it does not explain the offset parameter or enumerate all layer values beyond lapsed, leaving some work to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists the contents of a layer ('See what's in one layer'), explicitly including the 'lapsed' layer to answer 'what did I let go of'. This distinguishes it from sibling tools like stats or undo, which are clearly different operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear context on when to use it (to inspect any layer) and cautions about pagination: 'default limit 50, raise it only if you actually need more in one call.' It also warns about the large unpaginated JSON and the housekeeping side effect, but does not explicitly name alternative tools or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
restoreBring a lapsed item backA
MUTATING TOOL. Move one or more lapsed items back to pending, resetting their 24-hour clock. Only works on items currently lapsed — for kept/watching items that need reverting, use undo instead. This call may first persist lazy expiry/drip housekeeping (see README) even if you only meant to read.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | One or more item ids, from today/list_layer output. Max 25 per call. | |
| actorClaim | No | Attribution claim only — this is NOT proof of user consent. This server has no way to verify who is really behind a call; omit this field unless you have a specific reason to claim "user" or "ai" (omitted calls are recorded as "mcp-client" in history). "ai" is rejected unless the user has set BOOKMARKS_LIFECYCLE_AUTO_DECIDE=true — and even then, real protection against unwanted changes comes from every mutation being undoable via `undo`, not from this field. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It opens with 'MUTATING TOOL' and discloses a subtle side effect: 'This call may first persist lazy expiry/drip housekeeping (see README) even if you only meant to read.' It also notes the clock reset, which is behavioral. It could be more comprehensive, but the disclosed side effects are significant and well-stated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, front-loaded with 'MUTATING TOOL'. Each sentence serves a distinct purpose: state the action, specify applicable conditions and alternative, and disclose side effects. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's mutation side effects and conditional applicability, the description covers the key operational context: what it does, when it works, alternative for other states, and a warning about housekeeping writes. It doesn't mention return values, but no output schema exists, so that's not required. It could mention the `undo` capability as a safety net, but overall it is well-rounded.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The tool description does not add additional parameter semantics beyond the schema; the schema already explains `ids` (from today/list_layer output, max 25) and `actorClaim` (attribution claim, not proof of consent). The description's mention of 'resetting their 24-hour clock' indirectly supports `ids`, but no extra value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Move one or more `lapsed` items back to `pending`, resetting their 24-hour clock', which is a specific verb+resource+scope. It also distinguishes from sibling `undo` by specifying that it only works on `lapsed` items, not `kept`/`watching` items.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use: 'Only works on items currently `lapsed`'. It also gives an explicit alternative: 'for `kept`/`watching` items that need reverting, use `undo` instead'. This fully covers usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
statsLifecycle statsA
Counts per layer, how many decisions landed today (local calendar day on the machine running this server — see README), and how much is still sitting in inbox waiting for its daily drip slot. This call may first persist lazy expiry/drip housekeeping (see README) even if you only meant to read.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full responsibility. It explicitly discloses a non-obvious side effect: the call may persist lazy housekeeping ('may first persist lazy expiry/drip housekeeping') even for a read. It also clarifies the timezone basis ('local calendar day on the machine running this server'), adding meaningful behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, consisting of two sentences. The first sentence front-loads the core counting purpose, while the second adds a crucial behavioral caveat. Every phrase adds value, and the README references are appropriate for follow-up details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no parameters and no output schema, the description covers the essential aspects: the data reported (counts per layer, inbox pending), the time window, and the potential write side-effect. It does not detail the return format, but that is not critical given the simple question-and-answer nature of the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema contains no parameter information. The description does not discuss parameters (none exist), but per the rubric, a 0-parameter tool gets a baseline of 4. The description adds no parameter details because there are none to add.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Counts') and clearly identifies the resource ('per layer', 'inbox'). It explains what is counted (decisions landed today) and the time window ('local calendar day'), which distinguishes it from sibling tools that likely provide individual records or different views.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use this tool: to obtain daily lifecycle counts and pending inbox volume. It does not explicitly state alternatives or exclusions, but the scoped purpose ('per layer', 'today') implies the intended usage without ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
todayToday's pending layerA
The 24-hour layer, oldest first — the actual to-do list. Each item includes remainingMs until it lapses on its own. hasEverIntaken: false means nothing has ever been scanned in (an empty pending list in that case means "you haven't started", not "you're caught up") — call intake first. This is where daily_triage starts. This call may first persist lazy expiry/drip housekeeping (see README) even if you only meant to read.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full disclosure. It candidly warns that the call 'may first persist lazy expiry/drip housekeeping even if you only meant to read,' revealing potential write side effects. It also clarifies the meaning of remainingMs and hasEverIntaken, adding valuable behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded with the core purpose. Every sentence adds distinct value: definition, item semantics, caveat, usage context, and side-effect warning. No redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no parameters and no annotations, the description is remarkably complete. It covers meaning of results, behavior on empty lists, prerequisite actions, and potential side effects. The reference to daily_triage and README provides additional context without overburdening the description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there are no parameter semantics to describe; the baseline of 4 applies. However, the description enhances understanding by explaining the meaning of the returned fields (remainingMs, hasEverIntaken), which is helpful given the lack of an output schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool's function: 'The 24-hour layer, oldest first — the actual to-do list.' This differentiates it from siblings by specifying the layer type and ordering. Also highlights its role as 'where daily_triage starts,' making its purpose and position among related tools unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance on when to use this tool versus alternatives: 'This is where daily_triage starts' and 'call intake first' when hasEverIntaken is false. While it doesn't explicitly say 'don't use list_layer,' the contextual cues are strong enough to guide correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
undoUndo a specific state change, by history eventA
MUTATING TOOL. Revert an item to whatever it was immediately before one of ITS OWN history events — this works for kept and watching, not just lapsed (that's what restore is for). Only an item's current LATEST event can be undone; anything else comes back as not-latest-event, showing you the actual latest one to target instead. Select events either with explicit eventIds (from any tool's history[].eventId), or with filter (by source id / time range / attribution) to batch-undo every matching item's latest event at once. Pass preview: true to see exactly what would change first. Undoing never erases history — it appends a new entry, so the full trail including undos stays intact. This call may first persist lazy expiry/drip housekeeping (see README) even if you only meant to read.
| Name | Required | Description | Default |
|---|---|---|---|
| note | No | ||
| filter | No | Alternative to eventIds: undo every item's LATEST event matching these criteria | |
| preview | No | See what would be undone without changing anything | |
| eventIds | No | Specific history event ids to undo | |
| actorClaim | No | Attribution claim only — this is NOT proof of user consent. This server has no way to verify who is really behind a call; omit this field unless you have a specific reason to claim "user" or "ai" (omitted calls are recorded as "mcp-client" in history). "ai" is rejected unless the user has set BOOKMARKS_LIFECYCLE_AUTO_DECIDE=true — and even then, real protection against unwanted changes comes from every mutation being undoable via `undo`, not from this field. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and succeeds: it flags mutating behavior, reveals that undo appends a new history entry rather than erasing, and discloses the side-effect that lazy expiry/drip housekeeping may persist even for read-like calls. This is strong, honest behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded paragraph that opens with the key purpose and mutating nature. Each sentence adds a distinct detail (constraints, selection methods, preview, history behavior, side effects), and there is no filler, though it is somewhat dense.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with 5 parameters, no output schema, and nested filter objects, the description covers the essential return signal (`not-latest-event`), side effects, and usage patterns. It does not spell out all possible response fields, but the provided detail is enough to use the tool safely and effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 80%, so baseline is 3, but the description adds meaning beyond the schema by explaining how `eventIds` come from any tool's `history[].eventId` and how `filter` selects events across items via source/time/attribution. It also contextualizes `preview` as a way to see changes first. Only the `note` parameter receives no added explanation, but the schema covers the main semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'MUTATING TOOL. Revert an item to whatever it was immediately before one of ITS OWN history events', a clear and specific verb+resource statement. It distinguishes itself from the sibling tool `restore` by noting undo works for `kept` and `watching` as well as `lapsed`, which clarifies scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when undo is appropriate, the constraint that only the latest event can be undone, and alternatives like using `filter` for batch operations or `preview` to dry-run. It also references `restore` as the alternate tool for lapsed-state reverts, giving clear when-to-use vs. when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
7 tool updates
v0.2.0- First observed
decide - First observed
intake - First observed
list_layer - First observed
restore - First observed
stats - First observed
today - First observed
undo
TDQS
Most tools have clearly distinct purposes: intake scans, decide mutates, stats aggregates, undo/restore handle reversal. However, list_layer and today overlap somewhat in that today is essentially a specialized view of the pending layer with extra metadata, which could cause an agent to pick either when trying to see pending items.
Tool names are a mix of single verbs (intake, decide, restore, undo), single nouns (stats, today), and one snake_case verb_noun (list_layer). There is no consistent verb_noun or action-oriented pattern, making the set feel stylistically inconsistent.
Seven tools is well-scoped for a bookmark lifecycle server. Each tool addresses a distinct stage or operation (ingestion, viewing, deciding, stats, reversal), with no trivial or redundant tools.
The lifecycle is well covered: intake brings items in, today/list_layer expose them, decide moves them, restore/undo handle reversals, and stats provides feedback. Minor gaps include no direct way to edit item metadata outside of rescanning, but this does not block core workflows.
Maintenance
Related MCP Connectors
Personal knowledge base MCP server with semantic search, auto-categorization, metadata extraction
Personal knowledge graph as an AI memory layer over MCP - read, save, and link your memories.
Markdown-based note-taking with a hosted MCP server. Your notes serve you and your AI.
One memory, every AI. A shared, user-owned markdown memory your AI clients read and write over MCP.
Related MCP Servers
- AlicenseCqualityCmaintenanceA local-first MCP server that turns browser bookmark exports into a searchable knowledge base with classification, merging, full-text indexing, and Chrome integration.20MIT
- AlicenseNot gradedqualityAmaintenanceMCP server for Linkwarden bookmarks providing read-first search and preserved content access with opt-in write, delete, and collection-delete tools, plus heuristic triage workflows.574MIT
- AlicenseAqualityAmaintenanceA local, read-only MCP server that makes bookmarks from browsers, read-later apps, and export files accessible to AI assistants, enabling search, triage, and summarization without sending data anywhere.8103MIT
- FlicenseNot gradedqualityBmaintenanceA stateless MCP server that lets AI coding agents consult a curated library of development bookmarks when making decisions. It provides read-only tools to search, inspect, and list curated items, plus a reusable decision prompt.1-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Fisher521/bookmarks-lifecycle'
If you have feedback or need assistance with the MCP directory API, please join our Discord server