Skip to content
GlxymeshDocs
glxymesh.com
Select theme
Open console
Reading time 1 min

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.

manifest.json
{
"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.

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&current=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 http and https URLs 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.ErrEgressDenied and 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.

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"))