feat(mcp): serve brain and infra over Tailscale Serve with real TLS
release / tag (push) Successful in 1s
release / tag (push) Successful in 1s
Replaces the raw NodePort URLs with Tailscale Serve endpoints on koala: brain https://koala.tail30472e.ts.net:8443/mcp -> 127.0.0.1:30330 infra https://koala.tail30472e.ts.net:8444/mcp -> 127.0.0.1:30342 Why this beats both alternatives that were tried: The public d-ma.be path exits to Cloudflare and NPM to reach a k3s service on the machine the session is running on, and Cloudflare rate-limits and size-caps tool results — the original complaint. The raw NodePort path fixed that but only worked from koala: every namespace carries default-deny-ingress and an allow policy naming the traefik namespace, so kube-proxy's KUBE-EXTERNAL-SERVICES chain RSTs external callers. Admitting tailnet clients there would need externalTrafficPolicy: Local on each service plus an ipBlock per policy, because the default Cluster policy SNATs the source and an ipBlock can never match. Serve sidesteps all of it. tailscaled terminates TLS with a genuine cert and proxies over loopback, so the request reaches the NodePort from koala itself — the case the NetworkPolicy already permits. No policy change, no externalTrafficPolicy change, no firewall rule, no cert-manager, no DNS record. Port-per-service rather than path-per-service: the mapping is 1:1 with no prefix rewriting, so what the client requests and what the server sees cannot desync. Verified: 200 authenticated in 7.6ms from koala, and `claude mcp list` reports Connected against the Serve URL. An earlier apparent OAuth resource-metadata mismatch turned out to be an artifact of testing without an Authorization header — with a valid bearer the client never enters OAuth discovery. Client requirement: `tailscale set --accept-dns=true`. Confirmed on iguana that 100.100.100.100 resolves the MagicDNS name correctly while the system resolver does not, so the name fails to resolve until Tailscale is accepted as a DNS provider. Tracked in #24 as the Mac prerequisite. Note Serve matches on SNI, so substituting the raw tailnet IP is not a workaround. Bump-Type: minor Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BeAp5LTscnz2W7Ubt4eJ6m
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"_comment": "Tailnet-direct NodePorts, not the public d-ma.be hostnames. The public path goes out through Cloudflare and NPM to reach a k3s service on koala, which imposes rate limits and message-size caps on tool results and adds a full internet round trip - for a service on the same machine most sessions run on. Requires koala to allow these ports on the Tailscale interface; see mathias/skills#24.",
|
||||
"_comment": "Tailscale Serve on koala, not the public d-ma.be hostnames. The public path exits to Cloudflare and NPM to reach a k3s service on the same machine most sessions run on, which imposes rate limits and message-size caps on tool results. Serve terminates TLS with a real Tailscale cert and proxies to the NodePort over loopback, so traffic reaches the service from koala itself and satisfies the default-deny-ingress NetworkPolicy with no cluster change. Clients need 'tailscale set --accept-dns=true' for the MagicDNS name to resolve; see mathias/skills#24.",
|
||||
"mcpServers": {
|
||||
"brain": {
|
||||
"type": "http",
|
||||
"url": "http://koala:30330/mcp",
|
||||
"url": "https://koala.tail30472e.ts.net:8443/mcp",
|
||||
"headers": {
|
||||
"Authorization": "Bearer ${BRAIN_MCP_TOKEN}"
|
||||
}
|
||||
},
|
||||
"infra": {
|
||||
"type": "http",
|
||||
"url": "http://koala:30342/mcp"
|
||||
"url": "https://koala.tail30472e.ts.net:8444/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user