Skip to Content
FeaturesModel Context Protocol

Model Context Protocol

Pilot includes a built-in MCP (Model Context Protocol) server that exposes 56 tools for external AI agents to interact with your Kafka cluster.

Overview

MCP is an open protocol that allows AI agents (like Claude Desktop, custom agents, or other MCP-compatible tools) to discover and invoke operations on your cluster programmatically. The MCP server is enabled by default.

PILOT_MCP_ENABLED=true # Enabled by default

Tool Categories

Read Tools (30+ tools)

Read-only operations that inspect cluster state:

ToolDescription
get_cluster_overviewCluster overview: brokers, topics, partitions, controller
get_cluster_healthHealth: URPs, offline partitions, unavailable counts
get_partition_activityPartition activity rates and sizes
get_broker_racksBroker rack assignments
get_topic_configTopic configuration
search_topicsSearch topics by name
search_topics_by_configSearch topics by config values
list_aclsList ACL bindings
list_consumer_groupsList consumer groups
describe_consumer_groupGroup details with members
get_consumer_group_lagPer-partition consumer lag
browse_messagesBrowse messages in a topic
get_topic_watermarksPartition watermarks
list_quotasList client quotas
list_proposalsList rebalance proposals
generate_proposalRead the current rebalance candidate and authoritative readiness decision
get_cluster_logdirsLog directory info
what_if_simulateSimulate cluster scenarios
blast_radius_analyzeAnalyze failure impact
search_audit_logSearch audit events

Mutate Tools (20+ tools)

Operations that modify cluster state (require approval):

ToolDescription
update_topic_configUpdate topic configuration
bulk_update_topic_configUpdate config for multiple topics
create_aclsCreate ACL bindings
delete_aclsDelete ACL bindings
reset_consumer_group_offsetsReset consumer offsets
delete_consumer_groupDelete a consumer group
update_quotaSet quota values
delete_quotaDelete quota keys
redistribute_topicRedistribute topic partitions
redistribute_partitionReassign a single partition
bulk_reassign_partitionsBulk partition reassignment
cancel_reassignmentCancel active reassignment
apply_proposalApply a rebalance proposal. Refused with status: "blocked" and a reason when decision.applicationAllowed is false, before approval and again when approved. MCP has no force override
set_broker_maintenanceEnter broker maintenance
remove_broker_maintenanceExit broker maintenance
preferred_leader_electionTrigger PLE
move_broker_logdirsMove log directories
revert_audit_eventRevert an audited change. A reassignment revert is refused, with nothing moved, when a partition changed since the audited change, so later moves are not undone. Pilot’s own selfheal.apply events cannot be reverted

Meta Tools (3 tools)

Approval workflow management:

ToolDescription
approve_actionApprove a pending mutation
reject_actionReject a pending mutation
list_pending_actionsList pending approvals

Output Limits and Drill-Down

List-shaped tools return bounded summaries by default so results stay small enough for LLM context windows. Complete data remains available through drill-down parameters, dedicated detail tools, and the REST API.

Result Envelope

Bounded list results wrap their rows in a common envelope:

KeyMeaning
countRows returned in this response
totalRows available before the limit was applied
truncatedtrue when rows were dropped
hintPresent only when truncated; names the parameter or tool to use for a narrower query

Per-row field sets are stable and envelope keys are additive-only; tools that predate the envelope keep historical key names such as totalTopics, totalPartitions, and historyTotal. Aggregate figures (totals, rollups, health counts) stay complete even when rows are truncated.

Limits per Tool

limit is optional everywhere it appears. Omitted or 0 selects the default; values above the maximum are clamped to the maximum. Rows marked “fixed” have no limit parameter.

ToolRows keyDefaultMaxOrder
get_cluster_overviewtopics100500Partition count desc, then name
get_cluster_healthnotRackAwareDetails20fixed-
get_partition_activity (plain)partitions50200Topic asc, partition asc
get_partition_activity (aggregate="topic")topics20100Sort key desc
get_partition_activity (sortBy only)partitions50200Sort key desc
search_topicstopics1001000Name asc
list_aclsbindings100500Resource type, resource name, principal
list_consumer_groupsgroups100500Group ID asc
get_consumer_group_lagtopPartitions20200Lag desc
get_topic_watermarkspartitions1001000Partition asc
get_cluster_logdirs (summary)topics20100Size desc
get_cluster_logdirs (detail)partitions50200Size desc
list_reassignmentshistory (embedded)10fixedNewest first
get_reassignment_historyhistory20100Newest first
get_partition_optimizationrecommendations20100High > Medium > Low, then topic
search_audit_logevents50200Newest first
browse_messagesmessages2050Seek order
get_proposal, generate_proposalreassignments (embedded)50fixed-

Proposal tools return the backend’s authoritative decision, shared with Overview and proposal review. Use decision.applicationAllowed and nextAction to determine whether a candidate can be reviewed for application. Move counts, raw optimizer status, storage status ready and confidence scores do not override it. generate_proposal reads the server-selected current candidate without starting a separate calculation. Its candidateAvailable flag means a candidate exists, not that it can be applied. List entries each include their own decision; historical proposals are not current recommendations.

