protoc-gen-jsonschema

mcp
Guvenlik Denetimi
Uyari
Health Uyari
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 6 GitHub stars
Code Gecti
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
  • Permissions — No dangerous permissions requested

Bu listing icin henuz AI raporu yok.

SUMMARY

Define MCP tool JSON Schemas in Protobuf — a protoc/buf plugin & Go library that generates JSON Schema from proto, with constraints

README.md

protoc-gen-jsonschema

Define MCP tool schemas in Protobuf. Convert Protocol Buffers messages into JSON Schema — as a Go library (dynamic) or a protoc/buf plugin (static).

BSR
Go Reference

简体中文 · English

Table of Contents

Features

  • Define MCP tool schemas in proto — generate the JSON Schema an MCP server
    advertises as a tool's inputSchema straight from your message definitions.
  • Define JSON Schema constraints with Protobuf extension options.
  • Two modes: dynamic generation (library) and static generation (plugin).
  • Field-level and message-level options.
  • Static output as JSON files or zero-overhead Go constants.
  • High performance: ~8 μs dynamic, ~0.3 ns static access.

Install

One-line install (no Go toolchain required):

curl -fsSL https://raw.githubusercontent.com/sunerpy/protoc-gen-jsonschema/main/scripts/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/sunerpy/protoc-gen-jsonschema/main/scripts/install.ps1 | iex

Override the version or destination:

PGJ_VERSION=0.0.7 PGJ_INSTALL_DIR=/usr/local/bin \
  curl -fsSL https://raw.githubusercontent.com/sunerpy/protoc-gen-jsonschema/main/scripts/install.sh | sh

Prebuilt binary (no pipe-to-shell):

Download a prebuilt archive for your platform from the
Releases page,
extract it, and put protoc-gen-jsonschema on your PATH.

Go library:

go get github.com/sunerpy/protoc-gen-jsonschema

Plugin binary via Go:

go install github.com/sunerpy/protoc-gen-jsonschema/cmd/protoc-gen-jsonschema@latest

Make sure $(go env GOPATH)/bin is on your PATH.

Proto extensions via the Buf Schema Registry (BSR):

The extension definitions are published at
buf.build/sunerpy/protoc-gen-jsonschema.
Add it as a dependency in your buf.yaml:

version: v2
deps:
  - buf.build/sunerpy/protoc-gen-jsonschema

Then run buf dep update.

Quick start

As a Go library (dynamic)

Annotate a message:

syntax = "proto3";
package example;

import "mcp/jsonschema/jsonschema.proto";

message UserRequest {
  option (mcp.jsonschema.title) = "User Request";

  string email = 1 [
    (mcp.jsonschema.required) = true,
    (mcp.jsonschema.format) = "email"
  ];
  string name = 2 [
    (mcp.jsonschema.required) = true,
    (mcp.jsonschema.min_length) = 3,
    (mcp.jsonschema.max_length) = 50
  ];
  int32 age = 3 [
    (mcp.jsonschema.minimum) = 18,
    (mcp.jsonschema.maximum) = 120
  ];
}

Generate at runtime:

package main

import (
	"encoding/json"
	"fmt"
	"log"

	pb "example/pb"
	"github.com/sunerpy/protoc-gen-jsonschema"
)

func main() {
	schema, err := jsonschema.GenerateFromMessage(&pb.UserRequest{})
	if err != nil {
		log.Fatal(err)
	}
	out, _ := json.MarshalIndent(schema, "", "  ")
	fmt.Println(string(out))
}

As a protoc/buf plugin (static)

JSON files (default):

protoc --jsonschema_out=. user.proto

Go constants (zero-overhead, recommended for hot paths):

protoc --go_out=. --jsonschema_out=format=go_const:. user.proto

buf.gen.yaml:

version: v2
plugins:
  - remote: buf.build/protocolbuffers/go
    out: pb
    opt:
      - paths=source_relative
  - local: protoc-gen-jsonschema
    out: pb
    opt:
      - format=go_const
      - paths=source_relative

The generated *_jsonschema.pb.go exposes zero-overhead accessors:

msg := &pb.UserRequest{}
schema := msg.GetJSONSchema()         // string, ~0.29 ns
bytes  := msg.GetJSONSchemaBytes()    // []byte, HTTP-ready
raw    := msg.GetJSONSchemaRawMessage() // json.RawMessage

Plugin options

Option Default Description
format json Output format: json or go_const.
suffix _jsonschema Go file suffix (go_const only).
paths source_relative or import.
preserve_order false Preserve proto field order in the schema.
schema_struct false Also emit a jsonschema.Schema struct literal.
google_schema false Also emit a github.com/google/jsonschema-go struct literal.

Schema options

Field options (mcp.jsonschema.*):

Option Type Description
required bool Mark the field as required.
description string Field description.
example string Example value.
format string Format constraint (e.g. email, date-time).
pattern string Regular expression.
min_length / max_length int32 String length bounds.
minimum / maximum double Numeric bounds.
default string Default value (JSON-encoded).
hidden bool Exclude the field from the schema.
json_name string Override the JSON field name.

Message options (mcp.jsonschema.*):

Option Type Description
title string Schema title.
message_description string Schema description.
generate_schema bool Set false to skip generation for this message.

Note on google.protobuf.Timestamp: when a Timestamp appears as a field, the
generated schema uses a oneOf accepting both an RFC3339 string and a
{seconds, nanos} object. The proto runtime (protojson) itself only accepts
the RFC3339 string form; the object branch targets generic JSON consumers.

Using with an LLM

The Model Context Protocol (MCP) requires each
tool to advertise an inputSchema — a JSON Schema describing its arguments. This
plugin lets you define that schema in Protobuf and generate it, so your proto
message is the single source of truth for the tool contract: constraints
(required, format, pattern, min_length, minimum, …) become JSON Schema
keywords the LLM uses to produce valid arguments.

message SearchToolArgs {
  option (mcp.jsonschema.title) = "search";
  option (mcp.jsonschema.message_description) = "Full-text search over the corpus";

  string query = 1 [
    (mcp.jsonschema.required) = true,
    (mcp.jsonschema.min_length) = 1,
    (mcp.jsonschema.description) = "The search query"
  ];
  int32 limit = 2 [
    (mcp.jsonschema.minimum) = 1,
    (mcp.jsonschema.maximum) = 100,
    (mcp.jsonschema.example) = "10"
  ];
}

Generate the schema once at build time, then hand GetJSONSchemaBytes() to your
MCP server as the tool's inputSchema — no hand-written, drift-prone JSON.

Install in one line, then drive the plugin from an agent:

curl -fsSL https://raw.githubusercontent.com/sunerpy/protoc-gen-jsonschema/main/scripts/install.sh | sh
  • protoc --jsonschema_out=. user.proto — emit JSON Schema files for the messages.
  • protoc --go_out=. --jsonschema_out=format=go_const:. user.proto — emit
    zero-overhead Go constants (GetJSONSchema() / GetJSONSchemaBytes()), ideal
    as an MCP tool's inputSchema.
  • For runtime use, call jsonschema.GenerateFromMessage(msg) — returns a schema
    ready to json.Marshal.

The generated schema is plain JSON (machine-readable); the plugin exits non-zero
with diagnostics on stderr when a message or option is invalid.

Performance

Static access is ~29,000× faster than dynamic generation, and a JSON string
constant is HTTP-ready with zero serialization cost. See
docs/PERFORMANCE.md for the full comparison.

Development

make help        # list targets
make fmt         # format Go + non-Go files
make lint        # golangci-lint
make test        # run tests
make buf-lint    # lint proto files
make check       # fmt-check + lint + buf-lint + test
make hooks       # install git hooks (fmt+lint on commit, test on push)

Commit messages follow Conventional Commits
feat:, fix:, feat!: for breaking changes — which drive automated version
bumps and the changelog.

Releases are automated via release-please:
merging the release PR cuts a v* tag, which triggers GoReleaser to build
multi-platform binaries and publish the GitHub Release. The proto module is
published to the BSR via buf push. The in-repo changelog lives in
changelog/, split by major version.

License

MIT

Yorumlar (0)

Sonuc bulunamadi