Codex MCP Expected Value Error? Disable Brotli Temporarily

Codex MCP Expected Value Error? Disable Brotli Temporarily

Aident AI

A compressed coral and violet ribbon passes through a cyan gateway and emerges as orderly geometric data tiles.

Codex MCP Expected Value Error? Disable Brotli Temporarily

If a remote MCP server initializes in Codex but fails on a larger response with Deserialize error: expected value at line 1 column 2, inspect the response headers. When the failing response has Content-Encoding: br, Codex may be handing Brotli-compressed bytes to its JSON parser.

The safest temporary fix is to make the Codex MCP client request an uncompressed response:

[mcp_servers.example.http_headers]
Accept-Encoding = "identity"

Replace example with the existing server name in your Codex configuration. If that server already has an http_headers table, add the header there instead of creating a second table. Restart Codex and retest. Remove the override after upgrading to a version that handles the response encoding correctly.

This workaround applies only when the response is actually Brotli-encoded. It will not fix OAuth, HTTP status, malformed SSE, or invalid JSON errors.

Confirm the Error Is a Compression Mismatch

The same word deserialize can describe several different MCP failures. Check the evidence before changing configuration.

Evidence

Likely boundary

Next check

initialize succeeds, tools/list fails, and the failing response has Content-Encoding: br

Compressed bytes reached the JSON parser

Request Accept-Encoding: identity

Response has no Content-Encoding and starts with event: or data:

SSE framing or content-type mismatch

Inspect Content-Type and the raw event stream

Response is 401 or 403

Authentication or authorization

Repair credentials or OAuth

Response is HTML

Proxy, login page, WAF, or upstream error

Inspect the HTTP status and first response bytes

Uncompressed body still fails JSON parsing

Invalid JSON or JSON-RPC shape

Validate the decoded body independently

In the reported Codex reproduction, a small initialize response succeeds. A larger tools/list response passes through a Kubernetes ingress, arrives with Content-Type: application/json and Content-Encoding: br, and fails immediately. The same bytes become valid JSON after Brotli decompression. Asking the endpoint for identity returns uncompressed JSON that Codex can parse.

That sequence is much stronger evidence than the error text alone.

Add the Client-Side Header

Find the existing remote MCP entry in the Codex configuration. Keep its URL and authentication settings unchanged, then add the header under that server:

[mcp_servers.example]
url = "https://mcp.example.com/mcp"

[mcp_servers.example.http_headers]
Accept-Encoding = "identity"

Do not copy a real authorization token into the file while testing. Preserve the credential mechanism that the server already uses.

Restart Codex so the MCP client rebuilds its connection. The expected result is:

  1. The server completes initialize.

  2. Codex reaches tools/list without the line 1 column 2 error.

  3. The response has no Content-Encoding: br header.

  4. The decoded body is valid JSON or a valid MCP event stream for its declared content type.

If the error stays exactly the same, confirm that the header reached the ingress. A proxy can strip or replace request headers. Check a sanitized request capture or ingress log rather than repeatedly editing the client.

Disable Compression on the MCP Route

If you own the server or reverse proxy, route-specific configuration is a better shared workaround. Disable dynamic Brotli compression for the MCP endpoint while leaving compression enabled for ordinary web assets.

For an Nginx deployment with the Brotli module, the relevant shape is:

location = /mcp {
    brotli off;
    gzip off;
    proxy_pass http://mcp_upstream;
}

Apply the equivalent route rule in your ingress or CDN. Verify the deployed behavior rather than assuming the setting took effect:

curl -sS -D - -o /dev/null \
  -H 'Accept-Encoding: br' \
  https://mcp.example.com/mcp

curl -sS -D - -o /dev/null \
  -H 'Accept-Encoding: identity' \
  https://mcp.example.com/mcp

An MCP endpoint commonly rejects these unauthenticated GET requests with 401, 404, or 405. That is acceptable for this narrow header check. For a conclusive test, repeat the comparison against a staging endpoint with a valid, redacted MCP POST request.

Do not remove Content-Encoding from an already compressed response without decompressing its body. That produces mislabeled bytes and moves the failure to another client.

Why the Failure Looks Like Invalid JSON

HTTP content negotiation and JSON parsing are separate layers.

The Accept-Encoding request header tells the server which response codings the client can decode. The server describes the coding it selected with Content-Encoding. RFC 9110 allows broad server behavior when Accept-Encoding is absent, so a reverse proxy can select a compressed representation even when the application did not add compression itself.

Reqwest, the Rust HTTP client used in this path, makes Brotli decoding an optional feature. When that feature is enabled, Reqwest can recognize Content-Encoding: br and decompress the body before a caller parses it. Without that support, the first bytes seen by a JSON parser are compressed binary data, not an opening brace. The parser reports an early syntax error even though the decompressed representation is valid JSON.

That is why editing the JSON payload, shortening tool descriptions, or reinstalling the MCP server can appear to help without fixing the boundary. A smaller response may fall below a proxy compression threshold, hiding the problem until tools/list grows again.

Avoid These False Fixes

Do not treat every deserialize error as Brotli

Check Content-Encoding first. SSE envelopes, HTML error pages, non-2xx responses, and malformed JSON need different repairs.

Do not enable decompression only in one parser branch

An MCP client can receive JSON and SSE responses. The HTTP layer should decode the representation before either parser consumes it.

Do not globally disable compression without a reason

Static assets and normal web responses still benefit from compression. Scope the server workaround to the MCP route or the affected client.

Do not expose the endpoint to bypass the ingress

