When tools speak different schemas, put a typed capability boundary in between.
English · 한국어 · Docs · Examples · Contributing · Latest release
Stable release: 0.17.0 · Beta / pre-1.0
SchemaRouter is a typed capability routing and governed execution layer for AI agents across APIs, tools, and data systems.
It sits between an orchestrator and external tools/data sources, compiles heterogeneous schemas into one capability model, retrieves a bounded candidate set, and validates the selected call again at execution time. It is not an agent framework, identity provider, database proxy, or LLM gateway.
pip install schemarouterA normal tool router mainly answers which tool should I call? SchemaRouter also keeps track of which endpoint, parameters, output fields, schema version, access path, policy, and execution binding make that call valid.
user query
-> required semantic fields
-> bounded capability candidates
-> endpoint + parameters + output fields
-> policy / availability / schema validation
-> trusted execution
-> projected typed result
This is useful when a catalog mixes APIs, MCP servers, SDKs, databases, and framework tools whose names overlap but whose schemas and execution constraints differ.
Concepts → · Capability retrieval → · Execution boundary →
Provider-first onboarding lets an application start from the service it wants rather than knowing every underlying protocol first.
import asyncio
from schemarouter import PlanRequest, SchemaRouter
async def main():
router = SchemaRouter()
async with router:
registration = await router.add_provider("apis-guru")
tool = router.registry.get(registration.registered_tool_keys[0])
plan = router.plan(
PlanRequest(
query="API directory metrics total number of APIs",
preferred_tools=[tool.key],
max_calls=1,
)
)
result = (await router.execute(plan))[0]
print(result.tool, result.endpoint, result.data["numAPIs"])
asyncio.run(main())The flow is:
provider identity → schema/adaptor resolution → typed capability registration → bounded selection → validated execution → typed result
Quickstart → · Runnable examples →
flowchart LR
Q["User"] --> A["Agent / RAG / application"]
A --> SR["SchemaRouter"]
SR --> S["APIs / MCP / SDKs / databases"]
S --> SR
SR --> A
The surrounding application owns conversation, decomposition, memory, checkpoints, and final generation. SchemaRouter owns the registered capability and execution boundary.
Retrieval is side-effect free:
candidates = router.retrieve("current Young's modulus for MAT-7", k=5)
for candidate in candidates.candidates:
print(candidate.route_id, candidate.output_fields)Use retrieve_executable(...) when the shortlist must also have a currently valid execution
binding.
SchemaRouter supports several ingress families behind the same capability model.
| Family | Typical entry points |
|---|---|
| Provider identity | await router.add_provider(...) |
| Typed Python / ToolSpec | add_callable(...), add_tool(...), add_bound_tool(...) |
| API protocols | OpenAPI, MCP, OPTIMADE, GraphQL, OData, OpenRPC |
| Relational databases | SQLite, caller-owned SQLAlchemy Engine |
| Vector databases | Qdrant, Milvus, Pinecone, Weaviate, Chroma, PostgreSQL/pgvector |
| Graph / RDF | Neo4j, Neptune, ArangoDB, FalkorDB, SPARQL |
| Document / search / KV / time-series | MongoDB, Elasticsearch/OpenSearch, DynamoDB, Cosmos DB, Couchbase, ClickHouse, InfluxDB |
| Framework bridges | LangChain, LangGraph, LlamaIndex |
Credentials, connection pools, database clients, and transport state remain caller-owned. Vendor query languages are not exposed as model authority.
Choose an ingestion path → · Full ingestion matrix → · Provider-first registration → · Enterprise data onboarding →
SchemaRouter consumes a verified PrincipalContext from the host application and can apply
deny-by-default RBAC/ABAC before retrieval and again at execution.
The same policy model can narrow:
- visible tools/endpoints;
- database tables and fields;
- trusted row/tenant filters;
- vector metadata filters;
- document/search fields;
- graph relationships and hop depth.
SchemaRouter does not authenticate users and does not replace database-native roles, grants, RLS, ACLs, or network controls.
Authorization → · Database onboarding →
A retrieved candidate or model choice never grants authority by itself. Before a result crosses the runtime boundary, SchemaRouter can revalidate:
- tool/endpoint/schema fingerprints;
- arguments and JSON Schema contracts;
- principal policy and data scope;
- current execution binding and availability;
- raw output schema;
- final field projection.
Remote mutation/destructive operations fail closed unless explicitly authorized by local policy.
Security model → · Trust and release evidence →
SchemaRouter 0.17.0 is Beta / pre-1.0. Public APIs may still evolve,
but breaking changes are documented and release-gated.
Python 3.10–3.14 are release-blocking targets. Python 3.15 is a preview target.
Research benchmarks are kept separate from stable product guarantees. Experimental retrieval profiles or ranking methods are not promoted solely because one benchmark improves.
Versioning policy → · Research status → · Changelog →
| Topic | Guide |
|---|---|
| Installation and first use | Getting started |
| Architecture and concepts | What SchemaRouter is |
| Provider/API ingestion | Connect guides |
| Enterprise databases and access scope | Enterprise data onboarding |
| Runtime policy and authorization | Authorization |
| Operational inspection | Inspection |
| Public API | Reference |
| Research evidence | Research index |
Full documentation: https://jdeun.github.io/SchemaRouter/
SchemaRouter deliberately does not own agent loops, final answer generation, identity authentication, credential storage, or arbitrary database/query execution. Those remain outside the capability boundary.
MIT. See LICENSE.