MCP server

Add DeepSieve to Claude Code or any MCP client — browser login, or a scoped API key

The MCP server gives any MCP client outcome-shaped tools over the DeepSieve API. There are two ways to connect, and for a human at their editor the first is easier — no key to create, copy, or store.

Easiest of all: let your agent configure itself — paste Set up DeepSieve by following the instructions here: https://deepsieve.ai/setup.md into it and skip this page. See the Quickstart.

bash
claude mcp add --transport http deepsieve https://deepsieve.ai/mcp

Your client opens a browser, you sign in with the DeepSieve account you already have, and the client keeps the resulting short-lived token itself, so no key lands in a config file. This is OAuth 2.1 under the MCP authorization spec, with DeepSieve's own login screen doing the sign-in.

The sign-in page may show a yellow warning that the redirect points to an unverified application running on your machine. That is expected: clients like Claude Code receive the sign-in on your own computer, and the MCP specification asks sign-in pages to point that out. Check that the application origin is your client's own site (https://claude.ai for Claude Code), then allow access.

Verified with Claude Code. Other clients that connect to remote MCP servers over OAuth (Cursor, VS Code / Copilot, Codex) take the same --transport http shape but are not yet verified here. If one can't complete the sign-in, use the API-key path below.

Requires a DeepSieve deployment with MCP OAuth configured. On a deployment that hasn't enabled it, use the API-key path below.

What a browser-login session can do

Every browser-login session gets the same fixed set of permissions. The sign-in screen doesn't offer a narrower one.

  • It can: start and cancel research (which spends prepaid credits), read runs, read cited data and exports, read and write reports, ask the research agent, read Blueprints, create a new Blueprint and propose changes to one, and read webhooks and teammates. For a member or above (never a viewer) it can also change stored data the way the app does: for example, undo a change, merge duplicate rows, settle cells a person set, or confirm and revert a chat change. And it can write down your domain knowledge (what your team knows about the field) for later runs to carry, which changes no stored value.
  • It can't: apply a change to your active Blueprint (that stays with a person, in the app), create or manage API keys, start or change a charge, or do anything else admin. The one billing action it has is cancelling the subscription at the end of the period, for an admin only, because that stops spend (see cancel_subscription below).

Your own role in the organization still applies on top. For a narrower grant, such as read-only, use an API key with that preset on the stdio path below.

To disconnect every agent at once, use Sign out everywhere in Settings. Signing out of the browser alone leaves your agents connected.

CI, containers, and other headless environments

No browser? Use the stdio server with a scoped API key — the right choice for pipelines and services, where OAuth's browser step can't run.

Installs from PyPI (uvx deepsieve-mcp, no repo checkout). Create a key at Settings → API keys with the Agent preset — it runs research and reads results but can't touch your schema or billing.

Claude Code

bash
claude mcp add deepsieve \
  --env DEEPSIEVE_API_KEY=ds_live_... \
  --env DEEPSIEVE_API_URL=$BASE_URL \
  -- uvx deepsieve-mcp

Cursor / Claude Desktop (manual JSON)

json
{
  "mcpServers": {
    "deepsieve": {
      "command": "uvx",
      "args": ["deepsieve-mcp"],
      "env": {"DEEPSIEVE_API_KEY": "ds_live_...",
              "DEEPSIEVE_API_URL": "https://deepsieve.ai"}
    }
  }
}

DEEPSIEVE_API_URL defaults to http://localhost:8200 (local dev stack).

What the tools cover

