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

  1. Fix the provider to return application/json or text/event-stream with a standards-compliant Content-Type header for MCP responses.
  2. Check for middleware/proxies between the gateway and provider that rewrite or strip the Content-Type.
  3. 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

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


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/a79aa0d9e9a6323c. Report an issue: GitHub.