Kafka MCP
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| SR_TOKEN | No | Bearer token for Schema Registry, commonly referenced in the configuration file as {env:SR_TOKEN}. | |
| LOG_LEVEL | No | Logging level, e.g. DEBUG or INFO. | |
| LOG_PRETTY | No | Enable pretty logging. | |
| CONFIG_FILE | No | Path to the configuration file (YAML or JSON). If omitted, the server discovers kafka-mcp.{toml,yaml,yml,json} in the working directory, ~/.config/kafka-mcp/, or /etc. | |
| KAFKA_TOKEN | No | Static OAuth token for Kafka OAUTHBEARER, commonly referenced in the configuration file as {env:KAFKA_TOKEN}. | |
| SR_PASSWORD | No | Password for Schema Registry, commonly referenced in the configuration file as {env:SR_PASSWORD}. | |
| KAFKA_PASSWORD | No | Kafka SASL password, commonly referenced in the configuration file as {env:KAFKA_PASSWORD}. | |
| KAFKA_CLIENT_SECRET | No | OAuth client secret for Kafka OAUTHBEARER, commonly referenced in the configuration file as {env:KAFKA_CLIENT_SECRET}. | |
| KAFKA_MCP_HTTP_ADDRESS | No | HTTP listen address, overriding http.address in the configuration file. | :8090 |
| KAFKA_MCP_HTTP_BASE_PATH | No | Base path prefix for HTTP endpoints, overriding http.base_path in the configuration file. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| add_partitionsA | Increase the partition count of 1 to 1000 topics in one call through items, and report each topic's current count, affected consumer groups, sampled key usage and warnings. Changing one topic is an items array of length one. Kafka cannot remove partitions, and changing the count can break ordering for keyed messages. No change is made unless confirm is true; one confirm covers the whole batch, and changes are not atomic because Kafka cannot roll a successful item back. Results follow items order, each carrying index with result or error. Keyed samples also require acknowledge_key_ordering on the item. Requires Kafka ALTER permission. |
| alter_topic_configA | Change topic-level configuration of 1 to 1000 topics in one call through items. Each item sets keys (set) and removes overrides so the cluster default applies again (delete). Every key not named keeps its value: changes are incremental, never a full replace. Changing one topic is an items array of length one. No change is made unless confirm is true. The preview asks the broker to validate every item and returns, per key, the current value and its source (DYNAMIC_TOPIC_CONFIG means a deliberate topic setting; anything else is inherited) next to the requested value. Shortening retention.ms reports how many messages are already older than the new limit, because they become eligible for deletion straight away. Changing cleanup.policy or retention.bytes is warned about. One confirm covers the whole batch, and applying is not atomic: topics changed before a later item failed stay changed. Results follow items order, each carrying index with result or error. Requires Kafka ALTER_CONFIGS permission. |
| cluster_healthA | Check the health of the cluster this endpoint serves in one call: cluster id, controller, every broker (id, host, port, rack, and how many partitions it leads), a summary count, and every partition that is not fully healthy. A problem partition lists its issues:
A problem partition with reassigning true is being moved between brokers; adding_replicas catch up before joining the ISR, so under_replicated there is expected while the move runs, not an outage. healthy is true only when there are no problems. Use search to limit the check to topics whose name contains a substring (case-insensitive); internal topics are skipped unless include_internal is true. min_isr_unknown lists topics whose min.insync.replicas the broker did not report, so under_min_isr was not judged for them. |
| commit_offsetA | Move 1 to 1000 consumer group positions in one call through items. Each item names a group and topic and exactly one target: offset (one partition, the next offset the group reads), timestamp (RFC3339; each partition moves to its first message at or after that time, which is how messages are replayed since a moment), or position (earliest or latest). With timestamp or position, omit partition to move every partition of the topic. Moving one offset is an items array of length one. The response previews, per partition and in total, how many messages each move would skip or replay. No change is made unless confirm is true; one confirm covers the whole batch, and applying is not atomic because Kafka cannot roll back commits that succeeded before a later item failed. Results follow items order, each carrying index with result or error. Active groups are refused unless allow_active_members is set on the item, because running consumers may overwrite the commit. Requires Kafka offset-commit permission. |
| compare_clustersA | Compare the topics of 1 to 1000 other clusters against the one this endpoint serves, through items. Reports which topics only this cluster has, which only the other has, which exist on both but disagree, and how many brokers and topics each side has. Comparing one cluster is an items array of length one. Use it to find what preproduction has that production does not, or to check whether two environments still match. Topics reported as only on the other cluster carry their partition count, replication factor and explicitly-set configs, so the report can be handed straight to create_topic. This tool creates and changes nothing. To create the missing topics, pass them to create_topic, which previews them against the broker first. Only configs a topic sets for itself are compared. Two clusters may carry different broker defaults, and comparing inherited values would report every topic as different. Internal topics are excluded unless include_internal is set. Topic listings come from the client's metadata cache, so a topic created within the last few seconds may still be reported as missing. Repeat the comparison after a moment rather than creating it twice. |
| consumer_lagA | Measure consumer lag for 1 to 1000 topics in one call through items: production and consumption rates, and whether each topic's backlog is caught up, draining, growing, stalled or has no active consumers. Returns an ETA only when lag is shrinking. Results follow items order, each carrying index with result or error. Measuring one topic is an items array of length one. Consumption rate is sampled for sample_seconds, so the call waits that long. Up to 4 windows run at a time, so the call takes about sample_seconds per 4 items. Set skip_consume_rate for an immediate result without an ETA. |
| copy_messageA | Copy 1 to 500 existing messages in one call through items, each identified by topic, partition and offset, to an existing topic on this or another configured cluster. Preserves key, value and headers and adds traceable provenance headers. Copying one message is an items array of length one. No message is written unless confirm is true; one confirm covers the whole batch, and writing is not atomic because Kafka cannot retract a record produced before a later item failed. Results follow items order, each carrying index with result or error. The destination must be writable and requires Kafka write permission; a read-only cluster may still be the source. A key or value carrying a Schema Registry id is copied byte for byte. When the destination cluster uses a different registry the id may mean nothing there, so the response warns; set translate_schema to register the schema in the destination registry and rewrite the id. |
| create_topicA | Create 1 to 1000 Kafka topics in one call through items, each with optional partition count, replication factor and topic-level configs. Omitted values use broker defaults. Existing topics are refused rather than modified. Creating one topic is an items array of length one. No topic is created unless confirm is true; otherwise the broker only validates the requests. One confirm covers the whole batch, and creation is not atomic: topics created before a later item failed stay, because Kafka cannot roll them back. Results follow items order, each carrying index with result or error. Partition counts cannot be reduced later. Requires Kafka CREATE permission. |
| delete_consumer_groupA | Delete 1 to 1000 consumer groups in one call through items, removing each group's committed offsets. Use it to clean up groups whose consumers were decommissioned: their commits keep reporting lag that nobody will ever drain. Deleting one group is an items array of length one. No group is deleted unless confirm is true. The preview lists each group's state, the topics it has committed on, every committed offset with its lag, and the total lag that would disappear with it. A group with active members is refused: it is not abandoned, and deleting it would reset where its consumers resume. If a consumer later starts with the same group id, it begins wherever its auto.offset.reset points, not where the group left off. One confirm covers the whole batch, and deletion is not atomic: groups deleted before a later item failed stay deleted. Results follow items order, each carrying index with result or error. Requires Kafka DELETE permission on the group. |
| delete_recordsA | Delete the oldest messages of 1 to 1000 partitions in one call through items, without deleting the topic. Each item removes every message of one partition with an offset lower than before_offset; the message at before_offset becomes the first readable one. Alternatively give before_timestamp to cut at a moment, resolved per partition, and all_partitions to apply that moment to every partition of the topic in one item. Use it to purge test data, or a run of bad messages at the head of a partition, while keeping the topic, its configuration and its consumer groups. Truncating one partition is an items array of length one. No message is deleted unless confirm is true and the item sets acknowledge_data_loss. The preview reports the partition's start and end offsets, how many messages would be removed, and every consumer group whose committed offset is below the cut, with how many messages it would lose without ever processing them. Such a group resumes from the new start offset. Kafka cannot restore deleted records. One confirm covers the whole batch, and deletion is not atomic: partitions truncated before a later item failed stay truncated. Results follow items order, each carrying index with result or error. Compacted topics are not supported by every broker. Requires Kafka DELETE permission on the topic. |
| delete_topicA | Delete 1 to 1000 Kafka topics in one call through items. Deleting one topic is an items array of length one. This is the most destructive tool here. Deleting a topic destroys every message in it, and Kafka has no undo: recreating the topic does not bring the data back. Any consumer group reading it breaks. Nothing is deleted unless confirm is true; otherwise the response reports, per topic, how many messages would be destroyed, how many partitions it had, and which consumer groups had committed offsets for it. A topic that still holds messages also requires acknowledge_data_loss on its item, so destroying data is never a single unconsidered call. One confirm covers the whole batch, and deletion is not atomic: topics deleted before a later item failed stay deleted. Results follow items order, each carrying index with result or error. Internal topics are refused. Requires Kafka DELETE permission. |
| describe_consumer_groupA | Describe 1 to 1000 consumer groups in one call through items: state, assignor, coordinator broker, every running member (member_id, client_id, host and the partitions assigned to it), and for every partition the group owns or has committed on, the committed offset, end offset, lag, and the member, client id and host consuming it. Partitions and members are sorted. Use it to find which consumer instance owns a stuck or lagging partition, so the operator knows which pod or host to inspect. has_commit false means the group owns the partition but never committed there, so its starting point is decided by the consumer's auto.offset.reset rather than by an offset. An Empty group has no members but keeps its commits. sample_seconds watches the group for that long first and reports observation: the states it passed through and the members that joined or left. A group that keeps cycling through PreparingRebalance, or whose members keep changing, is rebalancing; the departing members' client_id and host point at the consumer that keeps leaving. Results follow items order, each carrying index with result or error. |
| describe_topicA | Describe 1 to 500 topics in one call through items: partitions, offset ranges, approximate message count, size on disk (size_bytes per partition and topic, replicated_size_bytes across replicas), oldest/newest timestamps and complete effective configuration. Config entries identify whether values are inherited or topic-specific. Results follow items order, each carrying index with result or error, so a topic that does not exist is reported against its own item rather than failing the call. Describing one topic is an items array of length one. Message counts are offset spans and may overcount after retention or compaction. |
| get_messageA | Read 1 to 500 Kafka messages at exact addresses in one call through items, and optionally nearby messages for context. Returns key, value, headers, timestamp and original value size. Values carrying a Schema Registry id (Avro, Protobuf, JSON Schema) and topics with a configured format are decoded to JSON; format, schema_id and message_type say what the bytes were. Anything else is returned as text, or base64 when it is binary, and decode_error explains a value that named a schema but could not be decoded. Results follow items order, each carrying index with result or error, so an invalid partition or an offset beyond the partition end is reported against its own item rather than failing the call. Reading one message is an items array of length one. |
| get_schemaA | Read 1 to 1000 schemas from this cluster's Schema Registry in one call through items, each by subject (latest version unless version is given) or by the schema id a message carries. Returns the schema text, its type (avro, protobuf or json_schema), id, version, every version of the subject, the schemas it references, and for an id the subject versions that use it. A subject lookup also reports the compatibility level in force. check_schema tests a candidate schema against the subject's latest version without registering it, returning whether it is compatible and the registry's reasons if not. Read the schema before producing to a schema-encoded topic: it names every field and enum a value needs, which a sampled message may not show. For Protobuf, message_types lists the names produce_message accepts as message_type. The subject for a topic's values is usually -value. Results follow items order, each carrying index with result or error. Fails as a whole when the cluster has no schema_registry configured. |
| list_aclsA | List the access control entries (ACLs) on the cluster this endpoint serves. Each entry has principal, host, resource_type, resource_name, pattern_type (literal, prefixed), operation (read, write, describe, ...) and permission (allow or deny). Results are sorted. Use it when a client fails with TOPIC_AUTHORIZATION_FAILED, GROUP_AUTHORIZATION_FAILED or similar: filter by the client's principal, or by the resource it was refused on. Filtering by resource_name returns every ACL the broker applies to that name, including prefixed and wildcard entries, so the answer covers what actually decides access. A deny overrides any allow. All filters are optional and combine. Fails with SECURITY_DISABLED when the broker has no authorizer, which means ACLs are not enforced at all. Needs DESCRIBE permission on the cluster. |
| list_clustersA | List the Kafka clusters this server serves, with whether each is reachable, whether it is configured read_only, and whether this session may write to it (writable). Connectivity is checked at call time. A cluster is a valid copy_message or produce_message destination_cluster only when writable is true. Broker and credential details are not exposed. |
| list_consumer_groupsA | List the consumer groups on the cluster, with their state, member count and the topics they consume. Filter by exact topic or group state. Empty groups may still hold committed offsets and lag; they have no active consumers to drain it. Topic filtering may inspect every group because Kafka has no topic-to-group index. |
| list_topicsA | List the topics on the endpoint's cluster, sorted by name, each with its partition count, replication factor and the configs it sets for itself. Filter with an optional JavaScript predicate. A name match is return topic.indexOf('orders') >= 0, and the predicate can also read partitions, replication_factor, internal and configs — questions a substring filter cannot express, such as which topics have more than six partitions, only one replica, or a compacted cleanup policy. Only configs a topic sets for itself are reported, because inherited cluster defaults would make every topic look configured. Topics whose predicate throws are counted in script_errors rather than listed, so a broken filter is never mistaken for an empty cluster. |
| open_transactionsA | Find open transactions holding back read_committed consumers on 1 to 1000 topics in one call through items. A consumer with isolation.level=read_committed cannot read past the first message of a transaction that has not been committed or aborted, so a transactional producer that hangs or dies mid-transaction stalls every such consumer on that partition. In consumer_lag this looks exactly like a poison message: members present, nothing consumed. For each topic, blocked says whether any partition's last stable offset trails its high watermark. Each such partition reports both offsets, how many messages read_committed consumers cannot see, and every producer with an open transaction there: producer id and epoch, the offset the transaction started at, and where the coordinator knows it, the transactional id (which names the application), state, when it started, how long it has been open and its timeout, after which the broker aborts it. The fix is in the producer, not the consumer: restart or fence the producing application, or wait for the timeout. Skipping offsets does not help. Results follow items order, each carrying index with result or error. Needs DESCRIBE on the topic and on transactional ids. |
| produce_messageA | Write 1 to 500 new messages in one call through items, or any number from an upload, to existing topics on this or another configured cluster. The caller supplies the key, value and headers, so unlike copy_message this can write content no producer ever sent. Writing one message is an items array of length one. Every message carries provenance headers naming this tool, the time and the principal, so a fabricated message stays distinguishable from a genuine one. upload sends a file on the user's own machine, one item per line as JSON, such as the file a transform_messages download saves. Over stdio the file is read at once; over HTTP the response is a link and a command to run there, once, as each run sends the file again. The file is never stored on the server, and the summary counts lines, shows a few examples and the failing lines by number. Without confirm the upload only checks the file. Nothing is written unless confirm is true; one confirm covers the whole batch, and writing is not atomic because Kafka cannot retract a record produced before a later item failed. Results follow items order, each carrying index with result or error. A produced message cannot be deleted: it stays until retention removes it, and any consumer reading the topic will process it. The destination must be writable and requires Kafka write permission; the endpoint you call may itself be read-only. Omit partition unless the exact partition matters. The key decides placement, and naming a partition puts a keyed message where its key does not hash to, which breaks ordering for that key. A topic whose consumers read Avro, Protobuf or JSON Schema needs value_schema: give the value as JSON and it is encoded to the destination registry's schema, refused with the offending field when it does not fit. A topic with a format configured in topic_formats is encoded to it without being asked. Check get_message or sample_messages first: a schema_id on the existing messages means the topic needs value_schema, and writing plain JSON there breaks its consumers. |
| sample_messagesA | Sample the newest messages of 1 to 500 topics in one call through items, and summarize value formats, field paths, key usage, the schemas values were written with, raw value sizes (value_bytes min/p50/max), and sampled offset ranges. Use this to design a search_messages predicate, and to find the schema to produce against. Avro, Protobuf and JSON Schema values carrying a Schema Registry id, and topics with a configured format, are decoded, so their field paths are reported like JSON. value_formats.undecodable counts values that named a schema but could not be decoded; decode_error on each message says why. Results follow items order, each carrying index with result or error. Sampling one topic is an items array of length one. The sample describes recent data only, and keys must not be used to guess partitions. |
| search_messagesA | Search message key, value, headers or metadata with a JavaScript predicate. The script returns true for a match and receives value (parsed JSON, a decoded Avro/Protobuf/JSON Schema record, or text), key, headers, partition, offset, timestamp, value_bytes, key_bytes, format, schema_id and decode_error. Omit it to match all messages. Schema-encoded values are searched by field exactly like JSON. group_by summarises instead of listing: an expression over the same variables returns a bucket name, and every match in the range is counted per bucket with one example address each. Use it to break a DLQ down by error header, find hot keys on a partition, or count messages per schema_id. Every partition is read together, one chunk deep at a time, so a limited newest-first search returns the newest matches in the topic rather than the newest in whichever partition was read first. Kafka orders records only within a partition, so matches are merged by timestamp; producers set timestamps unless the topic uses LogAppendTime. Kafka has no server-side search, so scans are bounded. Check complete, stopped_reason and scanned_ranges before treating no matches as conclusive. Use count_only for large result sets, and download to save them to a file on the user's machine without storing anything on the server: over stdio the file is saved at once, and over HTTP the response is a link and a command to run there, the search streaming every match when it is fetched. A script that runs past timeout_seconds is interrupted and counted in script_errors; scripts are not memory-sandboxed, so keep predicates simple. |
| server_configA | Report this endpoint's name, path, purpose, cluster, brokers, authentication, TLS, read-only policy, the other clusters it may write to (destinations), Schema Registry, configured topic formats and exposed tools. Use it to confirm the target and permissions before acting; several endpoints may target one cluster with different policies. Passwords are never returned. |
| transform_messagesA | Rewrite messages with a JavaScript transform and write the results as new messages: to the same topic, another topic, or a topic on another configured cluster. Use it to repair messages produced in the wrong shape, for example a document wrapped in a payload field: transform "return { value: value.payload }". The transform is JavaScript run once per message. It sees the same variables as search_messages and returns an object with any of value, key and headers; what it leaves out is kept from the original, and null skips the message. An integer beyond 2^53 arrives as a BigInt so ids are written back exactly. An optional script selects which messages to transform. Schema-encoded values (Avro, Protobuf, JSON Schema) are decoded for the transform and re-encoded with the same schema id; set value_schema to encode to a different schema or registry. The originals are never changed or deleted: Kafka cannot edit a message, so the new messages are appended. Writing back to the source topic stops at the end offset the call started with, so it never reads its own output. Every new message carries provenance headers naming the source topic, partition and offset. Nothing is written to Kafka unless confirm is true. Without it the response counts what would be written, shows before/after examples and groups failures by reason with example addresses. download saves the new messages on the user's machine instead, as produce_message items, one per line, so the set can be inspected and later sent with produce_message upload: over stdio at once, over HTTP through a link and command the transform runs behind when fetched. Nothing is stored on the server, and downloading works on a read-only cluster. Partitions are processed in ascending order and writing is not atomic: messages written before a timeout or failure stay. complete, stopped_reason and scanned_ranges say how far the run got; resume with partitions and from_offset. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 25 tools
Most tools target a distinct resource+action (create_topic vs delete_topic vs alter_topic_config vs add_partitions; produce_message vs copy_message vs transform_messages), and descriptions draw clear boundaries. The main soft spots are the message-reading trio get_message, sample_messages and search_messages, which all return message content and could be confused by an agent that just wants 'to look at messages', and list_clusters vs server_config which both report connectivity/permission context.
Overwhelmingly consistent snake_case verb_noun pattern (list_topics, create_topic, delete_records, commit_offset, describe_consumer_group). A few read-only report tools drop the verb (cluster_health, consumer_lag, server_config), which is a minor but noticeable deviation from the verb_noun convention.
At 25 tools this is at the top of the reasonable range, but the domain is genuinely broad (topics, partitions/configs, messages, consumer groups, offsets, ACLs, schemas, clusters) and each tool covers a distinct operation with no obvious filler. It is heavy but earns its footprint rather than padding it.
Topic lifecycle (create/describe/list/delete, partitions, configs), message read/write/copy/transform/truncate, consumer group and offset management, lag, transactions, health, schema reads and ACL listing give near-complete coverage of Kafka administration. Notable gaps remain: ACLs are read-only (no create/delete_acl), schema registration is only indirect via produce, and open_transactions is diagnostic only (no abort), and there is no partition reassignment action even though cluster_health surfaces reassignments.