graph-tool-call MCP server
Commit Oct 8, 2026Lets an AI client search large tool catalogs and fetch only the target tools and prerequisite producers it needs to act.
Also known as SonAIengine/graph-tool-call
- Stars
- 18
- Tools
- 3
- Downloads, 30 days
- —
- Latest version
- —
- Last commit
- Oct 8, 2026
- License
- MIT
What is graph-tool-call MCP?
graph-tool-call lets an AI client search large tool catalogs and fetch only the target tools and prerequisite producers it needs to act. It exposes 3 tools, such as evidence, token, side.
Summary generated from the project's README
About graph-tool-call MCP server
Managing massive tool catalogs for AI agents is what graph-tool-call enables by treating tool retrieval as a graph problem rather than a simple similarity search. It identifies not just the primary tool requested by a user, but also the prerequisite tools needed to produce the required inputs for that target. This approach ensures that an agent has a complete execution chain, such as finding an order ID before attempting to process a refund.
Developers can integrate this logic into Python applications using ToolGraph or deploy it as a remote MCP server via streamable HTTP. The system supports ingestion from OpenAPI, GraphQL, MCP tools, and Python functions. It works with major frameworks like OpenAI, Anthropic, and LangChain through specific middleware and patches. By providing token-budgeted schemas, it reduces the context sent to models, which helps stay within token limits while maintaining high selection quality.
What you can do with it
- 1Resolve complex tool dependency chainsAn AI agent can automatically identify that it needs to call a search tool to get an ID before it can call a specific action tool.
- 2Optimize LLM context usageReduce the number of tokens sent to a model by filtering a large catalog down to only the relevant tools and their necessary dependencies.
- 3Ingest diverse API specificationsConvert existing OpenAPI or GraphQL documentation into a structured graph that an AI can navigate.
Written from the project's README. Every use case is checked against a quote from it.
graph-tool-call MCP tools 3
Detected from the READMEevidencetokenside
| evidence | — | |
| token | — | |
| side | — |
Automated checks
Ran Nov 14, 2026Full report →Not verified yet. A server needs a score of 80, no serious finding, and enough data for us to check. How checks work · What to fix for more points
- Source repository linked and reachablesonaiengine/graph-tool-call is public and reachablegithub.com/sonaiengine/graph-tool-call ↗Pass
- Package names this repository as its sourceNot checked
- Build provenance (Sigstore attestation)Not checked
- Open source license (OSI)MITspdx.org/licenses/MIT.html ↗Pass
- Commit or release in the last yearLast commit or release 2026-10-08github.com/sonaiengine/graph-tool-call ↗Pass
- OpenSSF ScorecardNot checked
- Package name not close to a popular packageNot checked
- No critical advisory in the package or its dependenciesNot checked
- No hidden instructions to the model3 tool descriptions and the README read; no override phrases, credential paths or hidden charactersPass
- Destructive tools are labelledNo tool named like delete, drop or execPass
- Remote endpoint answers the MCP handshakeNot checked
README
View on GitHubgraph-tool-call
Graph-structured retrieval for large LLM tool catalogs.
Find the target tool, the prerequisite tools that produce its inputs, and the smallest schema bundle that fits the planner's token budget.
Documentation · Quickstart · PyPI · Benchmarks
English · 한국어
The Problem
A semantic search for "refund an order" can find refundOrder. That is not
enough when the operation requires an order_id that the user does not have.
A usable candidate set also needs the operation that produces that field:
findOrdersByEmail(email) -> order_id -> refundOrder(order_id)
Large catalogs create a second problem: sending every schema to the model wastes context and can lower selection quality. graph-tool-call treats retrieval as a contract-aware graph problem instead of flat similarity search.
It provides:
- deterministic ingestion from OpenAPI, GraphQL introspection, MCP tools, Python functions, and structured tool catalogs;
- hybrid target retrieval with keyword, graph, optional embedding, and MCP annotation signals;
- evidence-backed target selection and typed prerequisite expansion;
- token-budgeted, contract-projected schemas for the model-facing catalog;
- readiness, failure, and trace metadata for application-side diagnostics;
- adapters for OpenAI, Anthropic, LangChain v1, MCP, Docker, and Kubernetes.
Authentication, tenant policy, approval, and product-specific execution remain in the host application.
See It in 30 Seconds
No model, API key, or network call is required:
uvx graph-tool-call demo dependency-chain
Selected target:
refundOrder(order_id)
Required producer:
findOrdersByEmail(email) -> order_id
evidence: api_contract, openapi_link
Execution order:
1. findOrdersByEmail
2. refundOrder
Planner context:
6 catalog tools -> 2 required tools
estimated tokens: 1476 -> 160 (89% fewer)
This demo runs the real retriever, deterministic target selector, typed dependency closure, and schema admission pipeline.
Installation
The core search and graph package uses only the Python standard library. Optional integrations are installed explicitly:
pip install graph-tool-call
pip install "graph-tool-call[openapi]" # YAML OpenAPI documents
pip install "graph-tool-call[korean]" # Kiwi tokenizer
pip install "graph-tool-call[langchain]" # LangChain v1 middleware
pip install "graph-tool-call[mcp]" # MCP server and proxy
pip install "graph-tool-call[all]" # all optional features
Python 3.10 through 3.14 are tested in CI.
Build and Search
OpenAPI
from graph_tool_call import ToolGraph
graph = ToolGraph.from_url(
"https://petstore3.swagger.io/api/v3/openapi.json",
cache="petstore.graph.json",
)
for result in graph.retrieve_with_scores("create a new pet", top_k=5):
print(result.tool.name, result.score, result.confidence)
OpenAPI ingestion preserves request and response schemas, parameter locations,
content types, security requirements, links, examples, response envelopes, and
typed consumes/produces contracts. Swagger 2.0, OpenAPI 3.0, and OpenAPI 3.1
are supported.
Inspect a collection before exposing it to an agent:
graph-tool-call inspect-openapi ./openapi.json --json
graph-tool-call build-openapi-collection ./openapi.json -o collection.json
The report contains stable readiness issue codes, semantic coverage, and edge quality rather than a single opaque score.
Other sources
from graph_tool_call.ingest import ingest_source
openapi_result = ingest_source(openapi_document)
graphql_result = ingest_source(introspection_result)
mcp_result = ingest_source({"tools": mcp_tools}, format_hint="mcp-tools")
python_result = ingest_source([read_file, write_file])
Every adapter returns normalized ToolSchema objects, capability metadata, and
structured unsupported-feature diagnostics.
Choose an Integration
| Environment | Recommended surface | What graph-tool-call owns |
|---|---|---|
| Python application | ToolGraph / graphify APIs |
ingest, search, evidence, dependency closure |
| OpenAI Responses or Chat Completions | patch_openai |
per-request function-tool filtering |
| Anthropic Messages | patch_anthropic |
per-request tool filtering |
| LangChain v1 | create_tool_selection_middleware |
model-call tool selection |
| Claude Code, Cursor, Windsurf | MCP proxy | many MCP backends behind 3 gateway tools |
| OpenAI Agents, PydanticAI, Google ADK | remote MCP server | protocol-neutral search service |
| Docker or Kubernetes | Streamable HTTP MCP | private deployable service |
See the compatibility matrix for validation boundaries. Protocol compatibility does not imply that every framework or cloud release is tested by this repository.
OpenAI Responses
from graph_tool_call.middleware import patch_openai
patch_openai(client, graph=graph, top_k=5)
response = client.responses.create(
model=model_name,
input="delete a user account",
tools=all_function_tools,
)
Hosted tools such as web search pass through unchanged. The same patch keeps legacy Chat Completions support.
LangChain v1
from langchain.agents import create_agent
from graph_tool_call.langchain import create_tool_selection_middleware
selection = create_tool_selection_middleware(langchain_tools, top_k=5)
agent = create_agent(
model,
tools=langchain_tools,
middleware=[selection],
)
The middleware intersects with tools still allowed by earlier permission or feature-flag middleware; it does not reintroduce filtered tools.
MCP server
graph-tool-call ingest ./openapi.json -o graph.json
graph-tool-call serve \
--graph graph.json \
--transport streamable-http \
--host 127.0.0.1 \
--port 8000
The MCP endpoint is /mcp; HTTP deployments also expose /healthz and
/readyz. Keep remote endpoints private or behind an authenticated gateway.
MCP proxy
graph-tool-call proxy \
--config ./mcp-backends.json \
--transport streamable-http
The proxy accepts local stdio, SSE, and Streamable HTTP backends. In gateway
mode it exposes search_tools, get_tool_schema, and call_backend_tool, then
notifies capable clients when matching backend tools become visible.
Reproducible Evidence
The release headline is deliberately model-free and small enough to replay in CI. On seven curated commerce cases, adding typed producer expansion to the same selected target produced:
| Metric | Target only | Target + graph producers |
|---|---|---|
| Required-producer recall | 14.3% | 100% |
| Candidate plan coverage | 47.6% | 100% |
| Candidate binding support | 14.3% | 100% |
| Target Recall@5 | - | 100% |
The case-level v0.47.0 artifact records fixture hashes, every expected target and producer, and replay commands:
make launch-evidence
make launch-evidence-check
The separate
observability artifact
checks that tracing leaves engine inputs unchanged, replays deterministically,
scrubs secrets, explains every decision, and stays below the documented
5ms/span p95 capture-cost gate:
make observability-evidence-check
This is an engine regression suite, not a population-level estimate of LLM tool-calling accuracy and not a state-of-the-art claim. Larger external comparisons, model-loop experiments, confidence intervals, and known weak cases are reported in Benchmark Results and the paper protocol.
Production Boundary
graph-tool-call is the retrieval and contract layer. A production adapter still owns:
- user and service authentication;
- tenant authorization and approval policy;
- downstream secrets and cookie handling;
- side-effect confirmation, cleanup, and audit retention;
- provider/model lifecycle and final response policy.
Do not store raw credentials in graph artifacts, tool descriptions, trace records, or model-visible arguments.
Documentation
| Start here | Purpose |
|---|---|
| Quickstart | first search, graph, readiness, and execution loop |
| Mental model | understand the pipeline and boundaries |
| OpenAPI ingestion | contract extraction and collection build |
| Target selection | ranking evidence and deterministic guard |
| Integrations | frameworks, MCP, and deployment |
| API reference | stable public Python surface |
| Roadmap | current product and research priorities |
Development
git clone https://github.com/SonAIengine/graph-tool-call.git
cd graph-tool-call
poetry install --with dev --all-extras
poetry run ruff check .
poetry run ruff format --check .
poetry run pytest tests/ -q
See CONTRIBUTING.md and the release checklist.
License
graph-tool-call MCP questions
What tools does graph-tool-call MCP provide?
It exposes 3 tools, including evidence, token, side.
How does graph-tool-call reduce the tools sent to a model?
It retrieves the target tool plus typed prerequisite producers and admits only token-budgeted, contract-projected schemas to the model-facing catalog.
Which tool catalog formats can it ingest?
It ingests OpenAPI, GraphQL introspection, MCP tools, Python functions, and structured tool catalogs.
Does it run as an MCP server?
Yes, it can serve a built graph over Streamable HTTP at the /mcp endpoint, and a proxy mode puts many MCP backends behind three gateway tools.
Does it require extra Python dependencies?
The core search and graph package uses only the Python standard library; integrations like OpenAPI, LangChain, and MCP are optional extras.
Does it handle authentication and authorization?
No, it is the retrieval and contract layer; the host application owns authentication, tenant policy, and approval.