Show HN: Enframe – Drop-in sidecar that wraps any OpenAPI spec to an MCP server Developer Erwin Kramer released Enframe, a drop-in sidecar container that wraps any OpenAPI spec into a Model Context Protocol (MCP) server with almost no configuration, inferring API key, OAuth 2.0 and OpenID Connect authentication from the spec. Enframe accepts Swagger 2.0 and OpenAPI 3.0 through 3.2 specs, emits tool schemas as JSON Schema 2020-12, and runs on the official C# SDK 2.x implementing MCP spec revision 2026-07-28 while negotiating down to 2025-11-25 and earlier. The project ships as the container image ghcr.io/erwinkramer/enframe, is configured through environment variables such as Enframe__ApiSpecSource and Enframe__ApiBaseUrl, and has been confirmed with clients including Pi, OpenCode v2 CLI, MCP Inspector and VS Code local mode using pre-registration authorization via Entra ID. If you have a well-specified API with OpenAPI, Enframe rewards you : it takes almost no configuration to get an MCP server running, and even mixed authentication API key, OAuth 2.0, OpenID Connect is inferred. Let's wrap DummyJSON https://dummyjson.com/ into an MCP server and start it: podman run -d --name enframe -p 8080:8080 \ -e Enframe ApiSpecSource=https://dummyjson.com/openapi.json \ ghcr.io/erwinkramer/enframe:latest Confirm it's up and healthy by going to the health endpoint: http://127.0.0.1:8080/mcp/healthz http://127.0.0.1:8080/mcp/healthz . Now integrate the live server with your favorite harness, for Pi the mcp.json can be as minimal as: {"mcpServers":{"dummy":{"url":"http://127.0.0.1:8080/mcp"}}} Finally, think of some creative way to reach it in a session, such as...: get all smartphones from dummy mcp - OpenAPI: accepts Swagger 2.0 and OpenAPI 3.0- 3.2 https://spec.openapis.org/oas/v3.2.0.html specs, emits tool schemas as JSON Schema 2020-12 https://json-schema.org/draft/2020-12 ; the dialect OpenAPI 3.1+ and MCP share. - MCP: official C SDK https://github.com/modelcontextprotocol/csharp-sdk 2.x — implements spec revision 2026-07-28 https://modelcontextprotocol.io/specification/latest , negotiates down to 2025-11-25 and earlier. - Clients: any client conforming to the MCP spec, confirmed with following clients using pre-registration authz https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization/client-registration pre-registration inferred from OpenAPI spec via Entra ID https://learn.microsoft.com/en-us/entra/agent-id/secure-mcp-server-with-entra-id :Client Config, notes Pi https://pi.dev .pi/mcp.json https://github.com/erwinkramer/enframe/blob/main/.pi/mcp.json OpenCode v2 CLI https://opencode.ai/v2/docs/cli opencode.jsonc https://github.com/erwinkramer/enframe/blob/main/opencode.jsonc MCP Inspector https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector mcp.json https://github.com/erwinkramer/enframe/blob/main/mcp.json Local mode in VS Code https://code.visualstudio.com/docs/agents/run/agent-harnesses local authorize VS Code in the app reg https://learn.microsoft.com/en-us/azure/app-service/configure-authentication-mcp-server-vscode authorize-visual-studio-code-in-the-app-registration | Environment variable | Required | Description | |---|---|---| | ASPNETCORE HTTP PORTS | no | HTTP port to listen on; default 8080 | | Enframe ApiBaseUrl | no | Base URL of the target API that generated tools call; defaults to the first URL in the spec's servers , with server variables substituted by their defaults a relative URL is resolved against the spec's location | | Enframe ApiKey | conditional | API key sent for operations the spec protects with an apiKey scheme; required if the spec declares one | | Enframe ApiSpecSource | yes | OpenAPI spec to wrap: an http s URL fetched at startup or a file path relative to the executable | | Enframe Authority | no | Authorization server URL; defaults to the spec's openIdConnectUrl .well-known/openid-configuration suffix stripped . Bearer-token auth for MCP clients is enabled when the spec declares an OAuth2 scheme and the authorization server is identifiable this variable or the spec's openIdConnectUrl | | Enframe McpPath | no | URL prefix the MCP endpoint is served under; default /mcp leading/trailing slashes are normalized | | Enframe Resource | no | RFC 8707 resource identifier announced to MCP clients; defaults to the API URI authority https://www.rfc-editor.org/info/rfc3986/ section-3.2 via Enframe ApiBaseUrl + the MCP path Enframe McpPath | The general OpenAPI mapping behavior is summarized as the MCP server instructions https://modelcontextprotocol.io/specification/2026-07-28/server/discover data-types , via ServerInstructions.md https://github.com/erwinkramer/enframe/blob/main/src/Enframe.Mcp/ServerInstructions.md . Details about the mapping: | OpenAPI concept | MCP concept | |---|---| | Operation | One tool, named by its operationId sanitized to MCP's allowed characters | | summary / description | Tool title / description | | parameters path, query, header | inputSchema properties | | requestBody first JSON content | Required inputSchema property body | | 2xx response | Tool outputSchema and structuredContent on success : wrapper object with status , declared response headers , and body first JSON content | | Non-2xx response | isError: true plus the raw response body as text; no structured content, since the outputSchema describes the success shape only | | $ref to components/schemas | Inlined into the tool's input/output schemas | | HTTP verb | Tool annotations: GET / QUERY → readOnly, PUT / DELETE → destructive, non- POST → idempotent | | tags | Tool meta.tags | | info.title / version / description / contact.url | MCP server info: name, version, description, website URL | | servers first URL, variables at defaults | Base URL of the target API default of Enframe ApiBaseUrl | | securitySchemes OAuth2 scopes | MCP scopes supported ; token audience derived from the scope's base | | securitySchemes.openIdConnectUrl | MCP authorization server .well-known/openid-configuration suffix stripped | | security per operation | Call-time auth mode: bearer token forwarded, apiKey scheme → APIM key header, or none | 1. Configure 127.0.0.1 localhost.guanchen.nl or similar in the host file, so you'd have an easier time making your authorization server happy. 2. Build Enframe from source and wrap a spec that supports auth you have control over, for instance: podman build -t enframe . podman rm -f enframe podman run -d --name enframe -p 8080:8080 \ -e Enframe ApiKey="Lifetime Subscription" \ -e Enframe ApiSpecSource=https://ca.guanchen.nl/v1/openapi/spec.json \ -e Enframe Resource=http://localhost.guanchen.nl:8080/mcp \ enframe Now, the MCP server will be live and listening at http://localhost.guanchen.nl:8080/mcp . With the MCP Inspector https://github.com/modelcontextprotocol/inspector CLI we can test the behavior. The first run performs the interactive OAuth flow browser + loopback callback ; later runs reuse the cached token: export MCP INSPECTOR SECRET STORE=file export MCP OAUTH CALLBACK URL=http://localhost:6276/oauth/callback npx @modelcontextprotocol/inspector --cli --config ./mcp.json --method initialize npx @modelcontextprotocol/inspector --cli --config ./mcp.json --method servers/show --server enframe npx @modelcontextprotocol/inspector --cli --config ./mcp.json --method tools/list --format json --strict npx @modelcontextprotocol/inspector --cli --config ./mcp.json --method tools/call --tool-name GetBankTeller This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License http://creativecommons.org/licenses/by-nc-sa/4.0/ .