Skip to content

feat(schema): declare MCP prompts and static resources in the schema contract (contract-first, Phase 1) #138

Description

@rshade

Overview

Add additive contract declarations to the schema/ package for two MCP
primitives derived from the same reflection that already powers __schema:
prompts (workflow templates — server-vended "how do I use it") and
resources (static, read-only context — "show me that again"). This is
the committed Phase 1. The runtime projection into a live MCP server
(internal/mcpserver via the SDK's AddResourceTemplate/AddPrompt) is an
explicitly trigger-gated future phase and is NOT in scope here.

User Story

As an agent operating an ax-go CLI with zero filesystem context, I want the
server to declare reusable workflow templates (prompts) and addressable
static context (resources), So that I can learn how to drive the tool and
re-fetch stable reference material without the repo on disk and without
reading docs.

Problem Statement

Under the frame correction from the 2026-07-17 adversarial review, the
canonical consumer is an agent operating the CLI without the code on
disk
(query / execute / track). For that agent, MCP prompts are the
MCP-native answer to "how do I use it" (server-vended workflow templates)
and resources are the addressable answer to "show me that again" — neither
is replaceable by reading files. Today internal/mcpserver exposes only
tools (server.AddTool in newMCPServer, internal/mcpserver/server.go);
there is no prompt or resource surface. The canonization test converts the
original deferral into a trigger: the first per-repo hand-rolled prompt
template or static resource is the signal to flip the runtime phase on.
Phase 1 lands the always-safe half now: additive, host-independent contract
declarations.

Proposed Solution

Declare prompts and static resources as additive metadata reflected from the
existing command tree, projected (never originated) into __schema and the
--as=mcp adapter. No runtime server behavior changes in Phase 1.

Technical Approach

  • Extend the reflection in internal/schema/schema.go to derive prompt
    (workflow-template) and resource (static, read-only context) declarations
    from the same command-tree walk that already produces the command schema
    — one source of truth, no divergence.
  • Surface the declarations additively on schema.Schema /
    schema.CommandSchema in schema/schema.go (new omitempty fields /
    sections only), and project them through internal/mcp/mcp.go into the
    --as=mcp adapter as static metadata.
  • Hard narrowing (constitutional): resources are STATIC, READ-ONLY
    projections of declared context — never run-record state. The TRACK leg
    ("what did it do") stays served by structured logs / stderr; persisting
    run state is out of bounds and must be rejected in review and by a test.
  • Golden-pin the additive shape so the declarations are a stable contract.

Files Likely Affected

  • internal/schema/schema.go - reflection derives prompt/resource
    declarations from the shared command-tree walk (BuildCommand).
  • schema/schema.go - additive omitempty prompt/resource sections on
    Schema / CommandSchema.
  • internal/mcp/mcp.go - --as=mcp adapter projects the declared
    prompts/resources (additive; Build/Schema).
  • testdata/schema_ax.golden.json, testdata/schema_mcp.golden.json -
    updated golden fixtures.
  • schema/schema_test.go - golden + table-driven coverage; a negative test
    asserting resources cannot carry run-record/dynamic state.

Acceptance Criteria

  • The schema contract declares MCP prompts (workflow templates) and
    static read-only resources, derived from the same reflection that
    powers __schema.
  • Declarations appear in both __schema (ax-native) and
    __schema --as=mcp, golden-pinned and additive (trees declaring none
    emit byte-identical output to today).
  • Resources are provably static and read-only: a test rejects any
    attempt to declare run-record/dynamic state as a resource.
  • Output stays deterministic (same input -> byte-identical __schema).
  • Tests pass with adequate coverage (per AGENTS.md testing-first discipline).
  • Documentation updated if needed (README/examples/integration/).

Out of Scope

  • Phase 2 (runtime projection) — trigger-gated, unscheduled. Registering
    the declared prompts/resources on the live MCP server in
    internal/mcpserver via the SDK's AddResourceTemplate / AddPrompt
    (alongside the existing server.AddTool loop in newMCPServer). Separate
    Spec Kit feature.
  • Canonization trigger: the first per-repo hand-rolled prompt template or
    static resource flips the runtime phase on.
  • Constitutional narrowing: resources are static read-only projections
    only — run-record / persisted run state is permanently out of bounds (that
    is the TRACK leg, served by structured logs/stderr).
  • MCP sampling (discarded — violates output determinism).

Technical Notes

  • Contract-package placement: declarations are static metadata in the
    import-isolated schema/ contract package (reflection in
    internal/schema/), never the runtime; thin consumers pin the shape
    without compiling the MCP-runtime/telemetry stack.
  • Additive only: new omitempty sections on Schema/CommandSchema
    and additive --as=mcp metadata — no removed/retyped fields
    (Constitution XI). Not a breaking change; do not apply
    breaking-change-approved.
  • Declared Claims, Gated Projections: __schema and the MCP adapter
    project the contract and are never the source of truth; the future runtime
    registration is a projection gated behind the canonization trigger.
  • Distinct from feat(mcp-server): enrich MCP tool descriptions with pkg.go.dev module metadata #67: feat(mcp-server): enrich MCP tool descriptions with pkg.go.dev module metadata #67 enriches tool descriptions with pkg.go.dev
    module metadata; this issue adds the resources/prompts primitives. Keep
    the two aligned but separate.
  • Spec Kit routing: entry point only — routes through spec -> plan ->
    tasks (specs/015+).

Testing Strategy

  • Unit / table-driven tests for prompt/resource reflection in
    internal/schema.
  • Golden-file tests for __schema and __schema --as=mcp
    (testdata/schema_ax.golden.json, testdata/schema_mcp.golden.json).
  • Negative test asserting resources are static/read-only (no run-record
    state accepted).
  • Determinism test: a tree with no prompt/resource declarations produces
    byte-identical __schema to the pre-change golden.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    effort/mediumMedium effort - half day to 1 dayenhancementNew feature or requestroadmap/futureFuture milestones - Future Vision

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions