Skip to content

MCP agent boundary

This pattern is useful when an application discovers capabilities from an MCP server but does not want remote annotations to become authorization.

from schemarouter import ExecutionPolicy, PlanRequest, SchemaRouter

router = await SchemaRouter.from_url(
    "http://localhost:8000/mcp",
    kind="mcp",
    policy=ExecutionPolicy(
        allow_unclassified_remote=True,
    ),
)

results = await router.ainvoke(
    PlanRequest(
        query="add result",
        arguments={"a": 2, "b": 3},
    )
)

Production note

allow_unclassified_remote=True is broad. A production deployment with mixed read and write MCP tools should prefer a future trusted local classification layer or separate servers by authority domain.

The current design refuses to trust a remote server's own annotations as the final side-effect decision.

Optional no-match execution guard

For ordinary application calls, use the higher-level ainvoke_selective() entrypoint so the host need not coordinate two separately authorized artifacts:

from schemarouter import RetrievalAbstentionPolicy, ainvoke_selective

policy = RetrievalAbstentionPolicy(min_score=host_config.calibrated_min_score)
results = await ainvoke_selective(
    router, user_request, k=3, policy=policy, config=trusted_run_config,
)

The host must independently calibrate calibrated_min_score and may catch PolicyViolationError to return a no-capability response without a call. Both retrieval and planning use the same RunConfig principal. No tool can execute through this API after abstention. Plain ainvoke() does not use this optional gate.

router.ainvoke(...) above does not automatically reject an unsupported user request merely because the best-ranked capability is a poor match. To explicitly opt into an externally calibrated retrieval abstention check before actual execution, use the same trusted request and authorization context for retrieval and planning:

from schemarouter import (
    PlanRequest, PolicyViolationError, RetrievalAbstentionPolicy,
    execute_selective_plan,
)

request = PlanRequest(query=user_request)
policy = RetrievalAbstentionPolicy(min_score=host_config.calibrated_min_score)
retrieval = router.retrieve_executable(request, k=3)
plan = router.plan_executable(request)
try:
    results = await execute_selective_plan(router, retrieval, plan, policy=policy)
except PolicyViolationError:
    results = []  # No tool call dispatched by this optional guard.

This refuses an abstained shortlist, unknown fallback tools, schema mismatch and stale registry/query pairs. It does not certify an unsupported intent: the score and cutoff still require independent prospective calibration. The host must use this opt-in bridge consistently; plain ainvoke bypasses it. It never replaces SchemaRouter's normal authorization or execution policy.