Dirigex isn't a directory you consult and then call agents directly. It's a control plane on the request hot path: every invoke passes through Dirigex, which gates it and dispatches it. Nothing reaches an agent ungated.
- Application layer — your apps, the SDKs, public-catalog consumers.
- Dirigex control plane — discovers the agent, enforces the gates inline (verified tier · fresh verification · healthy endpoint · tenant isolation · rate limits), then dispatches. The gates are on the request path, not a sidecar you can route around.
- Cryptographic trust anchor — identity attestation, the verification lifecycle, and signed evidence feed the gates. Trust decisions are anchored, not asserted.
- Agent estate — third-party endpoints on open protocols (
mcp,a2a,http_json). Dirigex speaks each one natively.
The same filter governs listing and invocation: if an agent has fallen out of the trusted catalog, it isn't invocable either. There's no path that reaches an agent while skipping the gates.
One hardened dispatch path
However a request arrives — SDK call, public-catalog invoke, MCP, A2A — Dirigex normalizes it into one canonical envelope and dispatches it through one gated path. That's what makes the model auditable: a single shape, a single chokepoint.
// Illustrative shape — every request normalizes into one envelope: a capability
// query + routing + input + caller context. You never hand-build this; the SDK
// or the invoke route does, and Dirigex assigns the internal ids.
{
"schemaVersion": "dirigex.job.v1",
"capabilityQuery": {
"text": "Summarize this support thread",
"requestedSkills": ["text/summarization"]
},
"routing": { "maxCandidates": 3 },
"input": { "payload": { "thread": "…" } },
"callerContext": { "tenantId": "tenant.acme", "traceId": "…" }
}
From that single envelope, Dirigex dispatches to the agent on its own protocol — you never hand-roll the wire format:
// → MCP agent: JSON-RPC tools/call
{ "jsonrpc": "2.0", "id": "…", "method": "tools/call",
"params": { "name": "summarize", "arguments": { "thread": "…" } } }
// → A2A agent: JSON-RPC message/send (v0.3)
{ "jsonrpc": "2.0", "id": "…", "method": "message/send",
"params": { "message": { "role": "user",
"parts": [{ "kind": "text", "text": "…" }] } } }
The agent's reply comes back through the same path, wrapped in a normalized result envelope ({ accepted, mode, agentId, route, result }) — so your code handles one response shape regardless of which protocol answered.
Calling it
You don't construct the envelope — the SDK or the invoke route does. Four lines to a client:
from dirigex_sdk import create_dirigex_client
with create_dirigex_client(base_url="https://api.dirigex.ai",
get_token=lambda: my_auth.get_id_token()) as client:
result = client.tenant.agents.invoke(...) # one call → the hardened path
Or invoke a public-catalog agent over raw HTTPS:
POST /v1/catalog/agents/{agentId}/invoke
Idempotency-Key: 2026-06-29-summary-1
{ "...": "agent-specific payload (≤16 KB)" }
// normalized response — same shape for every protocol
{ "accepted": true, "mode": "public_catalog_invoke", "agentId": "agent.ext.…",
"route": { "type": "success" }, "result": { "...": "agent-defined" } }
Next: Trust & verification for what the gates enforce · Integrate the API for the full call surface · Build a governed agent to add one to the estate. Back to documentation home.