Skip to content

feat: generate JSON Schema for tool inputs from proto descriptors (protojson-compatible) #88

Closed

Description

@erikist

Part of #44. The official SDK validates tool arguments against the tool's input schema (mark3labs did not), so the schemas must accurately describe what protojson.Unmarshal accepts. Today's schemas don't: arguments are nested under the request-message name, "required": true is put on properties (invalid JSON Schema), and repeated, enum and most numeric fields are dropped.

Do

Add a self-contained schema builder to the plugin (e.g. cmd/protoc-gen-go-mcp/schema.go) that turns a protogen.Message into a JSON Schema (draft 2020-12) map[string]any or JSON. Don't wire it into the generated code yet (that's #89). The tool's input schema is the request message itself (top-level fields, not nested under the message name).

proto schema
message {"type":"object","properties":{...},"additionalProperties":false}; property names = field.Desc.JSONName() (lowerCamel, what protojson emits)
string string
bytes string, "contentEncoding":"base64"
bool boolean
int32/sint32/sfixed32 integer
uint32/fixed32 integer, minimum: 0
int64/sint64/sfixed64/uint64/fixed64 ["integer","string"] (protojson writes 64-bit ints as strings, accepts both)
float/double number
enum string with enum: the value names
repeated X array of X
map<K,V> object with additionalProperties: V
nested message inline; recursive messages via $defs + $ref
oneof / proto3 optional normal properties, never required; mention the oneof group in the description
well-known types Timestamp → string format: date-time; Duration → string; wrappers → the wrapped scalar; Struct → object; Value → {}; ListValue → array; FieldMask → string; Empty → object

Descriptions come from the proto leading comments (field and message). Proto3 has no required fields, so emit no required.

Acceptance criteria

  • A test proto under testdata/ (or cmd/protoc-gen-go-mcp/testdata/) covers every row above, including a recursive message, a map, an enum, a oneof and well-known types.
  • Unit tests check the schema for each kind.
  • Property test: for populated messages of that test proto, protojson.Marshal(msg) validates against the generated schema (use github.com/google/jsonschema-go, the library the official SDK uses), and so does an empty message.
  • Generated output of examples/ is unchanged (not wired yet).

Activity

  1. erikist commented on Oct 8, 2026

    @erikist
    ContributorAuthor

    🤖 Factory: picked up by dispatcher; working on branch factory/88-feat-generate-json-schema-for-tool.

  2. erikist commented on Oct 8, 2026

    @erikist
    ContributorAuthor

    🤖 Factory: opened #98 with a self-contained JSON Schema (draft 2020-12) builder in cmd/protoc-gen-go-mcp/schema.go (MessageInputSchema), covering every row of the table above plus a property test validating protojson.Marshal output against the generated schema. Not wired into the generated code yet, per the issue — that's left for a follow-up (#89). See the PR for test evidence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions