Protocol Buffers at runtime.
A schema registry on Git.
ProtoMolt is a modular Java toolkit that loads, validates, reshapes, indexes, and serves protobuf messages from descriptors rather than generated classes — and a schema registry that stores every version as a Git commit while speaking the Confluent protocol your serializers already use.
Forty-seven focused modules under one BOM, MIT-licensed, artifacts under
ai.pipestream on Maven Central.
Every claim on this page is enforced by CI, not asserted.
Run it now
One container is the whole thing: gRPC with reflection, JSON/REST with Swagger UI, an MCP endpoint, and a schema registry — with a sample schema seeded so every verb has something to say immediately.
docker run -p 8080:8080 -p 9090:9090 ghcr.io/ai-pipestream/protomolt-serve --demo
# Validate a message against the demo schema's declared rules:
curl -s -H 'content-type: application/json' \
-d '{"schema": {"type": "demo.shop.v1.Order"}, "message": {"id": "not-a-uuid"}}' \
http://localhost:8080/grpc-json/ProtoMoltService/ValidateMessage
# Any gRPC client sees a real, reflectable service:
grpcurl -plaintext localhost:9090 list
# Make an AI agent gRPC-aware with one command:
claude mcp add --transport http protomolt http://localhost:8080/mcp
Swagger UI lives at localhost:8080/docs.
Releases also attach runnable zips (JRE 21+ only). Then take a tutorial:
Python clients without protoc or
operating an OpenVINO server from an AI agent.
What it does
Use one module, or use the whole loop: gather → validate → register → serve → index.
Every code path works on Descriptor / FileDescriptor. A DynamicMessage resolved at runtime behaves exactly like a compiled-in type.
Filesystem trees, jars, Git repositories, Maven coordinates, Confluent and Apicurio registries. Text sources compile to descriptors at runtime, no protoc.
One commit per registration. History, review, and recovery are just Git; clients see the Confluent subjects API, and gRPC consumers fetch binary descriptor sets.
A typed diff engine with 35 named rules classifies changes by wire, JSON, and source impact under all registry modes, including transitive.
Rules travel as descriptor options. The protovalidate dialect passes the complete conformance suite, re-scored by buf’s own runner in CI.
Confluent and Apicurio publishers with topological reference registration, idempotent re-publish, and dry runs. Git stays the source of truth.
A descriptor-option standard for how fields come to rest in an index: analyzers, ranges, kNN vectors, map policies. Generates Lucene, OpenSearch, and Solr schemas.
Text mapping rules for reshaping messages, CEL filters and selectors where expressions matter, plus declared-metadata extraction.
A framework-agnostic REST gateway with OpenAPI 3 and JSON Schema generation, hosted on any of six servers. Inside the toolkit, everything stays binary.
Concrete examples
The same four steps a team actually takes, in the order they take them.
1 — Gather protos from a Git repo and compile them at runtime
ProtoGatherer gatherer = GitProtoGatherer.builder()
.repo("https://github.com/acme/schemas.git")
.ref("main")
.subdir("proto")
.build();
CompiledProtos compiled = ProtoSourceCompiler.compile(gatherer.gather());
DescriptorRegistry registry = DescriptorRegistry.create();
registry.addLoader(new GatheringDescriptorLoader(gatherer));
2 — Run a schema registry over a bare Git repository
var store = GitSchemaRegistryStore.open(Path.of("/srv/schemas.git"));
var server = new SchemaRegistryServer(config, store,
ActionCatalog.defaults(ActionContext.create()));
server.start();
Any Confluent-compatible client now works against it, and every registration is a commit:
curl -s -X POST localhost:8081/subjects/orders-value/versions \
-H 'Content-Type: application/vnd.schemaregistry.v1+json' \
-d @order.json
# gRPC consumers skip JSON entirely:
curl -s localhost:8081/protomolt/subjects/orders-value/descriptor-set -o orders.dsc
3 — Gate a change before it ships
var checker = CompatibilityChecker.builder().build();
var result = checker.check(oldSources, newSources, CompatibilityMode.BACKWARD);
// A removed field surfaces as a typed change, not a diff hunk:
// FIELD_REMOVED at orders.Order.discount_code
// impacts: [WIRE_BACKWARD, JSON_BACKWARD]
The registry runs the same engine on every write, so what passes locally registers cleanly.
4 — Depend on it
dependencies {
implementation platform('ai.pipestream:protomolt-bom:<version>')
implementation 'ai.pipestream:protomolt-registry-server'
implementation 'ai.pipestream:protomolt-compat'
}
One BOM aligns all forty-two modules. Pick the two you need today; the rest are there when you need them.
Any gRPC service, agent-operable
Point an AI agent at a running gRPC service and let it operate the service.
protomolt-mcp
serves the whole toolkit over the Model Context Protocol: thirteen tools on
plain-Java stdio, or over streamable HTTP from a running
protomolt-serve
— one process makes every agent on the network gRPC-aware, no local
install (claude mcp add --transport http protomolt http://host:8080/mcp).
The schema registry is browsable as resources. Three of
those tools close the loop on live services —
reflect
discovers a server’s schema from its address,
grpc-invoke
calls any unary or server-streaming method with no generated stubs on either
side, and generate-stubs
emits compilable clients in eight languages by running every libprotoc
generator as WebAssembly inside the JVM.
When a server does not enable reflection — OpenVINO Model Server, NVIDIA
Triton, and many production services do not — the agent falls back to the
schema the project publishes: gather the .proto
from its Git repository, register it once, and every step after that works
identically. The advanced tutorial walks the entire path against a real
OpenVINO server, ending with a live text → embedding inference
driven through the agent.
Meta for meta: the gRPC service of itself
gRPC is defined in protobuf. So is ProtoMolt’s future API surface.
Every operation — compile, validate, diff, check compatibility, render
schemas, evaluate CEL, reflect, invoke, generate — is a named action
with a machine-readable input schema, and the catalog is now literally a gRPC
service: ai.pipestream.protomolt.v1.ProtoMoltService,
thirteen typed RPCs defined in .proto.
The server compiles its own definition at startup and serves it over dynamic
messages — no generated stubs anywhere — with server reflection
on, so grpcurl, any gRPC client, or ProtoMolt’s own
reflect verb
discovers it. The tool that manages the format is spoken in the format.
One launcher, protomolt-serve,
mounts the same thirteen verbs everywhere at once: gRPC with reflection, the
JSON/REST gateway with a generated OpenAPI document, Swagger UI at
/docs, and
optionally the git-backed registry — every envelope identical across
gRPC, REST, and MCP. The test suite pins the punchline: ProtoMolt operates a
second live instance of itself through its own invoke verb.
Verification, not assertion
1,800+ tests run in the standard build. The complete protovalidate conformance suite is re-scored with buf’s own runner on every push. Live-registry integration suites run against real Apicurio and Confluent registries in CI — and fail the build if they silently skip.