MCP server

The remote Deliverd MCP server: connect Claude Code, Codex, Cursor and other clients with OAuth, and the 47 tools an agent can call.

Deliverd runs a hosted Model Context Protocol server at /api/mcp on your Deliverd address, over Streamable HTTP. Any agent that speaks MCP can use it to ask a person and to publish, with no code of yours in between. The server is the same service as the REST API: the same scopes, the same refusals and the same audit trail.

Connect

Authentication is OAuth, not a pasted token. The server implements the MCP authorisation specification, so your client registers itself and you approve it in a browser, choosing the organisation as you do. In Claude Code:

claude mcp add --transport http deliverd https://deliverd.dev/api/mcp

The first time a Deliverd tool runs, a browser window asks you to approve the connection. That approval is the credential. See Authentication for what it grants and how long it lasts.

Clients that cannot do OAuth can send an API key as a bearer token instead. It works, but it is a secret on disk; prefer OAuth where the client supports it.

Set up everything in one paste

Paste this into Claude Code, Codex, Cursor or Claude Desktop. It runs the installer from the CLI, tells you what it connected, and proves the connection by publishing a page.

Set up Deliverd so you can publish reports for me.

1. Run: npx deliverd setup --url https://deliverd.dev
   It looks for Claude Code, Codex, Claude Desktop and Cursor on this
   machine and adds the Deliverd MCP server to each one it finds.
   There is no API key to paste.

2. Tell me exactly what it connected and what it says to do next. Some
   tools need a restart, and Codex needs "codex mcp login deliverd"
   before the connection is live.

3. Once you can see the Deliverd tools, build a short, well-made HTML
   page summarising what you just set up, and publish it with the
   publish_report tool. Title it "Hello from Deliverd".

4. Give me the URL it returns.

If npx is unavailable, install the CLI first with: npm install -g deliverd

Each client

The same instructions as the Connect screen in the app, for every client that speaks MCP. Where a client can add a server from a link, the link comes first; the steps are the fallback.

Claude Code

claude mcp add --transport http deliverd https://deliverd.dev/api/mcp
  1. Add the server

    claude mcp add --transport http deliverd https://deliverd.dev/api/mcp

    Claude Code opens a browser the first time it is used, so you can pick the organisation and approve access.

Codex

codex mcp add deliverd --url https://deliverd.dev/api/mcp
  1. Add the server

    codex mcp add deliverd --url https://deliverd.dev/api/mcp
  2. Approve it in your browser

    codex mcp login deliverd

    Codex needs this second step — it does not begin the approval flow on its own.

  3. On an older Codex

    Streamable HTTP servers are only picked up when the rmcp client is on. If the server does not appear, upgrade Codex, or add [features] experimental_use_rmcp_client = true to ~/.codex/config.toml above the server entry.

Cursor

Opens Cursor and asks you to add the server; you approve the connection in your browser. If nothing happens, follow the steps below.

  1. Or add it to ~/.cursor/mcp.json

    {
      "mcpServers": {
        "deliverd": {
          "type": "http",
          "url": "https://deliverd.dev/api/mcp"
        }
      }
    }

    Keep any servers already listed there — replacing the file removes them.

  2. Reload Cursor

    Then approve the connection in your browser.

VS Code

Opens VS Code and asks you to add the server; you approve the connection in your browser. If nothing happens, follow the steps below.

  1. Or add it to .vscode/mcp.json

    {
      "servers": {
        "deliverd": {
          "type": "http",
          "url": "https://deliverd.dev/api/mcp"
        }
      }
    }

    In the project for one repository, or in your user settings for all of them. The key is “servers” — VS Code ignores an “mcpServers” block.

  2. Start it

    Run “MCP: List Servers” from the command palette, start the server, and approve the connection in your browser.

ChatGPT

  1. Turn on developer mode

    Settings → Apps → Advanced settings → Developer mode. Custom connectors need a paid ChatGPT plan.

  2. Add a custom connector with this address

    https://deliverd.dev/api/mcp

    The connector registers itself and sends you to a screen where you choose the organisation and approve access.

Claude desktop & web

  1. Settings → Connectors → Add custom connector

    https://deliverd.dev/api/mcp

Windsurf

  1. Add it to ~/.codeium/windsurf/mcp_config.json

    {
      "mcpServers": {
        "deliverd": {
          "serverUrl": "https://deliverd.dev/api/mcp"
        }
      }
    }

    Keep any servers already listed there. The key is “serverUrl” — a plain “url” is ignored.

  2. Refresh the servers

    In Cascade's MCP panel, refresh, then approve the connection in your browser.

Gemini CLI

gemini mcp add --transport http deliverd https://deliverd.dev/api/mcp
  1. Add the server

    gemini mcp add --transport http deliverd https://deliverd.dev/api/mcp
  2. Approve it

    /mcp auth deliverd

    Inside Gemini, if it has not already opened a browser for you.

For any other client, give it the server address and let it register itself:

https://deliverd.dev/api/mcp

