docs(roadmap): phase 5 — MCP as a way to populate a bundle
Committed by the operator; the design is open and the scope is not. Recorded in the roadmap with a scoping plan rather than in the v0.2 alignment doc, which is about OKF v0.2 conformance and is the wrong home. The plan settles nothing on purpose. It names the fork everything turns on — whether we are the MCP server (an agent calls our doors, Door B's territory, ours to design) or an MCP client (a manifest source type, which is normative in commons' ingest-spec and therefore starts as a request to them, not as code here). The two share a protocol and nothing else, including their owner. Constraints written down because each has already refused something: the one-runtime-dependency rule (an MCP SDK would be the second — stdlib JSON-RPC or an optional extra), no model calls in the run path (the model may CALL us, never the reverse), the guard persist gate (MCP is transport, not a bypass), the network opt-in, and the required ingested_at.
This commit is contained in:
parent
0a7a77d5a8
commit
ff9f2f82ca
2 changed files with 91 additions and 0 deletions
83
docs/plan/mcp-bundle-population.md
Normal file
83
docs/plan/mcp-bundle-population.md
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
# Phase 5 — MCP as a way to populate a bundle
|
||||
|
||||
**Status: scoped, not designed.** Committed by the operator 2026-07-27. This
|
||||
document records the commitment, the fork it turns on, and the constraints any
|
||||
design has to satisfy. It deliberately does not choose an implementation:
|
||||
the fork below decides who owns the work, and choosing it wrongly is expensive
|
||||
in a way writing it later is not.
|
||||
|
||||
## The fork — settle this first
|
||||
|
||||
"Support MCP to populate a bundle" names two different pieces of work. They
|
||||
share a protocol and nothing else.
|
||||
|
||||
**(A) We are the MCP server.** An agent connects to us and calls tools —
|
||||
`add_concept`, `list_bundle`, `generate_index` — and the bundle fills up through
|
||||
our doors. The natural home is **Door B**, which already answers "here is
|
||||
content, make it OKF": MCP would be a protocol surface over an existing door
|
||||
rather than a new ingestion path.
|
||||
|
||||
**(B) We are an MCP client.** A manifest names an MCP server as a source, the
|
||||
same way it names `file`/`sql`/`http` today, and Door A pulls concepts from it.
|
||||
|
||||
**Default reading, for confirmation rather than assumption:** the phrase "to
|
||||
populate a bundle" points at (A). Recorded as a reading, not a decision — the
|
||||
operator has not been asked which one, and the two have different owners.
|
||||
|
||||
## Why the fork decides the owner
|
||||
|
||||
(B) adds a **source type**, and the source type set is normative in commons'
|
||||
`ingest-spec.md`. This repo implements that spec and does not edit it. So (B)
|
||||
cannot start here: it starts as a request to commons, and it lands here only
|
||||
after they have specified it. (A) adds no source type and no spec surface — the
|
||||
concepts arrive through Door B exactly as dropped files do — so (A) is ours to
|
||||
design.
|
||||
|
||||
That asymmetry is the whole reason this document exists before any code.
|
||||
|
||||
## Constraints any design inherits
|
||||
|
||||
None of these are negotiable by this feature, and each one has already refused
|
||||
something:
|
||||
|
||||
1. **Exactly one runtime dependency, ever** (`llm-ingestion-guard`), enforced by
|
||||
a packaging test. An MCP SDK would be the second. Either the protocol is
|
||||
hand-rolled over stdlib JSON-RPC on stdio, or it lives behind an optional
|
||||
extra the way binary parsers do in `[extract]` — never in the core install.
|
||||
2. **No model calls anywhere in the run path.** MCP is model-facing, and that is
|
||||
fine in exactly one direction: under (A) the model is the *caller* and we
|
||||
stay deterministic tools. A design where this library calls a model to decide
|
||||
what to write is out of scope, and would be a different product.
|
||||
3. **The persist gate still applies.** Content arriving over MCP is untrusted by
|
||||
construction. It goes through Door B's injected guard gate like every other
|
||||
dropped file; MCP is a transport, never a reason to bypass a gate. Security
|
||||
stays the guard's, as always.
|
||||
4. **Network access is an explicit per-run opt-in.** A server listening on a
|
||||
socket, or a client dialing one, is network. The existing fail-fast refusal
|
||||
is the baseline, not something to reinvent.
|
||||
5. **Determinism.** `ingested_at` is a required argument with no wall-clock
|
||||
default. A protocol handler does not get to invent one because a call
|
||||
arrived "now".
|
||||
|
||||
## Open questions
|
||||
|
||||
- **Q1 — (A) or (B), or both in order?** Blocks everything else.
|
||||
- **Q2 — If (A): what is the tool surface?** Door B's public surface is
|
||||
`process_inbox` over a directory. An MCP tool taking one concept at a time is
|
||||
a different granularity, and the collision gate and index generation are
|
||||
currently per-run rather than per-concept. This is the real design work.
|
||||
- **Q3 — Transport.** stdio is the vendorable, zero-dependency answer and
|
||||
matches how the marketplace consumes things. HTTP would be a second network
|
||||
surface with its own gate question.
|
||||
- **Q4 — Which half?** Phase 4 puts a Node/ESM half next to the Python one. MCP
|
||||
servers in the plugin world are overwhelmingly Node. If (A) lands in Python
|
||||
only, the second-brain consumers cannot use it; if it lands in both, the
|
||||
"share contract and fixtures, not code" rule applies to the tool surface too.
|
||||
- **Q5 — Does an MCP-populated bundle differ observably** from one Door B wrote
|
||||
from files? It must not, or the transport has leaked into the artifact.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Reimplementing any security check the guard owns.
|
||||
- Calling a model from this library, under any transport.
|
||||
- Editing commons' source-type set locally to make (B) possible sooner.
|
||||
Loading…
Add table
Add a link
Reference in a new issue