MCPcopy Create free account
hub / github.com/garrytan/gstack / startStubMcpServer

Function startStubMcpServer

test/skill-e2e-setup-gbrain-remote.test.ts:29–81  ·  view source on GitHub ↗
(opts: { failWithStatus?: number; failBody?: string } = {})

Source from the content-addressed store, hash-verified

27
28// Spin up a stub MCP server that responds to initialize + tools/list.
29function startStubMcpServer(opts: { failWithStatus?: number; failBody?: string } = {}): Promise<{ url: string; close: () => Promise<void> }> {
30 return new Promise((resolve) => {
31 const server = http.createServer((req, res) => {
32 if (req.method !== 'POST' || !(req.url ?? '').endsWith('/mcp')) {
33 res.statusCode = 404;
34 res.end();
35 return;
36 }
37 let body = '';
38 req.on('data', (c) => (body += c));
39 req.on('end', () => {
40 if (opts.failWithStatus) {
41 res.statusCode = opts.failWithStatus;
42 res.setHeader('Content-Type', 'application/json');
43 res.end(opts.failBody ?? JSON.stringify({ error: 'fail' }));
44 return;
45 }
46 const reqJson = (() => {
47 try { return JSON.parse(body); } catch { return {} as any; }
48 })();
49 let respBody: any;
50 if (reqJson.method === 'initialize') {
51 respBody = {
52 result: {
53 protocolVersion: '2024-11-05',
54 capabilities: { tools: {} },
55 serverInfo: { name: 'gbrain', version: '0.27.1' },
56 },
57 jsonrpc: '2.0',
58 id: reqJson.id,
59 };
60 } else if (reqJson.method === 'tools/list') {
61 respBody = { result: { tools: [{ name: 'search' }, { name: 'put_page' }] }, jsonrpc: '2.0', id: reqJson.id };
62 } else {
63 respBody = { error: { code: -32601, message: 'unknown method' }, jsonrpc: '2.0', id: reqJson.id };
64 }
65 // SSE-shape since the verify helper supports both, and many MCP
66 // servers (including wintermute) wrap responses as SSE.
67 res.statusCode = 200;
68 res.setHeader('Content-Type', 'text/event-stream');
69 res.end(`event: message\ndata: ${JSON.stringify(respBody)}\n\n`);
70 });
71 });
72 server.listen(0, '127.0.0.1', () => {
73 const addr = server.address();
74 if (!addr || typeof addr === 'string') throw new Error('no address');
75 resolve({
76 url: `http://127.0.0.1:${addr.port}/mcp`,
77 close: () => new Promise((r) => server.close(() => r())),
78 });
79 });
80 });
81}
82
83// Stubbed `claude` binary: intercepts `mcp add` and `mcp list` commands so
84// the skill's Step 5a registration appears to succeed, while we record

Calls 2

endMethod · 0.80
closeMethod · 0.65

Tested by

no test coverage detected