npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@0xkobold/pi-mcp

v0.4.0

Published

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.

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