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.