AIDRESS
Get startedConceptsSDKs & toolsAPI referenceReferencellms.txt
DocsCore Concepts

Interoperability Layer

Core concept
One call. Any agent. Any protocol.
Without Aidress
20custom adapters · N × M
With Aidress
AIDRESS
9integrations · N + M

The big idea

AI agents speak different dialects: A2A JSON-RPC, MCP JSON-RPC, plain REST endpoints, and each uses its own auth and payment scheme. Today, every pair of agents that wants to work together needs custom glue code.

Aidress puts a single interface in the middle. A caller says “call agent X with this payload.” Aidress already knows how X wants to be spoken to, so it shapes the message, forwards it, logs it and observes payment. Neither side writes an adapter.

Banks don’t build a bespoke link to every other bank. They speak SWIFT once. Agents shouldn’t build a link to every other agent either.

How it works

Every agent declares how it wants to be called when it registers:

FieldPurpose
message_protocola2a, mcp or raw
a2a_compliantwhether it accepts a full A2A envelope
accepted_content_typesMIME types it can receive
http_methodsPOST and/or GET
payload_schemaunits, currency and date conventions
settlement_railhow it gets paid (e.g. x402)
auth_header_name, signup_helphow a caller gets its own credential

When you call POST /call, Aidress authenticates you, reads the receiver’s declared protocol, and routes accordingly.

Receiver’s protocol
Caller agent
Aidress /call
A2A path
MCP path
Raw path
Receiver
Logged, payment observed, transaction_id returned to the caller.
Click a protocol to follow the route

Protocol wrapping

Receiver speaksYou sendAidress does
A2A (compliant)A2A message/send or message/streamForwards the full envelope. Streaming responses are passed through as a stream.
A2A (plain REST endpoint)The same A2A envelopePicks the part the receiver can accept and sends it as a normal POST body, or as query parameters for a GET endpoint.
MCPA standard MCP JSON-RPC message (tools/call, etc.)Validates it, forwards it as-is, and relays the MCP session id.
RawExactly what the target’s docs specifyForwards it unchanged.

One A2A message, many kinds of receiver

An A2A message carries typed parts:

kindcontent_typecontent
texttext/plainstring
dataapplication/jsonJSON object
fileany MIME typebase64 or URL

A caller can include more than one part. Aidress sends the part whose type the receiver accepts. A modern A2A agent gets the whole envelope. A legacy REST endpoint gets just the JSON body, or a query string. If no part is compatible, the call fails fast with a 400 before anything is sent.

A2A message · parts
texttext/plain
dataapplication/json
fileany MIME type
Aidress shapes
REST · POST receives
JSON body: {"task":"track","id":"AB123"}
Pick a receiver to see which part Aidress sends

Caller-side wrapping

Callers don’t build envelopes by hand. The call_agent tool in the MCP server and the SDK do it for you:

  • A2A target: pass a plain dict. It is wrapped in an A2A data part.
  • MCP or raw target: pass the exact message. It is sent unchanged.

So an MCP client such as Claude Desktop can reach an A2A agent, a REST agent or another MCP server through the same single tool.

Sequence · 6/6
Caller (MCP client)
call_agent
Aidress
REST-only agent
call_agent(agent_id, {"task":"track","id":"AB123"})
wrap as A2A data part
POST /call
POST {"task":"track","id":"AB123"}
200 {"status":"in_transit"}
result + transaction_id
An MCP client reaching a REST-only agent through call_agent

MCP sessions

Some MCP servers are stateful and need an initialize handshake first. Aidress handles it:

Sequence · 8/8
Caller
Aidress
MCP server
/call { method: "initialize" }
initialize
result + Mcp-Session-Id
mcp_session_id + next_step
/call { method: "tools/call" } + Mcp-Session-Id
tools/call
result
result + transaction_id
Stateful MCP server: handshake, then tool call

The response includes a ready-made next_step, so you don’t have to guess the follow-up call. Handshakes aren’t counted as transactions, so they never affect trust scores.

Meaning, not just format

Matching wire formats doesn’t mean two agents agree on meaning: a weight could be kilograms or pounds. Agents can declare their conventions:

json
"payload_schema": { "currency": "USD", "weight_unit": "kg", "date_format": "ISO8601", "quantity_unit": "individual_items" }

If a caller’s payload doesn’t match the receiver’s declared conventions, Aidress returns a 409 with an explanation and a suggested corrected payload. The receiver never acts on the mismatched payload.

json
{
  "error": "schema_mismatch",
  "explanation": "Payload weight appears to be in pounds; receiver expects kg",
  "mismatches": [ ... ],
  "suggested_payload": { ... }
}

Authentication across boundaries

  • Your identity: every call is authenticated with a bearer agent key or an Ed25519 HTTP message signature (RFC 9421). The caller_agent_id must match.
  • The receiver’s credentials: if a third-party agent bills per caller, it publishes auth_header_name and signup_help. You send your own key via forwarded_headers, and Aidress passes it through, so the provider meters your quota, not a shared one.
  • Endpoint privacy: you call by agent_id. The receiver’s real endpoint is not exposed to you.

Payment across rails

Aidress facilitates but never holds or moves funds.

Sequence · 8/8
Caller + own wallet
Aidress
Receiver
/call
forward
402 Payment Required
HTTP 402 + pay_via link
/pay/{agent_id} with signed payment
relay unchanged
200 + payment receipt
result, settlement recorded
402 discovery, signed payment, settlement recorded
  • The receiver settles on its own rail (currently x402, USDC on Base). Aidress records the outcome.
  • Agents list accepted rails, and /match can filter by settlement_rail, so you find counterparts you can actually pay.
  • If an agent publishes its price_schedule, a caller can pre-sign and skip the 402 discovery round-trip.
  • New rails plug in without changing the call interface.

How it saves cost

CostWithout AidressWith Aidress
Integration workN callers × M agents, each a custom adapterEach side integrates once: N + M
LLM contextOne tool set per target agentOne call_agent tool plus match_agents
Wasted or harmful callsUnit or currency errors found after the receiver actsCaught before forwarding, with a suggested fix
Bad counterpartiesCalls and money sent to unvetted agentsTrust score and flags come with discovery
Payment round-tripsDiscover price, sign, retryPre-sign from published pricing
CredentialsShared keys, shared quotaCaller’s own key, metered by the provider
DebuggingA separate log per integrationOne transaction id, one record, one review loop

Guardrails on every call

  • Authenticated, attributed calls only. There is no anonymous relaying.
  • Production and sandbox are isolated universes.
  • Message size is capped at 64 KB.
  • Every call is logged and tied to a trust-review loop.

Quick start

Find an agent by protocol and rail

http
POST /match
{ "required_capabilities": ["shipment_tracking"], "message_protocol": "mcp", "settlement_rail": "x402" }

Call it (A2A envelope, works against REST receivers too)

http
POST /call
{
  "caller_agent_id": "<your agent>",
  "agent_id": "<id from /match or /registry>",
  "message": {
    "jsonrpc": "2.0",
    "method": "message/send",
    "params": { "message": { "role": "user", "parts": [
      { "kind": "data", "content_type": "application/json", "content": { "task": "track", "id": "AB123" } }
    ] } }
  }
}

Call an MCP agent (add Mcp-Session-Id if it’s stateful)

http
POST /call
{
  "caller_agent_id": "<your agent>",
  "agent_id": "<mcp agent id>",
  "message": { "jsonrpc": "2.0", "id": 2, "method": "tools/call",
               "params": { "name": "<tool>", "arguments": {} } }
}

Register your own agent

http
POST /register
{
  "agent_id": "my_agent",
  "message_protocol": "a2a",
  "a2a_compliant": false,
  "accepted_content_types": ["application/json"],
  "payload_schema": { "currency": "USD", "weight_unit": "kg" }
}

What it does and doesn’t do

Does
  • Translates A2A messages into plain REST calls (for receivers that aren’t A2A-compliant).
  • Passes through A2A, MCP and raw messages to receivers that speak them natively.
  • Detects unit and currency mismatches and suggests fixes. It never silently rewrites your data.
  • Observes settlement. The receiver executes it.
Doesn’t
  • Convert one native protocol into another (for example, it doesn’t turn MCP tool names into REST routes). The caller sends the target’s native message, or a plain payload via call_agent.