Kind
behavioural
Problem
Agent clients defer MCP tool schemas: until the model actively searches for a tool, the discovery signal is the tool name alone — descriptions and schemas surface only afterwards. Today okf mcp presents a name-only surface (okf-<name>__list-concepts, …) with bundle-blind descriptions ("List every concept in the bundle" — which bundle?), and its initialize result carries no instructions (observed: only capabilities, protocolVersion, serverInfo).
The server is launched per bundle, so it knows exactly which bundle it serves — but it never says so. In the first real deployment (the Anago bundle, 342 concepts, served to Claude Code), the result is that agents fall back to file greps and only reach for the tools when a human names the server explicitly. The per-bundle launch model should be the fix, not the cause: identity is known at startup and can be put in front of the model.
What to build
-
Initialize instructions. Return an instructions string (mcp_dart ≥ 2.4 supports it) identifying the served bundle — absolute root, title (bundle index.md H1), concept count — plus one sentence on when to prefer the tools: enumerating concepts, following relationships (query-graph), and reproducing the CI gate (validate) instead of ad-hoc file reads.
-
Bundle-aware tool descriptions. Interpolate the bundle identity into every tool description at startup, e.g. List every concept in the "<title>" knowledge bundle at <root>, with metadata. The fixed tool names stay fixed; only descriptions gain identity.
-
Optional bundle argument with deterministic discovery. Keep the one-server-per-bundle process model — a generic multi-bundle server with a per-call bundle parameter would reintroduce exactly the ambiguity this issue removes, and no real workflow needs it yet. Instead make registration generic: okf mcp with no argument serves the bundle discovered from the working directory by a closed rule — the cwd itself if it is a bundle root, else the single immediate child directory that is a bundle root; anything else (zero or several candidates) is a startup error on stderr naming the candidates. Clients that launch stdio servers with cwd at the project root then need only one registration line for every project.
Acceptance criteria
Context
Kind
behaviouralProblem
Agent clients defer MCP tool schemas: until the model actively searches for a tool, the discovery signal is the tool name alone — descriptions and schemas surface only afterwards. Today
okf mcppresents a name-only surface (okf-<name>__list-concepts, …) with bundle-blind descriptions ("List every concept in the bundle" — which bundle?), and its initialize result carries noinstructions(observed: onlycapabilities,protocolVersion,serverInfo).The server is launched per bundle, so it knows exactly which bundle it serves — but it never says so. In the first real deployment (the Anago bundle, 342 concepts, served to Claude Code), the result is that agents fall back to file greps and only reach for the tools when a human names the server explicitly. The per-bundle launch model should be the fix, not the cause: identity is known at startup and can be put in front of the model.
What to build
Initialize
instructions. Return aninstructionsstring (mcp_dart ≥ 2.4 supports it) identifying the served bundle — absolute root, title (bundleindex.mdH1), concept count — plus one sentence on when to prefer the tools: enumerating concepts, following relationships (query-graph), and reproducing the CI gate (validate) instead of ad-hoc file reads.Bundle-aware tool descriptions. Interpolate the bundle identity into every tool description at startup, e.g.
List every concept in the "<title>" knowledge bundle at <root>, with metadata.The fixed tool names stay fixed; only descriptions gain identity.Optional bundle argument with deterministic discovery. Keep the one-server-per-bundle process model — a generic multi-bundle server with a per-call
bundleparameter would reintroduce exactly the ambiguity this issue removes, and no real workflow needs it yet. Instead make registration generic:okf mcpwith no argument serves the bundle discovered from the working directory by a closed rule — the cwd itself if it is a bundle root, else the single immediate child directory that is a bundle root; anything else (zero or several candidates) is a startup error on stderr naming the candidates. Clients that launch stdio servers with cwd at the project root then need only one registration line for every project.Acceptance criteria
instructionsnaming the bundle root and title of the served bundle.tools/listdescription contains the bundle identity.okf mcpwith no argument serves the cwd-discovered bundle per the closed rule; ambiguous or absent discovery exits non-zero with the diagnostic on stderr, and stdout stays pure JSON-RPC throughout (per the MCP server: read surface #11 contract).okf mcp <bundle>behaviour is unchanged.Context
okfp mcpcomposing this server's machinery; whatever identity/instructions seam lands here should be reusable there.