Tools

The server carries 47 tools. Each requires the scope beside it, from the same list API keys use; a call without it is refused with a message naming the scope it needed. The list below is the one the server publishes for directories, so it is always the server's own; it leaves out find_report, a deprecated alias of find_reports kept for older clients.

Asking a person, and the record

Asking before acting comes first. check_gate asks your organisation's policy whether to perform a registered action — see the gate — and the rest ask a named person for an approval, a review or information, or tie them together in a flow. See Approvals, reviews and requests for the fields.

ToolWhat it doesScope
check_gateAsk whether you may perform a registered action before you perform it; policy answers allow, refuse, or a person decides.gates:write
get_gateThe state of a gate decision you raised, once a person has answered it.gates:read
request_approvalAsk named people to authorise an action before you take it; returns the request and its page.approvals:write
get_approvalThe status of an approval — pending, approved, rejected or expired — with any questions the approver asked.approvals:read
cancel_approvalWithdraw an approval you asked for, while it is still undecided.approvals:write
answer_approval_questionAnswer a question an approver asked about your request, on the approval page.approvals:write
request_reviewAsk named people to read work and say whether it is right; returns the request and its page.reviews:write
get_reviewThe outcome of a review — pending, approved or changes requested — with each reviewer's verdict and note.reviews:read
cancel_reviewWithdraw a review you asked for, while it is still unanswered.reviews:write
request_informationAsk named people typed questions and get structured answers back; returns the request and its page.collections:write
get_collectionThe answers to a request for information, with who replied and what they said.collections:read
cancel_collectionWithdraw a request for information you made, while it is still open.collections:write
create_flowStart a flow: the thread tying one job's approvals, reviews, requests and publishes together.flows:write
get_flowA flow with everything in it and the timeline of what happened across all of them, in order.flows:read
complete_flowSay the work a flow covers is done. Only whoever started it, and it takes no new members afterwards.flows:write
cancel_flowClose a flow as abandoned rather than done, so the history says which of the two happened.flows:write
get_evidenceAn evidence pack for a flow or a report: every step, who decided what, and the full timeline.every read scope

Publishing and reading

Publishing, sharing, datasets, comments and analytics. See Publishing reports.

ToolWhat it doesScope
publish_reportPublish HTML to a persistent secure URL, with an audience named in plain English.reports:write
update_reportPublish a new version of an existing report, keeping its URL and audience.reports:write
rename_reportChange a report's title or address; the old address keeps working.reports:write
move_reportFile a report into a workspace.reports:write
archive_reportStop a report's URL serving. Reversible; nothing is deleted.reports:write
unarchive_reportPut an archived report back, at the same URL and audience.reports:write
rollback_reportServe an earlier version again, without republishing it.reports:write
get_reportFetch a report's metadata, URL and current version.reports:read
find_reportsSearch reports by title or slug.reports:read
list_templatesReports the organisation offers as starting points.reports:read
share_reportGrant people, teams or groups access to a report.reports:share
revoke_accessTake a report's access away again, from the same audience phrase that granted it.reports:share
send_reportEmail a report to a list of addresses, with a covering note. Each gets their own link.reports:share
list_workspacesList workspaces, with who can already open a given report.workspaces:read
list_due_schedulesRecurring reports waiting on this agent.schedules:read
create_scheduleAsk an agent for a recurring publish, on a cron cadence.schedules:write
update_scheduleChange a schedule's cadence, or turn it on or off.schedules:write
delete_scheduleStop asking for a recurring publish.schedules:write
list_report_dataList the datasets a report reads when it is opened.reports:read
update_report_dataReplace a report's live data without publishing a new version.reports:write
delete_report_dataRemove a dataset from a report.reports:write
list_commentsRead reader feedback, with the quoted passage and context.comments:read
list_open_commentsEvery open comment thread across the organisation's reports — what needs attention.comments:read
get_report_analyticsWho read a report and when: views, readers, by day and by version.reports:read
get_org_analyticsReadership across every report, including the ones nobody has opened.reports:read
get_revision_briefThe open feedback on a report as one revision prompt, with the readers' screenshots.comments:read
comment_on_reportComment on a report, anchored to a quoted passage.comments:write
retract_commentTake back a comment nobody has answered yet.comments:write
resolve_commentMark a comment thread resolved.comments:write
resolve_audienceTurn natural-language audience phrases into concrete principals.audiences:read

Behaviour worth knowing

  • Audience parameters take plain language — "Finance team", "Sarah Jones", "everyone". When a phrase is ambiguous the tool returns candidates for the agent to confirm with you, then retry. resolve_audience checks a phrase without sharing anything.
  • A connection made with OAuth acts as the person who approved it. Their membership is checked on every call, so removing someone from the organisation cuts their agent off at once.
  • A refusal comes back as a tool result marked as an error. Most carry the same error code and message the REST API sends; see Errors and limits.
  • tools/list needs a credential like every other call. A directory reads the public server card at /.well-known/mcp/server-card.json instead.