Skip to content

feat: Add MCP Server Catalog with Per-Tool Agent Grants#3

Draft
bornakapusta wants to merge 8 commits intomainfrom
feat/mcp-server-catalog
Draft

feat: Add MCP Server Catalog with Per-Tool Agent Grants#3
bornakapusta wants to merge 8 commits intomainfrom
feat/mcp-server-catalog

Conversation

@bornakapusta
Copy link

Summary

  • Add global MCP server catalog where admins configure MCP servers once, discover tools via mcporter, and grant individual tools to agents
  • New mcpServers DB table with AES-256-GCM encrypted env vars, audit trail integration, and full CRUD API
  • pinchy-mcp OpenClaw plugin bridges MCP tools into agents via mcporter runtime with per-agent scoping
  • Settings page gets admin-only "MCP Servers" tab with add/edit/delete, status badges, test connection, and tool discovery
  • Agent permissions page gets "MCP Tools" section with tools grouped by server name
  • Config generation writes mcporter.json (0o600 permissions) and pinchy-mcp plugin config only when agents have MCP tools
  • Smithers knows about MCP servers and can guide admins through setup

Architecture

Admin configures MCP server in Pinchy UI
  → Stored in DB (mcpServers table, credentials encrypted)
  → Admin discovers tools, grants specific ones to agents
  → regenerateOpenClawConfig() generates mcporter.json + plugin config
  → pinchy-mcp plugin uses mcporter createRuntime() to connect
  → Plugin registers granted tools per-agent via api.registerTool()
  → Agent calls MCP tool → plugin → mcporter → MCP server
  → pinchy-audit hooks capture tool calls automatically

Changes

  • DB: New mcp_servers table + migration
  • Audit: mcp_server resource with created/updated/deleted events
  • Library: lib/mcp-servers.ts — CRUD, discovery, slug gen, config building
  • API: 6 new routes under /api/mcp-servers/
  • Config gen: Extends regenerateOpenClawConfig() with mcporter.json + pinchy-mcp
  • Plugin: packages/plugins/pinchy-mcp/ — mcporter bridge with factory scoping
  • Docker: Plugin copied to extensions, mcporter installed in OpenClaw container
  • UI: SettingsMcpServers component + MCP tools in agent permissions
  • Smithers: Updated platform knowledge

Testing

  • 46 new tests across lib, API, plugin, config gen, and tool registry
  • All 1535 existing tests pass
  • Production build verified

Post-Deploy Monitoring & Validation

  • What to monitor: Look for [pinchy-mcp] log entries in OpenClaw container
  • Validation: Add an MCP server in Settings → MCP Servers, verify tools discovered, grant to agent, test tool call in chat
  • Failure signal: Agent gets "Error calling MCP tool" messages or pinchy-mcp logs runtime errors
  • Rollback: Remove all MCP servers from Settings, regenerate config — agents revert to built-in tools only
  • Window: First 24 hours after deploy

…ore library

Add mcpServers DB table with encrypted env vars, extend audit trail with
mcp_server resource, and create lib/mcp-servers.ts with CRUD operations,
tool discovery via mcporter, slug generation, and mcporter config building.
CRUD routes (GET/POST/PATCH/DELETE), test connection, discover tools,
and flat tool list endpoints. All admin-only with audit logging. Extend
tool registry with "mcp" category and async getAllToolDefinitions().
…er.json

Generate mcporter.json with decrypted env vars (0o600 permissions) and
pinchy-mcp plugin config with per-agent tool grants when agents have
MCP tools assigned.
Plugin uses mcporter to bridge MCP server tools into OpenClaw agents.
Factory-based per-agent scoping, lazy runtime init, error returns (never
throws). Docker updates: copy plugin to extensions, install mcporter in
OpenClaw container.
Settings page gets new admin-only MCP Servers tab with CRUD table,
add/edit dialogs, status badges, test connection and refresh tools
buttons. Agent permissions page gets MCP Tools section with tools
grouped by server name.
mcporter requires Node.js built-ins (child_process, fs) that can't be
bundled for the browser. The dynamic import chain through tool-registry
pulled mcporter into client bundles. Remove server-only function since
the permissions UI fetches MCP tools via the HTTP API instead.
…p next to 16.1.7

- serverExternalPackages: ["mcporter"] prevents Turbopack from trying to
  resolve Node.js built-ins (child_process, fs) in mcporter at compile time
- Exclude .next/ from vitest to prevent running mcporter's bundled tests
- Bump next 16.1.6 → 16.1.7 to fix 5 security vulnerabilities (CSRF,
  request smuggling, image cache DoS, postponed buffering DoS, HMR CSRF)
@nickmarden
Copy link

@bornakapusta this feels like something @clemenshelm might want directly on the upstream. Perhaps you should open the MR against heypinchy/pinchy main instead of our main?

@bornakapusta bornakapusta marked this pull request as draft March 18, 2026 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants