How to connect an MCP server on Tailscale to Claude and ChatGPT

Claude.ai, ChatGPT and Grok can't reach your tailnet. Publish your MCP server with Tailscale Funnel, protect it, and add it to every assistant with Upsy.

Updated

Short answer

This guide is for an MCP server you run on a machine in your tailnet (your Tailscale network), such as a home server. Claude.ai, ChatGPT, Grok and Muse connect from their companies' clouds, so they can't reach it. Publish it with Tailscale Funnel, which gives it a public https://<machine>.<tailnet>.ts.net address. Add that address to each assistant, or once to Upsy, which shares it with all of them at the limits you set. It takes about ten minutes. The server then needs its own key or sign-in.

Want an MCP server that manages Tailscale itself? That's different. Tailscale's AI gateway, Aperture, added Tailscale and Tailscale SSH MCP endpoints in August 2026, and community servers such as HexSleeves/tailscale-mcp use the Tailscale CLI and API.

Who can reach a server on your tailnet

  • Local agents, directly. Claude Code, Codex, Cursor or Hermes on a tailnet machine reach the server by its MagicDNS name or Tailscale IP. For an HTTPS address only your tailnet can open, use tailscale serve. No Funnel or Upsy needed.
  • Not cloud assistants. Claude's custom connectors connect from Anthropic's cloud. ChatGPT and Grok connect from theirs, and Muse runs on its own computer in the cloud. xAI says it plainly: "Your MCP server must be reachable over the public internet" (Grok connectors). Upsy runs in the cloud too.
  • The assistants' own tunnels. Claude's MCP tunnels are a research preview for Enterprise organizations. ChatGPT's Secure MCP Tunnel runs a tunnel-client in your network. Neither uses Tailscale.

Serve or Funnel

Tailscale Serve Tailscale Funnel
Who can open the address Devices on your tailnet Anyone on the internet
Use it for Local agents Claude, ChatGPT, Grok, Muse, Upsy

Funnel traffic passes through Tailscale relays that can't decrypt it. TLS ends on your machine, and its IP address stays hidden. Bandwidth is limited, and a port can be Serve or Funnel, not both (Funnel docs).

What you need

  • An MCP server that speaks Streamable HTTP on a port of that machine. Upsy speaks only Streamable HTTP; a stdio server needs a wrapper (below).
  • Tailscale 1.38.3 or later, on a platform that runs the Tailscale CLI. On a Mac, Funnel depends on which Tailscale app you installed; Tailscale's docs list them.
  • MagicDNS, HTTPS certificates and the funnel node attribute for your tailnet. Changing the policy file takes an Owner, Admin or Network admin.
  • A key or OAuth on the server, since the address will be public.

Step 1: publish the server with Funnel

  1. In the admin console's DNS page, turn on MagicDNS, then Enable HTTPS under HTTPS Certificates. Machine names get published in a public certificate ledger, so rename any that say too much (Tailscale's HTTPS guide).

  2. On the Access controls page, expand Funnel and select Add Funnel to policy. Or skip this: the first time you run Funnel, Tailscale opens a page to approve it and adds the attribute and certificates itself.

  3. On the server's machine, start Funnel with your server's port, here 8000:

    tailscale funnel --bg 8000
    

    --bg keeps it running after you close the terminal. Funnel forwards public HTTPS on port 443 to http://127.0.0.1:8000 and prints the address, such as https://homelab.tail1234.ts.net.

  4. Add the MCP path, often /mcp: https://homelab.tail1234.ts.net/mcp.

A new address can take up to 10 minutes to appear in public DNS. tailscale funnel status shows what's published (Funnel CLI).

If your server only speaks stdio

supergateway serves a stdio server over Streamable HTTP at /mcp. Since version 4.2, --apiKey makes every request carry a key and --host limits where it listens:

npx -y supergateway --stdio "uvx mcp-server-time" \
  --outputTransport streamableHttp --port 8000 --host 127.0.0.1 --apiKey "$MCP_API_KEY"

Swap in your server's command, then run Funnel on port 8000. Clients send the key as Authorization: Bearer <key>, as Upsy does.

Option A: add the Funnel address to each assistant

Each assistant then calls your server directly. What matters is the sign-in it accepts:

  • Claude: Customize › Connectors, then Add › Custom › Web (or Add custom connector on some accounts). Paste the address, click Continue twice, then Add and Connect. It uses OAuth or No sign-in; an API key under Request headers is a beta for a few organizations (Anthropic's docs). See Claude custom connectors.
  • ChatGPT: Plugins › Add › Create custom MCP server. Authentication is OAuth, none, or a mix (OpenAI's docs), with no field for a fixed key. See ChatGPT custom MCP servers.
  • Grok: on grok.com, Connectors › New Connector › Custom, then the server's OAuth or API key step (xAI's docs). See Grok custom connectors.
  • Muse: ask it in a chat to add a custom connector. See Muse custom connectors.

Fine for a server with OAuth. With a key-only server, most Claude and ChatGPT users can't send the key, and adding it with no sign-in opens it to anyone. You also repeat the setup in every assistant.

Option B: add it once to Upsy

Upsy is one MCP server for all your assistants. It keeps your server's key, and each assistant signs in to Upsy with OAuth, so a key-only server works in Claude and ChatGPT too.

  1. Sign up at upsy.ai with Set up Upsy.
  2. Open Apps, click Connect an app, and under Any MCP server click Add on the MCP server on Tailscale card.
  3. Enter a Name assistants will see, such as Homelab, and the Funnel address with its path under MCP Endpoint.
  4. Paste the server's key under API key or token; Upsy sends it as a Bearer token. Leave it empty for a server with OAuth: Upsy finds the sign-in in its metadata and sends you there.
  5. Click Add MCP Server. Upsy lists the server's tools to check it works. If it can't, it says why and saves nothing.
  6. The server starts at No access for the assistants you've already added. Click Check which assistants can use it in the banner and pick Read-only, Full access or Pick actions… for each.

No assistants yet? Under Assistants, click Add assistant and pick one under Which assistant?: Copy prompt for Grok and Muse, a custom connector at https://upsy.ai/connect for Claude and ChatGPT. On Upsy's sign-in page your server is ticked at All; switch it to Read-only if you like.

Assistants reach its tools through Upsy's app_tools, app_read and app_call. Start a new chat if one doesn't see it.

Check that it works

Using Upsy, list the tools on my Homelab server, then run one that only reads.

The assistant should list the tools and run one, and the call shows in Upsy's History under that assistant.

Access levels for your own server

  • Read-only allows only tools your server marks readOnlyHint: true, and never one whose name says it changes something (create, delete, send, update…). If your server doesn't label its tools, Read-only allows nothing; use Pick actions.
  • Pick actions lets you choose tools one by one. Tools the server adds later stay off until you pick them.
  • Full access allows every tool. No access hides the server.

Troubleshooting

"Use a public https:// address. On Tailscale? Use the server's Funnel address (https://….ts.net)."

You entered a tailnet address: a MagicDNS name like http://homelab:8080/mcp, a Tailscale IP (100.64.0.0/10 or fd7a:115c:a1e0::/48), or an http:// ts.net address. Upsy only reaches public https:// addresses. Use the Funnel address.

"Couldn't reach Homelab. Turn on Tailscale Funnel for it…"

The ts.net address didn't answer from the internet. Run tailscale funnel status on the machine. A new address can take 10 minutes to resolve. Without --bg, closing the terminal stops Funnel.

"Couldn't use Homelab: …" or "Homelab didn't accept the token, or couldn't be reached: …"

The address answered, but the MCP request failed. Check:

  • The port. Funnel's port must match your server's. The public port must be 443, 8443 or 10000; with --https=8443, keep :8443 in the address.
  • Where the server listens. Funnel sends traffic to http://127.0.0.1:<port>, so a server bound only to its Tailscale IP, or in a container without a published port, won't answer. curl http://127.0.0.1:8000/mcp on the machine should get an HTTP answer, even an error, not "connection refused".
  • The path, usually /mcp.
  • The transport. An SSE-only server (often at /sse) or a stdio server needs a wrapper such as supergateway.
  • The key. Upsy sends Authorization: Bearer <key>. A server that reads another header, such as X-API-Key, won't see it.

It worked, then stopped

If Apps shows Reconnect and assistants get "Homelab refused its token", the server no longer accepts its key. Remove it on its page and add it again with a new key. A server with OAuth has a Reconnect button there instead.

A new tool doesn't show up

Upsy keeps each server's tool list for up to an hour. Wait, or remove the server and add it again.

Security and privacy

  • Funnel is public. Anyone who finds the address can send requests. Never publish an MCP server without its own key or OAuth.
  • Your key stays in Upsy, in your own storage. Assistants call Upsy, and Upsy calls your server, only at public internet addresses.
  • History lists every call to your server under the assistant that made it.
  • Alerts email you when a server is added, and when one assistant deletes 50+, sends 20+ or reads 100+ items in 10 minutes. Your server's tools count by name, such as delete_…, send_… or get_….
  • No approval step. Upsy doesn't ask before each call, so keep tools that change things behind Read-only or Pick actions.
  • Turning it off: set the server to No access, click Remove on its page in Upsy, or run tailscale funnel reset on the machine. Removing the funnel attribute from the policy stops Funnel for the whole tailnet.

FAQ

Is there an official Tailscale MCP server?

Tailscale's own MCP endpoints are part of Aperture, for agents working with your tailnet. The ones on GitHub are community projects. Neither puts your own server in front of cloud assistants; Funnel does.

Can Claude connect to an MCP server on my tailnet?

Claude Code can, from a tailnet machine. Claude's custom connectors can't: they connect from Anthropic's cloud, so publish the server with Funnel first.

Can ChatGPT connect to a local MCP server?

Not directly. Publish it at a public HTTPS address with Funnel, or set up OpenAI's Secure MCP Tunnel.

What is a Tailscale MCP gateway?

Tailscale's own is Aperture, which passes model and MCP traffic for people and agents on your tailnet. Upsy works the other way: a gateway in the cloud that cloud assistants can reach, which calls your Funnel address at each assistant's limits.

Is Tailscale Funnel safe for an MCP server?

Traffic is encrypted to your machine and your IP stays hidden, but the address is public. Use a long random key or OAuth, Read-only where you can, and turn Funnel off when you don't need it.

Related guides