list_proposals always returns summary rows; get_proposal and generate_proposal omit broker activity scores, cluster snapshots, every broker’s fair share (fairShare.shares), each load’s oversized partitions and the optimizer’s search diagnostics (movement.search), with totalReassignments and reassignmentsTruncated reporting the full size of the embedded list (complete data via the REST API). fairShare.loads is keyed by load name. topicSpread.atLimit is keyed by pair, for example orders on broker 1, and the topic cap’s pair and excess-leader counts (overCap, projectedOverCap, excessLeaders, projectedExcessLeaders) are left out; they stay in the REST API and the UI. Both return the per-metric balance breakdown instead: imbalance, whether the metric counts for balancing or has no traffic, largest per-broker difference, and busiest and quietest broker.

Drill-Down Parameters

Parameters that switch summary output to detail, or narrow it:

ToolParameterEffect
get_cluster_logdirstopic, brokerIdSwitch from broker and topic summaries to per-partition replica rows; combinable
get_partition_activityaggregate, sortBy, topic, brokerIdAggregate per topic, rank by rate or size, or filter rows
get_consumer_group_lagtopicScope rollups and partition rows to one topic
get_partition_optimizationpriorityOnly High, Medium, or Low recommendations
get_default_configskeyFilterCase-insensitive substring filter on config keys

For full detail on a single item, use the paired detail tool instead of raising the limit: describe_consumer_group for members and assignments, get_proposal for a full proposal, get_reassignment_by_id for one reassignment record, get_reassignment_history for older history.

Approval Workflow

All mutate tools require explicit approval before execution:

  1. An AI agent calls a mutate tool
  2. Pilot queues the action and returns a pending approval token
  3. A distinct identity approves or rejects the action
  4. If approved, the mutation executes and the result is returned

This ensures no AI agent can make unsupervised changes to your cluster.

Distinct Approver

Approval requires an identity different from the one that requested the mutation. An MCP client cannot approve its own pending action: a different identity, such as a second MCP client or token, must call approve_action. The Pilot UI and the assistant do not show MCP pending actions. The action stays pending until a distinct identity approves it or it expires. An unauthenticated client cannot self-approve either.

Execution Parity

MCP-driven mutations run through the same execution path as the HTTP API:

  • Same safety gating. Hard-health blockers (controller unhealthy, majority of brokers unavailable, sustained ISR shrink) block the mutation and are not overridable. Drains and reassignments are blocked while a rolling restart is in progress. See Apply-Time Safety Gating.
  • Throttled and concurrency-capped. Reassignments apply the same replication throttle and per-broker move cap as the HTTP path, so an MCP-driven move cannot saturate the cluster.
  • Single-flight. A server-wide mutation slot keeps MCP and HTTP from stacking uncoordinated reassignment load.
  • Run to completion. MCP reassignment actions execute fully and report status: "completed" rather than returning while the move is still in flight.
  • Audited the same way. Mutations are recorded in the audit log with method MCP, the approver in userId and the requester in requestedBy. Reassignment tools record one row per partition when the moves are submitted and add an event with status 500 if the execution then fails. Other tools add an event with status 500 when the change itself fails. Quota events carry the entity path used by the HTTP API, so MCP quota changes can be reverted from the audit log.

Authentication

When authentication is enabled, the MCP endpoint requires a valid Bearer token. Use a Personal Access Token (PAT) for long-lived, revocable access. PATs work with all Pilot API endpoints, not just MCP - see Personal Access Tokens for details.

Prerequisites: PATs require AUTH_PAT_ENABLED=true and a stable AUTH_PAT_HASH_SECRET to be configured on the server. See PAT Configuration for details.

Creating a Token

  1. Log into the Pilot UI via your OAuth provider
  2. Click your avatar (top right) -> Access Tokens -> New token
  3. Choose a name, scope (read or write), and optional expiry
  4. Copy the pat_... token (shown only once)

Scopes

ScopePermissions
readRead-only tools (cluster overview, topic configs, consumer groups, etc.) plus list_pending_actions
writeAll tools including mutations (reassignments, ACLs, quotas, maintenance, etc.)

Mutate tools always require the approval workflow regardless of scope.

Scope is enforced per tool on the MCP endpoint, not by HTTP method. A read token is refused approve_action and reject_action as well as every mutate tool, so it cannot release or cancel a mutation queued by someone else. It can still call list_pending_actions to see what is queued.

Integration

The MCP endpoint is available at:

POST https://your-pilot-host/api/v1/mcp

GitHub Copilot (VS Code)

Add to .vscode/mcp.json:

{ "servers": { "pilot": { "type": "http", "url": "https://pilot.example.com/api/v1/mcp", "headers": { "Authorization": "Bearer ${input:pilot-token}" } } } }

VS Code will prompt for the token on first use and store it securely.

Warp Terminal

Add to Warp’s MCP server configuration:

{ "mcpServers": { "pilot": { "serverUrl": "https://pilot.example.com/api/v1/mcp", "headers": { "Authorization": "Bearer pat_your_token_here" } } } }

Claude Desktop

Add to your Claude Desktop MCP configuration:

{ "mcpServers": { "pilot": { "type": "url", "url": "https://pilot.example.com/api/v1/mcp", "headers": { "Authorization": "Bearer pat_your_token_here" } } } }

Any MCP Client

The endpoint accepts standard MCP JSON-RPC messages over HTTP POST. Include the Authorization: Bearer <pat_token> header with each request when authentication is enabled. The server supports Streamable HTTP transport and advertises all available tools with their descriptions, input schemas, and categories.

Last updated on