Files
claude-code/packages/@ant/claude-for-chrome-mcp/src/mcpServer.ts
unraid 6738a76152 feat: enable Claude in Chrome MCP with full browser control
Replace the 6-line stub in @ant/claude-for-chrome-mcp with the complete
implementation (8 files, 3038 lines) from the reference project.

Provides 17 browser tools: navigate, screenshot, click, type, read DOM,
execute JS, record GIF, monitor console/network, manage tabs, etc.

No feature flag needed. No changes to src/ (already matches official).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 21:46:07 +08:00

97 lines
2.7 KiB
TypeScript

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { createBridgeClient } from "./bridgeClient.js";
import { BROWSER_TOOLS } from "./browserTools.js";
import { createMcpSocketClient } from "./mcpSocketClient.js";
import { createMcpSocketPool } from "./mcpSocketPool.js";
import { handleToolCall } from "./toolCalls.js";
import type { ClaudeForChromeContext, SocketClient } from "./types.js";
/**
* Create the socket/bridge client for the Chrome extension MCP server.
* Exported so Desktop can share a single instance between the registered
* MCP server and the InternalMcpServerManager (CCD sessions).
*/
export function createChromeSocketClient(
context: ClaudeForChromeContext,
): SocketClient {
return context.bridgeConfig
? createBridgeClient(context)
: context.getSocketPaths
? createMcpSocketPool(context)
: createMcpSocketClient(context);
}
export function createClaudeForChromeMcpServer(
context: ClaudeForChromeContext,
existingSocketClient?: SocketClient,
): Server {
const { serverName, logger } = context;
// Choose transport: bridge (WebSocket) > socket pool (multi-profile) > single socket.
const socketClient =
existingSocketClient ?? createChromeSocketClient(context);
const server = new Server(
{
name: serverName,
version: "1.0.0",
},
{
capabilities: {
tools: {},
logging: {},
},
},
);
server.setRequestHandler(ListToolsRequestSchema, async () => {
if (context.isDisabled?.()) {
return { tools: [] };
}
return {
tools: context.bridgeConfig
? BROWSER_TOOLS
: BROWSER_TOOLS.filter((t) => t.name !== "switch_browser"),
};
});
server.setRequestHandler(
CallToolRequestSchema,
async (request): Promise<CallToolResult> => {
logger.info(`[${serverName}] Executing tool: ${request.params.name}`);
return handleToolCall(
context,
socketClient,
request.params.name,
request.params.arguments || {},
);
},
);
socketClient.setNotificationHandler((notification) => {
logger.info(
`[${serverName}] Forwarding MCP notification: ${notification.method}`,
);
server
.notification({
method: notification.method,
params: notification.params,
})
.catch((error) => {
// Server may not be connected yet (e.g., during startup or after disconnect)
logger.info(
`[${serverName}] Failed to forward MCP notification: ${error.message}`,
);
});
});
return server;
}