{"_id":"@0xkobold/pi-mcp","name":"@0xkobold/pi-mcp","dist-tags":{"latest":"0.4.0"},"versions":{"0.4.0":{"name":"@0xkobold/pi-mcp","version":"0.4.0","description":"Model Context Protocol (MCP) integration for pi-coding-agent. Connect to any MCP server (stdio, SSE, StreamableHTTP, WebSocket) and use its tools, resources, and prompts natively.","keywords":["pi-package","pi-extension","mcp","model-context-protocol","tools","resources","prompts","0xkobold"],"author":{"name":"0xKobold"},"license":"MIT","type":"module","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"},"./client":{"import":"./dist/client/index.js","types":"./dist/client/index.d.ts"},"./config":{"import":"./dist/config/index.js","types":"./dist/config/index.d.ts"},"./tools":{"import":"./dist/tools/index.js","types":"./dist/tools/index.d.ts"}},"scripts":{"build":"tsc","dev":"tsc --watch","test":"bun test","prepublishOnly":"rm -rf dist && tsc"},"pi":{"extensions":["./dist/index.js"],"skills":["./skills/mcp/SKILL.md"]},"dependencies":{"@modelcontextprotocol/sdk":"^1.29.0"},"peerDependencies":{"@mariozechner/pi-coding-agent":">=0.62.0","@sinclair/typebox":">=0.32.0"},"devDependencies":{"@mariozechner/pi-coding-agent":">=0.62.0","@sinclair/typebox":">=0.32.0","@types/bun":"latest","@types/node":"^20.0.0","typescript":"^6.0.0"},"repository":{"type":"git","url":"git+https://github.com/0xKobold/pi-mcp.git"},"bugs":{"url":"https://github.com/0xKobold/pi-mcp/issues"},"homepage":"https://github.com/0xKobold/pi-mcp#readme","gitHead":"b834bac4494b102c7e7c726cd87f9e573012232c","_id":"@0xkobold/pi-mcp@0.4.0","_nodeVersion":"25.1.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-+bUGdmIdfCfO9e2LKkH53/Lr0tRLrCiL7GdGaiLp6aT7rgDZZG6xBEgl04dh/g4DFfhw/vYOhn9L7+AtRw1vbA==","shasum":"a3a67e70d0a2db12da6484e135d74fc7d067f06f","tarball":"https://registry.npmjs.org/@0xkobold/pi-mcp/-/pi-mcp-0.4.0.tgz","fileCount":20,"unpackedSize":174781,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDTgVE7+myW+5zAFIEJNxmKT0lwdEzz3NWWuseUo4PnmQIgb0zBp21cSWQ4AD8iAjXPZmC2QG5CLEojXJ2/IF0oLYk="}]},"_npmUser":{"name":"moikapy","email":"warrenckhan@gmail.com"},"directories":{},"maintainers":[{"name":"moikapy","email":"warrenckhan@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-mcp_0.4.0_1775601779662_0.4475127537952699"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-07T22:42:59.606Z","0.4.0":"2026-04-07T22:42:59.813Z","modified":"2026-04-07T22:43:00.104Z"},"maintainers":[{"name":"moikapy","email":"warrenckhan@gmail.com"}],"description":"Model Context Protocol (MCP) integration for pi-coding-agent. Connect to any MCP server (stdio, SSE, StreamableHTTP, WebSocket) and use its tools, resources, and prompts natively.","homepage":"https://github.com/0xKobold/pi-mcp#readme","keywords":["pi-package","pi-extension","mcp","model-context-protocol","tools","resources","prompts","0xkobold"],"repository":{"type":"git","url":"git+https://github.com/0xKobold/pi-mcp.git"},"author":{"name":"0xKobold"},"bugs":{"url":"https://github.com/0xKobold/pi-mcp/issues"},"license":"MIT","readme":"# @0xkobold/pi-mcp\n\n> Model Context Protocol (MCP) integration for [pi-coding-agent](https://github.com/nicholasgasior/pi-coding-agent)\n\nConnect to any MCP server and use its tools, resources, and prompts natively within your pi agent.\n\n## Features\n\n- 🌐 **Four Transport Types** - stdio, SSE, StreamableHTTP, and WebSocket\n- 🔧 **Auto Tool Registration** - MCP tools appear as native pi tools (with progressive dispatch for 50+ tool servers)\n- 🔒 **Tool Filtering** - Allowlist/denylist to control which tools are registered\n- 📦 **Resource Access** - Read MCP server resources directly (with TTL caching)\n- 💬 **Prompt Templates** - Use MCP prompt templates\n- 🌱 **Roots Support** - Servers can discover workspace roots\n- 🔄 **Auto-Reconnect** - Reconnects on disconnect with exponential backoff\n- 🔐 **Env Interpolation** - `${VAR}` in config resolved from environment\n- 📥 **Claude Desktop Import** - Import servers from `~/.claude/mcp.json`\n- 💊 **Health Monitoring** - Uptime, call counts, error tracking in `/mcp status`\n- 🧪 **Sampling Support** - Handle MCP `sampling/createMessage` requests via configurable callback\n- 🗂️ **Multi-Project Config** - `.0xkobold/mcp.json` merges with global config\n- ⚙️ **Hot Config** - Add/remove servers without restart (commands)\n\n## Quick Start\n\n### 1. Configure servers\n\nEdit `~/.0xkobold/mcp.json`:\n\n```json\n{\n  \"servers\": [\n    {\n      \"name\": \"filesystem\",\n      \"transport\": {\n        \"type\": \"stdio\",\n        \"command\": \"npx\",\n        \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/home/user\"]\n      },\n      \"enabled\": true,\n      \"autoReconnect\": true\n    }\n  ],\n  \"importClaudeDesktop\": true\n}\n```\n\n### 2. Or use commands\n\n```\n/mcp add filesystem npx -y @modelcontextprotocol/server-filesystem /home/user\n/mcp enable filesystem\n/mcp connect filesystem\n```\n\n### 3. Use tools\n\nThe agent will automatically discover and use MCP tools. You can also:\n\n```\n/mcp list          # See all configured servers\n/mcp status        # See active connections\n/mcp discover      # Find available tools\n```\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `/mcp` | Show help |\n| `/mcp list` | List all configured servers |\n| `/mcp connect <name>` | Connect to a server |\n| `/mcp disconnect <name>` | Disconnect from a server |\n| `/mcp enable <name>` | Enable auto-connect for a server |\n| `/mcp disable <name>` | Disable auto-connect for a server |\n| `/mcp add <name> <cmd> [args]` | Add a stdio server |\n| `/mcp add-http <name> <url>` | Add an HTTP server |\n| `/mcp add-ws <name> <url>` | Add a WebSocket server |\n| `/mcp filter <name> allow <tools>` | Only register listed tools for server |\n| `/mcp filter <name> deny <tools>` | Register all except listed tools |\n| `/mcp filter <name> clear` | Remove tool filters for server |\n| `/mcp remove <name>` | Remove a server from config |\n| `/mcp refresh <name>` | Re-discover tools/resources/prompts |\n| `/mcp import` | Import servers from Claude Desktop config |\n| `/mcp status` | Show active connections |\n\n## Tools\n\n| Tool | Description |\n|------|-------------|\n| `mcp_discover` | List available MCP tools, resources, and prompts |\n| `mcp_call_tool` | Call any MCP tool by server + tool name |\n| `mcp_<server>_<tool>` | Individual tools (auto-registered per server) |\n| `mcp_<server>_read_resource` | Read a resource from an MCP server |\n| `mcp_<server>_get_prompt` | Get a prompt from an MCP server |\n\n## Transport Types\n\n### stdio\nSpawns a local process and communicates via stdin/stdout:\n```json\n{\n  \"type\": \"stdio\",\n  \"command\": \"npx\",\n  \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/path\"],\n  \"env\": { \"API_KEY\": \"...\" },\n  \"cwd\": \"/working/dir\"\n}\n```\n\n### StreamableHTTP\nModern HTTP transport (recommended for remote servers):\n```json\n{\n  \"type\": \"streamable-http\",\n  \"url\": \"https://example.com/mcp\",\n  \"headers\": { \"Authorization\": \"Bearer ...\" }\n}\n```\n\n### SSE (legacy)\nServer-Sent Events transport:\n```json\n{\n  \"type\": \"sse\",\n  \"url\": \"https://example.com/sse\"\n}\n```\n\n### WebSocket\nReal-time bidirectional transport:\n```json\n{\n  \"type\": \"websocket\",\n  \"url\": \"ws://localhost:8080/mcp\"\n}\n```\n\n## Tool Filtering\n\nControl which tools are registered per server using allowlist or denylist:\n\n```json\n// Only register specific tools (allowlist)\n{\n  \"name\": \"filesystem\",\n  \"allowedTools\": [\"read_file\", \"list_directory\"],\n  ...\n}\n\n// Register all except (denylist)\n{\n  \"name\": \"github\",\n  \"deniedTools\": [\"delete_repository\", \"create_issue\"],\n  ...\n}\n```\n\nOr via commands:\n```\n/mcp filter github allow search_repositories,get_file_contents\n/mcp filter filesystem deny write_file,delete_file\n/mcp filter github clear\n```\n\n## Environment Variable Interpolation\n\nUse `${ENV_VAR}` patterns in config values to avoid hardcoding secrets:\n\n```json\n{\n  \"name\": \"github\",\n  \"transport\": {\n    \"type\": \"stdio\",\n    \"command\": \"npx\",\n    \"args\": [\"-y\", \"@modelcontextprotocol/server-github\"],\n    \"env\": {\n      \"GITHUB_TOKEN\": \"${GITHUB_TOKEN}\"\n    }\n  }\n}\n```\n\nHTTP headers also support interpolation:\n```json\n{\n  \"transport\": {\n    \"type\": \"streamable-http\",\n    \"url\": \"https://api.example.com/mcp\",\n    \"headers\": {\n      \"Authorization\": \"Bearer ${API_TOKEN}\"\n    }\n  }\n}\n```\n\n## As a Library\n\nYou can use `@0xkobold/pi-mcp` as a standalone library, without pi-coding-agent:\n\n```typescript\n// Main entry — extension + all re-exports\nimport mcpExtension, {\n  MCPConnectionManager,\n  ResourceCache,\n  interpolateEnv,\n  loadConfig,\n  saveConfig,\n  createDefaultConfig,\n  isToolAllowed,\n} from \"@0xkobold/pi-mcp\";\n\n// Client subpath — connection management only\nimport { MCPConnectionManager, type MCPServerConfig } from \"@0xkobold/pi-mcp/client\";\n\n// Config subpath — config loading/saving only\nimport { loadConfig, upsertServer, type MCPConfig } from \"@0xkobold/pi-mcp/config\";\n\n// Tools subpath — tool registration utilities only\nimport { isToolAllowed, DEFAULT_MAX_TOOLS } from \"@0xkobold/pi-mcp/tools\";\n```\n\nQuick start without pi-coding-agent:\n\n```typescript\nimport { MCPConnectionManager } from \"@0xkobold/pi-mcp/client\";\n\nconst manager = new MCPConnectionManager([process.cwd()]);\n\nconst serverConfig = {\n  name: \"filesystem\",\n  transport: { type: \"stdio\", command: \"npx\", args: [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/tmp\"] },\n  enabled: true,\n  autoReconnect: true,\n};\n\nconst info = await manager.connect(serverConfig);\nconsole.log(`Connected: ${info.tools.length} tools`);\n\nconst result = await manager.callTool(\"filesystem\", \"read_file\", { path: \"/tmp/hello.txt\" });\nconsole.log(result);\n```\n\n## Architecture\n\n```\nsrc/\n├── index.ts          # Extension entry point (commands, tools, lifecycle)\n├── client/\n│   └── index.ts      # MCPConnectionManager, ResourceCache, env interpolation\n├── config/\n│   └── index.ts      # Config loading/saving, Claude Desktop import, project merge\n└── tools/\n    └── index.ts      # Tool bridge - MCP tools → pi tools (with filtering)\n```\n\n## Configuration\n\n**Config file**: `~/.0xkobold/mcp.json`\n\n**Full schema**:\n```json\n{\n  \"servers\": [\n    {\n      \"name\": \"string (required)\",\n      \"transport\": {\n        \"type\": \"stdio | sse | streamable-http | websocket\",\n        // stdio fields:\n        \"command\": \"string\",\n        \"args\": [\"string\"],\n        \"env\": {},\n        \"cwd\": \"string\",\n        // http/sse fields:\n        \"url\": \"string\",\n        \"headers\": {},\n        \"sessionId\": \"string\",\n        // websocket fields:\n        \"url\": \"ws://...\"\n      },\n      \"enabled\": false,\n      \"autoReconnect\": true,\n      \"maxReconnectAttempts\": 5,\n      \"reconnectDelayMs\": 1000,\n      \"connectTimeoutMs\": 30000,\n      \"allowedTools\": [\"tool_name\"],\n      \"deniedTools\": [\"tool_name\"],\n      \"maxTools\": 50\n    }\n  ],\n  \"importClaudeDesktop\": true\n}\n```\n\n## Claude Desktop Compatibility\n\nSet `\"importClaudeDesktop\": true` to automatically discover servers from:\n- `~/.claude/mcp.json`\n- `~/.config/claude-code/mcp.json`\n\nOr run `/mcp import` to manually import.\n\n## Development\n\n```bash\n# Install dependencies\nbun install\n\n# Build\nbun run build\n\n# Development watch\nbun run dev\n\n# Test\nbun test    # 95 tests, 182 assertions\nbun test test/unit.test.ts  # Unit tests only\nbun test test/integration.test.ts  # Integration tests (requires npx)\n```\n\n## Sampling Support\n\nMCP servers can request LLM sampling via `sampling/createMessage`. The extension registers a handler for this capability.\n\n- **Default handler**: Logs the request and returns a placeholder response (pi extensions don't have direct LLM completion access)\n- **Custom handler**: Pass a `SamplingHandler` function to `MCPConnectionManager` constructor:\n\n```typescript\nimport { MCPConnectionManager, type SamplingHandler } from \"@0xkobold/pi-mcp/client\";\n\nconst handler: SamplingHandler = async (params) => {\n  // Bridge to your LLM here\n  return {\n    role: \"assistant\",\n    content: { type: \"text\", text: \"LLM response\" },\n    model: \"your-model\",\n    stopReason: \"endTurn\",\n  };\n};\n\nconst manager = new MCPConnectionManager([\"/workspace\"], 50, 300_000, handler);\n```\n\n## License\n\nMIT","readmeFilename":"README.md","_rev":"1-29927fea648cc26259273e75faaff07b"}