feat(mcp): the server carries the working method, and describe fans out
**A subagent inherits its session's MCP tools; it does not inherit its skills.** So the method A3 put in the skill reaches the main thread and no arm running below it, and the one place every caller sees is the server's own `instructions` and its tool descriptions. Both are truncated by Claude Code at 2 KB, and truncation is worse than rejection here -- a reader gets the first half of a method and no sign the rest existed -- so what travels is the SHORT form and the long one stays in the skill, which has no such cap. A test holds it under the limit WITH a control, so the assertion is a measurement and not a tautology. `okf_describe` without `bundle_id` now describes every served bundle, where it refused and `okf_ask` in the same position fanned out. The tool a caller is told to read FIRST was the one requiring a name it did not have yet, and a tool that refuses the call its sibling accepts is a shape a client must be told out of band -- the configuration this server exists to remove. The named call's shape is byte-unchanged, and so is every one-to-one server's: the fan-out replaces an ERROR, so no caller's bytes move. `okf project`'s closing lines and the README's first screen carry the one line the USER runs to register the server on user scope, verified against Claude Code's own MCP documentation (`claude mcp add [options] <name> -- <command>`). Nothing here starts Claude Code, and the line says whose it is. Measured: a project bundle at `<root>/<project>/.okf/<id>` is depth 3, inside `MAX_DISCOVERY_DEPTH`, so a `--root` server finds what `okf project` wrote -- a test builds one and discovers it rather than reasoning about the walk. A5, and it was free: `okf skill` without `--out` now refuses in the same `refused (<code>)` form as every other refusal in this chain. The exit code does not move -- 2 was already right, "the run did not happen" -- what was wrong was that a caller parsing our form got argparse's line on the one flag everybody forgets. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
30edd3f5d8
commit
e3408435d0
5 changed files with 289 additions and 13 deletions
26
README.md
26
README.md
|
|
@ -20,6 +20,19 @@ okf project ~/my-documents # folder in: bundle + Claude Code skill, in this di
|
|||
claude # start Claude Code here
|
||||
```
|
||||
|
||||
**Or connect every bundle at once.** Register the server once, on user scope,
|
||||
and every project you open can ask any bundle under that directory — no skill
|
||||
to install per project, and nothing to regenerate when a bundle is rebuilt.
|
||||
You run this line; `okf` never starts Claude Code:
|
||||
|
||||
```sh
|
||||
claude mcp add --scope user okf -- okf mcp --root ~/okf
|
||||
```
|
||||
|
||||
Subagents inherit MCP tools and do not inherit skills, so the server is also
|
||||
the only way the same working method reaches an arm running below the main
|
||||
thread.
|
||||
|
||||
Then ask in plain language. Three shapes of request work, and the skill states
|
||||
the rules for each:
|
||||
|
||||
|
|
@ -85,8 +98,6 @@ here was measured; none of it is a plan.
|
|||
`csv`, `json`, `odt` or `rtf` is unaccounted and therefore red. It is opt-in
|
||||
(`--accounting PATH`) for that reason. The full list is under
|
||||
[Build](#build).
|
||||
- **A few rough edges, named rather than fixed.** `okf skill` requires `--out`
|
||||
and exits 2 without it.
|
||||
- **There is no context graph and no visualisation.** Nothing in this package
|
||||
draws a bundle.
|
||||
|
||||
|
|
@ -1280,10 +1291,19 @@ says why it exists:
|
|||
| tool | what it answers |
|
||||
|---|---|
|
||||
| `okf_list` | which bundles are reachable right now, with each one's content identity and concept count (multi-bundle servers only) |
|
||||
| `okf_describe` | what one bundle is: id, ref, concept count, source documents, and how many concepts carry each conditionally-written field |
|
||||
| `okf_describe` | what one bundle is: id, ref, concept count, source documents, and how many concepts carry each conditionally-written field. Omitting `bundle_id` on a multi-bundle server describes them all, as `okf_ask` does |
|
||||
| `okf_ask` | one question, one bounded payload of excerpts, each with its bundle id, concept id, title and provenance locators. Omitting `bundle_id` on a multi-bundle server asks them all and splits the budget |
|
||||
| `okf_fetch` | one named concept, verbatim, with its frontmatter and locators |
|
||||
|
||||
**The server carries the working method, because a subagent inherits MCP tools
|
||||
and not skills.** Its `instructions` and the `okf_ask` description state the
|
||||
short form — read the map, put the question into the bundle's own words, split
|
||||
it into sub-questions, read what lay just outside the cut and ask again with
|
||||
its words, then write one answer in the questioner's language. Claude Code
|
||||
truncates both at 2 KB, so the long form stays in the skill, which has no such
|
||||
cap; a test holds the short one under the limit with a control, because a
|
||||
truncated method is worse than a missing one.
|
||||
|
||||
**Nothing is cached between calls, and that is the design.** Every call
|
||||
re-reads the directories and recomputes the bundle's content identity, so the
|
||||
identity in an answer is a fact about the bytes at the moment of the call
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue