diff --git a/extensions/cate.mcp/README.md b/extensions/cate.mcp/README.md index a52afaa..a33dda1 100644 --- a/extensions/cate.mcp/README.md +++ b/extensions/cate.mcp/README.md @@ -30,7 +30,7 @@ Built directly on the official [`@modelcontextprotocol/sdk`](https://www.npmjs.c - **Unified MCP endpoint at `/mcp`**: the extension server itself is an MCP server (streamable HTTP) aggregating every tool/resource/prompt of every enabled and running managed server, deterministically namespaced `__`. Upstream failures come back as tool errors, never protocol crashes; `listChanged` fires when upstreams change. Auth is the same bearer token Cate injects. The panel's Endpoint card shows the URL and header with copy buttons; point any MCP client (including a coding agent) at it. -- **One-click install into coding agents**: the Endpoint screen writes this endpoint into each agent's workspace-local config — Cate Agent (`.pi/mcp.json`, read by the `pi-mcp-adapter` package), Claude Code (`.mcp.json`), Cursor (`.cursor/mcp.json`), OpenCode (`opencode.json`), and Codex (`.codex/config.toml`), each in that agent's own shape, preserving every other key. Antigravity (global-only config) and PI (no MCP) are listed but disabled with the reason. The endpoint's port/token are reminted each Cate session, so an install is a snapshot: a stale entry is flagged with an Update button, and the endpoint only serves while the panel is open. +- **One-click install into coding agents**: the Endpoint screen writes this endpoint into each agent's workspace-local config — Agent panel (`.pi/mcp.json`, read by the `pi-mcp-adapter` package), Claude Code (`.mcp.json`), Cursor (`.cursor/mcp.json`), OpenCode (`opencode.json`), and Codex (`.codex/config.toml`), each in that agent's own shape, preserving every other key. Antigravity (global-only config) and PI (no MCP) are listed but disabled with the reason. The endpoint's port/token are reminted each Cate session, so an install is a snapshot: a stale entry is flagged with an Update button, and the endpoint only serves while the panel is open. - **Discover tab**: searches the official registry at `registry.modelcontextprotocol.io` (`GET /v0/servers?search=…` with cursor pagination) and one-click prefills the add-server form from a registry entry's npm/pypi/oci package or remote URL. Registry failures stay inside that tab. diff --git a/extensions/cate.mcp/manifest.json b/extensions/cate.mcp/manifest.json index 7d30108..b11dce2 100644 --- a/extensions/cate.mcp/manifest.json +++ b/extensions/cate.mcp/manifest.json @@ -1,7 +1,7 @@ { "id": "cate.mcp", "name": "MCP Servers", - "version": "1.3.0", + "version": "1.3.1", "description": "Native MCP server manager. Configure stdio and remote MCP servers in .cate/mcp.json, supervise them with health checks and auto-restart, browse their tools/resources/prompts, invoke tools from a playground, discover servers in the official MCP registry, and expose everything through one aggregated MCP endpoint any client can connect to.", "panels": [ { diff --git a/extensions/cate.mcp/package.json b/extensions/cate.mcp/package.json index c447e16..3d37756 100644 --- a/extensions/cate.mcp/package.json +++ b/extensions/cate.mcp/package.json @@ -1,7 +1,7 @@ { "name": "cate-mcp-extension", "private": true, - "version": "1.3.0", + "version": "1.3.1", "description": "Native MCP server manager, a server-backed Cate extension.", "scripts": { "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"", diff --git a/extensions/cate.mcp/src/server/agent-install.test.ts b/extensions/cate.mcp/src/server/agent-install.test.ts index 4453df2..b2bf52b 100644 --- a/extensions/cate.mcp/src/server/agent-install.test.ts +++ b/extensions/cate.mcp/src/server/agent-install.test.ts @@ -31,7 +31,7 @@ describe('AgentInstaller.list', () => { it('lists all agents; two are unsupported with a reason', () => { const agents = new AgentInstaller(tmp).list(EP) expect(agents.map((a) => a.id).sort()).toEqual( - ['antigravity', 'cate-agent', 'claude-code', 'codex', 'cursor', 'opencode', 'pi'].sort(), + ['agent-panel', 'antigravity', 'claude-code', 'codex', 'cursor', 'opencode', 'pi'].sort(), ) const anti = agents.find((a) => a.id === 'antigravity')! const pi = agents.find((a) => a.id === 'pi')! @@ -39,7 +39,7 @@ describe('AgentInstaller.list', () => { expect(anti.reason).toBeTruthy() expect(pi.supported).toBe(false) expect(agents.filter((a) => a.supported).map((a) => a.id).sort()).toEqual( - ['cate-agent', 'claude-code', 'codex', 'cursor', 'opencode'], + ['agent-panel', 'claude-code', 'codex', 'cursor', 'opencode'], ) }) @@ -99,13 +99,13 @@ describe('Claude Code (.mcp.json)', () => { }) }) -describe('Cate Agent (.pi/mcp.json, read by pi-mcp-adapter)', () => { +describe('Agent panel (.pi/mcp.json, read by pi-mcp-adapter)', () => { it('installs a url entry the adapter can read', () => { const inst = new AgentInstaller(tmp) - expect(inst.install('cate-agent', EP)).toEqual({ ok: true }) + expect(inst.install('agent-panel', EP)).toEqual({ ok: true }) const entry = JSON.parse(read('.pi/mcp.json')).mcpServers[ENTRY_NAME] expect(entry).toEqual({ url: EP.url, headers: { Authorization: `Bearer ${EP.token}` } }) - expect(statusOf(inst, 'cate-agent').installed).toBe(true) + expect(statusOf(inst, 'agent-panel').installed).toBe(true) }) }) diff --git a/extensions/cate.mcp/src/server/agent-install.ts b/extensions/cate.mcp/src/server/agent-install.ts index 0e0f8da..73838c2 100644 --- a/extensions/cate.mcp/src/server/agent-install.ts +++ b/extensions/cate.mcp/src/server/agent-install.ts @@ -228,13 +228,13 @@ function unsupported(id: string, label: string, relPath: string, reason: string) // --- registry --------------------------------------------------------------- const ADAPTERS: Adapter[] = [ - // Cate's own in-app agent (pi). pi has no native MCP, so this targets the + // The in-app agent panel (pi). pi has no native MCP, so this targets the // `pi-mcp-adapter` package's project-local pi config (`.pi/mcp.json`): a // top-level mcpServers map where a remote server is `url` + `headers`. The // adapter reads it on session start and proxies each server's tools. jsonAdapter({ - id: 'cate-agent', - label: 'Cate Agent', + id: 'agent-panel', + label: 'Agent panel', relPath: '.pi/mcp.json', sectionKey: 'mcpServers', buildEntry: (ep) => ({ url: ep.url, headers: bearer(ep.token) }),