Skip to content

feat(debugmcp): declare outputSchema for every tool - #8

Merged
htcom-code merged 1 commit into
mainfrom
feat/mcp-output-schema
Aug 12, 2026
Merged

feat(debugmcp): declare outputSchema for every tool#8
htcom-code merged 1 commit into
mainfrom
feat/mcp-output-schema

Conversation

@htcom-code

Copy link
Copy Markdown
Owner

Every debugmcp tool already returns its success as structuredContent, but none declared an outputSchema. A client had no contract for the object it receives — it could only guess the shape or fall back to parsing the text block. This adds the missing half of the contract.

Where to look first

The two-shape tools are the only judgement call here. launch / continue / step_* return either a stopped event (reason, source, line, function, depth) or a finished one (results, optional error); get_source returns either the whole text or a snippet. For those, required lists only the discriminating key (event, id) and the schema declares the union of the rest as optional. Requiring anything more would make the schema promise keys that a legitimate success sometimes omits.

The schemas describe successful results only. A tool-level failure comes back as an isError result carrying {"error": …}, which is deliberately a different shape and is not covered — consistent with how outputSchema is specified. Worth confirming you agree with that reading, since it is the one place the declaration does not describe everything the tool can emit.

Changes

  • outputSchema on all 11 tools. The four control tools share one schema through a small control() helper, since their contract is identical and only the description differs.
  • Fixed the no-argument inputSchema: obj(nil) was serialising "properties": null, which is not valid JSON Schema. Now {}.
  • No behavioural change to any handler; payloads are exactly as before.

What keeps this honest

Declarations rot when the handler that feeds them changes. Two tests prevent that:

  • TestToolSchemasAreComplete — every tool declares both schemas, both are well-formed objects, every required key is actually declared, and handlers and definitions agree in both directions (a handler with no definition is invisible; a definition with no handler is a dead promise).
  • TestToolOutputMatchesDeclaredSchema — drives a real debug session and validates each emitted payload against its declared schema: required keys present, no undeclared keys, declared types and enums honoured, descending into arrays and the nested frame/variable shapes. It runs the program to completion so both the stopped and finished variants are covered, and calls get_source both ways.

The second test was checked to be non-vacuous: dropping a single key (depth) from the declaration fails it with emitted undeclared key "depth".

Verification

gofmt clean · go vet ok · go test -race ./debugmcp ok · make check 30/33 (RUN-ERR 1 = gc.lua, SKIP 2 = driver scripts) — the existing ceiling, no regression.

Every tool already reports success as structuredContent, but none
declared an outputSchema. A client therefore had no contract for the
structured object it receives — it could only guess the shape or fall
back to parsing the text block. A tool that emits structured output
should describe it.

- declare outputSchema on all 11 tools; the control tools share one
  schema, since a run either stops or finishes
- require only the key present in every success (event, id) and declare
  the union of the rest, so the tools with two success shapes stay
  honest rather than promising keys they sometimes omit
- emit an empty object rather than null for the no-argument inputSchema
  properties, which was not valid JSON Schema

The declarations are held to the handlers by tests: one asserts every
tool declares both schemas with required a subset of properties, the
other drives a real debug session and validates each emitted payload
against its declared schema, covering both success shapes.

Tags: #lua-pure #debugmcp #mcp #schema #contract
Co-Authored-By: htjulia <htjulia1@gmail.com>
@htcom-code
htcom-code merged commit 1da4f4e into main Aug 12, 2026
7 checks passed
@htcom-code
htcom-code deleted the feat/mcp-output-schema branch August 13, 2026 00:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant