Skip to content

Demo

Watch an AI agent use tools through pmcp — from chat to wire protocol.
MCP Host
Claude, Cursor, etc.
JSON-RPC / stdio
pmcp
Go binary
protobuf / unix socket
Your Code
Python, TS, Go, Rust
hot reload dynamic tool lists progress reporting cancellation

Tool Calls

The core flow — AI calls a tool, pmcp translates JSON-RPC to protobuf, your tool process handles it, result flows back.

Tool Call Flow
Agent Chat
Protocol Flow
What’s the weather in San Francisco?
Let me check that for you.
weatherrunning
{ city: “San Francisco” }
{ “temp”: 62, “condition”: “foggy”, “wind”: “12mph” }
It’s 62°F and foggy in San Francisco with 12mph winds.
JSON-RPCHost→pmcptools/call “weather”
protobufpmcp→AppCallToolRequest
protobufApp→pmcpCallToolResult
JSON-RPCpmcp→Hostresult: {“temp”: 62, …}

Progress Reporting

Long-running tools report progress in real time. Notifications flow back through pmcp to the host — no polling needed.

Progress Reporting
Agent Chat
Protocol Flow
Search src/ for all Python files
Scanning the directory tree now.
search_filesrunning
{ dir: “src”, pattern: “*.py” }
found 47 files across 12 directories
Found 47 Python files across 12 directories in src/.
JSON-RPCHost→pmcptools/call “search_files”
protobufpmcp→AppCallToolRequest
protobufApp→pmcpProgressNotification 33%
protobufApp→pmcpProgressNotification 66%
protobufApp→pmcpProgressNotification 100%
protobufApp→pmcpCallToolResult
JSON-RPCpmcp→Hostresult: 47 files

Dynamic Tool Lists

The tool process controls which tools are visible. Here, the login handler returns enable_tools in its result — pmcp updates the tool list and notifies the host. No restart, no config change.

Dynamic Tool Lists
Agent Chat
Protocol Flow
Log me in as admin
Authenticating you now.
loginrunning
{ user: “admin” }
Authenticated
+create_record +delete_record
You’re logged in. create_record and delete_record are now available.
Create a new user record for Alice
create_recordrunning
{ name: “Alice”, role: “editor” }
Created user Alice (id: usr_847)
JSON-RPCHost→pmcptools/call “login”
protobufpmcp→AppCallToolRequest
protobufApp→pmcpCallToolResult + enable_tools
JSON-RPCpmcp→Hostresult: “Authenticated”
JSON-RPCpmcp→Hostnotifications/tools/list_changed
JSON-RPCHost→pmcptools/call “create_record”
protobufpmcp→AppCallToolRequest
protobufApp→pmcpCallToolResult
JSON-RPCpmcp→Hostresult: “Created user Alice”

Hot Reload

A tool call fails. The developer fixes the bug and saves. pmcp hot-reloads the fix — no restart needed. The AI retries and it works.

Hot Reload
Agent Chat
Protocol Flow
Export the sales data as CSV
I’ll export that for you.
export_csvrunning
{ dataset: “sales” }
error [INVALID_FORMAT]: CSV writer not initialized
The export tool has a bug — the CSV writer isn’t initialized.

⟳ File changed: tools.py — reloading…

✓ Reconnected · 3 tools registered

Tools reloaded. Let me retry.
export_csvrunning
{ dataset: “sales” }
Exported 1,204 rows to sales.csv
Done — 1,204 rows exported to sales.csv.
JSON-RPCHost→pmcptools/call “export_csv”
protobufpmcp→AppCallToolRequest
protobufApp→pmcpCallToolResult (is_error)
JSON-RPCpmcp→Hosterror: INVALID_FORMAT
internalpmcpfile watch: tools.py modified
protobufpmcp→AppReloadRequest
protobufApp→pmcpReloadResponse { success: true }
JSON-RPCpmcp→Hostnotifications/tools/list_changed
JSON-RPCHost→pmcptools/call “export_csv”
protobufpmcp→AppCallToolRequest
protobufApp→pmcpCallToolResult
JSON-RPCpmcp→Hostresult: “1,204 rows”

