<?xml version="1.0" encoding="UTF-8"?>
<spec xmlns="https://vibevm.org/spec/1">
  <title id="root">PROP-027 — `mcp` packages: the agent-server kind and its delivery</title>
  <status stage="impl" state="done" comment="B0 2026-07-24: IMPLEMENTED with the MCP-SOVEREIGNTY waves"/>
  <p p="1"><fact id="milestone-line" status="impl/done">**Milestone:** M1.26 candidate («MCP sovereignty» —
[MCP-SOVEREIGNTY-PLAN-v0.1](../../../legacy-spec/terraforms/MCP-SOVEREIGNTY-PLAN-v0.1.md)).</fact></p>
  <p p="2"><fact id="status-line" status="impl/done">**Status:** IMPLEMENTED — the kind and the manifest laws (§2.1–§2.3)
shipped with the plan's Wave 1; the servers themselves (Waves 3–4:
`mcp:org.vibevm.ai-native/rust-ai-native-mcp`, `…/typescript-ai-native-mcp`, both
live-chained vibe-free); the registration lifecycle (§2.4–§2.5) with
Wave 5 (`vibe mcp install/uninstall/status` speak package servers; the
pin-server fixture e2e pins the walk). §2.7's composition rows inherit
the kind-agnostic feature suites — no feature branches on `kind`, and
the mcp e2e exercises code-bearing + binaries + the pin end to end. Units typed at REQ grain; the code carries the matching
`scope!` / `#[spec(implements)]` / `#[verifies]` edges.</fact></p>
  <p p="3"><fact id="related" status="spec/done">**Related:** [PROP-015](PROP-015-mcp-integration.xml) (the product MCP
server + the agent-integration command family this PROP extends),
[PROP-025](../vibe-workspace/PROP-025-binary-delivery.xml) (the binary
delivery an `[[mcp_server]]` rides), [PROP-024](../../common/PROP-024-code-bearing-packages.xml)
(code-bearing packages; §2.4 is why mcp packages vendor),
[`VIBEVM-SPEC.md` §4.1](../../../VIBEVM-SPEC.md) (the kind register,
amended under owner sanction 2026-07-07).</fact></p>
  <section id="motivation" title="1. Motivation">
    <list ordered="false" p="4">
      <item><fact id="motivation-gap" status="impl/done">The discipline stacks ship engines, gates, CLIs, and type oracles —
  everything an agent-facing toolchain needs EXCEPT the transport.</fact></item>
      <item><fact id="prototype-cycle" status="impl/done">The
  prototype topology served them through vibevm's own MCP
  (`vibe mcp serve` + the `tcg_*` adapters), which put the whole vibevm
  product into every consumer's runtime path and closed an operational
  cycle over vibevm itself (the tool served its own development).</fact></item>
      <item><fact id="OWNER-RESOLUTION" status="impl/done">The
  owner's resolution (2026-07-07): agent-server delivery is a first-class
  package concern — a KIND, not a bolt-on surface — and vibe's job there
  is install-time wiring, never serving.</fact></item>
    </list>
  </section>
  <section id="decisions" title="2. Decisions">
    <section id="kind" title="2.1 The `mcp` kind">
      <p p="5"><fact id="req-kind" status="impl/done">`req r1`</fact></p>
      <p p="6"><fact id="MCP-KIND-DEF" status="impl/done" action="continue" actionstage="doc" audience="author">An **`mcp` package** is one whose primary deliverable is one or more
Model Context Protocol servers.</fact></p>
      <list ordered="false" p="7">
        <item><fact id="KIND-REGISTER" status="impl/done">`kind = "mcp"` joins the installable
  register (VIBEVM-SPEC §4.1); slots materialise under
  `vibedeps/&lt;group&gt;.&lt;name&gt;/&lt;version&gt;/` like every other kind (the identity slot — PROP-022 §2.1, owner ruling 2026-08-13; the path carried a kind prefix before that ruling).</fact></item>
        <item><fact id="TABLE-ONLY-IN-KIND" status="impl/done" action="continue" actionstage="doc" audience="author">The
  `[[mcp_server]]` table (§2.2) is **legal only in this kind** — the kind
  IS the taxonomy, enforced by `Manifest::validate`, not advisory.</fact></item>
        <item><fact id="KIND-PROMISES-SERVER" status="impl/done" action="continue" actionstage="doc" audience="author">An
  `mcp`-kind manifest that declares NO `[[mcp_server]]` is refused: the
  kind promises a server.</fact></item>
      </list>
    </section>
    <section id="manifest" title="2.2 The `[[mcp_server]]` declaration">
      <p p="8"><fact id="req-manifest" status="impl/done">`req r1`</fact></p>
      <fence lang="toml" p="9">[[mcp_server]]
