yvgude--lean-ctx
26382a7ac6
CI / Clippy (push) Failing after 15m13s
CI / Test (ubuntu-latest) (push) Failing after 16m1s
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Build (no embeddings / no ORT) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Cookbook (Node) (push) Has been cancelled
CI / Pi Extension (Node) (push) Has been cancelled
CI / Rust SDK (lean-ctx-client) (push) Has been cancelled
CI / Embed SDK (lean-ctx-sdk) (push) Has been cancelled
CI / Python SDK (leanctx) (push) Has been cancelled
CI / Hermes Plugin (Python) (push) Has been cancelled
CI / SDK Conformance Matrix (push) Has been cancelled
CI / Coverage (push) Has been cancelled
CI / cargo-deny (push) Has been cancelled
CI / Adversarial Safety (push) Has been cancelled
CI / Benchmarks (push) Has been cancelled
CI / Output-Quality Gate (eval A/B) (push) Has been cancelled
CI / Documentation (push) Has been cancelled
CI / CI Green (push) Has been cancelled
JetBrains Plugin / Actionlint (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (rust) (push) Has been cancelled
JetBrains Plugin / Validation (push) Has been cancelled
JetBrains Plugin / Build (push) Has been cancelled
JetBrains Plugin / Test (push) Has been cancelled
Security Check / Security Scan (push) Has been cancelled
91 行
3.7 KiB
JavaScript
91 行
3.7 KiB
JavaScript
#!/usr/bin/env node
|
|
// MCP stdio fixture for the deeper-addon-integration E2E (#1102).
|
|
//
|
|
// A *real* MCP stdio server (newline-delimited JSON-RPC 2.0) whose tools return
|
|
// the output shapes the L1–L4 pipeline consumes, so the gateway's production
|
|
// proxy → postprocess → adapters path is exercised end to end against a spawned
|
|
// child process (no protocol mocks). Tools:
|
|
// echo -> `echo:<text>` (drives L1/L2/L3 + secret redaction)
|
|
// pack_codebase -> repomix-shaped JSON {outputId, directoryStructure, …}
|
|
// query_graph -> code-graph JSON {edges:[{from,to,type}]}
|
|
// search_memories -> memory JSON {results:[{memory,id,score}]}
|
|
// compress_text -> `compressed:<text>` (drives the compression adapter)
|
|
// Only Node.js is required.
|
|
|
|
import { createInterface } from 'node:readline';
|
|
|
|
const rl = createInterface({ input: process.stdin });
|
|
const send = (msg) => process.stdout.write(JSON.stringify(msg) + '\n');
|
|
const textResult = (id, text) =>
|
|
send({ jsonrpc: '2.0', id, result: { content: [{ type: 'text', text }], isError: false } });
|
|
|
|
const TOOLS = [
|
|
{ name: 'echo', description: 'Echo back the provided text',
|
|
inputSchema: { type: 'object', properties: { text: { type: 'string' } }, required: ['text'] } },
|
|
{ name: 'pack_codebase', description: 'Pack a repository (repomix-shaped)',
|
|
inputSchema: { type: 'object', properties: { directory: { type: 'string' } } } },
|
|
{ name: 'query_graph', description: 'Return code-graph edges',
|
|
inputSchema: { type: 'object', properties: { q: { type: 'string' } } } },
|
|
{ name: 'search_memories', description: 'Search stored memories',
|
|
inputSchema: { type: 'object', properties: { query: { type: 'string' } } } },
|
|
{ name: 'compress_text', description: 'Compress text',
|
|
inputSchema: { type: 'object', properties: { text: { type: 'string' } }, required: ['text'] } },
|
|
];
|
|
|
|
function callTool(id, name, args) {
|
|
switch (name) {
|
|
case 'echo':
|
|
return textResult(id, 'echo:' + (args.text ?? ''));
|
|
case 'compress_text':
|
|
return textResult(id, 'compressed:' + (args.text ?? ''));
|
|
case 'pack_codebase':
|
|
return textResult(id, JSON.stringify({
|
|
outputId: 'rmx_e2e_001',
|
|
directoryStructure: 'src/\n auth.rs\n db.rs\n',
|
|
totalFiles: 2,
|
|
totalTokens: 4321,
|
|
}));
|
|
case 'query_graph':
|
|
return textResult(id, JSON.stringify({
|
|
edges: [
|
|
{ from: 'src/auth.rs', to: 'src/db.rs', type: 'calls' },
|
|
{ from: 'src/api.rs', to: 'src/auth.rs', type: 'imports' },
|
|
],
|
|
}));
|
|
case 'search_memories':
|
|
return textResult(id, JSON.stringify({
|
|
results: [
|
|
{ memory: 'the user prefers structured logging', id: 'mem-e2e-1', score: 0.88 },
|
|
],
|
|
}));
|
|
default:
|
|
return send({ jsonrpc: '2.0', id, error: { code: -32602, message: 'unknown tool: ' + name } });
|
|
}
|
|
}
|
|
|
|
rl.on('line', (line) => {
|
|
const trimmed = line.trim();
|
|
if (!trimmed) return;
|
|
let req;
|
|
try { req = JSON.parse(trimmed); } catch { return; }
|
|
const { id, method, params } = req;
|
|
|
|
if (method === 'initialize') {
|
|
send({ jsonrpc: '2.0', id, result: {
|
|
protocolVersion: (params && params.protocolVersion) || '2025-06-18',
|
|
capabilities: { tools: {} },
|
|
serverInfo: { name: 'mcp-stdio-addon', version: '0.1.0' },
|
|
} });
|
|
} else if (method === 'notifications/initialized') {
|
|
// no response
|
|
} else if (method === 'tools/list') {
|
|
send({ jsonrpc: '2.0', id, result: { tools: TOOLS } });
|
|
} else if (method === 'tools/call') {
|
|
callTool(id, params && params.name, (params && params.arguments) || {});
|
|
} else if (id !== undefined && id !== null) {
|
|
send({ jsonrpc: '2.0', id, error: { code: -32601, message: 'method not found: ' + method } });
|
|
}
|
|
});
|
|
|
|
rl.on('close', () => process.exit(0));
|