Call external APIs from an MCP tool
Make outbound HTTP requests from a Glxymesh MCP tool. The egress allowlist in manifest.json, subdomain matching, redirects, timeouts and response size limits.
Tools have no sockets. All outbound traffic goes through the platform, which denies everything by
default. A tool can reach only the hosts listed in its manifest.json.
Allow a host
Section titled “Allow a host”{ "name": "weather", "egress": { "allow": ["api.open-meteo.com"] }}Each entry matches that hostname and all of its subdomains, so example.com also allows
api.example.com. Matching ignores case. An entry can also include a port (localhost:8080), and then
it matches only that exact host and port.
The manifest is published with the tool, so changing the allowlist means pushing the tool again.
Make a request
Section titled “Make a request”Use the client from host.HTTPClient(). It’s a standard *http.Client, so net/http code, and any
SDK that accepts a custom client, works unchanged:
import ( "errors" "io" "net/http"
"glxymesh.com/mcp-core/host")
func forecast(city string) (string, error) { req, err := http.NewRequest(http.MethodGet, "https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t=temperature_2m", nil) if err != nil { return "", err } resp, err := host.HTTPClient().Do(req) if errors.Is(err, host.ErrEgressDenied) { return "", errors.New("api.open-meteo.com is not in manifest.json egress.allow") } if err != nil { return "", err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) return string(body), err}http.DefaultClient and http.Get don’t work, because there’s no network stack inside the sandbox.
Always use host.HTTPClient().
- Only
httpandhttpsURLs are allowed. - Redirects are followed, and each redirect target is checked against the allowlist too.
- A request to a host that isn’t allowed fails with
host.ErrEgressDeniedand never leaves the platform. - Each request header has one value. If you set the same header more than once, only one value is sent.
- Each request has a 10-second timeout, and response bodies are limited to 4 MiB.
- Time spent waiting on the upstream still counts toward the tool’s 30-second call limit. See Limits.
Authenticating to an API
Section titled “Authenticating to an API”Keep credentials out of your source. Store them as project secrets, read them with
os.Getenv, and set the header yourself:
req.Header.Set("Authorization", "Bearer "+os.Getenv("GITHUB_TOKEN"))