KubeMQ
AiwayMCP

MCP

Expose KubeMQ messaging and the A2A agent bridge as Model Context Protocol tools that Claude and other AI models can discover and invoke.

The MCP connector exposes KubeMQ messaging operations as Model Context Protocol tools, so Claude and other AI models can publish, subscribe, and call KubeMQ — and reach registered agents — without a KubeMQ-specific client library. It speaks MCP protocol version 2025-11-25 over JSON-RPC 2.0 at a single endpoint on the shared HTTP server.

Part of Aiway. MCP is one of the two doors into KubeMQ Aiway, the AI Agents Fabric. New here? Start with the Aiway overview, or follow the end-to-end Aiway tutorial.

What MCP is

The Model Context Protocol is an open standard for connecting AI models to external tools and data over a uniform JSON-RPC 2.0 interface. A model's MCP client connects to an MCP server, asks it which tools it offers (tools/list), and invokes them by name (tools/call). KubeMQ is one such server: every KubeMQ messaging operation is published as a named MCP tool.

Because the protocol is standard, any MCP-aware model or runtime can use KubeMQ with no KubeMQ code on the caller. You point the official MCP SDK for your language — or a client like Claude Desktop — at the endpoint, and the model gains messaging, persistent events, request/reply, channel introspection, and a bridge to A2A agents as native tools.

Why MCP with KubeMQ

  • No KubeMQ SDK on the caller — clients use the official MCP SDK for their language; KubeMQ is just an MCP server they connect to.
  • One endpointPOST /mcp for JSON-RPC requests (single or batch), plus GET /mcp for a keepalive SSE stream, both on the shared HTTP port 9090.
  • 15 ready-to-use tools — 11 core messaging tools plus 4 agent-bridge tools, covering every KubeMQ pattern.
  • A bridge to agents — the model can list, inspect, and message agents registered with the A2A connector through the same tool interface.
  • Enabled by default — start kubemq-server and /mcp is live; there is no flag to turn it on.

How it works

An MCP client connects to the /mcp endpoint, completes the initialize handshake to obtain a session, then calls tools. The connector translates each tool call into a native KubeMQ operation; agent-bridge tools forward over the broker to the A2A registry.

The MCP connector turns JSON-RPC tool calls into KubeMQ operations and bridges to A2A agents.

The connector runs on the shared HTTP server and inherits its middleware, authentication, and observability. The reserved _AGENTS_. channel prefix is rejected for direct messaging tools — use the agent-bridge tools to reach agents.

The 15 tools

KubeMQ exposes 15 MCP tools across five categories — 11 core messaging tools that are always available, plus 4 agent-bridge tools that appear when the agent registry is present.

CategoryToolsCount
Queuequeue_send, queue_receive, queue_peek3
Eventsevents_publish, events_store_publish, events_store_read, events_store_read_latest4
Command / Querycommand_send, query_send2
Channel managementchannel_list, channel_info2
Agent bridgeagent_list, agent_info, agent_send, agent_query4
Total15

Endpoint surface

MethodPathDescription
POST/mcpJSON-RPC 2.0 request handler (single or batch)
GET/mcpSSE keepalive stream

JSON-RPC methods on POST /mcp: initialize, notifications/initialized, ping, tools/list, and tools/call. The MCP-Protocol-Version response header is always 2025-11-25, and MCP-Session-Id carries the session returned by initialize. See the endpoints reference for full signatures.

Discover the tools

The tools/list method returns every available tool with its name, description, and inputSchema. It is the first call after initialize — it tells the model what KubeMQ can do.

curl -X POST http://localhost:9090/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list"
  }'
using ModelContextProtocol.Client;

var url = Environment.GetEnvironmentVariable("KUBEMQ_MCP_URL") ?? "http://localhost:9090";
var transport = new HttpClientTransport(new HttpClientTransportOptions { Endpoint = new Uri($"{url}/mcp") });
await using var client = await McpClientFactory.CreateAsync(transport);

var tools = await client.ListToolsAsync();
foreach (var tool in tools)
{
    Console.WriteLine($"{tool.Name}: {tool.Description}");
}
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/mark3labs/mcp-go/client"
	"github.com/mark3labs/mcp-go/mcp"
)

func main() {
	url := os.Getenv("KUBEMQ_MCP_URL")
	if url == "" {
		url = "http://localhost:9090"
	}

	c, err := client.NewStreamableHttpClient(url + "/mcp")
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		log.Fatal(err)
	}

	result, err := c.ListTools(ctx, mcp.ListToolsRequest{})
	if err != nil {
		log.Fatal(err)
	}

	for _, tool := range result.Tools {
		fmt.Printf("%s: %s\n", tool.Name, tool.Description)
	}
}
import io.modelcontextprotocol.sdk.McpClient;
import io.modelcontextprotocol.sdk.client.transport.HttpClientStreamableHttpTransport;

