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
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
Add the server
codex mcp add deliverd --url https://deliverd.dev/api/mcp
Approve it in your browser
codex mcp login deliverd
Codex needs this second step — it does not begin the approval flow on its own.
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.
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.
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.
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.
Start it
Run “MCP: List Servers” from the command palette, start the server, and approve the connection in your browser.
ChatGPT
Turn on developer mode
Settings → Apps → Advanced settings → Developer mode. Custom connectors need a paid ChatGPT plan.
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
Settings → Connectors → Add custom connector
https://deliverd.dev/api/mcp
Windsurf
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.
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
Add the server
gemini mcp add --transport http deliverd https://deliverd.dev/api/mcp
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.
| Tool | What it does | Scope |
|---|---|---|
check_gate | Ask whether you may perform a registered action before you perform it; policy answers allow, refuse, or a person decides. | gates:write |
get_gate | The state of a gate decision you raised, once a person has answered it. | gates:read |
request_approval | Ask named people to authorise an action before you take it; returns the request and its page. | approvals:write |
get_approval | The status of an approval — pending, approved, rejected or expired — with any questions the approver asked. | approvals:read |
cancel_approval | Withdraw an approval you asked for, while it is still undecided. | approvals:write |
answer_approval_question | Answer a question an approver asked about your request, on the approval page. | approvals:write |
request_review | Ask named people to read work and say whether it is right; returns the request and its page. | reviews:write |
get_review | The outcome of a review — pending, approved or changes requested — with each reviewer's verdict and note. | reviews:read |
cancel_review | Withdraw a review you asked for, while it is still unanswered. | reviews:write |
request_information | Ask named people typed questions and get structured answers back; returns the request and its page. | collections:write |
get_collection | The answers to a request for information, with who replied and what they said. | collections:read |
cancel_collection | Withdraw a request for information you made, while it is still open. | collections:write |
create_flow | Start a flow: the thread tying one job's approvals, reviews, requests and publishes together. | flows:write |
get_flow | A flow with everything in it and the timeline of what happened across all of them, in order. | flows:read |
complete_flow | Say the work a flow covers is done. Only whoever started it, and it takes no new members afterwards. | flows:write |
cancel_flow | Close a flow as abandoned rather than done, so the history says which of the two happened. | flows:write |
get_evidence | An 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.
| Tool | What it does | Scope |
|---|---|---|
publish_report | Publish HTML to a persistent secure URL, with an audience named in plain English. | reports:write |
update_report | Publish a new version of an existing report, keeping its URL and audience. | reports:write |
rename_report | Change a report's title or address; the old address keeps working. | reports:write |
move_report | File a report into a workspace. | reports:write |
archive_report | Stop a report's URL serving. Reversible; nothing is deleted. | reports:write |
unarchive_report | Put an archived report back, at the same URL and audience. | reports:write |
rollback_report | Serve an earlier version again, without republishing it. | reports:write |
get_report | Fetch a report's metadata, URL and current version. | reports:read |
find_reports | Search reports by title or slug. | reports:read |
list_templates | Reports the organisation offers as starting points. | reports:read |
share_report | Grant people, teams or groups access to a report. | reports:share |
revoke_access | Take a report's access away again, from the same audience phrase that granted it. | reports:share |
send_report | Email a report to a list of addresses, with a covering note. Each gets their own link. | reports:share |
list_workspaces | List workspaces, with who can already open a given report. | workspaces:read |
list_due_schedules | Recurring reports waiting on this agent. | schedules:read |
create_schedule | Ask an agent for a recurring publish, on a cron cadence. | schedules:write |
update_schedule | Change a schedule's cadence, or turn it on or off. | schedules:write |
delete_schedule | Stop asking for a recurring publish. | schedules:write |
list_report_data | List the datasets a report reads when it is opened. | reports:read |
update_report_data | Replace a report's live data without publishing a new version. | reports:write |
delete_report_data | Remove a dataset from a report. | reports:write |
list_comments | Read reader feedback, with the quoted passage and context. | comments:read |
list_open_comments | Every open comment thread across the organisation's reports — what needs attention. | comments:read |
get_report_analytics | Who read a report and when: views, readers, by day and by version. | reports:read |
get_org_analytics | Readership across every report, including the ones nobody has opened. | reports:read |
get_revision_brief | The open feedback on a report as one revision prompt, with the readers' screenshots. | comments:read |
comment_on_report | Comment on a report, anchored to a quoted passage. | comments:write |
retract_comment | Take back a comment nobody has answered yet. | comments:write |
resolve_comment | Mark a comment thread resolved. | comments:write |
resolve_audience | Turn 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_audiencechecks 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
errorcode and message the REST API sends; see Errors and limits. tools/listneeds a credential like every other call. A directory reads the public server card at/.well-known/mcp/server-card.jsoninstead.