different-ai/openwork · error
MCP_HTTP_CONTENT_TYPE
MCP_HTTP_CONTENT_TYPE
Error message
MCP_HTTP_CONTENT_TYPE
What it means
MCP_HTTP_CONTENT_TYPE is raised when an MCP-phase response has a Content-Type that is neither application/json nor text/event-stream (and it is not the exempt MCP_INITIALIZED 202/204 case). It signals MCP_TRANSPORT / unexpected_content_type: the server answered, but not with a standards-compliant MCP payload encoding, so the client cannot parse it. Non-retryable, owned by the provider admin.
Source
Thrown at ee/apps/den-api/src/capability-sources/external-mcp-diagnostics.ts:997
operatorAction: "Inspect provider and proxy logs for the failing HTTP request using the diagnostic reference.",
}
}
if (phase.startsWith("MCP_") && input.contentType === "text/html") {
return {
phase: "HTTP_ROUTING",
category: "unexpected_html",
code: "MCP_HTTP_HTML_RESPONSE",
retryable: false,
actionOwner: "organization_admin",
operatorAction: "Verify the MCP path is not a sign-in page, portal route, or proxy-generated HTML response.",
}
}
if (phase === "MCP_INITIALIZED" && (status === 202 || status === 204)) return null
if (phase.startsWith("MCP_") && input.contentType !== "application/json" && input.contentType !== "text/event-stream") {
return {
phase: "MCP_TRANSPORT",
category: "unexpected_content_type",
code: "MCP_HTTP_CONTENT_TYPE",
retryable: false,
actionOwner: "provider_admin",
operatorAction: "Return an MCP JSON or event-stream response with a standards-compliant Content-Type header.",
}
}
return null
}
function classifyByCode(code: string): Classification | null {
if (code === "MCP_OAUTH_AUTHORIZATION_ID_REQUIRED") {
return {
phase: "CONFIGURATION",
category: "oauth_authorization_transaction_invalid",
code,
retryable: false,
actionOwner: "openwork",
operatorAction: "Start OAuth through Den so the callback is bound to a signed, expiring authorization transaction.",
}View on GitHub (pinned to 2b7df46e8a)
Solutions
- Fix the provider to return application/json or text/event-stream with a standards-compliant Content-Type header for MCP responses.
- Check for middleware/proxies between the gateway and provider that rewrite or strip the Content-Type.
- Confirm the endpoint is actually the streamable-HTTP MCP server, not a legacy/custom handler with different response encoding.
Example fix
// before: plain-text error response
return new Response('oops', { status: 200 })
// after
return new Response(JSON.stringify({ jsonrpc: '2.0', error }), { status: 200, headers: { 'Content-Type': 'application/json' } }) Defensive patterns
Strategy: validation
Validate before calling
// assert standards-compliant content type before accepting the endpoint
const allowed = ['application/json', 'text/event-stream']
const ct = (res.headers.get('content-type') ?? '').split(';')[0].trim()
if (!allowed.includes(ct)) throw new Error(`non-MCP Content-Type: ${ct}`) Type guard
function isBadContentType(d: { code: string }): boolean {
return d.code === 'MCP_HTTP_CONTENT_TYPE'
} Try / catch
try {
return await parseMcpResponse(res)
} catch (e) {
if (isBadContentType(e.diagnostic)) {
// non-retryable: provider must fix its Content-Type header; capture it for the bug report
throw new Error(`provider returned Content-Type '${res.headers.get('content-type')}'`)
}
throw e
} Prevention
- Always set Content-Type: application/json (or text/event-stream for streams) on provider MCP responses.
- Audit proxies/middleware for header rewriting or body re-encoding.
- Add an integration test asserting response Content-Type on initialize, tools/list, and tools/call.
When it happens
Trigger: Any MCP request whose response Content-Type is, e.g., text/plain, application/octet-stream, or missing entirely — instead of application/json or text/event-stream — during discovery, execution, or other MCP phases.
Common situations: Provider returning plain-text error bodies with wrong headers; a non-JSON endpoint deployed at the MCP path; proxy middleware (compression, body rewrites) stripping or replacing the Content-Type header; provider server upgrade regressing streamable-HTTP content negotiation (e.g. always replying JSON where SSE was negotiated, or vice versa, with a bad header).
Related errors
- invalid_jsonrpc_envelope
- request_id_mismatch
- unsupported_transport
- MCP_PROVIDER_DECLARED_ERROR
- MCP_HTTP_404
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/a79aa0d9e9a6323c.
Report an issue: GitHub.