Skip to main content
Glama

watch

Destructive

Starts and manages leases on tracked Figma scopes, follows revisions or saved searches, and acknowledges change checkpoints so agents can read updates without an index call.

Instructions

Watching tracked scopes and change-tracking consumers. start: this server holds a lease on tracked scope of one source (sourceId when the workspace has several) and the workspace's shared runner refreshes it on each save, so changes shows new revisions without an index call; the server renews its leases every 10 s and ends them when it exits, and an unrenewed lease ends after 30 s. A requestId replays this server's live lease and reports an ended one as ended (untracked when its scope was untracked or retracked since), never restarting it, for 1 h after the end among the newest 1024 ended leases; past that it is unknown and starts a new lease. A requestId of a lease another running process holds is refused. stop ends one lease this server holds (leaseId). status lists the workspace's leases and runner, read-only. ack moves consumer's checkpoint for these filters (sourceId, scope), or a subscription's own (subscriptionId), forward to cursor, the nextCursor of the last changes page it handled with the same filters; an older or equal cursor normally leaves it, so a retry is safe. A cursor issued before retention deleted revisions it had not passed is event_gap, writing nothing: follow its recovery. A current recovery cursor before a checkpoint that is behind such a deletion moves the checkpoint back to it, so the kept revisions replay. Replies with advanced, true only when the checkpoint moved forward, and the checkpoint now held, which is authoritative. subscribe follows one source, scope or exact node (node: a layer id that must name one layer kind in the published index, else target_missing or identity_uncertain, never a same-name layer) from its newest visible revision; a repeat returns the same subscription; owner marks it temporary for that task. subscribe with query (and type) saves a workspace search of one source's scope (default 0:0) and stores its first evaluation of the top 50; evaluate stores a newer one after a publication, and a watch lease on that scope makes its runner store it unasked; changes with its subscriptionId reads the stored evaluations (causes such as source_changed only for new file bytes or index_rebuilt; enteredTopK and leftTopK are exact sourceId/snapshotId/nodeId refs in the new and old snapshot, rankChanged the new snapshot's refs with from and to positions, null when rankComparable is false, all within the top-50 window, not the whole result set; nodes compare by sourceId, which relocate keeps; total only when the search counted every hit) and reports evaluation pending with an evaluate step, never computing one; an evaluation past 128 KiB is unavailable evaluation_too_large, nothing stored. sources (instead of sourceId) saves the search, or a library question (library), over a fixed set: visible resolves once to the sources this caller sees now, or a comma-separated list, at most 10, returned sorted in subscription.sources; it never gains a source added later. A member's publication evaluates it (its runner too); causes source_changed names members with new bytes in delta.changedSourceIds, corpus_changed a member's relocation or publication, or for a ranked search of several members their shared statistics; refs carry their sourceId and snapshot. A library question lists up to 50 uses with definitionMatch against the definition, followed by its exact nodeId in its source's current snapshot (delta.definitionMatchChanged); coverage.transitive is not_followed: a definition's own library dependencies are never traversed, and delta.notFollowedSourceIds names changed members that hold no use and are not the definition's source, whose dependent uses may be stale. A caller who cannot see every member reads the subscription as unknown; removing a member source disables it (state disabled, disabled.reason source_removed, evaluations deleted; a damaged stored set reads disabled with sources_unreadable): unsubscribe, then subscribe again. list pages the visible subscriptions with their state (subscriptionId: only that one, empty when unknown to the caller). unsubscribe removes one subscription and its checkpoint (or, with owner, that owner's temporary ones); forget removes a consumer's raw checkpoint views. Neither untracks or deletes history. A consumer holds at most 64 subscriptions and checkpoints, a workspace 4096: past that, workspace_busy names list, unsubscribe and forget; nothing is evicted.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "action": "<action>",
      "workspaceId": "<workspaceId>"
    },
    "name": "watch"
  }
}

Input Schema

