cd /news/ai-agents/show-hn-enframe-drop-in-sidecar-that… · home › topics › ai-agents › article
[ARTICLE · art-159861] src=github.com ↗ pub= topic=ai-agents verified=true sentiment=↑ positive

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.

read4 min views1 publishedOct 28, 2026
Show HN: Enframe – Drop-in sidecar that wraps any OpenAPI spec to an MCP server
Image: Michielbdejong (auto-discovered)

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 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.

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 specs, emits tool schemas asJSON Schema 2020-12 ; the dialect OpenAPI 3.1+ and MCP share. #

MCP: officialC# SDK 2.x — implementsspec revision 2026-07-28 , negotiates down to2025-11-25 and earlier. #

Clients: any client conforming to the MCP spec, confirmed with following clients usingpre-registration authz (inferred from OpenAPI spec) viaEntra ID :Client Config, notes Pi.pi/mcp.jsonOpenCode v2 CLIopencode.jsoncMCP Inspectormcp.jsonLocal mode in VS Codeauthorize VS Code in the app reg

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'sopenIdConnectUrl )
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 (viaEnframe__ApiBaseUrl ) + the MCP path (Enframe__McpPath )

The general OpenAPI mapping behavior is summarized as the MCP server instructions, via 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 propertybody
2xx response Tool outputSchema (andstructuredContent on success): wrapper object withstatus , declared responseheaders , andbody (first JSON content)
Non-2xx response isError: true plus the raw response body as text; no structured content, since theoutputSchema describes the success shape only
$ref tocomponents/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 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.

── more in #ai-agents 4 stories · sorted by recency
── more on @enframe 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/show-hn-enframe-drop…] indexed:0 read:4min 2026-10-28 · —