Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AI Agent Standards and Protocols: a Walkthrough...

AI Agent Standards and Protocols: a Walkthrough of MCP, A2A, and more...

AI agent foundations are built over a handful of common protocols that you need to master, to make the best out of your LLM and agent framework. That’s why it’s important to understand them. But some are catching up, others are not.

In this deep dive, we will explore the ecosystem showing you these standards and focusing on the important ones. Knowing some of the frameworks is useful too to get started faster. Welcome MCP, A2A, ACP protocols, and ADK, Arc, Quarkus, LangChain4j frameworks!

After giving you an overview of the main standards and protocols, their merit and their popularity, we will start by building an agent using Agent Development Kit (ADK) and walk through making a tool call. From there, zooming on MCP, we’ll see how to standardize that tool via a local MCP server and then deploy it as a remote MCP server to share it with others.

Next, we’ll dive into the A2A protocol and enable our agent to participate in multi-agent conversations. And to do that, we will use another framework, Quarkus and LangChain4j, showing how different stacks interact seamlessly through A2A.

You’ll learn not just what these protocols do and how they work, but why they matter, with detailed walkthroughs and live demos throughout.

If you’re struggling to understand all the protocol details around AI agents, this session is for you!

Avatar for Guillaume Laforge

Guillaume Laforge

January 15, 2026
Tweet

More Decks by Guillaume Laforge

Other Decks in Technology

Transcript

  1. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Emmanuel Bernard @EmmanuelBernard Guillaume Laforge

    @glaforge AI Agents standards and protocols: a walkthrough of MCP, A2A, and more…
  2. @EmmanuelBernard (Hexactgon) — @glaforge (Google) The AI agent equation AI

    agent 🟰 LLM ➕ memory ➕ planning ➕ tool use
  3. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Key characteristics & phases of

    AI agents THINK 🧠 Analyze user’s prompt & data, system prompt, to define a goal to reach 🗺 PLAN Check available tools, define the strategy to realize the requested goal REFLECT ♻ Evaluate & loop over the output, to fix errors, to suggest improvements 🎬 ACT RAG searches, API calls, code execution, invoke other agents, request human’s help
  4. @EmmanuelBernard (Hexactgon) — @glaforge (Google) A Plethora of STandards &

    Protocols… AGENTS.md — readme for coding agent ACP — Agent Client Protocol MCP — Model Context Protocol A2A — Agent 2 Agent protocol ACP — Agent Communication Protocol AP2 — Agent Payment Protocol ACP — Agentic Commerce Protocol UCP — Universal Commerce Protocol AAIF — Agentic AI Foundation MCP-UI — Interactive UI components for MCP A2UI — A2A UI protocol
  5. @EmmanuelBernard (Hexactgon) — @glaforge (Google) A Plethora of STandards &

    Protocols… AGENTS.md ACP MCP A2A ACP AP2 ACP UCP AAIF MCP-UI A2UI Standards for AI coding agents to guide their work, and to integrate within IDEs and text editors
  6. @EmmanuelBernard (Hexactgon) — @glaforge (Google) A Plethora of STandards &

    Protocols… AGENTS.md ACP MCP A2A ACP AP2 ACP UCP AAIF MCP-UI A2UI Protocols for defining tool calling behavior and inter-agent communication
  7. @EmmanuelBernard (Hexactgon) — @glaforge (Google) A Plethora of STandards &

    Protocols… AGENTS.md ACP MCP A2A ACP AP2 ACP UCP AAIF MCP-UI A2UI Payment & commerce protocols to automate, process payments, to integrate with search and chat platforms
  8. @EmmanuelBernard (Hexactgon) — @glaforge (Google) A Plethora of STandards &

    Protocols… AGENTS.md ACP MCP A2A ACP AP2 ACP UCP AAIF MCP-UI A2UI Extension of the Linux Foundation to regroup standardization efforts around MCP and AGENTS.md
  9. @EmmanuelBernard (Hexactgon) — @glaforge (Google) A Plethora of STandards &

    Protocols… AGENTS.md ACP MCP A2A ACP AP2 ACP UCP AAIF MCP-UI A2UI Beyond textual chat conversations, adding a UI visual & interaction layer to make agent interfaces richer and more intuitive
  10. @EmmanuelBernard (Hexactgon) — @glaforge (Google) The Big Ones Today: MCP

    & A2A Model Context Protocol Agent 2 Agent Protocol
  11. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Standardizing tool calling An open

    protocol that defines a standardized way to provide tools (functions) & context to your LLMs modelcontextprotocol.io
  12. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Recap on Function Calling Chatbot

    app LLM What’s the weather like in Grenoble? It’s sunny in Grenoble! External API or service user prompt + getWeather(String) function contract call getWeather(“Grenoble”) for me please 󰚦 getWeather(“Grenoble”) {“forecast”:”sunny”} function response is {“forecast”:”sunny”} Answer: “It’s sunny in Grenoble!”
  13. @EmmanuelBernard (Hexactgon) — @glaforge (Google) MCP, the USB-C protocol for

    agent tools? https://norahsakal.com/blog/mcp-vs-api-model-context-protocol-explained/
  14. @EmmanuelBernard (Hexactgon) — @glaforge (Google) MCP, the USB-C protocol for

    agent tools? https://norahsakal.com/blog/mcp-vs-api-model-context-protocol-explained/
  15. @EmmanuelBernard (Hexactgon) — @glaforge (Google) MCP Hosts, Clients, Servers... Server

    MCP Host / Application MCP Server Streamable HTTP MCP Server STDIO MCP Client MCP Client local resource local resource remote resource remote resource JSON-RPC 2.0
  16. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Primitives MCP Server MCP Client

    Tools LLM controlled Resources App controlled Prompts User controlled Sampling Roots Elicitation Functions LLMs request to be called on their behalf to do something or know more. Static data giving access to file contents, DB schemas, API docs. Predefined prompt templates users can use to tell the LLM how to work with tools & resources. Lets servers request LLM generation via the client. Client pays the tokens! But client controls permissions & security. Specify which files servers can access. Client handles security boundaries. Servers can request extra info from users in a structured way (standard UI widgets) - search flight - send message - create event - retrieve doc - read calendar - access a knowledge base - plan a vacation - draft an email - meeting summary Airline sends list of flights and asks LLM to pick the best one. Server booking travel may be given access to specific dir to read user’s files. Asks for user’s airline contact number for finalizing booking
  17. @EmmanuelBernard (Hexactgon) — @glaforge (Google) MCP Client MCP Server notifications/initialized

    Params: • protocolVersion • capabilities • clientInfo Result: • capabilities • serverInfo initialize request with protocol version & client capabilities initialize response with protocol version & server capabilities Initialization
  18. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Tools MCP Server MCP Client

    Tools LLM controlled Resources App controlled Prompts User controlled Sampling Roots Elicitation Functions LLMs request to be called on their behalf to do something or know more. Static data giving access to file contents, DB schemas, API docs. Predefined prompt templates users can use to tell the LLM how to work with tools & resources. Lets servers request LLM generation via the client. Client pays the tokens! But client controls permissions & security. Specify which files servers can access. Client handles security boundaries. Servers can request extra info from users in a structured way (standard UI widgets) - search flight - send message - create event - retrieve doc - read calendar - access a knowledge base - plan a vacation - draft an email - meeting summary Airline sends list of flights and asks LLM to pick the best one. Server booking travel may be given access to specific dir to read user’s files. Asks for user’s airline contact number for finalizing booking Tools enable AI models to interact with external systems Each tool defines a specific operation with inputs and outputs Model-controlled: The model requests tool execution based on context
  19. @EmmanuelBernard (Hexactgon) — @glaforge (Google) MCP Client MCP Server tools/list

    request tools/list response with tools list tools/call request tools/call response with tool result Tools
  20. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Tools — The Full Picture

    User Application MCP Client MCP Server LLM GitHub What repos do I own? Need list of avail. tools Here are the tools tools/list req tools/list resp Query + available tools Function call request Run this tool with args tool/call req tool/call result Request to GitHub Response from GitHub Send tool call result Your repositories are… Execution outcome
  21. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Tools — ADK client StreamableHttpServerParameters

    params = StreamableHttpServerParameters .builder(embeddedServer.getURI().toString() + "/mcp") .build(); try (McpToolset mcpToolset = new McpToolset(params)) { List<BaseTool> moonPhasesTools = mcpToolset.getTools(null).toList().blockingGet(); LlmAgent moonExpertAgent = LlmAgent.builder() .name("moon-expert") .model("gemini-2.5-flash") .description("a moon expert") .instruction(""" You are a knowledgeable astronomy expert focusing on everything about the moon. """) .tools(moonPhasesTools) .build();
  22. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Tools — LangChain4j Client ChatModel

    model = GoogleAiGeminiChatModel.builder() .modelName("gemini-2.5-flash") .apiKey(System.getenv("GOOGLE_API_KEY")) .build(); McpTransport transport = StreamableHttpMcpTransport.builder() .url(embeddedServer.getURI().toString() + "/mcp") .build(); McpClient mcpClient = DefaultMcpClient.builder() .key("MoonPhaseClient") .transport(transport) .build(); McpToolProvider toolProvider = McpToolProvider.builder() .mcpClients(mcpClient) .build();
  23. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Tools — LangChain4j Client interface

    Bot { String chat(String msg); } Bot bot = AiServices.builder(Bot.class) .chatModel(model) .toolProvider(toolProvider) .build(); String response = bot.chat( "What's the current phase of the moon?");
  24. @EmmanuelBernard (Hexactgon) — @glaforge (Google) var transport = HttpClientStreamableHttpTransport .builder(embeddedServer.getURI().toString()

    + "/mcp") .build(); McpSyncClient client = McpClient.sync(transport) .requestTimeout(Duration.ofSeconds(10)) .build(); client.initialize(); McpSchema.ListToolsResult tools = client.listTools(); McpSchema.CallToolResult result = client.callTool( new McpSchema.CallToolRequest("moon-phase-at-date", Map.of("date", "2026-01-15")) ); Tools — MCP SDK Client
  25. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Tools — Server in Micronaut

    public class MoonPhasesMcpServer { @Inject MoonPhasesService moonPhasesService; @Tool(name = "current-moon-phase", description = "Provides the current moon phase") public MoonPhase currentMoonPhase() { return moonPhasesService.currentMoonPhase(); } @Tool(name = "moon-phase-at-date", description = "Provides the moon phase at a certain date (yyyy-MM-dd)") @NotNull public MoonPhase moonPhaseAtDate(@Valid MoonPhaseRequest moonPhaseRequest) { return moonPhasesService.moonPhaseAtDate(moonPhaseRequest.date()); } }
  26. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Tools — Server in Quarkus

    public class MoonPhasesMcpServer { @Inject MoonPhasesService moonPhasesService; @Tool(name = "current-moon-phase", description = "Provides the current moon phase") public MoonPhase currentMoonPhase() { return moonPhasesService.currentMoonPhase(); } @Tool(name = "moon-phase-at-date", description = "Provides the moon phase at a certain date (yyyy-MM-dd)") @NotNull public MoonPhase moonPhaseAtDate(@Valid MoonPhaseRequest moonPhaseRequest) { return moonPhasesService.moonPhaseAtDate(moonPhaseRequest.date()); } }
  27. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Resources MCP Server MCP Client

    Tools LLM controlled Resources App controlled Prompts User controlled Sampling Roots Elicitation Functions LLMs request to be called on their behalf to do something or know more. Static data giving access to file contents, DB schemas, API docs. Predefined prompt templates users can use to tell the LLM how to work with tools & resources. Lets servers request LLM generation via the client. Client pays the tokens! But client controls permissions & security. Specify which files servers can access. Client handles security boundaries. Servers can request extra info from users in a structured way (standard UI widgets) - search flight - send message - create event - retrieve doc - read calendar - access a knowledge base - plan a vacation - draft an email - meeting summary Airline sends list of flights and asks LLM to pick the best one. Server booking travel may be given access to specific dir to read user’s files. Asks for user’s airline contact number for finalizing booking Resources and resource templates provide read-only access to data that the AI application can retrieve and provide as context to models
  28. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Resources @ResourceTemplate( uriTemplate = "https://arxiv.org/abs/{id}",

    description = "The abstract of the paper") public TextResourceContents getAbstract(@ResourceTemplateArg String id) { Feed feed = performSearch(null, id, 0, 1, null, null); if (feed.entries != null && !feed.entries.isEmpty()) { return TextResourceContents.create( "https://arxiv.org/abs/" + id, feed.entries.get(0).summary); } throw new RuntimeException("Paper not found: " + id); }
  29. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Prompts MCP Server MCP Client

    Tools LLM controlled Resources App controlled Prompts User controlled Sampling Roots Elicitation Functions LLMs request to be called on their behalf to do something or know more. Static data giving access to file contents, DB schemas, API docs. Predefined prompt templates users can use to tell the LLM how to work with tools & resources. Lets servers request LLM generation via the client. Client pays the tokens! But client controls permissions & security. Specify which files servers can access. Client handles security boundaries. Servers can request extra info from users in a structured way (standard UI widgets) - search flight - send message - create event - retrieve doc - read calendar - access a knowledge base - plan a vacation - draft an email - meeting summary Airline sends list of flights and asks LLM to pick the best one. Server booking travel may be given access to specific dir to read user’s files. Asks for user’s airline contact number for finalizing booking Provide reusable prompts and prompt templates for a domain, or showcase how to best use the MCP server
  30. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Prompts @Prompt( name = "summarize_paper",

    description = "Summarize the given paper") public PromptMessage summarizePaper(String id) { Feed feed = performSearch(null, id, 0, 1, null, null); if (feed.entries != null && !feed.entries.isEmpty()) { String summary = feed.entries.get(0).summary; return PromptMessage.withUserRole( "Please summarize this paper abstract " + "(ID: " + id + "):\n\n" + summary); } return PromptMessage.withUserRole("Error: Paper not found"); }
  31. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Sampling MCP Server MCP Client

    Tools LLM controlled Resources App controlled Prompts User controlled Sampling Roots Elicitation Functions LLMs request to be called on their behalf to do something or know more. Static data giving access to file contents, DB schemas, API docs. Predefined prompt templates users can use to tell the LLM how to work with tools & resources. Lets servers request LLM generation via the client. Client pays the tokens! But client controls permissions & security. Specify which files servers can access. Client handles security boundaries. Servers can request extra info from users in a structured way (standard UI widgets) - search flight - send message - create event - retrieve doc - read calendar - access a knowledge base - plan a vacation - draft an email - meeting summary Airline sends list of flights and asks LLM to pick the best one. Server booking travel may be given access to specific dir to read user’s files. Asks for user’s airline contact number for finalizing booking MCP server asks MCP client to make LLM calls on its behalf But keeps the human in the loop for approval, as token costs are on them!
  32. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Sampling MCP Server MCP Client

    User LLM sampling/createMessage Server initiates sampling Human in the Loop review Present request approval Human approve / modify Model interaction Complete request Return approved response Forward approved request Return generation Response review Response for approval Human approve / modify
  33. @EmmanuelBernard (Hexactgon) — @glaforge (Google) var summaryTool = AsyncToolSpecification.builder() .tool(McpSchema.Tool.builder()

    .name("summarize_text") .description("Requests a summary of the provided text from the model") .inputSchema(new McpSchema.JsonSchema("object", Map.of("text", Map.of("type", "string")), List.of("text"), null, null, null)) .build()) .callHandler((exchange, request) -> { String text = (String) request.arguments().get("text"); // … Sampling — MCP Server
  34. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Sampling — MCP Server //

    … // Create the sampling request for the client var createMessageRequest = CreateMessageRequest.builder() .messages(List.of(new SamplingMessage( Role.USER, new TextContent("Please summarize this: " + text)))) .systemPrompt("You are a concise summarizer.") .maxTokens(100) .build(); // …
  35. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Sampling — MCP Server //

    … // Send the request to the client and return the result return exchange.createMessage(createMessageRequest) .map(samplingResult -> { String summary = ((TextContent) samplingResult.content()).text(); return CallToolResult.builder() .addTextContent("Summary: " + summary) .build(); }); }) .build();
  36. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Sampling — MCP Client //

    Define the client-side sampling handler Function<CreateMessageRequest, Mono<CreateMessageResult>> clientSamplingHandler = request -> { // In a real scenario, the client would forward this to a local or remote LLM System.out.println("Server requested sampling with prompt: " + request.systemPrompt()); // Construct and return the result return Mono.just(CreateMessageResult.builder() .role(Role.ASSISTANT) .content(new TextContent("Mock summary generated by the client.")) .model("gemini-3-flash") .stopReason(StopReason.END_TURN) .build()); }; // …
  37. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Sampling — MCP Client //

    … // Build the client with sampling support McpAsyncClient client = McpClient.async(transport) .capabilities(ClientCapabilities.builder() .sampling() // Advertise sampling support .build()) .sampling(clientSamplingHandler) // Register the handler .build();
  38. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Roots MCP Server MCP Client

    Tools LLM controlled Resources App controlled Prompts User controlled Sampling Roots Elicitation Functions LLMs request to be called on their behalf to do something or know more. Static data giving access to file contents, DB schemas, API docs. Predefined prompt templates users can use to tell the LLM how to work with tools & resources. Lets servers request LLM generation via the client. Client pays the tokens! But client controls permissions & security. Specify which files servers can access. Client handles security boundaries. Servers can request extra info from users in a structured way (standard UI widgets) - search flight - send message - create event - retrieve doc - read calendar - access a knowledge base - plan a vacation - draft an email - meeting summary Airline sends list of flights and asks LLM to pick the best one. Server booking travel may be given access to specific dir to read user’s files. Asks for user’s airline contact number for finalizing booking Roots are a mechanism for clients to communicate filesystem access boundaries to servers
  39. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Roots — Client // Define

    a root McpSchema.Root projectRoot = new McpSchema.Root( "file:///path/to/project", "Project Directory"); // Build the client with roots support McpAsyncClient client = McpClient.async(transport) .capabilities(ClientCapabilities.builder() .roots(true) // Advertise client supports listing roots & notifications .build()) .roots(projectRoot) // Set initial roots .build(); // Dynamically add a root later client.addRoot(new McpSchema.Root( "file:///path/to/another", "Secondary Assets")) // Notify server roots changed .then(client.rootsListChangedNotification()) .subscribe();
  40. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Roots — Server var listFilesTool

    = AsyncToolSpecification.builder() .tool(Tool.builder() .name("list_project_files") .description("Lists files within the client-provided roots") .build()) .callHandler((exchange, request) -> { // Retrieve all roots from the client return exchange.listRoots() .map(result -> { List<McpSchema.Root> roots = result.roots(); // Implement logic to list files within these root URIs return CallToolResult.builder() .addTextContent("Accessible roots: " + roots) .build(); }); }) .build();
  41. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Elicitation MCP Server MCP Client

    Tools LLM controlled Resources App controlled Prompts User controlled Sampling Roots Elicitation Functions LLMs request to be called on their behalf to do something or know more. Static data giving access to file contents, DB schemas, API docs. Predefined prompt templates users can use to tell the LLM how to work with tools & resources. Lets servers request LLM generation via the client. Client pays the tokens! But client controls permissions & security. Specify which files servers can access. Client handles security boundaries. Servers can request extra info from users in a structured way (standard UI widgets) - search flight - send message - create event - retrieve doc - read calendar - access a knowledge base - plan a vacation - draft an email - meeting summary Airline sends list of flights and asks LLM to pick the best one. Server booking travel may be given access to specific dir to read user’s files. Asks for user’s airline contact number for finalizing booking Elicitation enables MCP servers to request approval, ask for missing info, clarification requests from users via MCP clients for more dynamic workflows
  42. @EmmanuelBernard (Hexactgon) — @glaforge (Google) MCP Client MCP Server 2.

    elicitation/create (more info needed) User 3. Present elicitation UI 4. Provide requested information 5. Return user response 1. tools/call request 6. tools/call response Elicitation
  43. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Elicitation — MCP SERVER var

    elicitationTool = AsyncToolSpecification.builder() .tool(Tool.builder() .name("get_user_info") .description("Fetches user details") .build()) .callHandler((exchange, request) -> { var elicitRequest = ElicitRequest.builder() .message("Please provide your name to proceed.") .requestedSchema(Map.of( "type", "object", "properties", Map.of("name", Map.of("type", "string")), "required", List.of("name") )) .build(); // …
  44. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Elicitation — MCP SERVER //

    … // Send the request and handle the result return exchange.createElicitation(elicitRequest) .map(result -> { if (result.action() == Action.ACCEPT) { String name = (String) result.content().get("name"); return CallToolResult.builder() .addTextContent("Hello, " + name + "!") .build(); } else { return CallToolResult.builder() .addTextContent("User declined") .isError(true) .build(); } }); }) .build();
  45. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Elicitation — MCP Client Function<ElicitRequest,

    Mono<ElicitResult>> clientElicitHandler = request -> { // In a real application, this might trigger a UI form or CLI prompt System.out.println("Server is asking: " + request.message()); // Simulate user accepting and providing data return Mono.just(ElicitResult.builder() .message(ElicitResult.Action.ACCEPT) .content(Map.of("name", "John Doe")) .build()); }; // Build the client with the capability and handler McpAsyncClient client = McpClient.async(transport) .capabilities(ClientCapabilities.builder() .elicitation() // Advertise support for elicitation .build()) .elicitation(clientElicitHandler) // Register the handler .build();
  46. @EmmanuelBernard (Hexactgon) — @glaforge (Google) MCP supports • Progress reporting

    from MCP servers • Progress tracking in MCP clients for long-running operations Progress Reporting & Monitoring
  47. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Progress notification: 0.0 / 1.0

    Progress notification: 0.5 / 1.0 Progress notification: 1.0 / 1.0 Progress MCP Client MCP Server Progress updates… Tool request with progress token Tool response Operation completed Initiating request
  48. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Progress — MCP Server //

    … .callHandler((exchange, request) -> { // 1. Extract the progress token from the request metadata var progressToken = (String) request.meta().get("progressToken"); // 2. Send progress updates through the exchange return exchange.progressNotification( new ProgressNotification(progressToken, 0.0, 1.0, "Started")) .then(exchange.progressNotification( new ProgressNotification(progressToken, 0.5, 1.0, "Processing"))) .then(exchange.progressNotification( new ProgressNotification(progressToken, 1.0, 1.0, "Finished"))) .thenReturn(CallToolResult.builder() .addTextContent("Task completed successfully") .build());
  49. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Progress — MCP Client McpAsyncClient

    client = McpClient.async(transport) // Register the progress monitor .progressConsumer(notif -> Mono.fromRunnable(() -> { System.out.println( "Progress update for [" + notif.progressToken() + "]: " + notif.message() + " (" + notif.progress() + "/" + notif.total() + ")"); })) .build(); // When calling a tool, provide a progress token in the request metadata McpSchema.CallToolRequest request = McpSchema.CallToolRequest.builder() .name("long-running-task") .meta(Map.of("progressToken", "my-unique-task-id")) .build(); client.callTool(request).subscribe();
  50. @EmmanuelBernard (Hexactgon) — @glaforge (Google) MCP Support in Various Tools

    Feature Category Feature Gemini CLI Claude Code Claude Desktop OpenAI Codex VS Code GitHub Copilot OpenCode Core Server Features Tools ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full Resources ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full ❌ No Support ✅ Full (@ syntax) Prompts ✅ Slash Cmds ✅ Full ✅ Full ✅ Slash Cmds ✅ Slash Cmds ❌ No Support ✅ Slash Cmds Server Utilities Completion ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full Logging ✅ UI Footer ✅ Full ⚠ File Only ✅ Full ✅ Output Channel ✅ Full ✅ Full Pagination ❓ Unknown ❓ Unknown ❌ No UI ✅ Full ✅ Full ✅ Full ✅ Full Client Specific Elicitation ⚠ Basic ✅ Full ⚠ Chat Stream ✅ TUI Forms ✅ Input Box ✅ Full ✅ TUI Forms Sampling ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full Roots ⚠ Partial ✅ Full ✅ Strict ✅ Strict ✅ Multi-Root ✅ Full ✅ Full Base Protocol Cancellation ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full Ping ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full ✅ Full Progress ❌ Broken/Issue ✅ Full ❌ Not Planned ✅ Full ✅ Full ✅ Full ✅ Full Tasks (Exp) ❌ No Support ✅ Pipelining ⚠ Experimental ✅ Full ⚠ Experimental ❌ No Support ✅ Full
  51. @EmmanuelBernard (Hexactgon) — @glaforge (Google) MCP Feature Matrix for the

    Java ecosystem Feature Category Feature Spring Boot / Spring AI Quarkus LangChain4j ADK Micronaut Core Server Tools ✅ Native (@McpTool) ✅ Native (@Tool) N/A ✅ Native (@McpTool) ✅ Native (@Tool) Resources ✅ Native (Subscribable) ✅ Native ✅ Native (Consumption) 🛠 Manual (SDK access) ✅ Native Prompts ✅ Native ✅ Native ✅ Native (Consumption) 🛠 Manual (SDK access) ✅ Native Server Utilities Completion ✅ Native (SDK wrap) ✅ Native (@Complete) N/A 🛠 Manual (SDK access) ✅ Native (@PromptCompletion) Logging ✅ Native (context.info) ✅ Rich (Auto-Config) ✅ Native (Handler) ⛔ Unsupported 🛠 Manual (SDK) Pagination 🛠 Manual (Resources) ✅ Auto (Default 50) N/A 🛠 Config via SDK 🛠 Manual (Cursor) Client specific Elicitation ✅ Native (@McpElicitation) N/A (Server Focus) ⚠ Missing/Manual ✅ Native (Future) N/A Sampling ✅ Robust (Bidirectional) ⚠ Partial (API only) ⚠ Experimental ✅ Auto-managed ⚠ Unsupported Roots ✅ Full (Events) ⚠ Basic (Parsing) ✅ Native (Config) ⚠ Gap / Manual ⚠ Unsupported Base Protocol Cancellation ✅ Native (Reactive) ✅ Native ✅ Native ✅ Basic ✅ Native (SDK) Ping ✅ Native (context.ping) ✅ Native ✅ Native 🛠 Manual ✅ Native (SDK) Progress ✅ Native (context.progress) ✅ Native (API) ✅ Native (Callback) ⛔ N/A ✅ Native (SDK) Tasks ⚠ Gap (Use Progress) ⚠ Gap ⚠ Gap ⚠ Gap ⚠ Gap
  52. @EmmanuelBernard (Hexactgon) — @glaforge (Google) What is A2A really User

    Client Agent C# 😜 Local agents Agentic framework LLM Remote Agent (java) Local agents Agentic framework LLM A2A Client A2A Client A2A protocol A2A server Remote Agent (python) Local agents Agentic framework LLM A2A server
  53. @EmmanuelBernard (Hexactgon) — @glaforge (Google) What for Advanced apps With

    full autonomous decisions Composing capabilities Expose Silos So they work collaboratively Interoperability Cross platform Cross vendors
  54. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Discovery — Agent Card {

    "protocolVersion": "0.3.0", "name": "GeoSpatial Route Planner Agent", "description": "Provides advanced route planning ...", "url": "https://georoute-agent.example.com/a2a/v1", "preferredTransport": "JSONRPC", "version": "1.2.0", "capabilities": { "streaming": true, "pushNotifications": true }, "securitySchemes": { "google-openid": { "type": "openIdConnect", "openIdConnectUrl": "..." } }, "security": [{ "google-openid": ["openid", "profile", "email"] }], "defaultInputModes": ["application/json", "text/plain"], "defaultOutputModes": ["application/json", "image/png"], ...
  55. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Discovery — Agent Card ...

    "skills": [ { "id": "route-optimizer-traffic", "name": "Traffic-Aware Route Optimizer", "description": "Calculates the optimal driving route between ...", "tags": ["maps", "routing", "navigation", "directions", "traffic"], "examples": [ "Plan a route from '1600 Amphitheatre Parkway, Mountain View, CA' to 'San Francisco International Airport' avoiding tolls.", "{\"origin\": {\"lat\": 37.422, \"lng\": -122.084}, \"destination\": {\"lat\": 37.7749, \"lng\": -122.4194}, \"preferences\": [\"avoid_ferries\"]}" ], "inputModes": ["application/json", "text/plain"], "outputModes": ["application/json", "application/vnd.geo+json", ... ] }, ... ] }
  56. @EmmanuelBernard (Hexactgon) — @glaforge (Google) What is in a message

    Message role: user|agent messageId taskId? contextId? Part(s) Text, file, data Task status taskId contextId? Artifact[] (artifact) Message[] (history) Artifact artifactId name description Part(s) Text, file, data
  57. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Life of a task Submitted

    Input required Failed auth required Completed Cancelled (user) Rejected (server) Working Unknown
  58. @EmmanuelBernard (Hexactgon) — @glaforge (Google) A simple interaction Client Server

    Message “Request 1” Message “Answer 1” Message “Request 2” Message “Answer 2”
  59. @EmmanuelBernard (Hexactgon) — @glaforge (Google) A task interaction Client Server

    Message “request” Task submitted Task working Message “More input” Task completed Artifact Task input-required
  60. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Message or task Task Goal

    oriented Long running (including async) Parallel tasks Contextual isolation Flexibility (and its cost) Message only Task only Hybrid
  61. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Three protocols JSON-RPC 2.0 Method

    call based over HTTPS+JSON Streaming : SSE with JSON-RPC envelopes Push via webhook gRPC Method call based over HTTPS+Protobuf Streaming: server streaming RPCs Push via webhook HTTP & JSON / REST More RESTy Streaming: SSE (Server Sent Events) Push via webhook
  62. @EmmanuelBernard (Hexactgon) — @glaforge (Google) 3 communication approaches Client Server

    Message send Message “Answer” Message 2 send Message “Answer 2” Client Server Message streaming Task working Task artifact-update Artifact p2 Client Server Message push Task submitted (push ack) Task get Task input-needed Artifact Push notif Task artifact-update Artifact p1 Task completed Sync Stream Push (webhook)
  63. @EmmanuelBernard (Hexactgon) — @glaforge (Google) The demo Browser Todo Backend

    Websocket A2A Client Weather Agent A2A server Java Quarkus Weather service HTTP JSON RPC REST Movie Agent A2A server JS GenKit TMDB HTTP JSON RPC REST Java Quarkus
  64. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Diagram A2A, agents local, MCP

    User Client Agent C# 😜 Local agents Agentic framework LLM Remote Agent (java) Local agents Agentic framework LLM A2A Client A2A Client A2A protocol A2A server Remote Agent (python) Local agents Agentic framework LLM A2A server MCP tool MCP tool API and enterprise apps MCP tool MCP tool API and enterprise apps MCP tool API and enterprise apps
  65. @EmmanuelBernard (Hexactgon) — @glaforge (Google) A2A or MCP MCP Agent

    to tool • Tool ecosystem Contract based solutions • structured input/output Deterministic • Retry capabilities Claude Desktop like A2A Agent to agent • Agent ecosystem Isolated memory context Unstructured exchange Negotiation capable • More info • Changing goals mid flight
  66. @EmmanuelBernard (Hexactgon) — @glaforge (Google) A2A Summary Use cases •

    OK for simple use cases • Complex flows are still up in the air Very promising • Ecosystem of agents • Extensible • A solid spec unlike others But very fresh • Spec at 0.3 • Undefined areas • Complex flows are not nailed
  67. @EmmanuelBernard (Hexactgon) — @glaforge (Google) GitHub Links for our demos

    and samples Resources Feedback, questions, and rate this talk
  68. @EmmanuelBernard (Hexactgon) — @glaforge (Google) Les Cast Codeurs Podcast! Don’t

    forget to listen to Les Cast Codeurs podcast! And to visit Emmanuel’s new company website! Hexactgon.com