MCP Streamable HTTP handshake fails with n8n MCP server after initialize
Summary
Codex CLI fails to start a Streamable HTTP MCP server backed by n8n's official instance-level MCP endpoint. The remote endpoint is reachable and returns the expected MCP server info/tools when queried directly, but Codex startup fails during the post-initialize notifications/initialized step with Transport channel closed.
This looks related to prior Streamable HTTP/RMCP handshake edge cases, but still reproduces with the current Codex CLI release in this n8n MCP combination.
Environment
- Codex CLI:
codex-cli 0.130.0 - oh-my-codex wrapper:
oh-my-codex v0.16.2 - Platform: macOS / darwin arm64
- Node.js:
v24.1.0 - Remote MCP server: n8n official instance-level MCP endpoint
- Remote MCP serverInfo from
initialize:name: "n8n MCP Server",version: "1.1.0" - Transport: Streamable HTTP
Codex MCP config shape
[mcp_servers.n8n_mcp]
url = "https://<n8n-host>/mcp-server/http"
http_headers = { "authorization" = "Bearer <redacted>" }
codex mcp get n8n_mcp reports:
n8n_mcp
enabled: true
transport: streamable_http
url: https://<n8n-host>/mcp-server/http
bearer_token_env_var: -
http_headers: authorization=*****
Failure during Codex/OMX startup
⚠ MCP client for `n8n_mcp` failed to start: MCP startup failed: handshaking with MCP server failed: Send message error Transport
[rmcp::transport::worker::WorkerTransport<rmcp::transport::streamable_http_client::StreamableHttpClientWorker<codex_rmcp_client::http_client_adapter::StreamableHttpClientAdapter>>]
error: Transport channel closed, when send initialized notification
⚠ MCP startup incomplete (failed: n8n_mcp)
What works outside Codex
Using the same URL/token, a direct JSON-RPC initialize request succeeds and returns SSE:
HTTP/2 200
content-type: text/event-stream
serverInfo: { name: "n8n MCP Server", version: "1.1.0" }
capabilities: { tools: { listChanged: true }, resources: { listChanged: true } }
A direct tools/list request to the same endpoint/token returns 25 tools, including write/build tools:
search_workflows
execute_workflow
get_execution
get_workflow_details
publish_workflow
unpublish_workflow
prepare_test_pin_data
test_workflow
search_data_tables
create_data_table
rename_data_table
add_data_table_column
delete_data_table_column
rename_data_table_column
add_data_table_rows
search_nodes
get_node_types
get_suggested_nodes
validate_workflow
create_workflow_from_code
search_projects
search_folders
archive_workflow
update_workflow
get_sdk_reference
A basic direct notifications/initialized POST also receives HTTP/2 202 from the endpoint when sent manually with curl, but Codex/RMCP still fails at this startup phase. That suggests the issue may depend on the exact request shape/session/header handling used by the Streamable HTTP client during handshake.
Additional observation
Testing mcp-remote as a stdio proxy against the same endpoint also fails during the initialized notification stage:
Connection error: StreamableHTTPError: Streamable HTTP error: Error POSTing to endpoint:
...
code: 400
So this may be a broader client/server interoperability edge case around Streamable HTTP initialization rather than a simple auth or endpoint configuration problem.
Expected behavior
Codex should successfully complete MCP startup and expose the n8n MCP tools, including create_workflow_from_code, update_workflow, validate_workflow, and publish_workflow.
Actual behavior
Codex fails MCP startup after initialize, when sending the initialized notification, and the server is not registered for use inside Codex.
Notes
- The token and actual host are intentionally redacted.
- The same endpoint/token can be used directly to initialize and list tools, so auth and server availability appear valid.
- Related-looking prior issue: #5208 / PR #5542, but this reproduces on
codex-cli 0.130.0with n8n MCP Server1.1.0.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