The tools are outcome-shaped rather than one-per-endpoint, and their docstrings tell the agent what each returns. In outline:

  • Subscription — cancel_subscription (at period end; nothing new is charged, except a first charge already in flight), only when your human asked. It answers with get_account's subscription block. There is no resume tool, on purpose: resuming re-arms a charge, so no MCP session can do it. Send your human (an admin) to the billing page ({app_url}/billing), or they can use an API key with billing:write (POST /v1/subscription/resume, deepsieve subscription resume).
  • Orientation — get_account, list_blueprints, get_blueprint. Entity keys and column names come from get_blueprint; the other tools take the same blueprint_id, so an agent never guesses a key. start_research and estimate_research require it.
  • Research — estimate_research prices a run before anything is spent; start_research, get_run_status, list_runs, cancel_run drive it. list_monitoring shows every monitored report: what it costs past its free 30 days, which reports duplicate each other's monitoring (duplicated_units, the number to act on), and how much included re-research is left this billing period. set_monitoring turns a report's monitoring on or off. Turning it back on after the free 30 days commits 30 days: the tool returns lock_confirmation_required with details.locked_until until it is called with commit_lock=True, which an agent sends only after its human agrees, with expected_locked_until echoed from details (a moved date is refused lock_quote_changed, and nothing is committed). get_reruns lists the re-research waiting for approval on a report (which entities and facts, today's total, and a quote_id); approve_reruns pays for exactly those rows with expected_total_cents and quote_id as shown, which an agent sends only after its human agrees (if anything waiting changed, even at the same total, it is refused rerun_price_changed with the new total, and nothing is charged: read get_reruns again); set_rerun_auto_approve turns automatic approval on or off. On is standing authority to spend up to a monthly limit (auto_approve_cap_cents, required), so an agent shows its human the limit and asks first. It is recorded against the key or app that set it: it switches off if that key is revoked or expires, or its user signs out everywhere, and pauses while the key is suspended. Revoking the app at AuthKit alone does not stop it: sign out everywhere, or turn it off. There is no decline: a rerun left waiting costs nothing, but its value is not treated as verified until it is decided again when the report's re-research renews, and on a plan with no included re-research waiting never clears it. retry_run retries a failed run. A retry that would charge returns retry_confirmation_required with the quote in details (total_price_cents, the failed run's refund, and funding.covered_by, what would pay: the total is the list price even when the free run or plan credits cover it) until it is called with expected_total_cents set to that total, which an agent sends only after its human agrees. Pass expected_funding set to that covered_by as well, so what pays is bound too (a moved price or rail is refused retry_price_changed with the new quote, and nothing is charged). When covered_by is mixed (plan credits for part of the run, the balance for the rest), also pass expected_prepaid_cents set to funding.prepaid_cents. start_research takes expected_total_cents the same way: pass the estimate's run_price_cents once your human agrees, and a run that would now cost more is refused run_price_changed with the new total, nothing charged. Both the estimate and the start take allowed_sources, the list of hosts and patterns a run is allowed to cite. Research is steered toward the list, but the guarantee is that it is enforced: a cell supported only by sites outside the list is left blank and its URLs come back as a lead. The estimate's warnings say so before you spend. seeds and allowed_sources take a list or one comma-separated string. start_research also takes guidance (what to prioritise and what to ignore) and monitored: the default true bills ongoing freshness, and false is a one-off run. Both the estimate and the start take additive_to (a run id whose report the run extends: only the entities that report lacks are researched and charged), reuse_existing (keep current data the workspace already holds instead of re-researching it, so those seeds are not charged) and temporal_cutoff ({date, kind, column}, an enforced date bound), and search_hints ({exact_phrases, file_types}: extra searches, never a filter; a query sets them, the estimate's intake.search_hints shows them, and you send the ones to keep, or {} for none). Estimate with the same values you will start with: the quote prices exactly the request the start charges, and a request the start would refuse (every seed already in the report, or an unknown date column) is refused by the estimate the same way, before any spend.
  • Cited data — query_entities reads rows with per-cell citations; export_dataset streams the whole dataset.
  • Change history — get_column_changes is the log of one column across records, newest first, each entry labelled initial, changed, unchanged, amended, observed or unknown (amended: QA corrected the value in place, and pre_amend_value is what it replaced), and each carrying a persistent cell_id. Hand that id to get_cell_changes for every value one cell has ever held, with the run and sources that wrote each one; include="rechecks" adds the re-checks that found a different value and chose not to apply it. Together they answer "when did this change, and on whose evidence" without re-running anything.
  • Merges, renames, successor links and removed links — list_changes lists them, newest first; undo_change undoes one the way the app's Undo does. Undo changes the customer's data, so the tool asks the agent to confirm with its human first, and it needs data:write with a member role: a viewer's connection is refused.
  • Cells a person set on purpose — list_held_cells lists them, with what research found since that was not applied (pending=True for only those). apply_cell_finding takes the finding the agent showed its human (a newer one since is refused, not applied), keep_cell_value keeps the person's value and dismisses the finding (research does not ask again unless it finds a different value or a new page), and release_cell stops protecting the cell. All three change the customer's data and need data:write with a member role.
  • Cells stated more than one way — when one run states a cell more than one way and the quality check supports two or more of the values, the cell shows the better-sourced one until someone chooses. list_conflicting_cells lists those cells with every value, its verdict and its sources; choose_cell_value makes one of them the cell's value, as the app's "Use this value" does (a cell that changed since is refused, not written). The cell is then held, and undo_change undoes the choice. It changes the customer's data and needs data:write with a member role.
  • Removing a wrong link — remove_link takes one many-to-many link out of a record (a person who left a fund, a mis-matched name), and research does not add it back. It is reversible with undo_change and the answer's change_id, so there is no confirm step, but the tool tells the agent to say what it removed. It needs data:write with a member role, like a merge.
  • Marking rows as duplicates — preview_merge shows what a merge would do, and merge_records applies it, given the preview's preview_digest: it applies exactly the merge that was previewed. If anything changed since, it is refused (merge_changed) with the merge as it stands now, for the agent to show its human before trying again; apply_without_preview merges with no preview, on purpose. A tie (two rows with equally good evidence disagreeing) is never settled silently: the agent must pass the choice its human made for each one, or accept the survivor's values outright. Two rows' lists of links are combined, never a tie.
  • Creating a Blueprint — create_blueprint starts a draft from a description; poll get_blueprint_draft until ready or awaiting_input. awaiting_input means the draft has follow-up questions and will not move until you answer them with answer_blueprint_question (ask your human when acting for one) or approve it as it stands. adjust_blueprint changes the draft in one synchronous turn and returns the agent's reply and the measured changes. It waits for the model, so it can take a couple of minutes; to retry one that timed out, pass the first response's message_id, and the stored turn comes back without a second model call. approve_blueprint creates the tables. Changing a Blueprint that is already active stays human-only: propose_blueprint_change asks what a change would be.
  • Domain knowledge — what your team knows about the field (where the reliable data is, which sources mislead, what a value means and its plausible range, what to leave out). Later runs carry each entry wherever it applies; it is guidance, never evidence, and changes no stored value. list_knowledge lists the entries; add_knowledge, edit_knowledge, retire_knowledge, restore_knowledge and delete_knowledge change them, with knowledge:write and a member role (a viewer's connection is refused). The tools tell the agent to write only what its human stated, to show its human a knowledge_conflict before resending with on_conflict, and to retire rather than delete. get_run_knowledge says what a run's knowledge did, keeping three things apart: entries the run carried, cells QA cited one in its verdict (a model's claim), and cells it decided (by code). A run whose record was not kept is "not recorded", never zero. A cell's own decisions are on its citation in query_entities with receipts=True. get_knowledge_usage says how each entry was used across recent runs, with one state per entry: it decided something, it was checked and changed no outcome, nothing in its scope came up, or it was not checked and why. It counts decisions, not cells, and the tool tells the agent never to report a state as a bare zero. On a Blueprint still being created, pass draft_id (the session id) instead of blueprint_id: the notes go on the draft and go live when it is approved, and writing them needs blueprint:create. Expertise the human states in their description or a setup-chat message is saved as a note in their own words, never invented. When the description states none, the draft asks one domain_knowledge question, which answer_blueprint_question can skip (skip=True) when they have nothing to add.
  • Reports — list_reports, get_report_columns and get_report_data read the curated views; create_report makes one.
  • Chat — ask_research_agent asks the research agent about a run's report and returns at once; poll get_chat_thread for the answer. Every change proposed in chat comes back pending_confirmation and was not written: confirm_chat_action applies it anyway and dismiss_chat_action declines it. Confirm only after your human has seen its warnings and decided. A viewer's connection may ask and dismiss, as in the app; what its questions propose waits for a member, and confirm and revert need data:write with a member role. revert_chat_action undoes an applied one.
  • Account — list_webhooks and list_members are read-only.

Change history needs deepsieve-mcp 0.4.0 or later on the stdio path, and answer_blueprint_question needs 0.5.0 or later; the domain knowledge tools, get_knowledge_usage, draft_id and answer_blueprint_question's skip need 0.10.0 or later. On the stdio path, the synchronous adjust_blueprint, monitored, a comma-separated seeds, re-research approval, retry_run, set_monitoring and remove_link need 0.7.0 or later (see the changelog). The browser-login server always carries the current tool set.

Two transports, both shipped: the hosted Streamable-HTTP server with OAuth 2.1 (the browser-login path at the top of this page, with no key in a config file) and the local stdio server shown here, which is the spec-recommended path when you want key-based auth, a narrower grant, or an air-gapped setup.

MCP server — DeepSieve API