@0xkobold/pi-mcp

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.

Package details

extensionskill

Install @0xkobold/pi-mcp from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@0xkobold/pi-mcp
Package
@0xkobold/pi-mcp
Version
0.4.0
Published
Apr 7, 2026
Downloads
353/mo ยท 150/wk
Author
moikapy
License
MIT
Types
extension, skill
Size
170.7 KB
Dependencies
1 dependency ยท 2 peers
Pi manifest JSON
{
  "extensions": [
    "./dist/index.js"
  ],
  "skills": [
    "./skills/mcp/SKILL.md"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

@0xkobold/pi-mcp

Model Context Protocol (MCP) integration for pi-coding-agent

Connect to any MCP server and use its tools, resources, and prompts natively within your pi agent.

Features

  • ๐ŸŒ Four Transport Types - stdio, SSE, StreamableHTTP, and WebSocket
  • ๐Ÿ”ง Auto Tool Registration - MCP tools appear as native pi tools (with progressive dispatch for 50+ tool servers)
  • ๐Ÿ”’ Tool Filtering - Allowlist/denylist to control which tools are registered
  • ๐Ÿ“ฆ Resource Access - Read MCP server resources directly (with TTL caching)
  • ๐Ÿ’ฌ Prompt Templates - Use MCP prompt templates
  • ๐ŸŒฑ Roots Support - Servers can discover workspace roots
  • ๐Ÿ”„ Auto-Reconnect - Reconnects on disconnect with exponential backoff
  • ๐Ÿ” Env Interpolation - ${VAR} in config resolved from environment
  • ๐Ÿ“ฅ Claude Desktop Import - Import servers from ~/.claude/mcp.json
  • ๐Ÿ’Š Health Monitoring - Uptime, call counts, error tracking in /mcp status
  • ๐Ÿงช Sampling Support - Handle MCP sampling/createMessage requests via configurable callback
  • ๐Ÿ—‚๏ธ Multi-Project Config - .0xkobold/mcp.json merges with global config
  • โš™๏ธ Hot Config - Add/remove servers without restart (commands)

Quick Start

1. Configure servers

Edit ~/.0xkobold/mcp.json:

{
  "servers": [
    {
      "name": "filesystem",
      "transport": {
        "type": "stdio",
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user"]
      },
      "enabled": true,
      "autoReconnect": true
    }
  ],
  "importClaudeDesktop": true
}

2. Or use commands

/mcp add filesystem npx -y @modelcontextprotocol/server-filesystem /home/user
/mcp enable filesystem
/mcp connect filesystem

3. Use tools

The agent will automatically discover and use MCP tools. You can also:

/mcp list          # See all configured servers
/mcp status        # See active connections
/mcp discover      # Find available tools

Commands

Command Description
/mcp Show help
/mcp list List all configured servers
/mcp connect <name> Connect to a server
/mcp disconnect <name> Disconnect from a server
/mcp enable <name> Enable auto-connect for a server
/mcp disable <name> Disable auto-connect for a server
/mcp add <name> <cmd> [args] Add a stdio server
/mcp add-http <name> <url> Add an HTTP server
/mcp add-ws <name> <url> Add a WebSocket server
/mcp filter <name> allow <tools> Only register listed tools for server
/mcp filter <name> deny <tools> Register all except listed tools
/mcp filter <name> clear Remove tool filters for server
/mcp remove <name> Remove a server from config
/mcp refresh <name> Re-discover tools/resources/prompts
/mcp import Import servers from Claude Desktop config
/mcp status Show active connections

Tools

Tool Description
mcp_discover List available MCP tools, resources, and prompts
mcp_call_tool Call any MCP tool by server + tool name
mcp_<server>_<tool> Individual tools (auto-registered per server)
mcp_<server>_read_resource Read a resource from an MCP server
mcp_<server>_get_prompt Get a prompt from an MCP server

Transport Types

stdio

Spawns a local process and communicates via stdin/stdout:

{
  "type": "stdio",
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"],
  "env": { "API_KEY": "..." },
  "cwd": "/working/dir"
}

StreamableHTTP

Modern HTTP transport (recommended for remote servers):

{
  "type": "streamable-http",
  "url": "https://example.com/mcp",
  "headers": { "Authorization": "Bearer ..." }
}

SSE (legacy)

Server-Sent Events transport:

{
  "type": "sse",
  "url": "https://example.com/sse"
}

WebSocket

Real-time bidirectional transport:

{
  "type": "websocket",
  "url": "ws://localhost:8080/mcp"
}

Tool Filtering

Control which tools are registered per server using allowlist or denylist:

// Only register specific tools (allowlist)
{
  "name": "filesystem",
  "allowedTools": ["read_file", "list_directory"],
  ...
}

// Register all except (denylist)
{
  "name": "github",
  "deniedTools": ["delete_repository", "create_issue"],
  ...
}

Or via commands:

/mcp filter github allow search_repositories,get_file_contents
/mcp filter filesystem deny write_file,delete_file
/mcp filter github clear

Environment Variable Interpolation

Use ${ENV_VAR} patterns in config values to avoid hardcoding secrets:

{
  "name": "github",
  "transport": {
    "type": "stdio",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-github"],
    "env": {
      "GITHUB_TOKEN": "${GITHUB_TOKEN}"
    }
  }
}

HTTP headers also support interpolation:

{
  "transport": {
    "type": "streamable-http",
    "url": "https://api.example.com/mcp",
    "headers": {
      "Authorization": "Bearer ${API_TOKEN}"
    }
  }
}

As a Library

You can use @0xkobold/pi-mcp as a standalone library, without pi-coding-agent:

// Main entry โ€” extension + all re-exports
import mcpExtension, {
  MCPConnectionManager,
  ResourceCache,
  interpolateEnv,
  loadConfig,
  saveConfig,
  createDefaultConfig,
  isToolAllowed,
} from "@0xkobold/pi-mcp";

// Client subpath โ€” connection management only
import { MCPConnectionManager, type MCPServerConfig } from "@0xkobold/pi-mcp/client";

// Config subpath โ€” config loading/saving only
import { loadConfig, upsertServer, type MCPConfig } from "@0xkobold/pi-mcp/config";

// Tools subpath โ€” tool registration utilities only
import { isToolAllowed, DEFAULT_MAX_TOOLS } from "@0xkobold/pi-mcp/tools";

Quick start without pi-coding-agent:

import { MCPConnectionManager } from "@0xkobold/pi-mcp/client";

const manager = new MCPConnectionManager([process.cwd()]);

const serverConfig = {
  name: "filesystem",
  transport: { type: "stdio", command: "npx", args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"] },
  enabled: true,
  autoReconnect: true,
};

const info = await manager.connect(serverConfig);
console.log(`Connected: ${info.tools.length} tools`);

const result = await manager.callTool("filesystem", "read_file", { path: "/tmp/hello.txt" });
console.log(result);

Architecture

src/
โ”œโ”€โ”€ index.ts          # Extension entry point (commands, tools, lifecycle)
โ”œโ”€โ”€ client/
โ”‚   โ””โ”€โ”€ index.ts      # MCPConnectionManager, ResourceCache, env interpolation
โ”œโ”€โ”€ config/
โ”‚   โ””โ”€โ”€ index.ts      # Config loading/saving, Claude Desktop import, project merge
โ””โ”€โ”€ tools/
    โ””โ”€โ”€ index.ts      # Tool bridge - MCP tools โ†’ pi tools (with filtering)

Configuration

Config file: ~/.0xkobold/mcp.json

Full schema:

{
  "servers": [
    {
      "name": "string (required)",
      "transport": {
        "type": "stdio | sse | streamable-http | websocket",
        // stdio fields:
        "command": "string",
        "args": ["string"],
        "env": {},
        "cwd": "string",
        // http/sse fields:
        "url": "string",
        "headers": {},
        "sessionId": "string",
        // websocket fields:
        "url": "ws://..."
      },
      "enabled": false,
      "autoReconnect": true,
      "maxReconnectAttempts": 5,
      "reconnectDelayMs": 1000,
      "connectTimeoutMs": 30000,
      "allowedTools": ["tool_name"],
      "deniedTools": ["tool_name"],
      "maxTools": 50
    }
  ],
  "importClaudeDesktop": true
}

Claude Desktop Compatibility

Set "importClaudeDesktop": true to automatically discover servers from:

  • ~/.claude/mcp.json
  • ~/.config/claude-code/mcp.json

Or run /mcp import to manually import.

Development

# Install dependencies
bun install

# Build
bun run build

# Development watch
bun run dev

# Test
bun test    # 95 tests, 182 assertions
bun test test/unit.test.ts  # Unit tests only
bun test test/integration.test.ts  # Integration tests (requires npx)

Sampling Support

MCP servers can request LLM sampling via sampling/createMessage. The extension registers a handler for this capability.

  • Default handler: Logs the request and returns a placeholder response (pi extensions don't have direct LLM completion access)
  • Custom handler: Pass a SamplingHandler function to MCPConnectionManager constructor:
import { MCPConnectionManager, type SamplingHandler } from "@0xkobold/pi-mcp/client";

const handler: SamplingHandler = async (params) => {
  // Bridge to your LLM here
  return {
    role: "assistant",
    content: { type: "text", text: "LLM response" },
    model: "your-model",
    stopReason: "endTurn",
  };
};

const manager = new MCPConnectionManager(["/workspace"], 50, 300_000, handler);

License

MIT