Ask Your Agent Whether the Kafka Schemas Drifted: Confluent Governance over MCP
"Did anything in the registry drift from what we agreed?" is a question a platform engineer answers with three terminal commands and a diff. It is also, increasingly, a question they type into a chat window — and the agent on the other end needs real tools, not guesses. CoreModels ships its Confluent Schema Registry governance as a set of MCP tools, so any MCP-capable agent — Claude, Claude Code, or anything speaking streamable HTTP — can run the same import, audit, generate, and status verbs the HTTP API exposes, with the same role enforcement and the same read-only guarantees.
Ask Your Agent Whether the Kafka Schemas Drifted: Confluent Governance over MCP
"Did anything in the registry drift from what we agreed?" is a question a platform engineer answers with three terminal commands and a diff. It is also, increasingly, a question they type into a chat window — and the agent on the other end needs real tools, not guesses. CoreModels ships its Confluent Schema Registry governance as a set of MCP tools, so any MCP-capable agent — Claude, Claude Code, or anything speaking streamable HTTP — can run the same import, audit, generate, and status verbs the HTTP API exposes, with the same role enforcement and the same read-only guarantees.
This article drives the whole loop from an agent's seat: connect, discover, audit with inline artifacts, handle a registry too big to inline, import, and generate schemas back out.
Connecting
The public MCP endpoint is /mcp, secured with OAuth 2.0 — dynamic client registration and PKCE, so there is no client id to pre-provision. Read-only tools live there. Write tools (including vendor import) are served only on the admin endpoint, /mcp-admin. In Claude Code:
claude mcp add --transport http coremodels https://coremodels.example.com/mcp
then complete the OAuth flow when prompted. For write access, add the admin endpoint the same way:
claude mcp add --transport http coremodels-admin https://coremodels.example.com/mcp-admin
In claude.ai or Claude Desktop it is Settings → Connectors → add a custom connector with the same URL. Either way, the enforced authorization boundary is the per-project role check: import requires Admin membership on the target project no matter which endpoint minted the token.
Step 1 — Discover what's connected
get_vendor_integration_status is the orientation tool. Called with only a project id, it lists every registered connector with capabilities and expected artifacts. Called with a vendor, it returns that vendor's last-import state in the project:
{ "graphProjectId": "0a1b2c3d4e5f60718293a4b5c6d7e8f9", "vendor": "confluent" }
The result says whether an import exists (imported), the recorded state (timestamps, artifact versions, fingerprint, counts — including how many subjects were Protobuf), and how many imported subjects currently resolve to governed Types. An agent that starts here never has to guess whether the estate is governed yet.
Step 2 — Audit with inline artifacts
The audit tool, audit_vendor_project, is Viewer-role and read-only, so it is available on the public endpoint. The agent passes the registry export — the JSON array of GET /subjects/{subject}/versions/latest responses — as a string in the artifacts map:
{ "graphProjectId": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"vendor": "confluent",
"artifacts": { "subjects": "<contents of subjects.json>" } }
Back comes the full audit report: errorCount, warningCount, infoCount, structured findings with section, severity, code, subject, message, and detail, plus the same markdown report the HTTP surface returns. The semantics are identical to the CI gate: errorCount > 0 means the estate violates governed meaning. An agent asked "is the registry clean?" has a precise, honest answer to relay — and because findings carry stable kebab-case codes (field-type-drift, enum-narrowed, fields-no-doc, protobuf-unparsed), it can group, filter, and explain them rather than paraphrase.
Who produces subjects.json? A human, a script, or the agent itself if it has shell access — the export is one credential-free loop against the registry's REST API, documented in the quickstart. The MCP server never talks to your registry; it only ever sees the file.
Step 3 — The artifactUrls flow for large registries
MCP clients cannot always inline a multi-megabyte payload into a tool call. For that, every artifact-bearing integration tool accepts artifactUrls alongside (or instead of) artifacts — a name-to-URL map the server fetches for you. The same audit_vendor_project call becomes:
{ "graphProjectId": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"vendor": "confluent",
"artifactUrls": { "subjects": "https://artifacts.example.net/exports/subjects.json" } }
Stage the export wherever your pipeline already puts build outputs — an artifact store, a release asset — and pass the link. These are server-side fetches of caller-supplied URLs, so they are deliberately locked down: https only, redirects disabled, hosts resolving to loopback, link-local, or private ranges refused, and a hard response-size cap. Anything the server refuses or fails to fetch is itemized in a fetchProblems list in the tool result instead of vanishing — if no artifact was usable at all, the call errors rather than auditing nothing.
Step 4 — Import, on the admin endpoint
Import is the one write in the set, and it is additive: datasets become Types, fields become Elements with Avro's own optionality, enums become Taxonomies, cross-subject record references become governed references, and vendor metadata rides alongside — but already-governed nodes are never mutated. The import_vendor_project tool requires Admin role and is served only on /mcp-admin:
{ "graphProjectId": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"vendor": "confluent",
"artifacts": { "subjects": "<subjects.json>" } }
The result mirrors the HTTP import: datasetsAdded, datasetsSkippedExisting, fieldsAdded, nodesEnriched, plus lossiness and errors. An agent on the public endpoint simply does not see this tool — a clean failure mode for governance: the read-only endpoint cannot be talked into writing.
Step 5 — Generate schemas back out
generate_vendor_artifacts is Viewer-role and read-only (it writes nothing to the project — it returns files):
{ "graphProjectId": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"vendor": "confluent",
"typeNames": ["Order", "Customer"] }
For Confluent the output is one registry-ready schemas/{Record}.avsc per governed Type: required fields as bare Avro types, optional fields as ["null", T] with default: null, taxonomies as sanitized Avro enums, DateTime as timestamp-millis. Omit typeNames to generate everything eligible. The practical agent workflow writes these files into a branch of the repo where schemas are authored and opens a pull request — governance proposes, humans merge.
The rest of the toolbox
The integration tools do not live alone on the endpoint. The same MCP server exposes the general CoreModels read tools — list_projects to find the governing project in the first place, get_project_summary for the labels and ids of the Types, Elements, and Taxonomies the import created, and search_nodes to drill into any of them. A useful agent pattern chains these after an audit: a field-type-drift finding names its subject, the agent looks up the governed Element behind it, and the explanation it hands back cites the governed type, the taxonomy terms, and the description — the actual agreed meaning, not a guess reconstructed from the schema text. All artifact-bearing calls also accept an optional spaces array when the governed estate lives in specific spaces of the project rather than its main space.
Why this shape works for agents
Three properties make these tools safe to hand to an autonomous caller. First, the read/write split is structural: audit, generate, and status are Viewer-role and available publicly; import is Admin-role on a separate endpoint. Second, every answer is grounded: findings carry codes and subjects an agent can quote verbatim, and the counts it reports are the same numbers a CI gate would enforce — no gap between what the agent says and what the pipeline does. Third, honesty is in-band: lossiness records, fetchProblems, and coverage findings like protobuf-unparsed mean the agent can tell you what is not governed with the same confidence it reports what is.
The result is a governance loop you can drive conversationally without weakening it: the agent audits on demand, explains drift by code, imports only when an Admin says so, and hands back schemas the registry will accept. For the export recipe and the HTTP equivalents of every call above, see the Confluent Schema Registry quickstart in the CoreModels docs.