MCP Integration
Overview
ClawGo ships MCP as a built-in runtime capability under tools.mcp. It is wired into configuration, runtime discovery, dynamic tool registration, and the WebUI:
- dedicated config schema under
tools.mcp - startup creates
MCPTool - remote MCP tools are discovered automatically
- discovered remote tools are registered as local ClawGo tools
- the WebUI has a dedicated MCP page
- the Gateway exposes an install endpoint for MCP servers
Recent WebUI changes also redesigned the MCP workflow into a server-card plus modal-editor flow:
- the main list shows one summary card per server
- create and edit actions now happen inside a modal
- save writes through
/api/configdirectly - discovered tools are shown in a separate section
- missing commands and install suggestions are surfaced both on the card and in the editor
For stdio servers, install assistance can now infer the installer from:
packageinstallercommand + args, such asnpx,uvx, orbunx
Supported Scope
Based on pkg/tools/mcp.go, pkg/config/validate.go, and the recent README changes, the supported transports are:
stdiohttpstreamable_httpsse
Supported bridge actions:
list_serverslist_toolscall_toollist_resourcesread_resourcelist_promptsget_prompt
Config Structure
Entry point:
{
"tools": {
"mcp": {
"enabled": true,
"request_timeout_sec": 20,
"servers": {
"context7": {
"enabled": true,
"transport": "stdio",
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"],
"env": {},
"working_dir": "tools/context7",
"permission": "workspace",
"description": "Context7 MCP server",
"package": "@upstash/context7-mcp"
}
}
}
}
}Per-server fields:
enabledtransportcommandargsurlenvworking_dirpermissiondescriptionpackage
Configuration Examples
Example 1: Minimal stdio Setup
This matches the current config.example.json shape:
{
"tools": {
"mcp": {
"enabled": true,
"request_timeout_sec": 20,
"servers": {
"context7": {
"enabled": true,
"transport": "stdio",
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"],
"working_dir": "tools/context7",
"permission": "workspace",
"package": "@upstash/context7-mcp"
}
}
}
}
}Example 2: Pin A Resolved Binary Path
{
"enabled": true,
"transport": "stdio",
"command": "/usr/local/bin/context7-mcp",
"args": [],
"permission": "full",
"working_dir": "/Users/example/project/tools/context7",
"package": "@upstash/context7-mcp"
}Example 3: Use A Hosted MCP Endpoint
{
"enabled": true,
"transport": "streamable_http",
"url": "https://mcp.example.com",
"description": "Hosted MCP server"
}Example 4: Pass Environment Variables
{
"enabled": true,
"transport": "stdio",
"command": "npx",
"args": ["-y", "@scope/example-mcp"],
"env": {
"EXAMPLE_API_KEY": "YOUR_KEY"
},
"permission": "workspace",
"working_dir": "tools/example"
}Validation Rules
The validator checks:
tools.mcp.request_timeout_sec > 0- server names are non-empty
transportmust be one ofstdio,http,streamable_http, orssestdioservers must definecommandhttp,streamable_http, andsseservers must defineurlpermissionmust beworkspaceorfull- with
permission = workspace,working_dirmay be relative but must resolve inside the workspace - with
permission = full,working_dirmay be absolute
What Happens At Startup
In pkg/agent/loop.go, when cfg.Tools.MCP.Enabled is true, ClawGo:
- creates
MCPTool - registers the
mcpbridge tool - creates a discovery context from
request_timeout_sec - calls
DiscoverTools() - registers each discovered remote tool as a local tool
That means the model can either call the generic mcp bridge or directly call discovered tools.
For http transport, initialization now also sends notifications/initialized as a real MCP notification without an id. This improves compatibility with stricter MCP servers.
Dynamic Tool Naming
Discovered remote tools are mapped into:
mcp__<server>__<tool>Examples:
mcp__context7__resolve_library_id
mcp__context7__query_docsThe names are sanitized, so spaces, dots, and other special characters are converted into safe identifiers.
MCP Bridge Tool Examples
List Configured Servers
{
"action": "list_servers"
}List Remote Tools
{
"action": "list_tools",
"server": "context7"
}Call A Remote Tool
{
"action": "call_tool",
"server": "context7",
"tool": "resolve-library-id",
"arguments": {
"libraryName": "vitepress",
"query": "How do I configure locales?"
}
}Read A Resource
{
"action": "read_resource",
"server": "context7",
"uri": "file:///absolute/path/to/file"
}Get A Prompt
{
"action": "get_prompt",
"server": "context7",
"prompt": "default",
"arguments": {
"topic": "vitepress locales"
}
}Dynamic Tool Usage Examples
After discovery, remote MCP tools can be called like normal local tools.
Example generated tool:
mcp__context7__resolve_library_idArguments:
{
"libraryName": "vitepress",
"query": "How do I configure locales?"
}Another example:
mcp__context7__query_docs{
"libraryId": "/vitejs/vitepress",
"query": "How do I add multiple locales?"
}WebUI Support
There is a dedicated page in:
webui/src/pages/MCP.tsx
It supports:
- adding and removing MCP servers
- switching between
stdio,http,streamable_http, andsse - editing
command,args,url,working_dir,permission, andpackage - checking whether the configured command exists
- suggesting install commands based on the package
- installing MCP servers with
npm,uv, orbun - viewing discovered
mcp__<server>__<tool>tools
Related WebUI APIs
GET /api/tools
Returns all tools and also:
mcp_toolsmcp_server_checks
The first list is for discovered remote tools. The second contains command-check results for configured servers.
POST /api/mcp/install
Example input:
{
"package": "@upstash/context7-mcp",
"installer": "npm"
}The server:
- ensures the required runtime is available
- runs the installer
- resolves the exposed binary
- returns
bin_nameandbin_path
Supported installers:
npmuvbun
Recommended Usage
For Fast Trials
- use
stdio + npx - keep
permissionasworkspace - use a workspace-relative
working_dir
For Stable Deployments
- pin
commandto the resolved binary path - use
httporstreamable_httpfor hosted MCP services - only use
permission: "full"when you really need it
Current Limits
There are still a few practical boundaries:
- dynamic tool discovery happens during startup
- changing an MCP server requires saving config and going through the follow-up discovery path
- transport support is broader now, but compatibility still depends on the target MCP server implementation