v1.14.1-mcp-poc: single-server MCP client against Context7
Validates the MCP-client loop end-to-end against one real MCP server before the full v1.15 port. New services/mcp-client.ts wraps @modelcontextprotocol/sdk v1.29.0 with Streamable HTTP transport. On startup (when MCP_CONTEXT7_URL is set), connects to Context7, discovers tools via tools/list, wraps each as a ToolDef prefixed context7_<name>, and appends to ALL_TOOLS via appendMcpTools. Read-only invariant guard rejects any tool with readOnlyHint: false. Tool dispatch is transparent — executeToolCall routes MCP calls through the ToolDef execute wrapper, which strips the prefix before calling the MCP server. Result size capped at 5MB with truncation. Graceful degradation: server down at startup → zero tools; server down mid-session → error result, model self-corrects. Adversarial review caught that a Zod .default() on the URL config made MCP always-on instead of opt-in — fixed by removing the default. MCP_CONTEXT7_URL must be explicitly set to enable. ALL_TOOLS changed from ReadonlyArray to mutable to support late-registration. appendMcpTools re-sorts and rebuilds TOOLS_BY_NAME after append. 348/348 server tests passing (16 new mcp-client tests). No schema changes, no frontend changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,8 @@ import { listSkills } from './services/skills.js';
|
||||
import * as compaction from './services/compaction.js';
|
||||
import { configureModelContext } from './services/model-context.js';
|
||||
import { cleanupTruncations } from './services/truncate.js';
|
||||
import { initialize as initMcpClient, getTools as getMcpTools } from './services/mcp-client.js';
|
||||
import { appendMcpTools } from './services/tools.js';
|
||||
|
||||
async function main() {
|
||||
const config = loadConfig();
|
||||
@@ -69,6 +71,22 @@ async function main() {
|
||||
// default_generation_settings.n_ctx — the value persisted as messages.ctx_max.
|
||||
configureModelContext({ llamaSwapUrl: config.LLAMA_SWAP_URL });
|
||||
|
||||
// v1.14.1-mcp-poc: connect to Context7 MCP server and register discovered
|
||||
// tools into ALL_TOOLS. Runs before route registration so the tool list is
|
||||
// complete when the first inference request arrives. Graceful degradation:
|
||||
// if Context7 is unreachable, zero MCP tools are registered and BooCode
|
||||
// functions normally with native tools.
|
||||
if (config.MCP_CONTEXT7_URL) {
|
||||
await initMcpClient(config, app.log);
|
||||
const mcpTools = getMcpTools();
|
||||
if (mcpTools.length > 0) {
|
||||
appendMcpTools(mcpTools);
|
||||
app.log.info({ count: mcpTools.length }, 'mcp: registered Context7 tools');
|
||||
}
|
||||
} else {
|
||||
app.log.info('mcp: MCP_CONTEXT7_URL not configured, skipping');
|
||||
}
|
||||
|
||||
await app.register(fastifyWebsocket);
|
||||
|
||||
app.get('/api/health', async () => {
|
||||
|
||||
Reference in New Issue
Block a user