public class ToolsList {
    public static void main(String[] args) {
        String url = System.getenv().getOrDefault("KUBEMQ_MCP_URL", "http://localhost:9090");
        var transport = HttpClientStreamableHttpTransport.builder(url).endpoint("/mcp").build();
        var client = McpClient.sync(transport).build();
        client.initialize();

        var tools = client.listTools();
        System.out.println(tools);

        client.closeGracefully();
    }
}
import io.modelcontextprotocol.kotlin.sdk.Implementation
import io.modelcontextprotocol.kotlin.sdk.client.Client
import io.modelcontextprotocol.kotlin.sdk.client.StreamableHttpClientTransport
import io.ktor.client.*
import io.ktor.client.plugins.sse.*
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val url = System.getenv("KUBEMQ_MCP_URL") ?: "http://localhost:9090"

    val httpClient = HttpClient { install(SSE) }
    val transport = StreamableHttpClientTransport(client = httpClient, url = "$url/mcp")
    val client = Client(clientInfo = Implementation(name = "kubemq-mcp-kotlin-example", version = "1.0.0"))
    client.connect(transport)

    val tools = client.listTools()
    println(tools)

    client.close()
    httpClient.close()
}
import asyncio
import os

from mcp.client.streamable_http import streamablehttp_client
from mcp import ClientSession

KUBEMQ_MCP_URL = os.environ.get("KUBEMQ_MCP_URL", "http://localhost:9090")


async def main():
    async with streamablehttp_client(f"{KUBEMQ_MCP_URL}/mcp") as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            tools = await session.list_tools()
            for tool in tools.tools:
                print(f"{tool.name}: {tool.description}")


if __name__ == "__main__":
    asyncio.run(main())
require "mcp"

url = ENV.fetch("KUBEMQ_MCP_URL", "http://localhost:9090")

client = MCP::Client.new(
  transport: MCP::Transport::StreamableHTTP.new("#{url}/mcp"),
  name: "kubemq-mcp-ruby-example",
  version: "1.0.0"
)
client.initialize_handshake

tools = client.list_tools
puts tools

client.close
use rmcp::transport::streamable_http::StreamableHttpClientTransport;
use rmcp::service::RunService;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let url = std::env::var("KUBEMQ_MCP_URL")
        .unwrap_or_else(|_| "http://localhost:9090".to_string());

    let transport = StreamableHttpClientTransport::from_uri(format!("{url}/mcp"))?;
    let client = ().serve(transport).await?;

    let tools = client.list_tools(Default::default()).await?;
    println!("{tools:#?}");
    Ok(())
}
import Foundation
import MCP

@main
struct ToolsList {
    static func main() async throws {
        let url = ProcessInfo.processInfo.environment["KUBEMQ_MCP_URL"] ?? "http://localhost:9090"

        let transport = HTTPClientTransport(endpoint: URL(string: "\(url)/mcp")!, streaming: true)
        let client = Client(name: "kubemq-mcp-swift-example", version: "1.0.0")
        try await client.connect(transport: transport)

        let (tools, _) = try await client.listTools()
        for tool in tools {
            print("\(tool.name): \(tool.description ?? "")")
        }
    }
}
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const KUBEMQ_MCP_URL = process.env.KUBEMQ_MCP_URL || "http://localhost:9090";

async function main() {
  const transport = new StreamableHTTPClientTransport(
    new URL(`${KUBEMQ_MCP_URL}/mcp`)
  );
  const client = new Client({ name: "kubemq-mcp-ts-example", version: "1.0.0" });
  await client.connect(transport);

  const tools = await client.listTools();
  console.log(JSON.stringify(tools, null, 2));

  await client.close();
}

main().catch(console.error);

Supported languages

Every operation has a curl example plus the official MCP SDK in nine languages. The SDK wraps the Streamable HTTP transport — session IDs, request IDs, and JSON-RPC serialization are handled for you.

LanguageMCP SDK packageSource
C#ModelContextProtocolNuGet
Gogithub.com/mark3labs/mcp-goGo modules
Javaio.modelcontextprotocol:sdkMaven Central
Kotlinio.modelcontextprotocol:kotlin-sdkMaven Central
PythonmcpPyPI
RubymcpRubyGems
Rustrmcpcrates.io
Swiftmcp-swift-sdkSwift Package Manager
TypeScript / JS@modelcontextprotocol/sdknpm

Next steps

Was this page helpful?

On this page