Pointing Codex directly at an unprotected origin can bypass authentication, TLS termination, rate limits, and network policy. Preserve the security boundary while changing only response encoding.

Do not leave the workaround undocumented

Record the affected Codex version, server route, ingress behavior, and removal condition. Temporary transport overrides have a habit of becoming permanent folklore.

Use Aident Loadout When You Need the Capability, Not the Custom Transport

If your goal is to let Codex use a supported external service rather than debug a custom MCP server, Aident Loadout can provide a separate capability boundary. It does not repair your remote MCP endpoint, but it can remove that endpoint from the critical path when the needed integration is already available.

Install or update it with this exact instruction:

Follow https://aident.ai/SETUP.md

Then inspect a read-only Action before execution:

aident account auth status
aident vault vault --action status

aident capabilities search \
  --queries '["find one read-only Action for the service I need"]' \
  --types '["action"]' \
  --targetEnv staging

aident capabilities get \
  --name "<Action name returned by search>" \
  --parts '["inputSchema","examples"]'

aident capabilities preflight \
  --name "<same Action name>" \
  --input '{"replace":"with reviewed values from the schema"}'

The expected result is a current Action, a reviewable input contract, and a price preflight without placing a provider credential in the repository. If no suitable Action exists, keep the custom MCP server and fix its transport boundary directly.

When to Remove the Workaround

After a Codex update:

  1. Record the new codex --version output.

  2. Remove the Accept-Encoding: identity override in a staging configuration.

  3. Reconnect to the same MCP endpoint through the same ingress.

  4. Confirm that a Brotli response is decoded or that Codex deliberately requests identity.

  5. Restore the override if the exact failure returns.

Success means the response coding is handled before JSON or SSE parsing, tools/list completes, and unsupported encodings produce a clear transport error instead of a misleading JSON error.

For broader connection failures, use How to Fix Claude Code MCP Failed to Connect Errors. For architecture choices, compare Local vs Remote MCP Servers.

Use Aident Loadout to discover and preflight a supported integration without putting a custom remote MCP transport in the critical path.

Sources

Home

Home

Home

Integrations

Integrations

Integrations

Vault

Vault

Vault

Audit

Audit

Audit

Arana Grande

Arana Grande

Arana Grande

Free

Free

Free

30-day audit summary

30-day audit summary

30-day audit summary

Daily action-call volume and the latest receipts from the Loadout audit trail.

Daily action-call volume and the latest receipts from the Loadout audit trail.

Daily action-call volume and the latest receipts from the Loadout audit trail.

View Audit

View Audit

View Audit

Loadout usage

Loadout usage

Loadout usage

617 action calls in the last 30 days

617 action calls in the last 30 days

617 action calls in the last 30 days

May 19 - Jun 17

May 19 - Jun 17

May 19 - Jun 17

10 active days

10 active days

10 active days

Less

Less

Less

More

More

More

Recent activity

Recent activity

Recent activity

Latest action-call receipts from connected agents

Latest action-call receipts from connected agents

Latest action-call receipts from connected agents

Apr 23, 09:23 AM

Apr 23, 09:23 AM

Apr 23, 09:23 AM

Shopify

Shopify

Shopify

Creates Or Updates An Asset For A Theme

Creates Or Updates An Asset For A Theme

Creates Or Updates An Asset For A Theme

Success

Success

Success

Apr 23, 09:21 AM

Apr 23, 09:21 AM

Apr 23, 09:21 AM

Shopify

Shopify

Shopify

Update Products Param Product Id

Update Products Param Product Id

Update Products Param Product Id

Success

Success

Success

Apr 23, 08:53 AM

Apr 23, 08:53 AM

Apr 23, 08:53 AM

Shopify

Shopify

Shopify

Update Products Param Product Id

Update Products Param Product Id

Update Products Param Product Id

Failed

Failed

Failed

Apr 22, 22:13 PM

Apr 22, 22:13 PM

Apr 22, 22:13 PM

Shopify

Shopify

Shopify

Create Product Image

Create Product Image

Create Product Image

Success

Success

Success

Apr 22, 22:12 PM

Apr 22, 22:12 PM

Apr 22, 22:12 PM

Shopify

Shopify

Shopify

Create Product Image

Create Product Image

Create Product Image

Success

Success

Success

Connected integration coverage

Connected integration coverage

Connected integration coverage

162

162

162

of 753 accessible connected

of 753 accessible connected

of 753 accessible connected

Callable actions

Callable actions

Callable actions

1,126

1,126

1,126

Vault credentials

Vault credentials

Vault credentials

8

8

8

Explore what's possible

Explore what's possible

Explore what's possible

See all Integrations

See all Integrations

See all Integrations

Google Ads

Google Ads

Google Ads

All available Goolge Ads tools via...

All available Goolge Ads tools via...

All available Goolge Ads tools via...

X (twitter)

X (twitter)

X (twitter)

All available X tools via...

All available X tools via...

All available X tools via...

Github

Github

Github

All available Github tools via...

All available Github tools via...

All available Github tools via...

Notion

Notion

Notion

All available Notion tools via...

All available Notion tools via...

All available Notion tools via...

Slack

Slack

Slack

All available Slack tools via...

All available Slack tools via...

All available Slack tools via...

Firecrawl

Firecrawl

Firecrawl

All available Firecrawl tools via...

All available Firecrawl tools via...

All available Firecrawl tools via...

753 integrations are available for loadouts.

753 integrations are available for loadouts.

753 integrations are available for loadouts.

The one tool

for every tool

your agent needs.

Give any AI agent real capabilities in seconds. Connect 1,000+ tools once, skip the setup headache, and let your agents execute.