Tool Groups

Tool groups bundle related actions under one tool name. A oneOf discriminated union schema guides the agent to the right parameters for each action.

Tool Groups
Agent Chat
Protocol Flow
Add the sales dataset from /data/sales.csv
I’ll ingest that dataset.
datarunning
{ action: “add”, data_path: “/data/sales.csv”, auto_clean: true }
Added 12,847 rows from sales.csv
Dataset loaded — 12,847 rows ingested.
JSON-RPCHost→pmcptools/call “data” (oneOf schema)
protobufpmcp→AppCallToolRequest
protobufApp→pmcpCallToolResult
JSON-RPCpmcp→Hostresult: “12,847 rows added”

Server-Defined Workflows

Multi-step workflows where the tool surface changes at each step. Tools appear and disappear as the workflow progresses — the available tools are the state machine.

Server-Defined Workflows
Agent Chat
Protocol Flow
Deploy PR #142
Starting deployment review.
deploy.reviewrunning
{ pr_url: “#142” }
3 files changed
Changes look good. Approving.
deploy.approverunning
{ reason: “Tests green, LGTM” }
Approved

⚡ Available tools changed: +deploy.run_tests −deploy.review −deploy.approve

deploy.run_testsrunning
{ }
42 tests passed

⚡ Available tools changed: +deploy.promote −deploy.run_tests −deploy.cancel

deploy.promoterunning
{ }
Live in production
Deployed PR #142 to production.
JSON-RPCHost→pmcptools/call “deploy.review”
protobufpmcp→AppCallToolRequest
protobufApp→pmcpCallToolResult + set_allowed
JSON-RPCpmcp→Hostresult: “3 files changed”
JSON-RPCpmcp→Hostnotifications/tools/list_changed
JSON-RPCHost→pmcptools/call “deploy.approve”
protobufpmcp→AppCallToolRequest
protobufApp→pmcpCallToolResult + set_allowed
JSON-RPCpmcp→Hostnotifications/tools/list_changed
JSON-RPCHost→pmcptools/call “deploy.run_tests”
protobufpmcp→AppCallToolRequest
protobufApp→pmcpCallToolResult + set_allowed
JSON-RPCpmcp→Hostnotifications/tools/list_changed
JSON-RPCHost→pmcptools/call “deploy.promote”
protobufpmcp→AppCallToolRequest
protobufApp→pmcpCallToolResult
JSON-RPCpmcp→Hostresult: “Live in production”

Local Middleware

Middleware runs in-process — no round-trip to the Go bridge. Here it intercepts an error, formats it for the agent, and the agent recovers.

Local Middleware
Agent Chat
Protocol Flow
Read /etc/shadow
Let me try that.
read_filerunning
{ path: “/etc/shadow” }
Permission denied: /etc/shadow — try a file you own
I don’t have permission. Let me try a different file.
read_filerunning
{ path: ”~/.profile” }
# .profile contents…
Here’s your profile file.
JSON-RPCHost→pmcptools/call “read_file”
middlewarein-processPermissionError → formatted message
JSON-RPCpmcp→Hosterror: “Permission denied”
JSON-RPCHost→pmcptools/call “read_file”
protobufpmcp→AppCallToolRequest
protobufApp→pmcpCallToolResult
JSON-RPCpmcp→Hostresult: “.profile contents”

What’s New

protomcp now supports advanced features for building complex MCP servers:

  • Tool Groups — group related actions with per-action schemas (oneOf discriminated unions)
  • Server-Defined Workflows — multi-step state machines where the tool surface is the state
  • Local Middleware — in-process middleware chains for error formatting, timing, and more
  • Declarative Validation — required fields, enum fuzzy matching, cross-parameter rules
  • Server Context — shared parameter resolvers injected automatically
  • Telemetry Sinks — structured tool-call events to pluggable, fail-safe sinks
  • Sidecar Management — managed companion processes with health checks
  • Handler Discovery — auto-discover tool handlers from a directory

See the Python Guide for the full API.

Try It Yourself

Terminal window
brew install msilverblatt/tap/protomcp
pmcp dev examples/python/basic.py

Check out the Quick Start guide or browse the examples.