name = "rust-ai-native"           # agent-visible server name = the family (PROP-028 §2.4)
binary = "rust-ai-native-mcp"     # must match a [[binary]] in this manifest
description = "AI-Native Rust discipline + type oracle over MCP"
args = ["--path", "{project_root}"]</fence>
      <list ordered="false" p="10">
        <item><fact id="SERVER-IS-BINARY" status="impl/done" action="continue" actionstage="doc" audience="author">The server IS a [PROP-025](../vibe-workspace/PROP-025-binary-delivery.xml)
  binary: delivery, consent, staleness, and slot residence come from that
  machinery wholesale — `binary` must resolve to a `[[binary]]` declared
  in the same manifest.</fact></item>
        <item><fact id="SERVER-NAME" status="impl/done">`name` is what an MCP host shows as the tool
  namespace; names are unique within the package.</fact></item>
        <item><fact id="ARGS-CLOSED-SET" status="impl/done" action="continue" actionstage="doc" audience="author">`args` may carry
  substitution tokens ONLY from the closed set `{project_root}` (the
  absolute, verbatim-free root of the consuming project, resolved at
  registration time); unknown `{…}` tokens are refused at validation.</fact></item>
      </list>
    </section>
    <section id="exact-pin" title="2.3 The exact-pin law">
      <p p="11"><fact id="req-exact-pin" status="impl/done">`req r1`</fact></p>
      <list ordered="false" p="12">
        <item><fact id="VENDORING-WHY" status="impl/done">Cargo path-deps cannot cross package slots (PROP-024 §2.4), so an mcp
  package VENDORS the crates of the toolchain it serves.</fact></item>
        <item><fact id="SKEW-REOPENED" status="impl/done">Vendoring
  re-opens the version skew the in-slot prototype excluded by
  construction: a server built from engine copy X enriching against a
  consumer whose gates run engine copy Y.</fact></item>
        <item><fact id="EXACT-PIN-LAW" status="impl/done" action="continue" actionstage="doc" audience="author">The pin closes it: **every
  `[requires.packages]` entry of an `mcp`-kind package MUST be an exact
  `=X.Y.Z` requirement** — the resolver holds the served engines and the
  consumer's gates to ONE version set; no runtime handshake exists or is
  needed.</fact></item>
        <item><fact id="PIN-VALIDATION" status="impl/done">`Manifest::validate` refuses any other requirement shape
  (caret, bare, partial `=X.Y`, compound ranges).</fact></item>
        <item><fact id="PIN-SOURCES" status="impl/done">Git-source deps pin by
  rev inherently; path-source deps are local-dev surfaces outside this
  law.</fact></item>
        <item><fact id="PIN-LOCKSTEP" status="impl/done">The operational consequence is accepted and priced by the plan:
  the mcp package bumps in lockstep with the package it serves.</fact></item>
      </list>
    </section>
    <section id="registration" title="2.4 Registration: `vibe mcp install` learns packages">
      <p p="13"><fact id="req-registration" status="impl/done">`req r1`</fact></p>
      <p p="14"><fact id="REG-TODAY" status="impl/done">`vibe mcp install` today writes vibevm's own server into agent configs
(PROP-015).</fact></p>
      <p p="15"><fact id="REG-PACKAGE-DISCOVERY" status="impl/done" action="continue" actionstage="doc" audience="user">It grows package discovery: every installed package of kind
