Files
ycode/scripts/test-mcp-server.mjs

33 lines
2.2 KiB
JavaScript

// Controlled real SDK server: stdio child or imported HTTP server factory. No external calls.
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js'
import { appendFile } from 'node:fs/promises'
export function fixtureServer(label, events, secret = '') {
const server = new Server({ name: 'ycode-controlled-' + label, version: '1.0.0' }, { capabilities: { tools: {} } })
const tool = name => ({ name, description: name === 'secret' ? 'Fixture secret masking' : 'Controlled ' + label + ' ' + name, inputSchema: { type: 'object', properties: { text: { type: 'string' } } } })
server.setRequestHandler(ListToolsRequestSchema, async request => {
await events({ type: 'list', cursor: request.params?.cursor || null })
return request.params?.cursor ? { tools: [tool('wait'), tool('secret'), tool('failure')] } : { tools: [tool('echo')], nextCursor: 'second' }
})
server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
await events({ type: 'call', name: request.params.name })
if (request.params.name === 'wait') {
await new Promise((resolve, reject) => {
const timer = setTimeout(resolve, 10000)
extra.signal.addEventListener('abort', () => { clearTimeout(timer); void events({ type: 'cancel' }); reject(Error('Cancelled fixture')) }, { once: true })
})
}
if (request.params.name === 'failure') throw Error('Controlled failure ' + secret)
return { content: [{ type: 'text', text: request.params.name === 'secret' ? secret : label + ':' + (request.params.arguments?.text || '') }], isError: false }
})
return server
}
if (process.argv[2] === 'stdio') {
const events = event => appendFile(process.argv[3], JSON.stringify(event) + '\n')
const server = fixtureServer('stdio', events, process.env.FIXTURE_SECRET || '')
// The host must discard server stderr, including credential-bearing diagnostics.
process.stderr.write('fixture stderr ' + (process.env.FIXTURE_SECRET || '') + '\n')
await server.connect(new StdioServerTransport())
}