loading…
Search for a command to run...
loading…
Turn your Spring Boot application into an MCP server instantly by reusing existing Swagger/OpenAPI documentation.
Turn your Spring Boot application into an MCP server instantly by reusing existing Swagger/OpenAPI documentation.
CI License Java Spring Boot Awesome MCP Servers
Turn any SpringDoc-powered Spring Boot API into a production-ready MCP gateway.
Swagger MCP Bridge discovers your OpenAPI operations, publishes them as safe MCP tools, and adds a smart gateway layer for API discovery, validation, response shaping, and multi-step workflow orchestration.
This repository intentionally separates the public surfaces so each one reads naturally in its own ecosystem:
| Surface | Name |
|---|---|
| Project / docs | Swagger MCP Bridge |
| Maven dependency | io.github.neo1228:openapi-mcp-spring-boot-starter |
| Official MCP Registry server | io.github.Neo1228/swagger-mcp-bridge |
| Runnable example image | ghcr.io/neo1228/swagger-mcp-bridge-example:<version> |
| Spring configuration prefix | swagger.mcp.* |
The project name keeps the established bridge branding, while the Maven artifact uses the neutral OpenAPI/Spring Boot starter coordinate expected by Java consumers. The registry server and GHCR image identify the packaged runnable example used by MCP directories.
Most MCP API bridges stop at a thin tool wrapper. Swagger MCP Bridge is designed as a runtime gateway: it exposes your existing Spring controllers to LLM clients while preserving contracts, guardrails, and operational visibility.
meta_get_api_capabilities, meta_validate_api_call, meta_discover_api_tools, meta_describe_api_tool, meta_list_api_groups, meta_plan_api_workflow, meta_invoke_api_workflow, meta_invoke_api_by_intent_headers filteringINVALID_ARGUMENT, SECURITY_DENIED, WORKFLOW_ERROR, and HTTP_DISPATCH_FAILED_confirm, blocked paths, role checks, audit logs, and structured client errorsgraph TD
User([User / LLM Client]) <--> MCP[MCP Client / Claude Desktop]
MCP <--> Bridge[Swagger MCP Bridge /starter/]
Bridge --> Catalog[Operation Catalog /groups + contracts/]
Bridge --> Workflow[Workflow Orchestrator /plan + dry-run + execute/]
Bridge <--> Docs[SpringDoc OpenAPI /v3/api-docs]
Bridge <--> API[Your Spring Controller /hello]
Use:
Gradle (build.gradle.kts):
plugins {
id("org.springframework.boot") version "3.5.14"
id("io.spring.dependency-management") version "1.1.7"
java
}
java {
sourceCompatibility = JavaVersion.VERSION_17
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springdoc:springdoc-openapi-starter-webmvc-api:2.8.17")
implementation("io.github.neo1228:openapi-mcp-spring-boot-starter:<version>")
}
The Maven artifact intentionally uses the neutral OpenAPI name rather than Swagger branding:
io.github.neo1228:openapi-mcp-spring-boot-starter
Maven (pom.xml):
<properties>
<openapi-mcp.version>0.1.0-SNAPSHOT</openapi-mcp.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
<version>2.8.17</version>
</dependency>
<dependency>
<groupId>io.github.neo1228</groupId>
<artifactId>openapi-mcp-spring-boot-starter</artifactId>
<version>${openapi-mcp.version}</version>
</dependency>
</dependencies>
Use a release version (for example 0.1.0) when consuming from a remote artifact repository.
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class HelloController {
@Operation(operationId = "getHello", summary = "Get greeting message")
@GetMapping("/hello")
public Map<String, Object> hello(@RequestParam(defaultValue = "world") String name) {
return Map.of("message", "Hello " + name);
}
}
application.yml)spring:
ai:
mcp:
server:
protocol: STREAMABLE_HTTP
streamable-http:
mcp-endpoint: /mcp
swagger:
mcp:
enabled: true
api-docs-path: /v3/api-docs
tool-name-prefix: api_
./gradlew bootRun or ./mvnw spring-boot:runhttp://localhost:8080/v3/api-docshttp://localhost:8080/mcpGenerated tool names follow <tool-name-prefix><operation-id> (example: api_gethello).
This starter exposes direct API tools and a meta-tool layer so general MCP clients can work with large APIs without guessing tool names upfront:
meta_get_api_capabilities returns API catalog stats, available gateway tools, orchestration features, safety policy, and response controls.meta_list_api_groups summarizes the exposed API catalog by OpenAPI tag/group.meta_discover_api_tools finds relevant operations for a natural-language request.meta_describe_api_tool returns the selected tool's method/path, parameters, required arguments, request body schema, risk flags, and full MCP input schema.meta_validate_api_call validates one generated API tool call without dispatching HTTP, including required arguments, risky-operation confirmation, and dispatch preview.meta_plan_api_workflow turns a workflow goal into a deterministic candidate step plan with contracts and risk flags.meta_invoke_api_workflow dry-runs or executes multiple generated API tools sequentially.meta_invoke_api_by_intent can select and invoke the best matching operation when the client already has enough arguments.The configured tool-name-prefix is still applied, so the default generated names are api_meta_get_api_capabilities, api_meta_validate_api_call, api_meta_list_api_groups, api_meta_discover_api_tools, api_meta_describe_api_tool, api_meta_plan_api_workflow, api_meta_invoke_api_workflow, and api_meta_invoke_api_by_intent.
When a tool call is rejected, the text content remains human-readable and structuredContent.error gives clients a stable machine contract:
{
"error": {
"code": "INVALID_ARGUMENT",
"message": "Missing required argument(s): path parameter: orderId",
"status": 400,
"retryable": false,
"details": { "toolName": "api_getorder" }
}
}
Recommended client loop:
api_meta_get_api_capabilities once to learn the gateway features and safety policy.api_meta_discover_api_tools or api_meta_list_api_groups to find candidate operations.api_meta_describe_api_tool for exact argument schema.api_meta_validate_api_call before risky or generated calls.api_meta_plan_api_workflow, then api_meta_invoke_api_workflow with dryRun=true, then execute with dryRun=false only after validation is clean.Workflow execution is intentionally safe by default:
meta_validate_api_call and meta_invoke_api_workflow dry-runs validate tool names, arguments, required fields, dispatch paths, and risk flags before dispatching HTTP.{ "id": "...", "toolName": "...", "arguments": { ... } }.${create:$.order.id}._confirm token even inside a workflow.Example validation payload:
{
"toolName": "api_getorder",
"arguments": {
"orderId": "order-1"
}
}
Example workflow payload:
{
"dryRun": false,
"steps": [
{
"id": "create",
"toolName": "api_createorder",
"arguments": {
"body": { "id": "order-1", "item": "shoe" },
"_confirm": "CONFIRM"
}
},
{
"id": "read",
"toolName": "api_getorder",
"arguments": {
"orderId": "${create:$.order.id}"
}
}
]
}
For larger APIs, set swagger.mcp.smart-context.gateway-only=true to expose only this gateway/meta layer instead of registering every operation as a top-level MCP tool.
If the artifact is not published to a remote registry yet:
./gradlew publishToMavenLocalmavenLocal() repository0.1.0-SNAPSHOT (or your chosen local version)swagger.mcp.enabled: enable/disable bridge (default true)swagger.mcp.api-docs-path: OpenAPI docs path (default /v3/api-docs)swagger.mcp.tool-name-prefix: tool name prefix (default api_)swagger.mcp.smart-context.gateway-only: expose only meta toolsswagger.mcp.execution.virtual-threads-enabled: run outbound API dispatch through virtual threads when the current runtime supports them (default true; safely falls back on Java 17)swagger.mcp.execution.allowed-argument-headers: optional allowlist for dynamic _headers passed by MCP clientsswagger.mcp.execution.blocked-argument-headers: denylist for dynamic _headers; defaults block hop-by-hop/transport-sensitive headers like Host, Content-Length, Connection, and Transfer-Encodingswagger.mcp.security.require-confirmation-for-risky-operations: require _confirm token for risky methodsFor risky HTTP methods (POST, PUT, PATCH, DELETE), default policy requires _confirm=CONFIRM. The adapter also validates missing required path/query/header/body arguments before dispatching HTTP, so MCP clients get a clear tool error instead of a malformed API call.
| Starter | Java | Spring Boot | springdoc-openapi | Spring AI BOM |
|---|---|---|---|---|
| 0.1.x | 17, 21, 25 tested; Java 17 bytecode | 3.5.x | 2.8.17 | 1.1.5 |
Spring Boot 4.x is intentionally not supported in the 0.1.x line. Stay on Spring Boot 3.5.x with springdoc-openapi 2.8.x unless this repository cuts a new major/minor compatibility line. The build uses --release 17, so the artifact remains consumable on Java 17 while CI verifies newer runtimes including Java 25.
See examples/minimal-webmvc-gradle for a minimal Spring Boot app using Swagger MCP Bridge.
The example can also be built as a runnable MCP server image for registry and marketplace submissions:
docker build \
-f examples/minimal-webmvc-gradle/Dockerfile \
-t ghcr.io/neo1228/swagger-mcp-bridge-example:local \
.
docker run --rm -p 8080:8080 ghcr.io/neo1228/swagger-mcp-bridge-example:local
Manual smoke checks after startup:
http://localhost:8080/v3/api-docshttp://localhost:8080/hello?name=Bridgehttp://localhost:8080/mcphttp://localhost:8080/.well-known/mcp/server-card.jsonhttp://localhost:8080/.well-known/mcp/server.jsonllms-install.mddocs/marketplace-readiness.mddocs/assets/swagger-mcp-bridge-logo.png.github/workflows/release-central.yml.github/workflows/publish-example-server.ymlregistry/server.jsonexamples/minimal-webmvc-gradle/src/main/resources/static/.well-known/mcp/scripts/verify-marketplace-metadata.shscripts/build-central-bundle.shThe official MCP Registry accepts Docker/OCI metadata, so the published example image carries the required io.modelcontextprotocol.server.name=io.github.Neo1228/swagger-mcp-bridge label and uses registry/server.json as the submission source. The starter artifact remains a normal Maven dependency with coordinates io.github.neo1228:openapi-mcp-spring-boot-starter. Smithery URL publishing is compatible once the example server is hosted at a public HTTPS /mcp endpoint; until then the repository provides the required static server-card and local/Uplink validation path.
RELEASING.mdVERSIONING.mdCHANGELOG.md./gradlew testCONTRIBUTING.mdSECURITY.mdApache License 2.0 (LICENSE)
Выполни в терминале:
claude mcp add neo1228-spring-boot-starter-swagger-mcp -- npx Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории development