/a2a/{assistant_id}.
Protocol version
Agent Server speaks the A2A v1.0 JSON-RPC binding and also accepts the v0.3 method names, so existing v0.3 clients keep working. The agent card declares one interface:Supported methods
Exactly four v0.3 names are accepted:
message/send, message/stream, tasks/get and
tasks/cancel. Anything else — including agent/getAuthenticatedExtendedCard and
tasks/resubscribe — returns -32601 Method not found.
Only the JSON-RPC binding is available. gRPC and HTTP+JSON are not implemented.
Task history in responses
A context holds many tasks. By defaultSendMessage, GetTask and ListTasks return the history
of the whole context, not just the task you asked about. The second task in a context replays
the first task’s messages, so a client that renders every history entry shows earlier turns again —
including earlier tool results and A2UI payloads.
Set historyScope to task to get back only the messages that belong to the task you asked about.
The default stays context, so existing integrations are unaffected.
Where the option goes depends on the method. SendMessage reads it from configuration:
GetTask and ListTasks read it directly from params:
capabilities.extensions, so you can detect support rather
than assume it:
- Streaming ignores both history options.
SendStreamingMessagereads neitherhistoryScopenorhistoryLength, and returns no error if you send them — so do not rely on either over SSE. historyLengthcaps at 10. A larger value returns-32602withhistoryLength cannot exceed 10.- Scope is applied before
historyLength, so you get the last N messages of that task.
-32602 with historyScope must be 'context' or 'task'. A mis-cased
key such as historyscope is not an error — it is ignored, and you silently get full-context
history, so check the spelling if filtering appears not to work.
Agent card discovery
Each assistant automatically exposes an A2A Agent Card that describes its capabilities and provides the information needed for other agents to connect. You can retrieve the agent card for any assistant using:Optional capabilities
These are configured per assistant throughmetadata.a2a on the Assistants API. langgraph.json
cannot set assistant metadata, so patch the assistant after deploy.
Declare input and output modes
defaultInputModes/defaultOutputModes and the generated skill’s
modes. They are advertisement only — an undeclared mode is still accepted. Replacement is per
field, so send both if you want both overridden, and note that an empty list is rejected.
File parts
FilePart works in both directions. Inbound file, image, audio and video parts become LangChain
content blocks. Outbound content blocks map back to FilePart, in task history and in the final
streamed artifact. MIME types, URIs and filenames pass through unchanged; inline data is
re-encoded as standard base64.
A2UI v0.9
Opt in per assistant:message.extensions. Payloads are validated in both
directions against the v0.9 schemas, and A2UI parts are preserved in message/send, tasks/get
and the final message/stream artifact. Responses carry
metadata.mimeType: "application/a2ui+json". application/json+a2ui is accepted as an alias on
input.
Filter tool results
By default every correlated tool result is published as aDataPart. To publish only some, set an
allowlist of tool names on the deployment:
Requirements
historyScope landed after the 0.14.0 release candidates were cut, so they arrive
in 0.15.0. That version is not published as a stable release yet — check
capabilities.extensions on the agent card before relying on historyScope.
Your graph’s state must include a messages key to accept A2A text and file parts. An assistant
whose input schema has no messages field is rejected with an explanatory error.
Creating an A2A-compatible agent
This example creates an A2A-compatible agent that processes incoming messages using OpenAI’s API and maintains conversational state. The agent defines a message-based state structure and handles the A2A protocol’s message format. To be compatible with the A2A “text” parts, the agent must have amessages key in state.
The A2A protocol uses two identifiers to maintain conversational continuity:
contextId: Groups messages into a conversation thread (like a session ID)taskId: Identifies each individual request within that conversation
contextId from the prior response and omit taskId, so each turn opens a new task inside the same conversation. Send a taskId only to add to a task that is still running, such as one waiting on input.
LangSmith Tracing: The Langsmith Deployment A2A endpoint automatically converts the A2A contextId to thread_id for LangSmith tracing, grouping all messages in the conversation under a single thread.
For example:
Agent-to-agent communication
Once your agents are running locally vialanggraph dev or deployed to production, you can facilitate communication between them using the A2A protocol.
This example demonstrates how two agents can communicate by sending JSON-RPC messages to each other’s A2A endpoints. The script simulates a multi-turn conversation where each agent processes the other’s response and continues the dialogue.
- Two LangGraph agents communicating - Example of two LangGraph agents using the A2A protocol
- Google ADK agent with LangChain agent - Example of a Google ADK agent interacting with a LangChain agent using the A2A protocol
Distributed tracing
When multiple agents communicate over A2A, LangSmith can group all their traces into a single thread, which gives you a unified view of the entire multi-agent conversation.How contextId maps to thread_id
The Agent Server A2A endpoint automatically converts the A2AcontextId to thread_id for LangSmith tracing. This means every message in a conversation, across all participating agents, is grouped under the same thread in LangSmith without any extra configuration on your part.
The flow works as follows:
- On the first message, the client omits
contextId. The server generates one and returns it in the response. - The client passes the
contextIdin all subsequent messages to maintain conversation continuity. - Agent Server maps the
contextIdtothread_idin LangSmith metadata, so all turns appear in the same thread.
Tracing across multiple agents
When agents from different frameworks communicate over A2A,contextId is what unifies their traces. Reuse the contextId returned by the first agent on every later request, to that agent and to the others.
The following code snippet demonstrates the key concepts. For a complete runnable implementation with two agents, refer to the Google ADK + LangChain example.
contextId inside the message object on follow-up turns so the server can associate them with the ongoing conversation. Omit it on the first message, because the server generates a contextId and returns it in the response. Do not resend taskId from a finished turn.
2. Send it: The contextId travels inside params.message. Agent Server uses it as the LangGraph thread_id, so there is no separate tracing field to set.
3. Share the context across agents: Let the first agent mint the contextId, then pass that same value to every agent for the rest of the conversation. That is what groups their traces into one thread.
Receive thread_id in non-LangGraph agents
The previous section covers the client side — propagatingcontextId when sending messages. If one of your agents is not built on LangGraph, it also needs to read that contextId on the receiving end and attach it as the thread identifier, so its traces land in the same LangSmith thread. Use langsmith.integrations.otel.configure() to set up automatic tracing, and read params.message.contextId from the incoming A2A request.
app after this middleware.
Set
LANGSMITH_API_KEY and optionally LANGSMITH_PROJECT in your environment to enable tracing. All agents in the conversation should use the same project so their traces are visible together.View traces in LangSmith
After running a multi-agent conversation, open the LangSmith UI and navigate to Threads. All turns from all participating agents will appear under a single thread, identified by the sharedthread_id.
Test your integration
Against your own deployment
Fetch the card, then send a message:result.task.id and result.task.contextId. Reuse the contextId on the
next message to continue the conversation.
For streaming, send Accept: text/event-stream and use SendStreamingMessage. The first event is
the Task; status and artifact updates follow.
Against the official conformance suite
A2A publishes a Technology Compatibility Kit at a2aproject/a2a-tck. It grades an implementation by RFC 2119 level and works against any A2A endpoint, including yours.The TCK drives some scenarios through
messageId prefixes such as tck-input-required, described
in its docs/SUT_REQUIREMENTS.md. A graph that does not implement those prefixes will report those
requirements as skipped rather than failed.What Agent Server currently fails
Agent Server runs the TCK on every CI build as a required check, gated against a checked-in list of known failures. CI fails if a new failure appears, and also if a listed requirement starts passing, so the list cannot drift from what the server actually does. Read this before you build against a capability:Disable A2A
To disable the A2A endpoint, setdisable_a2a to true in your langgraph.json configuration file:
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

