Docker And Kubernetes
The production-neutral deployment shape is a private MCP service. Keep credentials and public ingress in the host platform or a managed gateway.
Build And Run
docker build -t graph-tool-call:local .
docker run --rm -p 8000:8000 graph-tool-call:local \
--source https://petstore3.swagger.io/api/v3/openapi.json
The image:
- installs the checked-out source with MCP and OpenAPI extras;
- runs as a non-root user;
- defaults to Streamable HTTP on
0.0.0.0:8000; - exposes MCP at
/mcp; - checks
/healthzwith a Docker health check.
For a stable production startup, build a graph artifact ahead of time and mount it read-only:
graph-tool-call ingest ./openapi.json -o graph.json
docker run --rm -p 8000:8000 \
-v "$PWD/graph.json:/data/graph.json:ro" \
graph-tool-call:local --graph /data/graph.json
Kubernetes
Apply the checked-in starting manifest after replacing the image and source:
kubectl apply -f deploy/kubernetes/mcp-server.yaml
kubectl port-forward service/graph-tool-call 8000:8000
curl http://127.0.0.1:8000/readyz
The manifest uses a ClusterIP service, a read-only filesystem, a non-root security context, resource limits, and HTTP probes. Tune the limits and add organization policy for the target cluster.
Managed Gateways
For AWS AgentCore or Microsoft Foundry, deploy this service on a private
container platform and register https://SERVICE/mcp as a remote MCP target.
Let the managed gateway own inbound identity, downstream credential injection,
approval, and audit policy.
Do not place downstream API tokens in graph artifacts, MCP configuration files, tool descriptions, or model-visible arguments.
Verification
curl --fail http://127.0.0.1:8000/healthz
curl --fail http://127.0.0.1:8000/readyz
A complete smoke test also initializes an MCP client, calls search_tools, and
checks that get_tool_schema returns the selected tool contract.
/readyz returns HTTP 503 when a configured startup source cannot be loaded or
produces no tools. A server started without a source stays ready with
catalog_ready: false because clients can populate it through load_source.