`mcp` contributes its `[[mcp_server]]` entries, written into the target
agents' configs with</fact></p>
      <list ordered="false" p="16">
        <item><fact id="REG-COMMAND-PATH" status="impl/done">`command` = the absolute, **verbatim-free** path to the slot-resident
  built artifact (a real executable — no shim, no `cmd /c` wrapper
  class), `args` with the closed-set substitutions resolved;</fact></item>
        <item><fact id="REG-MANAGED-SIDECAR" status="impl/done" action="continue" actionstage="doc" audience="user">a **managed sidecar**: a top-level `"vibevm": { "managed": [...] }`
  object in the JSON config names the entries vibevm owns (never a key
  INSIDE a server entry — hosts validate entry shapes), so re-installs
  rewrite ONLY vibevm-managed entries and operator-owned servers are
  never touched — the `&lt;vibevm&gt;` block convention of the boot files,
  applied to agent configs.</fact></item>
        <item><fact id="REG-PROJECT-SCOPE" status="impl/done" action="continue" actionstage="doc" audience="user">Registration is PROJECT-scope only (the
  `{project_root}` substitution demands a project, and a project's
  servers belong in its committed config), and every project-scope
  agent config is JSON — so no TOML sidecar form exists;</fact></item>
        <item><fact id="REG-REFRESH" status="impl/done">lifecycle: `vibe mcp install` re-run refreshes paths after a slot
  move;</fact></item>
        <item><fact id="REG-STATUS" status="impl/done" action="continue" actionstage="doc" audience="user">`vibe mcp status` reports each declared server's artifact state
  (an unbuilt artifact registers fine and fails at agent launch — the
  recipe names `vibe bin build &lt;name&gt;`);</fact></item>
        <item><fact id="REG-UNINSTALL" status="impl/done">`vibe mcp uninstall` removes
  managed entries plus the emptied sidecar, and nothing else.</fact></item>
      </list>
    </section>
    <section id="consent" title="2.5 Consent: registration is the same trust act as building">
      <p p="17"><fact id="req-consent" status="impl/done">`req r1`</fact></p>
      <list ordered="false" p="18">
        <item><fact id="CONSENT-TRUST-ACT" status="impl/done">Registering a server schedules package code execution at agent-session
  start; building its binary compiles package code.</fact></item>
        <item><fact id="CONSENT-GATE-INHERITED" status="impl/done" action="continue" actionstage="doc" audience="user">One trust model, two
  verbs: registration inherits PROP-025's consent gate verbatim —
  `org.vibevm` packages are allow-listed; any other origin requires the
  explicit `--assume-yes` (or is refused with the recipe naming that
  exact flag).</fact></item>
        <item><fact id="CONSENT-WRITE-SCOPE" status="impl/done">Registration writes touch ONLY the target agent's config
  files and only managed entries; server processes receive the project
  root as cwd and NO secrets from vibe.</fact></item>
      </list>
    </section>
    <section id="vibe-free" title="2.6 Serving is vibe-free">
      <p p="19"><fact id="req-vibe-free" status="impl/done">`req r1`</fact></p>
      <list ordered="false" p="20">
        <item><fact id="VIBE-FREE-SERVING" status="impl/done">An mcp package's servers run without vibe: the artifact is launched by
  the agent host directly from the slot path, links its vendored engines,
  and speaks stdio MCP.</fact></item>
        <item><fact id="VIBE-ROLE" status="impl/done">`vibe` is required only to install, build, and
  register.</fact></item>
        <item><fact id="VIBE-FREE-ACCEPTANCE" status="impl/done">The acceptance form of this requirement: the server's live
  chain passes with `vibe` absent from `PATH` and no vibevm process
  running.</fact></item>
      </list>
    </section>
    <section id="composition" title="2.7 Composition: an mcp package is a full package">
      <p p="21"><fact id="req-composition" status="impl/done">`req r1`</fact></p>
      <p p="22"><fact id="COMPOSITION-LAW" status="impl/done">Every package-role feature applies to `mcp` packages exactly as to the
