{"id":49698588,"url":"https://github.com/kinotic-ai/vertx-mcp","last_synced_at":"2026-05-08T04:03:12.992Z","repository":{"id":309501653,"uuid":"1036458986","full_name":"kinotic-ai/vertx-mcp","owner":"kinotic-ai","description":"A Vert.x MCP Server built on top of MCP Java SDK","archived":false,"fork":false,"pushed_at":"2025-12-30T00:14:54.000Z","size":143,"stargazers_count":9,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-23T04:42:09.574Z","etag":null,"topics":["java","llms","mcp","mcp-server","vertx"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kinotic-ai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-12T05:36:20.000Z","updated_at":"2026-01-28T02:52:33.000Z","dependencies_parsed_at":"2025-08-12T09:33:08.701Z","dependency_job_id":null,"html_url":"https://github.com/kinotic-ai/vertx-mcp","commit_stats":null,"previous_names":["kinotic-foundation/vertx-mcp","mindsignited/vertx-mcp","mindignited/vertx-mcp","kinotic-ai/vertx-mcp"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/kinotic-ai/vertx-mcp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kinotic-ai%2Fvertx-mcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kinotic-ai%2Fvertx-mcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kinotic-ai%2Fvertx-mcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kinotic-ai%2Fvertx-mcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kinotic-ai","download_url":"https://codeload.github.com/kinotic-ai/vertx-mcp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kinotic-ai%2Fvertx-mcp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32766122,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T02:36:36.067Z","status":"ssl_error","status_checked_at":"2026-05-08T02:36:07.210Z","response_time":54,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","llms","mcp","mcp-server","vertx"],"created_at":"2026-05-08T04:03:11.998Z","updated_at":"2026-05-08T04:03:12.980Z","avatar_url":"https://github.com/kinotic-ai.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vert.x MCP Server\n\nA Vert.x-based transport implementation for the [Model Context Protocol (MCP) Java SDK](https://modelcontextprotocol.io/sdk/java/mcp-server). This project provides a lightweight, non-blocking transport layer that integrates MCP servers with Vert.x applications.\n\n## Overview\n\nThe Vert.x MCP Server provides:\n\n- **Vert.x Transport**: A `VertxMcpTransport` interface that provides a Vert.x Router for integration into your Vert.x applications\n- **SSE Transport**: Server-Sent Events (SSE) implementation for real-time bidirectional communication\n- **Streamable HTTP Transport**: New MCP 2025-06-18 Streamable HTTP transport implementation\n- **Verticle Support**: A ready-to-use `McpVerticle` for easy deployment\n- **Non-blocking**: Built on Vert.x for high-performance, event-driven architecture\n- **Session Management**: Automatic client session handling with graceful shutdown support\n\n## ⚠️ Experimental Status\n\n**This project is currently in experimental status and has not been fully tested in production environments.**\n\n- The implementation follows the MCP specification but may contain bugs or incomplete features\n- API changes are possible as the project matures\n- Performance characteristics have not been thoroughly benchmarked\n- Please report any bugs, issues, or unexpected behavior you encounter\n- Contributions and feedback are welcome to help improve the project\n\n## Installation\n\n### Maven\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.kinotic\u003c/groupId\u003e\n    \u003cartifactId\u003evertx-mcp\u003c/artifactId\u003e\n    \u003cversion\u003e4.5.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Gradle\n```gradle\ndependencies {\n    implementation 'org.kinotic:vertx-mcp:4.5.1'\n}\n```\n\n### Version Compatibility\n\n- **4.5.x versions**: Compatible with Vert.x 4.5.x\n- **5.0.x versions**: Will be compatible with Vert.x 5.x (not yet supported)\n\n## Quick Start\n\n### 1. Create an MCP Server\n\nFirst, create your MCP server using the official [Java MCP SDK](https://modelcontextprotocol.io/sdk/java/mcp-server):\n\n```java\nimport io.modelcontextprotocol.server.McpServer;\nimport io.modelcontextprotocol.server.McpServerFeatures;\nimport io.modelcontextprotocol.spec.McpSchema;\nimport io.modelcontextprotocol.spec.ServerCapabilities;\nimport java.util.List;\nimport reactor.core.publisher.Mono;\n\n// Create a simple calculator tool\nvar calculatorTool = McpServerFeatures.AsyncToolSpecification.builder()\n    .tool(McpSchema.Tool.builder()\n        .name(\"calculator\")\n        .description(\"Basic calculator\")\n        .inputSchema(\"\"\"\n            {\n              \"type\": \"object\",\n              \"properties\": {\n                \"operation\": {\"type\": \"string\", \"enum\": [\"add\", \"subtract\", \"multiply\", \"divide\"]},\n                \"a\": {\"type\": \"number\"},\n                \"b\": {\"type\": \"number\"}\n              },\n              \"required\": [\"operation\", \"a\", \"b\"]\n            }\n            \"\"\")\n        .build())\n    .callHandler((exchange, toolReq) -\u003e {\n        String operation = (String) toolReq.arguments().get(\"operation\");\n        double a = ((Number) toolReq.arguments().get(\"a\")).doubleValue();\n        double b = ((Number) toolReq.arguments().get(\"b\")).doubleValue();\n        \n        double result = switch (operation) {\n            case \"add\" -\u003e a + b;\n            case \"subtract\" -\u003e a - b;\n            case \"multiply\" -\u003e a * b;\n            case \"divide\" -\u003e a / b;\n            default -\u003e throw new IllegalArgumentException(\"Unknown operation: \" + operation);\n        };\n        \n        return Mono.just(McpSchema.CallToolResult.builder()\n            .textContent(List.of(String.valueOf(result)))\n            .isError(false)\n            .build());\n    })\n    .build();\n\n// Create the MCP server specification (don't call .build() yet)\nvar mcpServerSpec = McpServer.async(transportProvider)\n    .serverInfo(\"calculator-server\", \"1.0.0\")\n    .capabilities(ServerCapabilities.builder()\n        .tools(true)\n        .build())\n    .tools(calculatorTool);\n```\n\n### 2. Create the Vert.x Transport\n\n#### Option A: Use the Legacy HTTP+SSE Transport\n\n```java\nimport io.vertx.ext.mcp.transport.VertxMcpSseServerTransportProvider;\nimport com.fasterxml.jackson.databind.ObjectMapper;\n\n// Create the transport\nvar transport = VertxMcpSseServerTransportProvider.builder()\n    .baseUrl(\"http://localhost:8080\")\n    .messageEndpoint(\"/mcp/message\")\n    .sseEndpoint(\"/mcp/sse\")\n    .keepAliveInterval(Duration.ofSeconds(30))\n    .objectMapper(new ObjectMapper())\n    .vertx(vertx)\n    .build();\n```\n\n#### Option B: Use the New Streamable HTTP Transport\n\n```java\nimport io.vertx.ext.mcp.transport.VertxMcpStreamableServerTransportProvider;\nimport com.fasterxml.jackson.databind.ObjectMapper;\n\n// Create the Streamable HTTP transport\nvar transport = VertxMcpStreamableServerTransportProvider.builder()\n    .objectMapper(new ObjectMapper())\n    .mcpEndpoint(\"/mcp\")\n    .disallowDelete(false)\n    .vertx(vertx)\n    .build();\n```\n\n### 3. Integrate with Your Vert.x Application\n\nUse the provided Verticle for easy integration:\n\n```java\nimport io.vertx.ext.mcp.McpVerticle;\n\n// Deploy the MCP verticle (pass transport and server specification)\nvertx.deployVerticle(new McpVerticle(8080, transport, mcpServerSpec), ar -\u003e {\n    if (ar.succeeded()) {\n        System.out.println(\"MCP Verticle deployed successfully\");\n    } else {\n        System.err.println(\"Failed to deploy MCP Verticle: \" + ar.cause());\n    }\n});\n```\n\n### 4. Complete Examples\n\n#### Example A: Legacy HTTP+SSE Transport\n\nHere's a complete working example using the legacy HTTP+SSE transport:\n\n```java\nimport io.vertx.core.Vertx;\nimport io.vertx.ext.mcp.McpVerticle;\nimport io.vertx.ext.mcp.transport.VertxMcpSseServerTransportProvider;\nimport io.modelcontextprotocol.server.McpServer;\nimport io.modelcontextprotocol.server.McpServerFeatures;\nimport io.modelcontextprotocol.spec.McpSchema;\nimport io.modelcontextprotocol.spec.ServerCapabilities;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport java.time.Duration;\nimport java.util.List;\nimport reactor.core.publisher.Mono;\n\npublic class LegacyMcpServerExample {\n    public static void main(String[] args) {\n        Vertx vertx = Vertx.vertx();\n        \n        // Create MCP server with a simple calculator tool\n        var calculatorTool = McpServerFeatures.AsyncToolSpecification.builder()\n            .tool(McpSchema.Tool.builder()\n                .name(\"calculator\")\n                .description(\"Basic calculator\")\n                .inputSchema(\"\"\"\n                    {\n                      \"type\": \"object\",\n                      \"properties\": {\n                        \"operation\": {\"type\": \"string\", \"enum\": [\"add\", \"subtract\", \"multiply\", \"divide\"]},\n                        \"a\": {\"type\": \"number\"},\n                        \"b\": {\"type\": \"number\"}\n                      },\n                      \"required\": [\"operation\", \"a\", \"b\"]\n                    }\n                    \"\"\")\n                .build())\n            .callHandler((exchange, toolReq) -\u003e {\n                String operation = (String) toolReq.arguments().get(\"operation\");\n                double a = ((Number) toolReq.arguments().get(\"a\")).doubleValue();\n                double b = ((Number) toolReq.arguments().get(\"b\")).doubleValue();\n                \n                double result = switch (operation) {\n                    case \"add\" -\u003e a + b;\n                    case \"subtract\" -\u003e a - b;\n                    case \"multiply\" -\u003e a * b;\n                    case \"divide\" -\u003e a / b;\n                    default -\u003e throw new IllegalArgumentException(\"Unknown operation: \" + operation);\n                };\n                \n                return Mono.just(McpSchema.CallToolResult.builder()\n                    .textContent(List.of(String.valueOf(result)))\n                    .isError(false)\n                    .build());\n            })\n            .build();\n\n        // Create legacy HTTP+SSE transport\n        var transport = VertxMcpSseServerTransportProvider.builder()\n            .baseUrl(\"http://localhost:8080\")\n            .messageEndpoint(\"/mcp/message\")\n            .sseEndpoint(\"/mcp/sse\")\n            .keepAliveInterval(Duration.ofSeconds(30))\n            .objectMapper(new ObjectMapper())\n            .vertx(vertx)\n            .build();\n\n        // Create MCP server specification (don't call .build() yet)\n        var mcpServerSpec = McpServer.async(transport)\n            .serverInfo(\"calculator-server\", \"1.0.0\")\n            .capabilities(ServerCapabilities.builder()\n                .tools(true)\n                .build())\n            .tools(calculatorTool);\n\n        // Deploy the MCP verticle (pass transport and server specification)\n        vertx.deployVerticle(new McpVerticle(8080, transport, mcpServerSpec), ar -\u003e {\n            if (ar.succeeded()) {\n                System.out.println(\"MCP Server started on port 8080\");\n                System.out.println(\"SSE endpoint: http://localhost:8080/mcp/sse\");\n                System.out.println(\"Message endpoint: http://localhost:8080/mcp/message\");\n            } else {\n                System.err.println(\"Failed to start MCP Server: \" + ar.cause());\n            }\n        });\n    }\n}\n```\n\n#### Example B: New Streamable HTTP Transport\n\nHere's a complete working example using the new MCP 2025-06-18 Streamable HTTP transport:\n\n```java\nimport io.vertx.core.Vertx;\nimport io.vertx.ext.mcp.McpVerticle;\nimport io.vertx.ext.mcp.transport.VertxMcpStreamableServerTransportProvider;\nimport io.modelcontextprotocol.server.McpServer;\nimport io.modelcontextprotocol.server.McpServerFeatures;\nimport io.modelcontextprotocol.spec.McpSchema;\nimport io.modelcontextprotocol.spec.ServerCapabilities;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport java.time.Duration;\nimport java.util.List;\nimport reactor.core.publisher.Mono;\n\npublic class StreamableMcpServerExample {\n    public static void main(String[] args) {\n        Vertx vertx = Vertx.vertx();\n        \n        // Create MCP server with a simple calculator tool\n        var calculatorTool = McpServerFeatures.AsyncToolSpecification.builder()\n            .tool(McpSchema.Tool.builder()\n                .name(\"calculator\")\n                .description(\"Basic calculator\")\n                .inputSchema(\"\"\"\n                    {\n                      \"type\": \"object\",\n                      \"properties\": {\n                        \"operation\": {\"type\": \"string\", \"enum\": [\"add\", \"subtract\", \"multiply\", \"divide\"]},\n                        \"a\": {\"type\": \"number\"},\n                        \"b\": {\"type\": \"number\"}\n                      },\n                      \"required\": [\"operation\", \"a\", \"b\"]\n                    }\n                    \"\"\")\n                .build())\n            .callHandler((exchange, toolReq) -\u003e {\n                String operation = (String) toolReq.arguments().get(\"operation\");\n                double a = ((Number) toolReq.arguments().get(\"a\")).doubleValue();\n                double b = ((Number) toolReq.arguments().get(\"b\")).doubleValue();\n                \n                double result = switch (operation) {\n                    case \"add\" -\u003e a + b;\n                    case \"subtract\" -\u003e a - b;\n                    case \"multiply\" -\u003e a * b;\n                    case \"divide\" -\u003e a / b;\n                    default -\u003e throw new IllegalArgumentException(\"Unknown operation: \" + operation);\n                };\n                \n                return Mono.just(McpSchema.CallToolResult.builder()\n                    .textContent(List.of(String.valueOf(result)))\n                    .isError(false)\n                    .build());\n            })\n            .build();\n\n        // Create Streamable HTTP transport\n        var transport = VertxMcpStreamableServerTransportProvider.builder()\n            .objectMapper(new ObjectMapper())\n            .mcpEndpoint(\"/mcp\")\n            .disallowDelete(false)\n            .vertx(vertx)\n            .keepAliveInterval(Duration.ofSeconds(30))\n            .build();\n\n        // Create MCP server specification (don't call .build() yet)\n        var mcpServerSpec = McpServer.async(transport)\n            .serverInfo(\"calculator-server\", \"1.0.0\")\n            .capabilities(ServerCapabilities.builder()\n                .tools(true)\n                .build())\n            .tools(calculatorTool);\n\n        // Deploy the MCP verticle (pass transport and server specification)\n        vertx.deployVerticle(new McpVerticle(8080, transport, mcpServerSpec), ar -\u003e {\n            if (ar.succeeded()) {\n                System.out.println(\"MCP Server started on port 8080\");\n                System.out.println(\"Streamable HTTP endpoint: http://localhost:8080/mcp\");\n                System.out.println(\"Supports: GET (SSE), POST (messages), DELETE (sessions)\");\n            } else {\n                System.err.println(\"Failed to start MCP Server: \" + ar.cause());\n            }\n        });\n    }\n}\n```\n\n\n\n## Configuration Options\n\n### Legacy HTTP+SSE Transport\n\nThe `VertxMcpSseServerTransportProvider` supports several configuration options:\n\n- **`baseUrl`**: Base URL for your server (required)\n- **`messageEndpoint`**: Endpoint for receiving JSON-RPC messages (default: `/message`)\n- **`sseEndpoint`**: Endpoint for SSE connections (default: `/sse`)\n- **`keepAliveInterval`**: Interval for keep-alive ping messages (default: 30 seconds)\n- **`objectMapper`**: Jackson ObjectMapper for JSON serialization\n- **`vertx`**: Vert.x instance\n\n### Streamable HTTP Transport\n\nThe `VertxMcpStreamableServerTransportProvider` supports:\n\n- **`objectMapper`**: Jackson ObjectMapper for JSON processing (required)\n- **`mcpEndpoint`**: The MCP endpoint path (default: `/mcp`)\n- **`disallowDelete`**: Whether to disable session deletion (default: `false`)\n- **`vertx`**: Vert.x instance (required)\n- **`keepAliveInterval`**: Interval for keep-alive ping messages (default: 30 seconds)\n\n## Architecture\n\n### Legacy HTTP+SSE Transport\n\nThe transport implements the MCP protocol using:\n\n1. **SSE Connection** (`/sse`): Establishes Server-Sent Events connection for server-to-client communication\n2. **Message Endpoint** (`/message`): Receives JSON-RPC messages from clients\n3. **Session Management**: Automatically manages client sessions and cleanup\n4. **Keep-alive**: Sends periodic ping messages to prevent connection timeouts\n\n### Streamable HTTP Transport\n\nThe new Streamable HTTP transport follows the MCP 2025-06-18 specification:\n\n1. **Single Endpoint** (`/mcp`): Handles all HTTP methods (GET, POST, DELETE)\n2. **Session Management**: Uses MCP SDK session management with unique session IDs\n3. **Stream Resumption**: Supports resuming broken connections via Last-Event-ID headers\n4. **Protocol Compliance**: Full compliance with the latest MCP specification\n\n## Testing\n\nYou can test your MCP server using any MCP client:\n\n### Legacy Transport\n- **SSE endpoint**: `http://localhost:8080/mcp/sse` for establishing connections\n- **Message endpoint**: `http://localhost:8080/mcp/message?sessionId=\u003cid\u003e` for sending requests\n\n### Streamable Transport\n- **Single endpoint**: `http://localhost:8080/mcp` for all operations\n- **GET**: Establish SSE listening streams\n- **POST**: Send JSON-RPC messages\n- **DELETE**: Terminate sessions\n\n## Graceful Shutdown\n\nThe transport supports graceful shutdown:\n\n```java\n// Close the transport gracefully\ntransport.closeGracefully()\n    .doOnSuccess(v -\u003e System.out.println(\"Transport closed successfully\"))\n    .doOnError(e -\u003e System.err.println(\"Error closing transport: \" + e))\n    .subscribe();\n```\n\n## Roadmap\n\nThe following features are planned for future releases:\n\n### Vert.x 5 Support\nSupport for Vert.x 5.x versions, including:\n- Compatibility with Vert.x 5.x APIs\n- Updated transport implementations for Vert.x 5\n- Performance improvements leveraging new Vert.x 5 features\n\n### Authorization Support\nImplementation of [MCP Authorization](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization) capabilities including:\n- OAuth 2.1 compliant authorization flow\n- Dynamic client registration\n- Access token validation and audience binding\n- Resource parameter support for secure token issuance\n\n## Contributing\n\nContributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests.\n\n## License\n\nThis project is licensed under the Apache License, Version 2.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkinotic-ai%2Fvertx-mcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkinotic-ai%2Fvertx-mcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkinotic-ai%2Fvertx-mcp/lists"}