Pad MCP — Local
Connect AI desktop apps to your local Pad workspace
Run Pad as a local Model Context Protocol server. Claude Desktop, Cursor, and Windsurf get a curated v0.2 catalog of eight resource × action tools — for items, workspaces, collections, project intelligence, search, roles, and server introspection — plus read-only resources for items and the dashboard, and prompts for planning workflows. One install command per client, without copy-pasting JSON or scripting anything.
1. Quick start (under 2 minutes)
If pad is already installed and you've got a workspace:
pad mcp install claude-desktop # or: cursor, windsurf, --all
# Restart the client, ask it to use the "pad" MCP server.
That's the whole thing. The install command:
- Resolves the right config file for your OS (paths in §4).
- Adds an
mcpServers.padentry pointing the client atpad mcp serve. - Preserves any other MCP servers you've already configured (we never clobber the file).
- Sets the file to mode
0600so other servers' API keys stay private.
After restarting the client, ask it: "Set the workspace to my-project and show me my dashboard." The client calls pad_set_workspace + reads pad://workspace/my-project/dashboard.
2. What's exposed over MCP
Heads up — v0.2 surface (clean break)
Pad's earlier MCP surface auto-derived ~85 flat verb tools (item_create, item_block, item_star, …) from the CLI help tree. As of tool_surface_version: "0.2" that's gone, replaced with a hand-curated
catalog of 8 resource-action tools. There is no compatibility shim — anything
pinning against the v0.1 tool names won't dispatch. Pin against tool_surface_version from pad://_meta/version going forward.
Tools — 8 resource-action tools
Instead of one tool per leaf CLI command, the MCP catalog is organized as resource × action: a small set of top-level tools, each accepting an action enum that selects the operation. This keeps the surface small enough
to fit in an agent's tool list without crowding out everything else.
| Tool | Actions | Notes |
|---|---|---|
pad_item | create, update, delete, get, list, move, link, unlink, deps, star, unstar, starred, comment, list-comments, bulk-update, note, decide | The main resource. link / unlink take a link_type enum (blocks, blocked-by, supersedes, implements, split-from). bulk-update takes refs: array<string> instead
of a scalar ref. |
pad_workspace | list, members, invite, storage, audit-log | Workspace operations. |
pad_collection | list, create | Collection types. |
pad_project | dashboard, next, standup, changelog | Computed views. |
pad_role | list, create, delete | Agent roles. |
pad_search | query | Cross-workspace full-text search. |
pad_meta | server-info, version, tool-surface | Server introspection. tool-surface returns the full catalog as
JSON — useful for generating docs against a live server. |
pad_set_workspace | (no action — workspace arg required) | Pin the session-default workspace; see §6. |
Every tool except pad_meta and pad_set_workspace accepts an
optional workspace parameter. Resolution order is described in §6.
Interactive / destructive / streaming commands are intentionally not on the surface — auth setup/login, db backup/restore, init, workspace export/import, item edit (opens $EDITOR), project watch (streaming) all stay CLI-only.
Resources — read workspace state without a tool call
Resources let agents read workspace state by URL without picking a tool. Four workspace-scoped templates plus two server-wide static resources are advertised:
| URI | Returns | MIME |
|---|---|---|
pad://workspaces | Top-level workspace list (slug, name, updated_at, default) | application/json |
pad://workspace/{ws}/items/{ref} | Single item — heading, parent link, fields, body | text/markdown |
pad://workspace/{ws}/items | List of every item in the workspace | application/json |
pad://workspace/{ws}/dashboard | Computed project overview (active items, plans, attention, blockers) | application/json |
pad://workspace/{ws}/collections | Collection list + JSON Schemas | application/json |
pad://_meta/version | Server-wide tool-surface stability metadata — see Stability contract | application/json |
pad://workspaces is the entry point an agent should hit when it has no
workspace context yet — it lists every workspace the caller can see, marks the default,
and gives the agent enough information to either pick one and call pad_set_workspace, or ask the user.
Prompts — drop-in workflows from the /pad skill
Four multi-step workflows are exposed as MCP prompts so an agent can prompts/get one and have the workflow text injected as a system message. Identical content to what
ships in the /pad skill — same workflow, different transport.
pad_plan— load context, propose an outline, decompose into tasks with--parentlinks.pad_ideate— search related items, discuss, capture asidea/docwith confirmation.pad_retro— pull a completed plan + its tasks, generate what-shipped/what-was-deferred/lessons, save as a retro doc.pad_onboard— workspace state check, look for an Onboarding playbook, codebase scan, suggest conventions.
Stability contract — two version constants
The MCP surface is a public contract, but it has two independent moving parts that
version separately. Tool names, argument shapes, and resource URIs are stable within a
major tool_surface_version; the underlying CLI help tree is versioned by cmdhelp_version. Bumps to either are reserved for incompatible changes.
tool_surface_version(currently"0.2") — the MCP tool catalog contract. This is what external agents should pin against. Advertised in the initialize handshake atresult.capabilities.experimental.padToolSurface.cmdhelp_version(currently"0.1") — the CLI help-tree contract used at dispatch time. Advertised atresult.capabilities.experimental.padCmdhelp. Most consumers don't need to care about this one; it tracks the shape ofpad help --format json.
Both surface together in one document at pad://_meta/version:
{
"pad_version": "0.1.5",
"cmdhelp_version": "0.1",
"tool_surface_version": "0.2",
"tool_surface_stable": true,
"mcp_protocol_version": "2025-11-25"
}
mcp_protocol_version is the maximum MCP wire revision the server
can negotiate (sourced from the underlying mcp-go library so it tracks upstream). tool_surface_version is what changes when tool renames, argument shape
changes, or resource URI changes break consumers — pin against it.
3. Install in detail
pad mcp status # Show install state across supported clients
pad mcp install claude-desktop # Install for one client
pad mcp install cursor
pad mcp install windsurf
pad mcp install --all # Install for every supported client
pad mcp uninstall cursor # Remove the entry (other servers preserved)
pad mcp install with no arguments prints the same status table as pad mcp status — useful as a quick "did it take?" check.
Installs are idempotent. Re-running pad mcp install claude-desktop after
the binary moves on disk just refreshes the command path in the config —
the rest of the file is untouched.
4. Where pad writes the config
| Client | macOS / Linux | Windows |
|---|---|---|
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)~/.config/Claude/claude_desktop_config.json (Linux) | %APPDATA%\Claude\claude_desktop_config.json |
| Cursor | ~/.cursor/mcp.json | ~/.cursor/mcp.json |
| Windsurf | ~/.codeium/windsurf/mcp_config.json | %APPDATA%\Codeium\windsurf\mcp_config.json |
5. Manual configuration (advanced)
If you want to wire pad into a client we don't yet support, use this entry shape (any MCP-compatible client accepts it):
{
"mcpServers": {
"pad": {
"command": "/usr/local/bin/pad",
"args": ["mcp", "serve"]
}
}
}
The client spawns pad mcp serve; the server speaks JSON-RPC over stdio
and shuts down on EOF / SIGINT / SIGTERM.
6. Setting the active workspace
Every workspace-scoped tool call needs a workspace context. (pad_meta and pad_set_workspace are the two exceptions — they're server-wide.)
Resolution order:
- Explicit per-call: the client passes
workspacein the tool's arguments. Always wins. - Session default: the agent calls
pad_set_workspaceonce and subsequent calls inherit it for the lifetime of that MCP session. - CWD
.pad.toml: if the server's working directory contains a workspace marker, that workspace is used. (For local installs spawned by a desktop client, the CWD is whatever the client launched from — usually your home directory, so this rarely fires unless you've set up a workspace there.)
If none of those resolves, the call doesn't fail silently — it returns a
structured no_workspace error envelope (see §7) with
an available_workspaces array. Agents are expected to read that, pick a
workspace, call pad_set_workspace, and retry. The pad://workspaces resource gives the same list ahead of time if the agent
wants to choose proactively.
Resource URIs always include the workspace explicitly
(pad://workspace/{ws}/...) so reads never depend on session state.
7. Error envelopes
Every 4xx / 5xx response comes back as a structured JSON envelope with a closed
eight-code taxonomy, not as an opaque string. Agents can branch on error.code and self-recover for the common ones (no_workspace, unknown_workspace) without involving the human.
| Code | When | Extra fields |
|---|---|---|
no_workspace | No workspace context resolves | available_workspaces |
unknown_workspace | Slug doesn't exist or isn't visible to the caller | available_workspaces |
auth_required | Credentials missing or expired | hint |
permission_denied | Auth ok, role insufficient | required_role, current_role |
item_not_found | Bad item ref or slug | hint |
validation_failed | Bad input | field, expected, got |
conflict | Concurrent state collision | hint |
server_error | Catch-all for unexpected failures | hint (with raw detail) |
Wire shape:
{
"error": {
"code": "no_workspace",
"message": "No workspace context. Pass `workspace` explicitly, ...",
"hint": "Available workspaces: docapp, pad-web",
"available_workspaces": [
{ "slug": "docapp", "default": true },
{ "slug": "pad-web", "default": false }
]
}
}
Agents that branch on error.code stay robust across error message
rewording. The eight codes are the contract; the prose is not.
8. Server instructions
The initialize response carries a top-level instructions string telling agents when to reach for pad — what kinds of user asks
should trigger a tool call (issue refs like TASK-5, "what's on my
plate", planning / standup / changelog), and a quick orientation to the v0.2 tool
catalog and resources.
Most clients surface this string to the model verbatim, so it's part of the contract.
The authoritative text lives at internal/mcp/instructions.md — that file is what the server actually sends. The page sections above are extended
guidance that complements it (the live instructions are deliberately short to fit in
the model's system context).
9. Troubleshooting
Client says "could not find server 'pad'"
- Run
pad mcp status— confirm the client's row shows[x]with the right binary path. - If the path looks wrong (e.g. you moved
padafter installing), re-runpad mcp install <client>to refresh. - Restart the client app after install — most clients only re-read MCP config on launch.
Where do MCP server logs go?
stderr. stdout is reserved for JSON-RPC; writing to it from
the server would corrupt the protocol stream. Run with --debug for
verbose output:
pad mcp serve --debug 2> /tmp/pad-mcp.log
Most clients capture the spawned server's stderr to their own log file — check the
client's docs for where (Claude Desktop: ~/Library/Logs/Claude/ on
macOS).
Will my other MCP servers still work?
Yes. pad mcp install only modifies the mcpServers.pad key;
every other entry in the file is preserved verbatim. pad mcp uninstall removes only that key.
"Permission denied" reading the config file
Pad sets the config file to mode 0600. If the client app you're using
runs as a different user (e.g. inside a container), you may need to adjust ownership
manually.
10. The cloud variant: Pad Cloud as a remote MCP server
This page covers the local MCP server — pad runs on your machine,
the client spawns it as a subprocess. The complement is Pad Cloud's remote MCP server: same v0.2 catalog, served over Streamable HTTP at https://mcp.getpad.dev, authenticated with OAuth
so any cloud-based agent (web apps, mobile, hosted Claude) can connect without a local
install. See the cloud MCP docs for per-agent setup, the auth model, and the full tool catalog.