Skip to content
pdcli
Get started

MCP server

pdcli mcp serve runs pdcli as a Model Context Protocol (MCP) server over stdio, so an MCP host — Claude Desktop, Claude Code, or any other client — can drive your Pipedrive account as a set of typed tools.

It is the same CLI you already trust, wrapped in a tool surface. Every tool call re-invokes pdcli itself as a child process under your auth profile, so the tools honor the same host-lock, the same keychain credentials, and the same rate-limit handling as the commands you run by hand. Nothing new touches your token.

The design goal is that connecting the server can’t hurt you:

  • Read-only out of the box. The default tool set is a curated 45 read-only tools — core entity list/get, search, deal intelligence (deal context/history/summary), every metric, funnel, digest, audit, rep scorecard, user me, and more. No tool that writes is even registered unless you ask for it.
  • Writes are opt-in. Every command is classified read, write, or destructive. Writes and destructive operations are exposed only under --allow-writes.
  • Dangerous surfaces are excluded entirely — they never appear as tools, even with --all-tools. That includes the raw api escape hatch, auth:*, config:*, alias:*, profile:* (all of which manage your local machine, not CRM data), doctor, watch, changes (advances a stateful watermark), sync warehouse, backup (but backup diff, a zero-API local read, is kept), webhook listen, and mcp serve itself.

Register the server with Claude Code in one line:

Terminal window
claude mcp add pipedrive -- pdcli mcp serve

Or add it to an .mcp.json (Claude Code project config, Claude Desktop, or any MCP host) by hand:

{
"mcpServers": {
"pipedrive": {
"command": "pdcli",
"args": ["mcp", "serve"]
}
}
}

That’s the read-only server. To let the host create and update records, add the flag to the args["mcp", "serve", "--allow-writes"] — or to the claude mcp add command after the --.

Authenticate pdcli once (pdcli auth login, or an env-var token) before starting a host; the server itself needs no credentials — its child processes resolve them.

On start the server logs a single line to stderr and then waits for the host over stdio:

pdcli MCP server ready — 45 tools (read-only)

The count is the number of tools actually registered, so it moves with your flags: --allow-writes changes the suffix to (writes enabled) and raises the count, and --topics/--all-tools change it too. On the host side, confirm the connection by opening the tool list — Claude Code and Claude Desktop show the registered pdcli tools in their tool picker. If you see neither the stderr line nor the tools, the server never came up.

Tool selection happens in two stages: scope, then the write gate.

Scope decides which commands are candidates:

| Flag | Tools exposed | | ----------------------- | ------------------------------------------------------------------- | | (none) | the curated core set — 45 read tools, small enough not to overwhelm a host | | --topics deal,person | every command under those topics, instead of the curated set | | --all-tools | every non-excluded command |

The write gate then filters that scope: reads are always exposed; write and destructive tools appear only with --allow-writes. With the default scope, --allow-writes adds ~14 core write tools — the create/update commands on core entities plus the idempotent upserts (person/org/deal upsert).

Terminal window
pdcli mcp serve # curated, read-only (default)
pdcli mcp serve --allow-writes # curated reads + core writes
pdcli mcp serve --topics deal,person,org # everything under those topics (reads)
pdcli mcp serve --all-tools --allow-writes # the whole CLI as tools

One command is deliberately kept out of the curated default even though it’s a read: lookup. Its exit-3 “no match” result is a normal branch for a script, but an MCP host reads a non-zero exit as a tool error — noisy for an agent. It stays reachable via --all-tools; for match-or-branch logic inside an agent, prefer search or the upsert tools.

The point of the read-only default is that an agent can gather real CRM context and act on it without you wiring up a single API call. A support agent asked to chase a stalled order does the whole thing through the curated tools:

  1. Find the deal. The user knows a purchase-order number, not a deal ID, so the agent calls the search tool with that term and gets back the matching deal.
  2. Pull its full context. It hands that ID to deal context, which returns the denormalized bundle in one call — the deal plus its person, organization, open activities, recent notes, and line-item products — with custom fields already resolved to human names, so the agent reads "Renewal date", not a hash key.
  3. Act on it. With the whole picture in the prompt, the agent drafts a follow-up email and flags the two overdue activities — all from a server that can’t write anything.

Only when you trust that workflow do you add --allow-writes, at which point the same agent can idempotently upsert the next-step activity instead of just proposing it.

Every tool call forces --resolve-fields, so the host sees human-readable custom field names (and option labels) instead of Pipedrive’s 40-character hash keys — on both input and output. An agent can ask for "Renewal date", not "a1b2c3…". Each call also forces --output=json (so the parent’s stdio channel stays clean) and --yes (no interactive confirm can block a headless call).

Each tool call is a child process with guardrails:

  • --tool-timeout <seconds> (default 120) bounds how long a call may run before its child is terminated (SIGTERM, escalating to SIGKILL).
  • Output is capped at 16 MB across stdout and stderr combined; a runaway call is killed rather than flooding the host.

Both a timeout and an overflow surface to the host as a tool error with a self-describing message, never as a silent success.

If your agent already has a shell — a terminal agent like Claude Code or Codex — you may not need MCP at all. pdcli is built to be driven from bash directly: --output json, --jq, self-describing --help, and deterministic exit codes give a shell-capable agent everything it needs, with the full command set and no tool-registration step.

Reach for mcp serve when the host can’t run shell commands — Claude Desktop and other GUI/chat hosts that speak MCP but have no terminal. There, the MCP server turns pdcli into first-class typed tools with the same safety posture you’d get on the command line.

pdcli v0.22.0 · MIT · not affiliated with Pipedrive