Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/XxYouDeaDPunKxX/chatgpt-local-agent-mcp/llms.txt

Use this file to discover all available pages before exploring further.

Cloudflare Tunnel is the recommended way to make the local MCP server reachable over the internet. Instead of opening a raw port on your router or relying on a dynamic DNS service, Cloudflare Tunnel creates an outbound-only encrypted connection from your machine to Cloudflare’s edge network. TLS termination happens at the Cloudflare edge, so your local server only needs to listen on plain HTTP at 127.0.0.1:8789. No inbound firewall rules, no raw port forwarding, and no self-signed certificates are required.
The recommended setup is a Cloudflare Tunnel, not a Cloudflare Worker. You do not need to write or deploy a Worker for the normal MCP server configuration.

What you need

  • A Cloudflare account
  • A domain with DNS managed by Cloudflare
  • cloudflared installed locally (the tunnel connector daemon)
  • The local MCP server already passing Path A smoke checks

Steps

1

Create a Cloudflare Tunnel

Create a named tunnel either through the Cloudflare Zero Trust dashboard or via the cloudflared CLI.Using the dashboard:Navigate to Zero Trust → Networks → Tunnels, click Create a tunnel, choose Cloudflared, and follow the prompts. Give the tunnel a name — for example, chatgpt-local-agent-mcp — and save the tunnel token or configuration credentials file that Cloudflare provides.Using the CLI:
cloudflared tunnel create chatgpt-local-agent-mcp
This creates a tunnel and writes credentials to %USERPROFILE%\.cloudflared\<tunnel-id>.json.
2

Create a DNS record pointing to the tunnel

In Cloudflare DNS, create a CNAME record for your MCP hostname that points to the tunnel. The target should be your tunnel’s UUID address in the format:
<tunnel-id>.cfargotunnel.com
Using the CLI:
cloudflared tunnel route dns chatgpt-local-agent-mcp mcp.your-domain.example
This creates the proxied CNAME record automatically. The record must be orange-clouded (proxied through Cloudflare) for the tunnel to work.
3

Configure the cloudflared ingress routes

Create or edit the cloudflared configuration file at %USERPROFILE%\.cloudflared\config.yml. The tunnel must route the MCP hostname to the local server’s bind address.A minimal configuration looks like this:
tunnel: chatgpt-local-agent-mcp
credentials-file: C:\Users\you\.cloudflared\<tunnel-id>.json

ingress:
  - hostname: mcp.your-domain.example
    service: http://127.0.0.1:8789
  - service: http_status:404
The final service: http_status:404 catch-all is required by cloudflared — any request that does not match a hostname rule returns a 404 instead of an error.
The tunnel route must forward to http://127.0.0.1:8789 (plain HTTP). Cloudflare handles TLS termination at the edge and sends decrypted traffic to the local connector. Do not point the ingress route at an HTTPS local address unless you have specifically configured the local server to use TLS.
4

Set the matching .env values

Update the MCP server .env to match the public hostname you configured:
PUBLIC_BASE_URL=https://mcp.your-domain.example
CLOUDFLARE_TUNNEL_ENABLED=true
CLOUDFLARED_CONFIG=C:\Users\you\.cloudflared\config.yml
CLOUDFLARE_TUNNEL_NAME=chatgpt-local-agent-mcp
  • PUBLIC_BASE_URL must match the public HTTPS URL exactly. The server uses this to construct OAuth redirect URLs and the MCP resource URI.
  • CLOUDFLARE_TUNNEL_ENABLED=true enables the tunnel status panel in the local dashboard and gates the AUTH_REQUIRED=false guard (the server will refuse to start with auth disabled when the tunnel is enabled).
  • CLOUDFLARED_CONFIG should be the absolute path to the config.yml file you created in the previous step.
When CLOUDFLARE_TUNNEL_ENABLED=true, the server automatically uses the CF-Connecting-IP header that Cloudflare injects to key rate limiting on the real client IP rather than the tunnel connector address. No additional setting is needed for this.TRUST_PROXY_HEADERS is a separate option. When set to true, the server uses X-Forwarded-For for rate-limit keying — this applies when traffic passes through a different proxy that sets that header, not through Cloudflare Tunnel. For a standard Cloudflare Tunnel setup, leave it at the default:
TRUST_PROXY_HEADERS=false
5

Start cloudflared and verify active replicas

Start the tunnel connector:
cloudflared tunnel run chatgpt-local-agent-mcp
Or, if you are using the config file:
cloudflared tunnel --config C:\Users\you\.cloudflared\config.yml run
After a few seconds, check the Cloudflare Zero Trust dashboard under Networks → Tunnels. The tunnel should show a green Healthy status with at least one active connector replica. A tunnel that shows Inactive or Down with zero replicas means cloudflared is not connected, even if the DNS record and ingress configuration are correct.
6

Test the public health endpoint

With both the local MCP server and cloudflared running, test that the public endpoint is reachable:
https://mcp.your-domain.example/healthz
This should return a successful health response. If it does, Cloudflare Tunnel is routing correctly and the local server is reachable from the public internet. You are ready to proceed with the full OAuth and ChatGPT connector setup in Path B.

Troubleshooting

A 530 error means Cloudflare resolved the DNS record to a tunnel, but the tunnel connector is not currently connected. The tunnel route configuration is likely correct.Check all of the following:
  • The MCP server is listening on http://127.0.0.1:8789
  • cloudflared is running (check Task Manager or your terminal)
  • The Cloudflare Zero Trust dashboard shows at least one active replica for the tunnel
  • The tunnel ingress route points to http://127.0.0.1:8789 (not an HTTPS address)
Starting cloudflared again should resolve a 530 caused by the connector being stopped.
This usually means the credentials file path in config.yml is wrong or the tunnel ID in config.yml does not match the credentials file. Verify that:
  • The tunnel: field in config.yml matches the tunnel name or UUID you created
  • The credentials-file: path points to the correct JSON file at %USERPROFILE%\.cloudflared\<tunnel-id>.json
  • The credentials file is readable by the Windows user running cloudflared
If cloudflared starts cleanly but requests to mcp.your-domain.example return 404, verify that the hostname: in the ingress block matches the CNAME record exactly — including any subdomain. The ingress catch-all (service: http_status:404) is required and must be the last entry in the ingress list.

Build docs developers (and LLMs) love