other kinds; no feature branches on `kind`, so each row inherits its
feature's own kind-agnostic suite (the mcp-kind e2e adds the
code-bearing + binaries + exact-pin composition end to end):</fact></p>
      <table p="23">
        <tr>
          <td>Feature</td>
          <td>Spec</td>
          <td>Composition rule</td>
        </tr>
        <tr>
          <td><fact id="ROW-CODE-BEARING" status="impl/done">Code-bearing layout</fact></td>
          <td><fact id="ROW-CODE-BEARING-SPEC" status="impl/done">PROP-024</fact></td>
          <td><fact id="ROW-CODE-BEARING-COMPOSITION-RULE" status="impl/done">the package IS code-bearing by definition; `spec/` for prompt content, crates at root</fact></td>
        </tr>
        <tr>
          <td><fact id="ROW-BINARIES" status="impl/done">Binaries</fact></td>
          <td><fact id="ROW-BINARIES-SPEC" status="impl/done">PROP-025</fact></td>
          <td><fact id="ROW-BINARIES-COMPOSITION-RULE" status="impl/done">`[[mcp_server]].binary` references them; `vibe bin list/build/exec` see them like any other</fact></td>
        </tr>
        <tr>
          <td><fact id="ROW-SKILLS" status="impl/done">Skills</fact></td>
          <td><fact id="ROW-SKILLS-SPEC" status="impl/done">PROP-015 §2.8, PROP-018 §2.4</fact></td>
          <td><fact id="ROW-SKILLS-COMPOSITION-RULE" status="impl/done">`[[skill]]` legal; a server may ship its teaching skill</fact></td>
        </tr>
        <tr>
          <td><fact id="ROW-BOOT-SNIPPET" status="impl/done">Boot snippet</fact></td>
          <td><fact id="ROW-BOOT-SNIPPET-SPEC" status="impl/done">PROP-009</fact></td>
          <td><fact id="ROW-BOOT-SNIPPET-COMPOSITION-RULE" status="impl/done">legal but not required; agents learn servers via registration, not boot text</fact></td>
        </tr>
        <tr>
          <td><fact id="ROW-HOOKS" status="impl/done">Hooks</fact></td>
          <td><fact id="ROW-HOOKS-SPEC" status="impl/done">PROP-020</fact></td>
          <td><fact id="ROW-HOOKS-COMPOSITION-RULE" status="impl/done">pre/post-install hooks run in the slot as usual</fact></td>
        </tr>
        <tr>
          <td><fact id="ROW-MATERIALIZATION" status="impl/done">Materialization modes</fact></td>
          <td><fact id="ROW-MATERIALIZATION-SPEC" status="impl/done">PROP-022</fact></td>
          <td><fact id="ROW-MATERIALIZATION-COMPOSITION-RULE" status="impl/done">snapshot/in-place per the standard rules</fact></td>
        </tr>
        <tr>
          <td><fact id="ROW-BRIDGES" status="impl/done">Bridges / submodules</fact></td>
          <td><fact id="ROW-BRIDGES-SPEC" status="impl/done">PROP-023 / PROP-021</fact></td>
          <td><fact id="ROW-BRIDGES-COMPOSITION-RULE" status="impl/done">no special-casing</fact></td>
        </tr>
        <tr>
          <td><fact id="ROW-PUBLISH" status="impl/done">Publish</fact></td>
          <td><fact id="ROW-PUBLISH-SPEC" status="impl/done">PROP-002 §2.10</fact></td>
          <td><fact id="ROW-PUBLISH-COMPOSITION-RULE" status="impl/done">standard registry publish; the exact-pin law travels in the manifest</fact></td>
        </tr>
        <tr>
          <td><fact id="ROW-MUTABILITY" status="impl/done">In-workspace mutability</fact></td>
          <td><fact id="ROW-MUTABILITY-SPEC" status="impl/done">PROP-011 §2.6</fact></td>
          <td><fact id="ROW-MUTABILITY-COMPOSITION-RULE" status="impl/done">dev-loop re-materialisation applies</fact></td>
        </tr>
      </table>
    </section>
  </section>
  <section id="rejected" title="3. Rejected alternatives">
    <list ordered="false" p="24">
      <item><fact id="REJ-ANY-KIND" status="spec/done">**`[[mcp_server]]` as an any-kind surface** (the plan's original
  draft): rejected by the owner — the taxonomy should say what a
  package IS; embedded servers would blur the register and hide the
  vendoring/pinning obligations §2.3 makes explicit.</fact></item>
      <item><fact id="REJ-CROSS-SLOT" status="spec/done">**Cross-slot path-deps or manifest rewriting** instead of vendoring:
  PROP-025 v2 territory, specified-only; the reproducible-hash model
  (PROP-024 §2.2) forbids post-materialise rewriting today.</fact></item>
      <item><fact id="REJ-HANDSHAKE" status="spec/done">**A runtime version handshake** instead of the exact pin: weaker (it
  detects skew instead of preventing it) and needs a wire surface;
  the resolver already enforces equality for free.</fact></item>
      <item><fact id="REJ-VIBE-LAUNCHER" status="spec/done">**vibe as the server launcher** (`vibe mcp exec &lt;name&gt;` in agent
  configs): would keep vibe in the runtime path — the exact property
  this PROP removes.</fact></item>
    </list>
  </section>
  <section id="open" title="4. Open questions">
    <list ordered="true" p="25">
      <item><fact id="OPEN-MULTI-SERVER" status="spec/work">Multi-server packages (legal today) — does `vibe mcp install` offer
   per-server opt-out? v1: all-or-nothing per package.</fact></item>
      <item><fact id="OPEN-APP-KIND" status="spec/work">The `app` kind (anticipated, VIBEVM-SPEC §4.1) — whether it reuses
   §2.4's managed-entry machinery for desktop-integration surfaces.</fact></item>
      <item><fact id="OPEN-STABLE-PATHS" status="spec/work">Stable artifact paths (PROP-025 v2 shims) would make managed entries
   survive version bumps without a re-install; deferred with it.</fact></item>
    </list>
  </section>
</spec>