NameRequiredDescriptionDefault
nodeNosubscribe: follow this exact layer
typeNosubscribe with query: only these node types, comma-separated, as search takes them
afterNolist: the next of the previous page
ownerNosubscribe: a task-owned temporary subscription; unsubscribe (with consumer): remove that owner's temporary ones
queryNosubscribe: save this workspace search of the scope instead of following revisions
scopeNostart: the tracked scope to watch; ack: the scope filter of that changes call; subscribe: only this scope; forget: only its views
actionYesstart, stop, status, ack, subscribe, evaluate, list, unsubscribe or forget
cursorNoack: nextCursor from changes with the same filters
leaseIdNostop: the lease to end
libraryNosubscribe: save this library question over sources (or sourceId) instead of a search: {kind, namespace, key} and optional definition {sourceId, snapshotId, nodeId}, an exact ref to the definition's current published snapshot in one of the sources
sourcesNosubscribe with query or library, instead of sourceId: a fixed set, visible (the sources you see now) or comma-separated sourceIds, at most 10
storageNoabsolute custom storage directory, only for a workspace kept outside the default storage; must be under the server's --storage-root
consumerNothe consumer's name, 1-128 bytes: ack without subscriptionId, subscribe and forget need it; list narrows to it
sourceIdNostart: the source to watch; ack: the sourceId filter of that changes call; subscribe: the source to follow; forget: only its views; evaluate takes none (it evaluates the subscription's own source)
requestIdNostart: replays this request's lease
workspaceIdYesws_... from the index tool
subscriptionIdNoack, evaluate or unsubscribe this subscription; list reads only it

Output Schema

NameRequiredDescriptionDefault
nextNolist: pass as after for the next page
scopeNostart: the leased scope
stateNostart, stop: active, or ended with a reason
leasesNostatus: leaseId, sourceId, scope, state (active, unauthorized, untracked, expired or ended, with reason), expiresAtMs, mine; live leases first, then the newest ended ones
reasonNostart, stop: why an ended lease ended (stopped, released, expired, start_failed, reset, source_removed)
runnerNostart, status: the workspace's runner: state running, stopping, stopped or unknown; placement independent, or in_host_job when a Windows job object kept it inside the host and it ends with that job
createdNosubscribe: false when the same subscription already existed
leaseIdNostart, stop: the lease
removedNounsubscribe, forget: rows removed
advancedNoack: true only when the visible checkpoint moved forward
consumerNo
sourceIdNostart: the leased source
trackingNosubscribe: the followed scopes' tracking state
truncatedNostatus: true when older ended leases are left out
checkpointNoack, subscribe: a cursor at the checkpoint now held; null when retention deleted that revision
evaluationNosubscribe with query or library, evaluate: state evaluated (evaluationId, causes, delta), current, pending (reason, nextSteps), unavailable (reason such as query_changed, search_failed or evaluation_too_large, nextSteps) or disabled (nextSteps)
expiresAtMsNostart: when the lease ends unless renewed
workspaceIdYes
renewEveryMsNostart: how often the holder renews; MCP renews for you
subscriptionNosubscribe: subscriptionId, consumer, sourceId (null for a set), sources, scope, kind (source, scope, node or query), node, nodeKind, query, types, library, definition, topK, state (active, target_missing, identity_uncertain or disabled), disabled, lifetime (durable or temporary), filterVersion
subscriptionsNolist: one page, as subscription
subscriptionIdNoack of a subscription
initialPositionNosubscribe: tail (the newest revision it can see), initial_evaluation (a query, before its first evaluation) or existing
subscriptionIdsNounsubscribe: the removed subscriptions' ids
keptUnknownOwnershipNoforget: views written before their sources were recorded, kept because this caller does not see every source

Schema Changelog

Changes observed during successful MCP inspections.

  1. Addedv0.11.3

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the destructiveHint/readOnlyHint annotations, the description discloses lease renewal every 10 s with a 30 s expiry, the requestId replay window (1 h / newest 1024 ended leases), refusal when another process holds the lease, retry safety of ack with an older or equal cursor, event_gap and recovery semantics that can move a checkpoint backward, the 50-entry library cap and not_followed coverage caveat, capacity limits (64 per consumer, 4096 per workspace) with workspace_busy naming the affected actions, and explicitly states unsubscribe 'Neither untracks or deletes history'. This is unusually complete behavioral disclosure for a mutating, stateful tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The entire definition is one enormous paragraph of semicolon-chained clauses with no per-action headings or line breaks, so the highest-value facts (lease TTL, requestId replay, capacity limits) are buried mid-stream. Almost every sentence carries useful content, but the lack of structure makes the description hard to scan and directly costs retrieval accuracy.

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 nine-action, seventeen-parameter stateful tool, the description covers every action's inputs, its error and edge states (target_missing, identity_uncertain, evaluation_too_large, sources_unreadable, workspace_busy), the limits, and the recovery path for event_gap. With an output schema present, it correctly leaves return-value shapes to the schema and focuses on semantics.

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 100%, so baseline is 3; the description adds genuine meaning on top, e.g. cursor must be the nextCursor from changes with matching filters and older cursors are no-ops, requestId replays a live lease and reports an ended one as ended, sources resolves 'visible' once and never gains later sources, node must name exactly one layer kind in the published index. It does not repeat schema text and clarifies cross-parameter relationships the schema cannot express.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening clause names the domain (watching tracked scopes and change-tracking consumers) and each of the nine actions gets a specific account of what it does (start holds a lease, ack advances a checkpoint, subscribe follows revisions or saves a search). It is clearly distinct from siblings like `changes` and `index`, both of which it references. It falls short of 5 only because there is no single front-loaded sentence stating the tool's overall job.

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?

Substantial routing guidance is embedded per action: ack exists because 'changes shows new revisions without an index call' when a lease is live, evaluate is for storing a newer evaluation, changes with subscriptionId reads stored evaluations and 'never computes one'. That gives the agent real alternatives and selection conditions. The guidance is not structured as when/when-not blocks, so an agent must reconstruct the decision tree from dense prose.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.