{
  "markdown": "# Siftable MCP Server\n\nA [Model Context Protocol](https://modelcontextprotocol.io/) server that exposes Siftable tools to IDE clients like Cursor, Claude Desktop, and VS Code.\n\n## ExecuFunction 0.4.0.0 hosted compatibility\n\nThe npm package is `1.3.0`; the hosted and source projection profile is\n`1.34.0`. Projection 1.34.0 standardizes bounded collection receipts, publishes\ndataset aggregate semantics, and distinguishes OAuth connections that must\nreconnect from sessions that can widen authorization in place. Projection\n1.33.0 recognizes natural-language source-search intent\nand returns the retired capability card with local recovery rather than routing\nthe request to curated code memories. Projection 1.32.0 added an explicit `no_matches` discovery outcome,\nrejects generic-operation and weak-prefix-only capability matches, preserves\ncanonical compound-intent matches, and captures HTTP status classes in failure\nreceipts. Projection 1.31.0 added governed lead-discovery scope requirements.\nProjection 1.29.0 added managed\nwork-lease sessions for hosted clients while keeping claim tokens server-side.\nProjection 1.28.0 added four governed\nlead-discovery tools and five app-equivalent person/organization enrichment tools.\n\nLead discovery is disabled by default. When enabled, it requires separately\ngranted `lead_discovery:read` or `lead_discovery:write` scopes; `mcp:*` does\nnot imply either scope. Hosted baseline catalogs therefore omit company search\nuntil `request_capability` approval and a catalog refresh expose the hosted-capable\ntool. A company search is bounded to one paid Crustdata\nrequest, shows a maximum charge before dispatch, settles the actual provider\ncredits, and saves results only as review candidates. Canonical CRM records\nare created through `lead_discovery_import_plan_create` followed by the\nexisting `crm_import_plan_approve` and `crm_import_plan_apply` review gates.\n\nPerson enrichment returns stored profile and fact proposals. Apply accepts\nonly proposal field names and fact IDs rehydrated from the completed run; it\ndoes not accept free-form replacements and is not retry-safe. Organization\nenrichment remains the app's paid preview-only flow and cannot apply canonical\nCRM changes.\n\n## 1.3.0 compatibility note\n\nVersion 1.3.0 publishes `sift.dataset.query.v2`, versioned aggregate receipts,\nuniform work-item collection metadata, and the `reconnect_required` capability\nstate. Consumers that validate the previous dataset-query receipt should select\nbehavior by `schemaId`.\n\n## 1.2.42 compatibility note\n\nVersion 1.2.42 closes the publication-readiness audit. Natural-language source\nsearch discovery returns the canonical retired/local-only recovery card, while\ncurated code-memory discovery remains distinct. The hosted setup guide now gives\nexact ChatGPT and Codex configuration steps.\n\n## 1.2.41 compatibility note\n\nVersion 1.2.41 closes two hosted audit failures. Dataset routes reject malformed\ndataset UUIDs at the HTTP boundary, and MCP receipts preserve the resulting 400\nas `bad_request`. `find_capability` now requires a direct domain signal plus an\naligned operation; unrelated intent returns `queryOutcome: no_matches` with\nempty capability lanes and rephrase guidance. Exact tool names, removed-tool\ncards, and virtual orientation tools bypass semantic rejection.\n\n## 1.2.40 compatibility note\n\nVersion 1.2.40 addresses the third round of live agent QA (the 2026-08-22\nhosted audit).\n\n- `claimability` is honest about lifecycle and lease state, not only\n  dependencies: `state` is one of `ready`, `waiting`, `dependency_failed`,\n  `leased`, `lease_expired`, `blocked`, `in_review`, `human_review_gate`, or\n  `terminal`, with `claimable`, `reason`, and `nextAction` alongside\n  `blockedBy`. Claimed, running, cancelled, and done work no longer advertise\n  `ready`; `claimable` is the authoritative boolean (a `lease_expired` item\n  and a legacy-converted `blocked` placeholder whose predecessors are\n  satisfied are `claimable: true` because an explicit claim recovers them).\n  Claiming a non-claimable item by ID returns a 409 that names the state\n  (`lease_active`, `work_item_terminal`, …) instead of `not_found`. The CLI\n  and TUI gate on `claimable` when the server provides it.\n- `agent_work_list` and `work_item_list` hide done/failed/cancelled items by\n  default (`includeTerminal: true` or an explicit `status` shows them), print\n  their ordering rule, and document that higher `queueRank` sorts earlier,\n  `0` is the default, and negative ranks are deferred (they sort after 0).\n- `work_item_heartbeat` says that a heartbeat on claimed work starts it\n  (claimed → running, same as `work_item_start`); `resultSummary` passed to\n  start, heartbeat, or release is now persisted instead of silently dropped.\n- `task_get` lists the executable work joined to the task (first ten, with a\n  marker when more exist; \"none yet\" with the `work_item_create` hint when\n  empty) when the connection can read work items; a missing scope keeps the\n  capability hint and an upstream failure is reported as such (single\n  attempt, no retry).\n- `entity_graph` reports each record's own status where it has one (a\n  completed task is `completed`, not `active`; notes/datasets active/archived;\n  connected projects now carry their name and status instead of\n  `[untitled entity]`/`active`) — migration V400 fixes the SQL function that\n  labelled every non-note node `active` and never joined projects. Other node\n  types keep their type-specific label in that slot (organization industry,\n  person relationship, news published date).\n- `note_search` ranks full-text matches (websearch syntax) ahead of semantic\n  neighbours, then literal-substring fallbacks, instead of sorting raw scores on\n  different scales; scores are comparable within a source, not across.\n- `object_find` distinguishes an unknown object type key from a known type\n  with zero records.\n- Code-memory listings label a `confirmed` fact without chunk evidence as\n  `not_recorded (confirmed; no source-chunk evidence recorded)` so the\n  evidence gap is visible without downgrading human-admitted facts.\n\nProjection 1.25.0 keeps hosted OAuth catalogs limited to tools callable with\nthe current token. `find_capability` still discovers tools that need scope\nelevation, and those tools appear after authorization and a catalog refresh.\nThe server initialization guidance is also shorter so clients do not repeat a\nlarge instruction block across tool descriptions.\n\n## 1.2.39 compatibility note\n\nVersion 1.2.39 addresses the second round of live agent QA.\n\n- `work_item_requeue` also returns a claimed/running item whose lease has\n  expired to the queue, without the original claim token; active leases are\n  still never requeued. `work_item_list` labels expired leases inline\n  (`[claimed · lease expired <time>]`), and `work_item_get` prefixes its JSON\n  with a `Lease: expired <time> — …` header saying the item is claimable\n  as-is or requeueable, instead of showing plain `claimed`.\n- `work_item_revision_history` / `work_item_verification_history` say so in a\n  sentence when there is nothing recorded instead of printing `[]`.\n- `object_find` names the object type it searched and points at\n  `schema_introspect` / `people_search` / `organization_search` when nothing\n  matches, instead of a bare \"No objects found.\"\n- `schema_introspect` summarises datasets (title, ID, rows, field count) by\n  default; `includeDatasetFields: true` restores the per-field dump.\n- `dataset_quality_check` counts blank strings as missing values and returns a\n  versioned structured result. Frequently repeated values are observations;\n  they are only quality violations when a field is declared unique.\n\nProjection 1.22.0 records the `schema_introspect` input schema and the tool\ndescription changes.\n\n## 1.2.38 compatibility note\n\nVersion 1.2.38 makes the agent path to work authority direct instead of a\nscavenger hunt (decision 2026-08-20, after live use from Grok and Claude).\n\n- Hosted OAuth first connect (no `scope` parameter, or `scopes_supported`\n  copied by the client) is issued `mcp:* work:read work:write` behind the\n  consent screen. Vault and AI scopes remain step-up/CLI-only.\n- Tools the connection could acquire through step-up are presented on\n  `tools/list`; calling one before approval returns an in-band tool error\n  carrying the same `elevation` link (or CLI/PAT guidance). The HTTP 403\n  `insufficient_scope` challenge is now issued only for `request_capability`\n  in `challenge` mode.\n- Elevation links live for one hour (was ten minutes); after an approval the\n  server publishes `tools/list_changed` so subscribed clients refresh, and the\n  guidance tells the agent to refresh the tool list or restart the connector\n  if the tools are still hidden.\n- `find_capability`, `request_capability`, and `context_current` render a\n  compact text summary (name, availability, next step) instead of the full\n  JSON; the complete projections remain in `structuredContent`.\n- `task_get` and the task tool descriptions no longer claim `work:read` is\n  missing; they point at `work_item_list` with `taskId` and defer to\n  `request_capability` only when the tool is not callable.\n- \"Stable handles\" in generic list text now name the field each ID came from\n  and group repeats, so a `projectId` shared by twenty rows reads as one\n  project reference rather than twenty new records.\n\nProjection 1.21.0 records the presented-tool and description changes.\nReconnect hosted MCP clients after upgrade to refresh the projection 1.21.0\nschemas.\n\n## 1.2.37 compatibility note\n\nVersion 1.2.37 makes scope step-up reachable from the agent's seat on hosted\nOAuth connections instead of depending on the client re-running OAuth.\n\n- `request_capability` (inspect) now returns `elevation` — a short-lived\n  (ten-minute), owner-bound approval link for the connected OAuth token,\n  replayable by the owner within its window — on Streamable HTTP whenever the\n  missing scopes are elevatable (`work:read`, `work:write`) and the server\n  supplied `capabilityAcquisition.createElevationGrant`. The user opens the\n  link, re-authenticates, approves on the first-party consent screen, and the\n  existing token is widened in place; the agent retries the tool without\n  reconnecting. `recommendedNextAction.type` is `open_elevation_url` in that\n  case and `reconnectRequired` is `false`. The reconnect guidance remains the\n  fallback for connections that cannot be elevated.\n- `find_capability`, `context_current`, and direct gated-tool rejections point\n  at that path instead of at a client reconnect.\n- Hosted OAuth now accepts an explicit `work:write` request (consent-gated);\n  in 1.2.37 the authorize default when a client omits `scope` was\n  `mcp:* work:read` and `scopes_supported` advertised only that pair (both\n  widened to the full work family in 1.2.38).\n\nProjection 1.20.0 records the `request_capability` output schema and\ndescription change. Reconnect hosted MCP clients after upgrade to refresh the\nprojection 1.20.0 schemas.\n\n## 1.2.36 compatibility note\n\nVersion 1.2.36 prepares the hosted endpoint for ChatGPT plugin-directory\npublication without changing the stdio tool surface.\n\n- `upload_document` no longer advertises `filePath` on the hosted profile:\n  the hosted schema requires inline `content` and `filename`, and a `filePath`\n  argument is rejected with a normalized `bad_request` failure at the MCP\n  boundary, at `executeTool`, and inside `SiftClient` unless the client was\n  constructed with `allowLocalFiles`. Only the local stdio entrypoint sets\n  that flag; hosted and remote clients can never reach the server's\n  filesystem.\n- Hosted tools now carry OpenAI-only hints under `_meta`, which other MCP\n  clients ignore by specification: `securitySchemes` listing only the scopes\n  the connected OAuth client can actually request (baseline `mcp:*`), and\n  tool-invocation status strings derived from each tool's title.\n- Every catalog tool now publishes an `outputSchema`: the 27 read-only query\n  tools that lacked one declare the `sift.action_receipt` envelope with a\n  `text/plain` result, matching what `tools/call` already returns.\n- Projections and catalog digests are computed from the transport-shaped\n  schema, so hosted `find_capability` and `schemaDigest` describe the tool\n  surface the client is actually presented.\n\nProjection 1.19.0 records the hosted `upload_document` schema and the\nenvelope output schemas. Reconnect hosted MCP clients after upgrade to\nrefresh the projection 1.19.0 schemas.\n\n## 1.2.35 compatibility note\n\nVersion 1.2.35 closes the remaining contract divergences found in the 1.2.32\nreview.\n\n- `schema_introspect` now exposes datasets only when both the deployment-wide\n  dataset switch and the caller's feature grant allow the dataset routes. Its\n  dataset and object-type queries now run with the caller's RLS identity.\n- `code_memory_delete` returned 500 for every memory that had ever existed.\n  `V351` gave the lifecycle event log an `ON DELETE CASCADE` foreign key **and**\n  an append-only trigger that raised unconditionally, so the cascade aborted\n  every delete. `V389` lets the referential cascade through while still refusing\n  a direct edit of the log, repairs two lineage foreign keys that would have\n  nulled a `NOT NULL` owner column, and returns an orphaned predecessor to\n  `needs_review` with an audit event when its successor is deleted.\n- Human admission actions are no longer callable over MCP. `code_memory_confirm`,\n  `code_memory_reject`, `code_memory_edit`, and `code_memory_supersede` are\n  hidden and refused on both hosted and local agent transports. Agents may\n  store candidates or mark facts `needs_review`; a human curates them in the\n  Siftable interface.\n- `project_get_context` reported each task's workflow *phase* in its `status`\n  field and left `phase` null. Both are now the real column values, on open,\n  blocked, and overdue tasks alike.\n\nProjection 1.18.0 records that human-curation boundary and removes four tools\nfrom the presented agent surface.\n\n**This release requires migration `V389__code_memory_delete_cascade.sql`.**\n`code_memory_delete` continues to fail until it is applied.\n\n## 1.2.34 compatibility note\n\nVersion 1.2.34 closes a set of defects where a call succeeded but the answer\nwas wrong or incomplete.\n\n- Writing a person with a `company` returned 500 unconditionally. The\n  organization upsert named a unique index that became partial in V357 without\n  supplying its predicate, so Postgres could not infer the conflict target.\n- Authored content is no longer stripped in transit. The request pipeline ran\n  `striptags()` over every string, which deleted `<` from filter operators,\n  turned `List<String>` into `List`, and removed markup from note titles —\n  silently, and for every MCP call, because the content allowlist only matched\n  top-level body keys. HTML is now escaped where it is rendered instead.\n- A range comparison (`>` `>=` `<` `<=`) against a text-typed column with a\n  numeric value is rejected with the retype path, instead of quietly comparing\n  as text where `'99'` sorts above `'199'`. Sorting such a column returns a\n  warning rather than an unmarked, plausible, wrong order.\n- `dataset_query` now carries `warnings` in its structured result.\n- `task_get` now carries the full task brief structurally — `rationale`,\n  `deliverable`, `verification`, `approachConstraints`, `acceptanceCriteria`,\n  and `scope`. Structured-first clients previously received a task with no\n  definition of done.\n\nReconnect MCP clients after upgrade to refresh the projection 1.18.0 schemas.\n\n## 1.2.33 compatibility note\n\nVersion 1.2.33 repairs hosted OAuth token exchange. The authorization server\nlooked up a hashed authorization code with a `consumed_at IS NULL` filter\nagainst a table that consumes codes by deletion and has no such column, so\nevery fresh Connect from Cursor, Codex, or any other remote client failed with\n`Internal Server Error` after Google consent. Existing authenticated sessions\nwere unaffected. Tool contracts and projection 1.16.0 schemas are unchanged; no\nreconnect is required beyond retrying a login that previously failed.\n\n## 1.2.32 compatibility note\n\nVersion 1.2.32 adds an explicit, metadata-only `repository_project_link` mutation so an agent can persist the project selected from `context_current.projectCandidates`. It also keeps unsupported-client matches in a secondary discovery lane and suppresses zero-score full-text note hits.\n\nReconnect MCP clients after upgrade to refresh the projection 1.16.0 schemas.\n\n## Hosted remote clients\n\nThe recommended hosted endpoint is:\n\n```text\nhttps://siftable.io/api/v1/mcp\n```\n\nClaude remote connectors, Cursor, Codex, Devin, Kimi Code, and Antigravity can\nconnect over Streamable HTTP. Prefer URL-only OAuth configuration: an\nauthorize request that omits `scope` is issued `mcp:* work:read work:write`\nby default behind the first-party consent form, and anything missing later can\nbe approved in place through the one-hour link `request_capability` returns\n(Streamable HTTP only; legacy `/sse` sessions reconnect instead). A\nconfigured Authorization header selects static PAT mode; that token's scopes\ncannot be expanded by an OAuth challenge or an elevation link.\n\nClient configuration keys and callback behavior differ (`url` in Cursor,\nCodex, and Kimi; `serverUrl` in Antigravity; UI-managed connections in Claude\nand Devin). See\n[`docs/runbooks/hosted-mcp-client-compatibility.md`](../../docs/runbooks/hosted-mcp-client-compatibility.md)\nfor the provider-grounded matrix and verification flow.\n\nThe npm package remains the local stdio path for clients that need an\nauthorized checkout or cannot use the hosted endpoint.\n\n## MCP Apps views\n\nSome tools can render in a sandboxed View in hosts that implement the MCP\nApps extension (Claude, ChatGPT, VS Code, Goose). Those tools carry\n`_meta.ui.resourceUri` pointing at a `ui://siftable/<view>.html` resource,\nlisted by `resources/list` and served by `resources/read` with the MIME type\n`text/html;profile=mcp-app`. The metadata is presentation only: it never\nchanges a tool's projection, scopes, presented catalog, or catalog digest,\nand `content` stays a complete text answer for every other client.\n\nUI metadata is attached only when the View bundle exists in `dist/ui/`. A\nbuild without bundles presents no UI metadata at all. The reviewed tool to\nView allowlist lives in `src/ui/viewRegistry.ts`; the design is in\n[`docs/design/mcp-ui-surfaces-plan.md`](../../docs/design/mcp-ui-surfaces-plan.md).\n\nThe bundles are built by the `@siftable/mcp-apps` workspace\n(`packages/exf-mcp-apps`, one self-contained HTML file per View) and copied\ninto `dist/ui/` by `scripts/copy-ui-bundles.mjs` at the end of `npm run\nbuild`. Through Nx the apps workspace builds first\n(`nx run @siftable/mcp-server:build`). A plain `npm run build` without an\napps build, which is what the hosted Docker image does today, copies nothing\nand stays inert. `verify:package`, `prepublishOnly`, and `pack:mcpb` build\nthe apps first and fail if a bundle is missing, so a published tarball or\n`.mcpb` always carries every View bundle (`dist/ui/graph.html`, `data.html`,\n`review.html`).\n\nViews available today:\n\n| View | Resource | Tools |\n| --- | --- | --- |\n| Graph | `ui://siftable/graph.html` | `entity_graph`, `object_links` |\n| Data | `ui://siftable/data.html` | `dataset_query`, `dataset_aggregate`, `dataset_summarize`, `dataset_quality_check`, `dataset_facets`, `dataset_compare`, `dataset_rank`, `dataset_plot_result`, `dataset_timeseries`, `dataset_bucket`, `people_search`, `organization_search`, `task_list` |\n| Review | `ui://siftable/review.html` | `lead_discovery_candidate_list`, `lead_discovery_run_get`, `crm_import_plan_get`, `crm_import_plan_create` |\n\n## Human gate on consequential tools\n\nSeven tools ask the human to confirm before they run: the four bulk deletes\non their apply call (`confirm: true` with a `previewId`; previews and dry runs\nnever prompt), `dataset_schema_modify` when it deletes a field,\n`crm_import_plan_approve`, and `lead_discovery_company_run`, whose prompt\nstates the approved ceiling in USD. The question travels as an MCP 2026-07-28\nmulti-round-trip `InputRequiredResult` carrying one form elicitation with a\nsingle `confirm` boolean; the client shows it, then retries the same call with\n`inputResponses`. On 2025-era sessions that have a backchannel (stdio or\nsessionful HTTP) the SDK's legacy shim sends the same prompt as an\n`elicitation/create` request. On the stateless 2025 HTTP fallback no client\ncapabilities are known per request, so the gate is not asked.\n\nA client that declares no elicitation capability runs the tool as before.\nEvery gated receipt, whether it succeeded, failed, or was rejected, records\nthe gate under `humanGate`: `elicitation` with `accepted`, or\n`unsupported_fallback` with `not_asked`, on receipts where the tool ran; and\n`elicitation` with the exact refusal, `declined`, `cancelled`, or\n`not_confirmed`, on the rejected receipt (`error.code: \"declined_by_user\"`)\nwhere nothing ran. The gate is a human-in-the-loop guarantee for honest\nhosts; OAuth scopes remain the authorization boundary. The seeded tool list is\nin `src/registry/mcpToolContractSeed.ts` and the wording in\n`src/humanGate.ts`.\n\n## 1.2.31 compatibility note\n\nThis release keeps task collection totals stable across cursor pages, resolves\nrepository context through durable identities under transaction-scoped RLS,\nand returns explicit project candidates instead of auto-linking repositories by\nname. Project resources now paginate with opaque cursors and surface backend\nfailures, while graph and people results provide usable canonical labels.\nReconnect MCP clients after upgrade to refresh the projection 1.15.0 schemas.\n\n## 1.2.30 compatibility note\n\nThis release requires caller-stable idempotency keys for agent creation, work\nclaims and lifecycle transitions, code-memory writes, document uploads, Vault\nentry creation, and governed approval, execution-grant, and materialization\nrequests. Same-key retries replay the original authoritative response; changed\npayloads conflict. Vault receipts retain metadata or runner-encrypted ciphertext,\nnever plaintext. `ai_generate` remains explicitly non-retry-safe because streamed\nprovider output is not persisted for replay. Reconnect MCP clients after upgrade\nto refresh the projection 1.14.0 schemas.\n\n## 1.2.29 compatibility note\n\nThis release makes hosted capability inspection terminal and reconnect-safe,\nadds task-state and governed-approval invariants, and puts stable IDs and typed\ndetails into project, task, dataset, schema, people, organization, and calendar\nresults. Retired source-index/search names route to local checkout search while\ncurated code memories remain available. The `dataset_create`,\n`dataset_mutate`, `dataset_schema_modify`, and `dataset_materialize_result`\ntools require a caller-stable `idempotencyKey`.\nReusing the same key with the same payload replays the original result; reusing\nit with a changed payload is rejected. Existing MCP sessions must reconnect to\nrefresh their cached tool schemas before invoking these mutations. Direct REST\ncallers remain backward compatible when the `Idempotency-Key` header is omitted.\n\n## Privacy Policy\n\nThe server sends tool calls to the Siftable API at the configured\n`SIFT_API_URL` (by default `https://siftable.io`) and to nothing else. It\nstores no data locally beyond the environment it is started with, and the\npersonal access token is only ever sent to that API. Siftable's privacy\npolicy, covering collection, use, storage, sharing, retention, and contact\ndetails, is at <https://siftable.io/privacy.html>.\n\n## Distribution artifacts\n\n`@siftable/mcp-server` is published from the monorepo; the public source\nmirror at <https://github.com/execufunction-mcp/mcp-server> is refreshed with\n`scripts/mirror-mcp-server.sh` and cannot build on its own.\n\n| Artifact | Command | Where it goes |\n| --- | --- | --- |\n| npm package | `npm publish --workspace @siftable/mcp-server` | `npx @siftable/mcp-server` for stdio clients |\n| Claude Desktop extension | `npm run pack:mcpb --workspace @siftable/mcp-server` | `build/siftable.mcpb`; attach to the GitHub release and submit through the desktop-extension form |\n| MCP Registry entry | `npm run publish:registry --workspace @siftable/mcp-server` after `mcp-publisher login github` | `io.github.Tom-R-Main/mcp-server`, which points at the npm package |\n\n`manifest.json` is the desktop-extension manifest; its `version` must match\n`package.json` and the bundle build asserts it. The bundle carries its own\nproduction `node_modules`, so it runs without the monorepo.\n\n## Quick Start\n\n### 1. Create a Personal Access Token\n\n1. Go to Siftable → Settings → Developer → Access Tokens\n2. Click \"Create Token\"\n3. Name it (e.g., \"Cursor MCP\")\n4. Select `mcp:*` for baseline MCP access, then add the specific scope families\n   your workflows need (for example `projects:read`, `tasks:write`, or\n   `work:read`). `mcp:*` is not universal authorization.\n5. **Save the token immediately** - it's only shown once!\n\n### 2. Configure Your MCP Client\n\n#### Claude Desktop\n\nEdit `~/Library/Application Support/Claude/claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"siftable\": {\n      \"command\": \"npx\",\n      \"args\": [\"@siftable/mcp-server\"],\n      \"env\": {\n        \"SIFT_API_URL\": \"https://siftable.io\",\n        \"SIFT_PAT\": \"sift_pat_your_token_here\"\n      }\n    }\n  }\n}\n```\n\n#### Cursor\n\nAdd to your Cursor MCP settings:\n\n```json\n{\n  \"siftable\": {\n    \"command\": \"npx\",\n    \"args\": [\"@siftable/mcp-server\"],\n    \"env\": {\n      \"SIFT_API_URL\": \"https://siftable.io\",\n      \"SIFT_PAT\": \"sift_pat_your_token_here\"\n    }\n  }\n}\n```\n\n#### VS Code\n\nConfigure in your MCP extension settings.\n\n### 3. Restart Your IDE\n\nAfter configuration, restart your IDE to load the MCP server.\n\n## Available Tools\n\n### Orientation and capability acquisition\n\nStart every new client session with `context_current`. It reports the effective\nworkspace, project, repository, transport, presented/effective scopes, missing\nrequestable scopes, and recommended next calls. Hosted MCP returns a null\ncheckout plus a reason unless the client explicitly provides a root hint.\n\nUse `find_capability` as the discovery entry point when a tool is absent or an\noperation is unauthorized. Call `request_capability` in `inspect` mode to get a\nstructured recovery plan without triggering an authorization challenge; use\n`challenge` mode only when the client can render the standards-compliant OAuth\naction from the HTTP 403 response.\n\nWhen no candidate meets the discovery confidence contract, `find_capability`\nreturns `queryOutcome: no_matches`, zero counts, and empty lanes. Rephrase with\nboth a Siftable domain and operation, or inspect `tools/list`; do not treat a\nzero-result response as authorization evidence.\n\n`task_*` manages human planning. `work_*` manages executable agent work. Prefer\nthe stable IDs returned by collection and mutation results in follow-on calls.\n\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `context_current` | Resolve principal, owner, project, repository, checkout, and effective capability context | No |\n| `find_capability` | Discover callable, missing, requestable, and unsupported capabilities | No |\n| `request_capability` | Inspect recovery or request an OAuth authorization challenge | No |\n\n### Projects\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `project_list` | List projects with status filtering, bounded cursor pagination, stable IDs, and compact summaries | No |\n| `project_create` | Create a new project | Yes |\n| `project_update` | Update project name, summary, status, emoji | Yes |\n| `project_archive` | Archive a project (destructive) | Yes |\n| `project_get_context` | Get full project context (tasks, notes, signals) | No |\n\n### Tasks\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `task_list` | List human planning tasks with project/status/phase/effort/title filters | No |\n| `task_get` | Get a single human planning task with full details | No |\n| `task_create` | Create a human planning task with priority, phase, effort, acceptance criteria | Yes |\n| `task_update` | Update human planning task fields (title, status, priority, phase, effort, scope) | Yes |\n| `task_delete` | Delete a task (destructive) | Yes |\n| `task_bulk_delete` | Preview or bulk delete tasks by IDs or filter | Yes |\n| `task_complete` | Mark a task as complete | Yes |\n\n### Agents\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `agent_list` | List user-visible agent aliases and capabilities | No |\n| `agent_get` | Get an agent alias by slug or ID | No |\n| `agent_create` | Create an agent alias | Yes |\n| `agent_update` | Update alias metadata, capabilities, or permissions | Yes |\n| `agent_disable` | Disable an alias without deleting history | Yes |\n| `agent_work_list` | List executable work assigned to an alias | No |\n\n### Work Items\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `work_item_list` | List work items with authoritative dependency claimability | No |\n| `work_item_get` | Get work details, dependencies, satisfaction, and claimability | No |\n| `work_item_create` | Create bounded work with optional UUID `dependsOn` edges | Yes |\n| `work_item_dependencies_replace` | Atomically replace a work item's UUID dependencies | Yes |\n| `work_item_claim` | Claim queued executable work with a lease | Yes |\n| `work_dependency_policy_get` | Get a project's default dependency gate | No |\n| `work_dependency_policy_update` | Set a project's default dependency gate | Yes |\n| `work_item_start` | Mark claimed work running | Yes |\n| `work_item_heartbeat` | Extend a lease | Yes |\n| `work_item_block` | Mark work blocked | Yes |\n| `work_item_review` | Mark work as needing review | Yes |\n| `work_item_complete` | Complete work with summary/artifacts | Yes |\n| `work_item_fail` | Mark work failed | Yes |\n| `work_item_release` | Release work back to the queue | Yes |\n| `work_item_cancel` | Cancel work | Yes |\n\n### Knowledge / Notes\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `note_list` | List notes with type, project, archive, and title filters | No |\n| `note_get` | Get a single note with full content | No |\n| `note_search` | Semantic search across knowledge base | No |\n| `note_create` | Create a new note (markdown) | Yes |\n| `note_update` | Update note title, content, or type | Yes |\n| `note_delete` | Delete a note (destructive) | Yes |\n| `note_bulk_delete` | Preview or bulk delete notes by IDs or filter | Yes |\n\n### People\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `people_search` | Search contacts with fuzzy or exact/prefix filters | No |\n| `person_create` | Create a contact | Yes |\n| `person_update` | Update a contact | Yes |\n| `person_delete` | Delete a contact (destructive) | Yes |\n| `people_bulk_delete` | Preview or bulk delete contacts by IDs or filter | Yes |\n| `person_enrichment_availability` | Check identity readiness and current app prices without dispatching providers | No |\n| `person_enrichment_run` | Run paid, idempotent app-equivalent enrichment and return stored proposals and billing evidence | Yes |\n| `person_enrichment_apply` | Apply selected stored profile fields and facts from a settled run; not retry-safe | Yes |\n\n### Organizations\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `organization_search` | Search organizations with fuzzy or exact/prefix filters | No |\n| `organization_create` | Create an organization | Yes |\n| `organization_update` | Update an organization | Yes |\n| `organization_delete` | Delete an organization (destructive) | Yes |\n| `organization_bulk_delete` | Preview or bulk delete organizations by IDs or filter | Yes |\n| `organization_enrichment_availability` | Check provider availability and current app prices without dispatching providers | No |\n| `organization_enrichment_preview` | Run the paid, idempotent app preview and save evidence without canonical CRM writes | Yes |\n\n### Lead Discovery\n\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `lead_discovery_company_search` | Run one bounded paid company search and stage source-backed review candidates | Yes |\n| `lead_discovery_candidate_list` | List candidates and their CRM match/review state | No |\n| `lead_discovery_candidate_review` | Shortlist or reject one candidate with a recorded reason | Yes |\n| `lead_discovery_import_plan_create` | Create a durable CRM import plan from shortlisted candidates; approval and apply remain separate | Yes |\n\nSee [Headless CRM import plans](../../docs/crm/headless-import-plans.md) for the\napproval and apply lifecycle shared by CLI and MCP.\n\n### Calendar\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `calendar_list_events` | List calendar events for a date range | No |\n| `calendar_create_event` | Create a new calendar event | Yes |\n| `calendar_update_event` | Update a calendar event | Yes |\n| `calendar_delete_event` | Delete a calendar event (destructive) | Yes |\n\n### Local Source Context\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `git_blame_symbol` | Run git blame on a local file range | No |\n\nSource inspection and search stay local to an authorized checkout through Git,\n`rg`, the editor, or agent-native tools. Siftable stores curated code memories;\nit does not index or semantically search repository source.\n\n### Code Memories\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `code_memory_store` | Store a curated code fact | Yes |\n| `code_memory_search` | Search stored code facts | No |\n| `code_memory_list` | List all stored code memories | No |\n| `code_memory_delete` | Delete a code memory (destructive) | Yes |\n\n### Vault / Secrets\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `vault_list` | List vault entries (metadata only) | No |\n| `vault_create` | Store a new encrypted secret | Yes |\n| `vault_update` | Update vault entry metadata | Yes |\n| `vault_search` | Search vault entries by name/description | No |\n| `vault_audit` | Inspect the Vault audit trail | No |\n| `vault_materialization_request` | Request approval for one exact materialization destination | Yes |\n| `vault_materialization_status` | Check materialization status without returning secret bytes | No |\n| `capability_list` | List governed Vault execution capabilities | No |\n| `capability_describe` | Describe a governed Vault execution capability | No |\n| `capability_execute` | Execute a governed capability without exposing secret bytes | Yes |\n\n`vault_read` is retired. MCP never returns plaintext secret bytes; use a governed capability or an explicitly approved materialization instead.\n\n### Entity Graph\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `entity_graph` | Traverse the entity relationship graph | No |\n| `schema_introspect` | Discover the full data model and entity types | No |\n\n### Document Upload\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `upload_document` | Upload a PDF, Markdown, or text file into Knowledge | Yes |\n\n### Datasets (feature flag: `DATASETS_ENABLED=true`)\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `dataset_list` | List datasets | No |\n| `dataset_create` | Create a dataset | Yes |\n| `dataset_query` | Query records by filters/sorts | No |\n| `dataset_mutate` | Create/update/delete records (destructive) | Yes |\n| `dataset_schema_modify` | Add/update/delete fields (destructive) | Yes |\n| `dataset_summarize` | Summarize schema and sample rows | No |\n| `dataset_facets` | Value distributions for fields | No |\n| `dataset_quality_check` | Missing-value metrics, invalid values, uniqueness issues, repeated-value observations | No |\n| `dataset_aggregate` | Grouped metrics (count, avg, sum, etc.) | No |\n| `dataset_bucket` | Bucket numeric/date fields into ranges | No |\n| `dataset_rank` | Rank records by sorts or weighted formula | No |\n| `dataset_analyze` | Generate natural-language insights | No |\n| `dataset_compare` | Compare metrics across segments | No |\n| `dataset_export` | Export records as CSV | No |\n| `dataset_join_rows` | Self-join with alias-scoped fields | No |\n| `dataset_compute_fields` | Compute derived columns (lag, diff, rolling) | No |\n| `dataset_timeseries` | Time series analysis with transforms | No |\n| `dataset_materialize_result` | Save derived result as a new dataset | Yes |\n| `dataset_plot_result` | Validate chart payload from derived result | No |\n\n### Ontology (feature flag: `DATASET_ONTOLOGY_ENABLED=true`)\n| Tool | Description | Mutates |\n|------|-------------|---------|\n| `object_find` | Find objects by type and property filters | No |\n| `object_links` | Traverse graph links for an object | No |\n| `object_action_run` | Run a declarative action on an object (destructive) | Yes |\n\n## Usage Examples\n\n### 1. Get project context and create a task\n\n**User prompt:** \"Get context for my auth project and create a task to fix the token refresh bug\"\n\n**Tools invoked:**\n1. `project_list` — Lists projects to find the auth project\n2. `project_get_context` — Retrieves tasks, notes, and signals for the project\n3. `task_create` — Creates a human planning task with title, description, and project linkage\n\n**Result:** The AI reads existing project context (open tasks, recent notes) to avoid duplicates, then creates a well-scoped task linked to the correct project.\n\nTo run an agent, create a linked executable work item with `work_item_create` and set `taskId` to the parent human task. Task tools should track planning state; work item tools should track execution, leases, artifacts, verification, and review state.\n\nDependencies are authoritative UUID references. Pass `dependsOn` as an array of `{ workItemId, requiredGate? }`, where `requiredGate` is `done` or `commands_passed`. An omitted gate resolves through the project's work-dependency policy. List and get results expose the resolved `dependencies` projection and derived `claimability` (`ready`, `waiting`, or `dependency_failed`). Replace the complete edge set with `work_item_dependencies_replace`; use an empty array to remove every dependency. Historical `verified` gates are normalized to `commands_passed` during the verifier-retirement migration.\n\nLease-owned lifecycle calls (`start`, `heartbeat`, `block`, `review`, and `fail`) require both the `claimOwner` and `claimToken` returned by `work_item_claim`; `release` requires the active token. `complete` accepts credentials for lease-owned completion but leaves them optional so a human can resolve `needs_review` without a lease. `cancel` is likewise tokenless. Claim tokens remain omitted from get/list output and should not be logged or persisted by clients.\n\n### 2. Knowledge search and note creation\n\n**User prompt:** \"Search for our deployment process and create a note summarizing the steps\"\n\n**Tools invoked:**\n1. `note_search` — Searches the knowledge base for \"deployment process\"\n2. `code_memory_search` — Searches stored code facts for deployment-related memories\n3. `note_create` — Creates a new note with a markdown summary of the deployment steps\n\n**Result:** The AI synthesizes information from existing notes and code memories into a single reference note, linked to the relevant project.\n\n## Resources\n\nThe server also exposes project context bundles as MCP resources:\n\n- `exf://projects/{id}/context` - Full context bundle for a project\n\n## Environment Variables\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `SIFT_API_URL` | Yes | Siftable API URL |\n| `SIFT_PAT` | Yes | Personal Access Token |\n\nLegacy `EXF_API_URL` and `EXF_PAT` remain supported for existing MCP configs.\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Run in development mode\nnpm run dev\n\n# Test with MCP Inspector\nnpm run inspect\n\n# Build for production\nnpm run build\n```\n\n## Security\n\n- PATs are stored as SHA-256 hashes - plaintext is never stored\n- Tokens can be revoked at any time from Siftable Settings\n- Use minimal scopes for your use case\n- Never commit tokens to version control\n\n## Scopes\n\n| Scope | Description |\n|-------|-------------|\n| `mcp:*` | Core project, task, calendar, knowledge, and people operations |\n| `projects:read` | Read project data |\n| `projects:write` | Create/update projects |\n| `tasks:read` | Read tasks |\n| `tasks:write` | Create/update/complete tasks |\n| `knowledge:read` | Search/read notes |\n| `knowledge:write` | Create notes |\n| `calendar:read` | View calendar/free slots |\n| `calendar:write` | Create calendar events |\n| `people:read` | Search/view contacts |\n| `people:write` | Create/update contacts |\n| `work:read` | Read executable work queues |\n| `work:write` | Mutate executable work queues |\n| `lead_discovery:read` | Read lead-discovery runs and candidates |\n| `lead_discovery:write` | Dispatch paid searches and review/import candidates |\n| `vault:metadata:read` | Read Vault metadata and materialization status |\n| `vault:manage` | Create/update Vault metadata and request materializations |\n| `vault:audit:read` | Read the Vault audit trail |\n\n## Troubleshooting\n\n### \"SIFT_API_URL environment variable is required\"\n\nMake sure you've configured the `env` section in your MCP client config.\n\n### \"Invalid token\"\n\n1. Check that your token starts with `sift_pat_` or legacy `exf_pat_`\n2. Verify the token hasn't been revoked\n3. Check the token hasn't expired\n\n### Tools not appearing\n\n1. Restart your IDE after configuration changes\n2. Check IDE logs for MCP errors\n3. Try running `npm run inspect` to test the server directly\n\n## License\n\nMIT\n",
  "bytes": 41796,
  "sha": "da4184cfbefad63033350771cd6fde8912f1d8a29be1a081df2444073208c6d2",
  "repo_slug": "execufunction-mcp/mcp-server",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_tom_r_main_mcp_server_7e0daf1a/readme"
}