Skip to main content
Glama
Fisher521

bookmarks-lifecycle

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?

inbox

Aggregated, not yet up for a decision

no

pending

The 24-hour layer — today's actual to-do list

yes

watching

The 30-day layer — "give it more time"

yes

kept

Decided: keep this for good

no

lapsed

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 event

From 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-lifecycle

Claude 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:

sourceStatus

Meaning

no_sources

No supported browser was even detected on this machine

permission_denied

At least one source failed to read (commonly Safari without Full Disk Access)

empty

Every source scanned successfully and genuinely has 0 bookmarks

ok

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:

  1. Open chrome://version in that browser (edge://version, brave://version, etc. — the same page exists in every Chromium browser) and copy the value next to Profile Path.

  2. In your MCP client's config for this server, add an environment variable CHROMIUM_BOOKMARKS_PATH set to that path with /Bookmarks appended, 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.

  3. 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"

intake — scans your browsers, adds new URLs to the inbox

"What should I look at today?"

today — the day's queue, oldest first, up to the daily quota

"Keep the first one, drop the last two"

decide — after you've confirmed, not before

"Actually, undo that"

undo — reverses any decision, including "keep"

"What did I let go of?"

list_layer on lapsed — everything is still there

"Bring that one back"

restore — returns it to the queue with a fresh clock

"How much is left?"

stats — counts per layer and what's still waiting in inbox

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 nextStep telling 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

intake

Scan bookmark sources, merge new ones into inbox, reconcile ones that moved or disappeared

today

The pending layer right now, oldest first — your daily entry point

decide

Judge one or more items: keep / watch / drop

list_layer

See any single layer, paginated (default 50/page), including lapsed ("what did I let go of")

restore

Bring a lapsed item back to pending, clock reset

undo

Revert an item to what it was right before one of its own history events — works for kept/watching too, not just lapsed

stats

Counts per layer, today's decision count, how much is waiting in inbox

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

clean_up_my_bookmarks

First time. Explains the decision-clock mechanism, runs intake, and does one small triage round with you.

daily_triage

Every day after that. today → a suggestion per item → waits for your confirmation → applies it.

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 set BOOKMARKS_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. restore reverses lapsed → pending. undo reverses any state change, including kept and watching, by history event, with a preview mode to check first. If an AI does something you didn't want, the fix is undo, not a promise that it couldn't have happened.

  • history records by: "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

BOOKMARKS_LIFECYCLE_PENDING_HOURS

24

Hours in the pending layer before an undecided item lapses

BOOKMARKS_LIFECYCLE_WATCHING_DAYS

30

Days in the watching layer before an undecided item lapses

BOOKMARKS_LIFECYCLE_DRIP_PER_DAY

15

Max inbox items promoted to pending per day (never accumulates across a gap)

BOOKMARKS_LIFECYCLE_AUTO_DECIDE

false

Whether decide/restore/undo calls claiming actorClaim: "ai" are allowed through (see Honesty about authorization — this is not a security guarantee)

BOOKMARKS_LIFECYCLE_STATE_DIR

~/.bookmarks-lifecycle

Where state.json (and its lock/backup files) live

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 own state.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 tools
decideJudge 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idsYesOne or more item ids, from today/list_layer output. Max 25 per call.
noteNoWhy — stored on the item and in its history, if given (this field is optional; omitting it is fine)
actionYeskeep -> kept, watch -> watching (30d), drop -> lapsed
actorClaimNoAttribution 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

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
sourceNoFilter by browser ("chrome", "safari", "firefox", …) or a source id from bookmarks-mcp's list_sources. Omit for all.

TDQS

A4.4/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
layerYes
limitNo
offsetNo

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idsYesOne or more item ids, from today/list_layer output. Max 25 per call.
actorClaimNoAttribution 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

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
noteNo
filterNoAlternative to eventIds: undo every item's LATEST event matching these criteria
previewNoSee what would be undone without changing anything
eventIdsNoSpecific history event ids to undo
actorClaimNoAttribution 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

A4.7/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

  1. 7 tool updatesv0.2.0
    • First observeddecide
    • First observedintake
    • First observedlist_layer
    • First observedrestore
    • First observedstats
    • First observedtoday
    • First observedundo

TDQS

A4.3/5.0
Disambiguation4/5

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.

Naming Consistency2/5

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.

Tool Count5/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP 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.
    574
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    A 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.
    8
    103
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    A 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

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