This is an automated email from the ASF dual-hosted git repository.

jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git


The following commit(s) were added to refs/heads/main by this push:
     new b4e96412b5 Add a2a extension
b4e96412b5 is described below

commit b4e96412b5a6c3caaade4ac2edca1cbbea2cac3c
Author: James Netherton <[email protected]>
AuthorDate: Fri Jul 3 12:57:41 2026 +0100

    Add a2a extension
    
    Fixes #8780
    
    Co-authored-by: Claude Opus 4.6 <[email protected]>
---
 catalog/pom.xml                                    |  13 +
 docs/modules/ROOT/examples/components/a2a.yml      |  13 +
 docs/modules/ROOT/nav.adoc                         |   1 +
 .../ROOT/pages/reference/extensions/a2a.adoc       |  61 +++
 extensions/a2a/deployment/pom.xml                  |  71 +++
 .../component/a2a/deployment/A2aProcessor.java     |  65 +++
 extensions/a2a/pom.xml                             |  39 ++
 extensions/a2a/runtime/pom.xml                     | 110 +++++
 extensions/a2a/runtime/src/main/doc/usage.adoc     |  11 +
 .../camel/quarkus/component/a2a/A2aRecorder.java   |  52 ++
 .../main/resources/META-INF/quarkus-extension.yaml |  36 ++
 extensions/pom.xml                                 |   1 +
 integration-tests/a2a/pom.xml                      | 167 +++++++
 .../quarkus/component/a2a/it/A2aResource.java      | 322 ++++++++++++
 .../camel/quarkus/component/a2a/it/A2aRoutes.java  | 151 ++++++
 .../component/a2a/it/TestExtensionHandler.java     |  38 ++
 .../a2a/src/main/resources/application.properties  |  24 +
 .../main/resources/cards/apikey-agent-card.json    |  28 ++
 .../src/main/resources/cards/emit-agent-card.json  |  14 +
 .../main/resources/cards/extension-agent-card.json |  19 +
 .../src/main/resources/cards/full-agent-card.json  |  36 ++
 .../src/main/resources/cards/oauth-agent-card.json |  27 ++
 .../src/main/resources/cards/push-agent-card.json  |  14 +
 .../main/resources/cards/streaming-agent-card.json |  14 +
 .../camel/quarkus/component/a2a/it/A2aIT.java      |  24 +
 .../component/a2a/it/A2aKeycloakTestResource.java  |  63 +++
 .../camel/quarkus/component/a2a/it/A2aTest.java    | 538 +++++++++++++++++++++
 .../a2a/src/test/resources/camel-realm.json        |  84 ++++
 integration-tests/pom.xml                          |   1 +
 poms/bom/pom.xml                                   |  15 +
 poms/bom/src/main/generated/flattened-full-pom.xml |  15 +
 .../src/main/generated/flattened-reduced-pom.xml   |  15 +
 .../generated/flattened-reduced-verbose-pom.xml    |  15 +
 tooling/scripts/test-categories.yaml               |   1 +
 34 files changed, 2098 insertions(+)

diff --git a/catalog/pom.xml b/catalog/pom.xml
index 3eac29e9ac..bbaf3e869d 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -84,6 +84,19 @@
         </dependency>
 
         <!-- The following dependencies guarantee that this module is built 
after them. You can update them by running `mvn process-resources -Pformat -N` 
from the source tree root directory -->
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-a2a</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>*</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-activemq</artifactId>
diff --git a/docs/modules/ROOT/examples/components/a2a.yml 
b/docs/modules/ROOT/examples/components/a2a.yml
new file mode 100644
index 0000000000..4ada35c7ca
--- /dev/null
+++ b/docs/modules/ROOT/examples/components/a2a.yml
@@ -0,0 +1,13 @@
+# Do not edit directly!
+# This file was generated by 
camel-quarkus-maven-plugin:update-extension-doc-page
+cqArtifactId: camel-quarkus-a2a
+cqArtifactIdBase: a2a
+cqNativeSupported: true
+cqStatus: Stable
+cqDeprecated: false
+cqJvmSince: 3.37.0
+cqNativeSince: 3.37.0
+cqCamelPartName: a2a
+cqCamelPartTitle: A2A
+cqCamelPartDescription: A2A endpoint for agent-to-agent communication.
+cqExtensionPageTitle: A2A
diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc
index 1a5629540b..1e808479ee 100644
--- a/docs/modules/ROOT/nav.adoc
+++ b/docs/modules/ROOT/nav.adoc
@@ -30,6 +30,7 @@
 * xref:reference/index.adoc[Reference]
 ** xref:reference/index.adoc[Extensions]
 // extensions: START
+*** xref:reference/extensions/a2a.adoc[A2A]
 *** xref:reference/extensions/amqp.adoc[AMQP]
 *** xref:reference/extensions/as2.adoc[AS2]
 *** xref:reference/extensions/asn1.adoc[ASN.1 File]
diff --git a/docs/modules/ROOT/pages/reference/extensions/a2a.adoc 
b/docs/modules/ROOT/pages/reference/extensions/a2a.adoc
new file mode 100644
index 0000000000..7ff4ebd1e2
--- /dev/null
+++ b/docs/modules/ROOT/pages/reference/extensions/a2a.adoc
@@ -0,0 +1,61 @@
+// Do not edit directly!
+// This file was generated by 
camel-quarkus-maven-plugin:update-extension-doc-page
+[id="extensions-a2a"]
+= A2A
+:linkattrs:
+:cq-artifact-id: camel-quarkus-a2a
+:cq-native-supported: true
+:cq-status: Preview
+:cq-status-deprecation: Preview
+:cq-description: A2A endpoint for agent-to-agent communication.
+:cq-deprecated: false
+:cq-jvm-since: 3.37.0
+:cq-native-since: 3.37.0
+
+ifeval::[{doc-show-badges} == true]
+[.badges]
+[.badge-key]##JVM since##[.badge-supported]##3.37.0## [.badge-key]##Native 
since##[.badge-supported]##3.37.0##
+endif::[]
+
+A2A endpoint for agent-to-agent communication.
+
+[id="extensions-a2a-whats-inside"]
+== What's inside
+
+* xref:{cq-camel-components}::a2a-component.adoc[A2A component], URI syntax: 
`a2a:agentCardSource`
+
+Please refer to the above link for usage and configuration details.
+
+[id="extensions-a2a-maven-coordinates"]
+== Maven coordinates
+
+https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-a2a[Create
 a new project with this extension on {link-quarkus-code-generator}, 
window="_blank"]
+
+Or add the coordinates to your existing project:
+
+[source,xml]
+----
+<dependency>
+    <groupId>org.apache.camel.quarkus</groupId>
+    <artifactId>camel-quarkus-a2a</artifactId>
+</dependency>
+----
+ifeval::[{doc-show-user-guide-link} == true]
+Check the xref:user-guide/index.adoc[User guide] for more information about 
writing Camel Quarkus applications.
+endif::[]
+
+[id="extensions-a2a-usage"]
+== Usage
+[id="extensions-a2a-usage-agent-card-json-files-in-native-mode"]
+=== Agent Card JSON files in native mode
+
+If you use JSON files to define agent cards that are loaded from the 
classpath, you must ensure they are included in the native image.
+Add the `quarkus.native.resources.includes` configuration property to 
`application.properties`. For example:
+
+[source,properties]
+----
+quarkus.native.resources.includes=cards/*.json
+----
+
+More information about selecting resources for inclusion in the native 
executable can be found at 
xref:user-guide/native-mode.adoc#embedding-resource-in-native-executable[Embedding
 resources in native executable].
+
diff --git a/extensions/a2a/deployment/pom.xml 
b/extensions/a2a/deployment/pom.xml
new file mode 100644
index 0000000000..09a1907a71
--- /dev/null
+++ b/extensions/a2a/deployment/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-a2a-parent</artifactId>
+        <version>3.37.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>camel-quarkus-a2a-deployment</artifactId>
+    <name>Camel Quarkus :: A2A :: Deployment</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-core-deployment</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-platform-http-deployment</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-jackson-deployment</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-a2a</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <annotationProcessorPaths>
+                        <path>
+                            <groupId>io.quarkus</groupId>
+                            
<artifactId>quarkus-extension-processor</artifactId>
+                            <version>${quarkus.version}</version>
+                        </path>
+                    </annotationProcessorPaths>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git 
a/extensions/a2a/deployment/src/main/java/org/apache/camel/quarkus/component/a2a/deployment/A2aProcessor.java
 
b/extensions/a2a/deployment/src/main/java/org/apache/camel/quarkus/component/a2a/deployment/A2aProcessor.java
new file mode 100644
index 0000000000..85d6c331ea
--- /dev/null
+++ 
b/extensions/a2a/deployment/src/main/java/org/apache/camel/quarkus/component/a2a/deployment/A2aProcessor.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.a2a.deployment;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.annotations.ExecutionTime;
+import io.quarkus.deployment.annotations.Record;
+import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
+import io.quarkus.deployment.builditem.FeatureBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
+import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
+import org.apache.camel.component.a2a.A2AComponent;
+import org.apache.camel.quarkus.component.a2a.A2aRecorder;
+import org.apache.camel.quarkus.core.deployment.spi.CamelRuntimeBeanBuildItem;
+import org.jboss.jandex.ClassInfo;
+import org.jboss.jandex.DotName;
+
+class A2aProcessor {
+
+    private static final String FEATURE = "camel-a2a";
+
+    @BuildStep
+    FeatureBuildItem feature() {
+        return new FeatureBuildItem(FEATURE);
+    }
+
+    @BuildStep
+    @Record(ExecutionTime.RUNTIME_INIT)
+    CamelRuntimeBeanBuildItem configureA2aComponent(A2aRecorder recorder) {
+        return new CamelRuntimeBeanBuildItem("a2a", 
A2AComponent.class.getName(),
+                recorder.createA2aComponent());
+    }
+
+    @BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
+    ReflectiveClassBuildItem 
registerModelClassesForReflection(CombinedIndexBuildItem combinedIndex) {
+        Set<String> modelClasses = combinedIndex.getIndex()
+                .getClassesInPackage("org.apache.camel.component.a2a.model")
+                .stream()
+                .map(ClassInfo::name)
+                .map(DotName::toString)
+                .collect(Collectors.toSet());
+
+        return ReflectiveClassBuildItem
+                .builder(modelClasses.toArray(new String[0]))
+                .methods(true)
+                .build();
+    }
+}
diff --git a/extensions/a2a/pom.xml b/extensions/a2a/pom.xml
new file mode 100644
index 0000000000..04cf09954c
--- /dev/null
+++ b/extensions/a2a/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-extensions</artifactId>
+        <version>3.37.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>camel-quarkus-a2a-parent</artifactId>
+    <name>Camel Quarkus :: A2A</name>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>deployment</module>
+        <module>runtime</module>
+    </modules>
+</project>
diff --git a/extensions/a2a/runtime/pom.xml b/extensions/a2a/runtime/pom.xml
new file mode 100644
index 0000000000..151dd1a4c0
--- /dev/null
+++ b/extensions/a2a/runtime/pom.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-a2a-parent</artifactId>
+        <version>3.37.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>camel-quarkus-a2a</artifactId>
+    <name>Camel Quarkus :: A2A :: Runtime</name>
+    <description>A2A endpoint for agent-to-agent communication.</description>
+
+    <properties>
+        <camel.quarkus.jvmSince>3.37.0</camel.quarkus.jvmSince>
+        <camel.quarkus.nativeSince>3.37.0</camel.quarkus.nativeSince>
+        <quarkus.metadata.status>preview</quarkus.metadata.status>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-a2a</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-platform-http</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-jackson</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>io.quarkus</groupId>
+                <artifactId>quarkus-extension-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <annotationProcessorPaths>
+                        <path>
+                            <groupId>io.quarkus</groupId>
+                            
<artifactId>quarkus-extension-processor</artifactId>
+                            <version>${quarkus.version}</version>
+                        </path>
+                    </annotationProcessorPaths>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+
+    <profiles>
+        <profile>
+            <id>full</id>
+            <activation>
+                <property>
+                    <name>!quickly</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.camel.quarkus</groupId>
+                        <artifactId>camel-quarkus-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>update-extension-doc-page</id>
+                                <goals>
+                                    <goal>update-extension-doc-page</goal>
+                                </goals>
+                                <phase>process-classes</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/extensions/a2a/runtime/src/main/doc/usage.adoc 
b/extensions/a2a/runtime/src/main/doc/usage.adoc
new file mode 100644
index 0000000000..8f74d7a9cc
--- /dev/null
+++ b/extensions/a2a/runtime/src/main/doc/usage.adoc
@@ -0,0 +1,11 @@
+=== Agent Card JSON files in native mode
+
+If you use JSON files to define agent cards that are loaded from the 
classpath, you must ensure they are included in the native image.
+Add the `quarkus.native.resources.includes` configuration property to 
`application.properties`. For example:
+
+[source,properties]
+----
+quarkus.native.resources.includes=cards/*.json
+----
+
+More information about selecting resources for inclusion in the native 
executable can be found at 
xref:user-guide/native-mode.adoc#embedding-resource-in-native-executable[Embedding
 resources in native executable].
diff --git 
a/extensions/a2a/runtime/src/main/java/org/apache/camel/quarkus/component/a2a/A2aRecorder.java
 
b/extensions/a2a/runtime/src/main/java/org/apache/camel/quarkus/component/a2a/A2aRecorder.java
new file mode 100644
index 0000000000..355b23e63c
--- /dev/null
+++ 
b/extensions/a2a/runtime/src/main/java/org/apache/camel/quarkus/component/a2a/A2aRecorder.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.a2a;
+
+import java.util.Map;
+
+import io.quarkus.runtime.RuntimeValue;
+import io.quarkus.runtime.annotations.Recorder;
+import org.apache.camel.Endpoint;
+import org.apache.camel.component.a2a.A2AComponent;
+import org.apache.camel.component.a2a.A2AConstants;
+import org.apache.camel.spi.annotations.Component;
+
+@Recorder
+public class A2aRecorder {
+
+    public RuntimeValue<A2AComponent> createA2aComponent() {
+        return new RuntimeValue<>(new CamelQuarkusA2AComponent());
+    }
+
+    @Component("a2a")
+    static final class CamelQuarkusA2AComponent extends A2AComponent {
+        @Override
+        protected Endpoint createEndpoint(String uri, String remaining, 
Map<String, Object> parameters) throws Exception {
+            Object binding = parameters.get("protocolBinding");
+            if (binding != null) {
+                String value = binding.toString();
+                if (A2AConstants.PROTOCOL_REST.equalsIgnoreCase(value)
+                        || 
A2AConstants.PROTOCOL_REST_ALIAS.equalsIgnoreCase(value)) {
+                    throw new IllegalArgumentException(
+                            "The A2A REST (HTTP+JSON) protocol binding is not 
supported on Quarkus. "
+                                    + "Use protocolBinding=JSONRPC instead.");
+                }
+            }
+            return super.createEndpoint(uri, remaining, parameters);
+        }
+    }
+}
diff --git 
a/extensions/a2a/runtime/src/main/resources/META-INF/quarkus-extension.yaml 
b/extensions/a2a/runtime/src/main/resources/META-INF/quarkus-extension.yaml
new file mode 100644
index 0000000000..fcaef15c73
--- /dev/null
+++ b/extensions/a2a/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -0,0 +1,36 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is a generated file. Do not edit directly!
+# To re-generate, run the following command from the top level directory:
+#
+#   mvn -N cq:update-quarkus-metadata
+#
+---
+name: "Camel A2A"
+description: "A2A endpoint for agent-to-agent communication"
+metadata:
+  icon-url: 
"https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg";
+  sponsor: "Apache Software Foundation"
+  guide: 
"https://camel.apache.org/camel-quarkus/latest/reference/extensions/a2a.html";
+  categories:
+  - "integration"
+  status: "preview"
+  integrates:
+    - name: "Camel"
+      artifact: "org.apache.camel:camel-base"
+      version: "${camel.version}"
\ No newline at end of file
diff --git a/extensions/pom.xml b/extensions/pom.xml
index 58a1390b6b..76282ca973 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -34,6 +34,7 @@
 
     <modules>
         <!-- extensions a..z; do not remove this comment, it is important when 
sorting via  mvn process-resources -Pformat -->
+        <module>a2a</module>
         <module>activemq</module>
         <module>activemq6</module>
         <module>amqp</module>
diff --git a/integration-tests/a2a/pom.xml b/integration-tests/a2a/pom.xml
new file mode 100644
index 0000000000..b4e6e5894a
--- /dev/null
+++ b/integration-tests/a2a/pom.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-build-parent-it</artifactId>
+        <version>3.37.0-SNAPSHOT</version>
+        <relativePath>../../poms/build-parent-it/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>camel-quarkus-integration-test-a2a</artifactId>
+    <name>Camel Quarkus :: Integration Tests :: A2A</name>
+    <description>Integration tests for Camel Quarkus A2A 
extension</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-a2a</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-direct</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-oauth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-resteasy</artifactId>
+        </dependency>
+
+        <!-- test dependencies -->
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.rest-assured</groupId>
+            <artifactId>rest-assured</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-test-keycloak-server</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>testcontainers</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>native</id>
+            <activation>
+                <property>
+                    <name>native</name>
+                </property>
+            </activation>
+            <properties>
+                <quarkus.native.enabled>true</quarkus.native.enabled>
+            </properties>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-failsafe-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>integration-test</goal>
+                                    <goal>verify</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>virtualDependencies</id>
+            <activation>
+                <property>
+                    <name>!noVirtualDependencies</name>
+                </property>
+            </activation>
+            <dependencies>
+                <!-- The following dependencies guarantee that this module is 
built after them. You can update them by running `mvn process-resources 
-Pformat -N` from the source tree root directory -->
+                <dependency>
+                    <groupId>org.apache.camel.quarkus</groupId>
+                    <artifactId>camel-quarkus-a2a-deployment</artifactId>
+                    <version>${project.version}</version>
+                    <type>pom</type>
+                    <scope>test</scope>
+                    <exclusions>
+                        <exclusion>
+                            <groupId>*</groupId>
+                            <artifactId>*</artifactId>
+                        </exclusion>
+                    </exclusions>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.camel.quarkus</groupId>
+                    <artifactId>camel-quarkus-oauth-deployment</artifactId>
+                    <version>${project.version}</version>
+                    <type>pom</type>
+                    <scope>test</scope>
+                    <exclusions>
+                        <exclusion>
+                            <groupId>*</groupId>
+                            <artifactId>*</artifactId>
+                        </exclusion>
+                    </exclusions>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.camel.quarkus</groupId>
+                    <artifactId>camel-quarkus-direct-deployment</artifactId>
+                    <version>${project.version}</version>
+                    <type>pom</type>
+                    <scope>test</scope>
+                    <exclusions>
+                        <exclusion>
+                            <groupId>*</groupId>
+                            <artifactId>*</artifactId>
+                        </exclusion>
+                    </exclusions>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>skip-testcontainers-tests</id>
+            <activation>
+                <property>
+                    <name>skip-testcontainers-tests</name>
+                </property>
+            </activation>
+            <properties>
+                <skipTests>true</skipTests>
+            </properties>
+        </profile>
+    </profiles>
+
+</project>
diff --git 
a/integration-tests/a2a/src/main/java/org/apache/camel/quarkus/component/a2a/it/A2aResource.java
 
b/integration-tests/a2a/src/main/java/org/apache/camel/quarkus/component/a2a/it/A2aResource.java
new file mode 100644
index 0000000000..3bc3de190b
--- /dev/null
+++ 
b/integration-tests/a2a/src/main/java/org/apache/camel/quarkus/component/a2a/it/A2aResource.java
@@ -0,0 +1,322 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.a2a.it;
+
+import java.util.Iterator;
+import java.util.List;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.MediaType;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.a2a.A2AConstants;
+import org.apache.camel.component.a2a.model.StreamResponse;
+import org.apache.camel.component.a2a.model.Task;
+import org.apache.camel.component.a2a.model.TaskPushNotificationConfig;
+import org.apache.camel.component.a2a.model.TextPart;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+
+@Path("/a2a")
+@ApplicationScoped
+public class A2aResource {
+
+    @Inject
+    CamelContext camelContext;
+
+    @Inject
+    ProducerTemplate producerTemplate;
+
+    @ConfigProperty(name = "quarkus.http.test-port", defaultValue = "8081")
+    int httpPort;
+
+    @Path("/send")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.APPLICATION_JSON)
+    public String sendMessage(String message) {
+        Exchange result = producerTemplate.request("direct:send-message", 
exchange -> {
+            exchange.getMessage().setBody(message);
+            exchange.getMessage().setHeader("CamelA2APort", httpPort);
+        });
+        Task task = result.getMessage().getBody(Task.class);
+        return 
String.format("{\"taskId\":\"%s\",\"contextId\":\"%s\",\"state\":\"%s\"}",
+                task.id(), task.contextId(), task.status().state().name());
+    }
+
+    @Path("/send-payload")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String sendMessagePayload(String message) {
+        Exchange result = 
producerTemplate.request("direct:send-message-payload", exchange -> {
+            exchange.getMessage().setBody(message);
+            exchange.getMessage().setHeader("CamelA2APort", httpPort);
+        });
+        return result.getMessage().getBody(String.class);
+    }
+
+    @Path("/send-raw")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String sendMessageRaw(String message) {
+        Exchange result = producerTemplate.request("direct:send-message-raw", 
exchange -> {
+            exchange.getMessage().setBody(message);
+            exchange.getMessage().setHeader("CamelA2APort", httpPort);
+        });
+        return result.getMessage().getBody(String.class);
+    }
+
+    @Path("/get-task")
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public String getTask(@QueryParam("taskId") String taskId) {
+        Exchange result = producerTemplate.request("direct:get-task", exchange 
-> {
+            exchange.getMessage().setHeader(A2AConstants.TASK_ID, taskId);
+            exchange.getMessage().setHeader("CamelA2APort", httpPort);
+        });
+        if (result.getException() != null) {
+            return String.format("{\"error\":\"%s\"}", 
result.getException().getMessage());
+        }
+        Task task = result.getMessage().getBody(Task.class);
+        return String.format("{\"taskId\":\"%s\",\"state\":\"%s\"}",
+                task.id(), task.status().state().name());
+    }
+
+    @Path("/cancel-task")
+    @POST
+    @Produces(MediaType.APPLICATION_JSON)
+    public String cancelTask(@QueryParam("taskId") String taskId) {
+        Exchange result = producerTemplate.request("direct:cancel-task", 
exchange -> {
+            exchange.getMessage().setHeader(A2AConstants.TASK_ID, taskId);
+            exchange.getMessage().setHeader("CamelA2APort", httpPort);
+        });
+        if (result.getException() != null) {
+            return String.format("{\"error\":\"%s\"}", 
result.getException().getMessage());
+        }
+        Task task = result.getMessage().getBody(Task.class);
+        return String.format("{\"taskId\":\"%s\",\"state\":\"%s\"}",
+                task.id(), task.status().state().name());
+    }
+
+    @Path("/create-rest-endpoint")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public String createRestEndpoint() {
+        try {
+            
camelContext.getEndpoint("a2a:test?protocolBinding=REST&validateAuth=false");
+            return "unexpected-success";
+        } catch (Exception e) {
+            Throwable cause = e;
+            while (cause.getCause() != null) {
+                cause = cause.getCause();
+            }
+            return cause.getMessage();
+        }
+    }
+
+    @Path("/send-stream")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.APPLICATION_JSON)
+    public String sendMessageStream(String message) {
+        Exchange result = 
producerTemplate.request("direct:send-message-stream", exchange -> {
+            exchange.getMessage().setBody(message);
+            exchange.getMessage().setHeader("CamelA2APort", httpPort);
+        });
+        if (result.getException() != null) {
+            return String.format("{\"error\":\"%s\"}", 
result.getException().getMessage());
+        }
+        Iterator<StreamResponse> events = 
result.getMessage().getBody(Iterator.class);
+        int statusUpdates = 0;
+        int artifactUpdates = 0;
+        while (events.hasNext()) {
+            StreamResponse event = events.next();
+            if (event.getStatusUpdate() != null) {
+                statusUpdates++;
+            }
+            if (event.getArtifactUpdate() != null) {
+                artifactUpdates++;
+            }
+        }
+        return String.format("{\"statusUpdates\":%d,\"artifactUpdates\":%d}", 
statusUpdates, artifactUpdates);
+    }
+
+    @Path("/list-tasks")
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @SuppressWarnings("unchecked")
+    public String listTasks(@QueryParam("contextId") String contextId) {
+        Exchange result = producerTemplate.request("direct:list-tasks", 
exchange -> {
+            if (contextId != null) {
+                exchange.getMessage().setHeader(A2AConstants.LIST_CONTEXT_ID, 
contextId);
+            }
+            exchange.getMessage().setHeader("CamelA2APort", httpPort);
+        });
+        if (result.getException() != null) {
+            return String.format("{\"error\":\"%s\"}", 
result.getException().getMessage());
+        }
+        Object body = result.getMessage().getBody();
+        if (body instanceof List) {
+            return String.format("{\"count\":%d}", ((List<Task>) body).size());
+        }
+        return "{\"count\":0}";
+    }
+
+    @Path("/send-context")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.APPLICATION_JSON)
+    public String sendMessageWithContext(String message, 
@QueryParam("contextId") String contextId) {
+        Exchange result = producerTemplate.request("direct:send-message", 
exchange -> {
+            exchange.getMessage().setBody(message);
+            exchange.getMessage().setHeader("CamelA2APort", httpPort);
+            if (contextId != null) {
+                exchange.getMessage().setHeader(A2AConstants.CONTEXT_ID, 
contextId);
+            }
+        });
+        if (result.getException() != null) {
+            return String.format("{\"error\":\"%s\"}", 
result.getException().getMessage());
+        }
+        Task task = result.getMessage().getBody(Task.class);
+        return 
String.format("{\"taskId\":\"%s\",\"contextId\":\"%s\",\"state\":\"%s\"}",
+                task.id(), task.contextId(), task.status().state().name());
+    }
+
+    @Path("/send-pojo")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.APPLICATION_JSON)
+    public String sendToPojo(String message) {
+        Exchange result = producerTemplate.request("direct:send-to-pojo", 
exchange -> {
+            exchange.getMessage().setBody(message);
+            exchange.getMessage().setHeader("CamelA2APort", httpPort);
+        });
+        if (result.getException() != null) {
+            return String.format("{\"error\":\"%s\"}", 
result.getException().getMessage());
+        }
+        Task task = result.getMessage().getBody(Task.class);
+        String latestText = "";
+        if (task.latest() != null && task.latest().parts() != null) {
+            for (Object part : task.latest().parts()) {
+                if (part instanceof TextPart tp) {
+                    latestText = tp.text();
+                    break;
+                }
+            }
+        }
+        return 
String.format("{\"taskId\":\"%s\",\"state\":\"%s\",\"response\":\"%s\"}",
+                task.id(), task.status().state().name(), latestText);
+    }
+
+    @Path("/send-to-push")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.APPLICATION_JSON)
+    public String sendToPush(String message) {
+        Exchange result = producerTemplate.request("direct:send-to-push", 
exchange -> {
+            exchange.getMessage().setBody(message);
+            exchange.getMessage().setHeader("CamelA2APort", httpPort);
+        });
+        if (result.getException() != null) {
+            return String.format("{\"error\":\"%s\"}", 
result.getException().getMessage());
+        }
+        Task task = result.getMessage().getBody(Task.class);
+        return 
String.format("{\"taskId\":\"%s\",\"contextId\":\"%s\",\"state\":\"%s\"}",
+                task.id(), task.contextId(), task.status().state().name());
+    }
+
+    @Path("/push-config/create")
+    @POST
+    @Produces(MediaType.APPLICATION_JSON)
+    public String createPushConfig(@QueryParam("taskId") String taskId, 
@QueryParam("url") String url) {
+        Exchange result = 
producerTemplate.request("direct:push-config-create", exchange -> {
+            exchange.getMessage().setHeader(A2AConstants.TASK_ID, taskId);
+            exchange.getMessage().setHeader("CamelA2APort", httpPort);
+            TaskPushNotificationConfig config = new 
TaskPushNotificationConfig();
+            config.setTaskId(taskId);
+            config.setUrl(url);
+            exchange.getMessage().setBody(config);
+        });
+        if (result.getException() != null) {
+            return String.format("{\"error\":\"%s\"}", 
result.getException().getMessage());
+        }
+        TaskPushNotificationConfig config = 
result.getMessage().getBody(TaskPushNotificationConfig.class);
+        return 
String.format("{\"id\":\"%s\",\"taskId\":\"%s\",\"url\":\"%s\"}",
+                config.getId(), config.getTaskId(), config.getUrl());
+    }
+
+    @Path("/push-config/get")
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public String getPushConfig(@QueryParam("taskId") String taskId, 
@QueryParam("configId") String configId) {
+        Exchange result = producerTemplate.request("direct:push-config-get", 
exchange -> {
+            exchange.getMessage().setHeader(A2AConstants.TASK_ID, taskId);
+            exchange.getMessage().setHeader(A2AConstants.PUSH_CONFIG_ID, 
configId);
+            exchange.getMessage().setHeader("CamelA2APort", httpPort);
+        });
+        if (result.getException() != null) {
+            return String.format("{\"error\":\"%s\"}", 
result.getException().getMessage());
+        }
+        TaskPushNotificationConfig config = 
result.getMessage().getBody(TaskPushNotificationConfig.class);
+        return 
String.format("{\"id\":\"%s\",\"taskId\":\"%s\",\"url\":\"%s\"}",
+                config.getId(), config.getTaskId(), config.getUrl());
+    }
+
+    @Path("/push-config/list")
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @SuppressWarnings("unchecked")
+    public String getPushConfigCount(@QueryParam("taskId") String taskId) {
+        Exchange result = producerTemplate.request("direct:push-config-list", 
exchange -> {
+            exchange.getMessage().setHeader(A2AConstants.TASK_ID, taskId);
+            exchange.getMessage().setHeader("CamelA2APort", httpPort);
+        });
+        if (result.getException() != null) {
+            return String.format("{\"error\":\"%s\"}", 
result.getException().getMessage());
+        }
+        Object body = result.getMessage().getBody();
+        if (body instanceof List) {
+            return String.format("{\"count\":%d}", 
((List<TaskPushNotificationConfig>) body).size());
+        }
+        return "{\"count\":0}";
+    }
+
+    @Path("/push-config/delete")
+    @DELETE
+    @Produces(MediaType.APPLICATION_JSON)
+    public String deletePushConfig(@QueryParam("taskId") String taskId, 
@QueryParam("configId") String configId) {
+        Exchange result = 
producerTemplate.request("direct:push-config-delete", exchange -> {
+            exchange.getMessage().setHeader(A2AConstants.TASK_ID, taskId);
+            exchange.getMessage().setHeader(A2AConstants.PUSH_CONFIG_ID, 
configId);
+            exchange.getMessage().setHeader("CamelA2APort", httpPort);
+        });
+        if (result.getException() != null) {
+            return String.format("{\"error\":\"%s\"}", 
result.getException().getMessage());
+        }
+        return "{\"deleted\":true}";
+    }
+}
diff --git 
a/integration-tests/a2a/src/main/java/org/apache/camel/quarkus/component/a2a/it/A2aRoutes.java
 
b/integration-tests/a2a/src/main/java/org/apache/camel/quarkus/component/a2a/it/A2aRoutes.java
new file mode 100644
index 0000000000..62f2e13da4
--- /dev/null
+++ 
b/integration-tests/a2a/src/main/java/org/apache/camel/quarkus/component/a2a/it/A2aRoutes.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.a2a.it;
+
+import java.util.List;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.a2a.A2AConstants;
+import org.apache.camel.component.a2a.A2AProgress;
+import org.apache.camel.component.a2a.model.Artifact;
+import org.apache.camel.component.a2a.model.Message;
+import org.apache.camel.component.a2a.model.TextPart;
+
+@ApplicationScoped
+public class A2aRoutes extends RouteBuilder {
+
+    @Override
+    public void configure() throws Exception {
+        // Consumer: expose an A2A agent using JSON-RPC binding (recommended 
for platform-http)
+        from("a2a:test-agent?name=Test Agent&description=A Quarkus test 
agent&version=1.0.0"
+                + "&protocolBinding=JSONRPC&validateAuth=false")
+                .setBody(simple("Echo: ${body}"));
+
+        // Producer routes that call the local consumer agent
+        from("direct:send-message")
+                .toD("a2a:http://localhost:${header.CamelA2APort}";
+                        + "?protocolBinding=JSONRPC&dataFormat=POJO");
+
+        from("direct:send-message-payload")
+                .toD("a2a:http://localhost:${header.CamelA2APort}";
+                        + "?protocolBinding=JSONRPC&dataFormat=PAYLOAD");
+
+        from("direct:send-message-raw")
+                .toD("a2a:http://localhost:${header.CamelA2APort}";
+                        + "?protocolBinding=JSONRPC&dataFormat=RAW");
+
+        from("direct:get-task")
+                .setHeader(A2AConstants.OPERATION, constant("TASK_GET"))
+                .toD("a2a:http://localhost:${header.CamelA2APort}";
+                        + "?protocolBinding=JSONRPC&dataFormat=POJO");
+
+        from("direct:cancel-task")
+                .setHeader(A2AConstants.OPERATION, constant("TASK_CANCEL"))
+                .toD("a2a:http://localhost:${header.CamelA2APort}";
+                        + "?protocolBinding=JSONRPC&dataFormat=POJO");
+
+        // Streaming consumer: emits SSE progress events and an artifact 
(separate basePath to avoid route collision)
+        
from("a2a:classpath:cards/streaming-agent-card.json?protocolBinding=JSONRPC&validateAuth=false&basePath=/streaming")
+                .process(exchange -> {
+                    A2AProgress.emit(exchange, "Step 1 complete");
+                    A2AProgress.emit(exchange, "Step 2 complete");
+                    Artifact artifact = Artifact.builder()
+                            .artifactId("art-1")
+                            .name("test-artifact")
+                            .parts(List.of(new TextPart("artifact content")))
+                            .build();
+                    A2AProgress.emitArtifact(exchange, artifact, false, true);
+                })
+                .setBody(constant("Streaming done"));
+
+        // Push notification consumer: enables push config CRUD testing
+        
from("a2a:classpath:cards/push-agent-card.json?protocolBinding=JSONRPC&validateAuth=false"
+                + "&basePath=/push&allowLocalWebhookUrls=true")
+                .setBody(simple("Push Echo: ${body}"));
+
+        // Full-feature consumer: rich agent card with all fields for 
serialization testing
+        
from("a2a:classpath:cards/full-agent-card.json?protocolBinding=JSONRPC&validateAuth=false&basePath=/full")
+                .setBody(simple("Full Echo: ${body}"));
+
+        // POJO data format consumer: receives Message object body
+        from("a2a:pojo-agent?name=POJO Agent&description=POJO data format 
test&version=1.0.0"
+                + 
"&protocolBinding=JSONRPC&validateAuth=false&basePath=/pojo&dataFormat=POJO")
+                .process(exchange -> {
+                    Message msg = exchange.getMessage().getBody(Message.class);
+                    exchange.getMessage().setBody(
+                            String.format("role=%s,parts=%d", 
msg.role().getValue(), msg.parts().size()));
+                });
+
+        // Streaming consumer using ${a2a:emit()} Simple language function
+        
from("a2a:classpath:cards/emit-agent-card.json?protocolBinding=JSONRPC&validateAuth=false&basePath=/emit")
+                .script(simple("${a2a:emit('Simple emit step 1')}"))
+                .script(simple("${a2a:emit('Simple emit step 2')}"))
+                .setBody(constant("Emit done"));
+
+        // API key authenticated consumer
+        
from("a2a:classpath:cards/apikey-agent-card.json?protocolBinding=JSONRPC"
+                + 
"&basePath=/apikey&apiKey=test-secret-key&apiKeyHeader=X-API-Key")
+                .setBody(simple("Authenticated: ${body}"));
+
+        // OAuth authenticated consumer
+        
from("a2a:classpath:cards/oauth-agent-card.json?protocolBinding=JSONRPC&basePath=/oauth&oauthProfile=a2a-test")
+                .setBody(simple("OAuth: ${body}"));
+
+        // Extension-aware consumer
+        
from("a2a:classpath:cards/extension-agent-card.json?protocolBinding=JSONRPC&validateAuth=false&basePath=/ext")
+                .setBody(simple("Extension: ${header.X-Extension-Tracking} 
${body}"));
+
+        from("direct:list-tasks")
+                .setHeader(A2AConstants.OPERATION, constant("TASK_LIST"))
+                .toD("a2a:http://localhost:${header.CamelA2APort}";
+                        + "?protocolBinding=JSONRPC&dataFormat=POJO");
+
+        from("direct:send-to-push")
+                .toD("a2a:http://localhost:${header.CamelA2APort}/push";
+                        + "?protocolBinding=JSONRPC&dataFormat=POJO");
+
+        from("direct:send-to-pojo")
+                .toD("a2a:http://localhost:${header.CamelA2APort}/pojo";
+                        + "?protocolBinding=JSONRPC&dataFormat=POJO");
+
+        from("direct:push-config-create")
+                .setHeader(A2AConstants.OPERATION, 
constant("PUSH_CONFIG_CREATE"))
+                .toD("a2a:http://localhost:${header.CamelA2APort}/push";
+                        + "?protocolBinding=JSONRPC&dataFormat=POJO");
+
+        from("direct:push-config-get")
+                .setHeader(A2AConstants.OPERATION, constant("PUSH_CONFIG_GET"))
+                .toD("a2a:http://localhost:${header.CamelA2APort}/push";
+                        + "?protocolBinding=JSONRPC&dataFormat=POJO");
+
+        from("direct:push-config-list")
+                .setHeader(A2AConstants.OPERATION, 
constant("PUSH_CONFIG_LIST"))
+                .toD("a2a:http://localhost:${header.CamelA2APort}/push";
+                        + "?protocolBinding=JSONRPC&dataFormat=POJO");
+
+        from("direct:push-config-delete")
+                .setHeader(A2AConstants.OPERATION, 
constant("PUSH_CONFIG_DELETE"))
+                .toD("a2a:http://localhost:${header.CamelA2APort}/push";
+                        + "?protocolBinding=JSONRPC&dataFormat=POJO");
+
+        from("direct:send-message-stream")
+                .setHeader(A2AConstants.OPERATION, constant("MESSAGE_STREAM"))
+                .toD("a2a:http://localhost:${header.CamelA2APort}/streaming";
+                        + "?protocolBinding=JSONRPC&dataFormat=POJO");
+    }
+}
diff --git 
a/integration-tests/a2a/src/main/java/org/apache/camel/quarkus/component/a2a/it/TestExtensionHandler.java
 
b/integration-tests/a2a/src/main/java/org/apache/camel/quarkus/component/a2a/it/TestExtensionHandler.java
new file mode 100644
index 0000000000..91c518e3db
--- /dev/null
+++ 
b/integration-tests/a2a/src/main/java/org/apache/camel/quarkus/component/a2a/it/TestExtensionHandler.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.a2a.it;
+
+import io.smallrye.common.annotation.Identifier;
+import jakarta.enterprise.context.ApplicationScoped;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.a2a.extension.A2AExtensionHandler;
+import org.apache.camel.component.a2a.model.AgentExtension;
+
+@ApplicationScoped
+@Identifier("testTrackingExtension")
+public class TestExtensionHandler implements A2AExtensionHandler {
+
+    @Override
+    public String extensionUri() {
+        return "urn:test:tracking";
+    }
+
+    @Override
+    public void beforeRoute(Exchange exchange, AgentExtension extension) 
throws Exception {
+        exchange.getMessage().setHeader("X-Extension-Tracking", "active");
+    }
+}
diff --git a/integration-tests/a2a/src/main/resources/application.properties 
b/integration-tests/a2a/src/main/resources/application.properties
new file mode 100644
index 0000000000..975c00a35e
--- /dev/null
+++ b/integration-tests/a2a/src/main/resources/application.properties
@@ -0,0 +1,24 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+quarkus.native.resources.includes=cards/*.json
+
+camel.oauth.a2a-test.base-uri=${cq.a2a.test.keycloak.url}
+camel.oauth.a2a-test.client-id=camel-client
+camel.oauth.a2a-test.client-secret=camel-client-secret
+camel.oauth.a2a-test.allow-insecure-http=true
+camel.oauth.a2a-test.allow-missing-audience=true
diff --git 
a/integration-tests/a2a/src/main/resources/cards/apikey-agent-card.json 
b/integration-tests/a2a/src/main/resources/cards/apikey-agent-card.json
new file mode 100644
index 0000000000..49253ea3ec
--- /dev/null
+++ b/integration-tests/a2a/src/main/resources/cards/apikey-agent-card.json
@@ -0,0 +1,28 @@
+{
+  "name": "API Key Agent",
+  "description": "A test agent with API key authentication",
+  "version": "1.0.0",
+  "securitySchemes": {
+    "apikey": {
+      "apiKeySecurityScheme": {
+        "location": "header",
+        "name": "X-API-Key"
+      }
+    }
+  },
+  "securityRequirements": [
+    {
+      "schemes": {
+        "apikey": {
+          "list": []
+        }
+      }
+    }
+  ],
+  "supportedInterfaces": [
+    {
+      "url": "http://localhost:8080";,
+      "protocolBinding": "JSONRPC"
+    }
+  ]
+}
diff --git 
a/integration-tests/a2a/src/main/resources/cards/emit-agent-card.json 
b/integration-tests/a2a/src/main/resources/cards/emit-agent-card.json
new file mode 100644
index 0000000000..98fd8985b2
--- /dev/null
+++ b/integration-tests/a2a/src/main/resources/cards/emit-agent-card.json
@@ -0,0 +1,14 @@
+{
+  "name": "Emit Test Agent",
+  "description": "A test agent using a2a:emit Simple language function",
+  "version": "1.0.0",
+  "capabilities": {
+    "streaming": true
+  },
+  "supportedInterfaces": [
+    {
+      "url": "http://localhost:8080";,
+      "protocolBinding": "JSONRPC"
+    }
+  ]
+}
diff --git 
a/integration-tests/a2a/src/main/resources/cards/extension-agent-card.json 
b/integration-tests/a2a/src/main/resources/cards/extension-agent-card.json
new file mode 100644
index 0000000000..f262e86b39
--- /dev/null
+++ b/integration-tests/a2a/src/main/resources/cards/extension-agent-card.json
@@ -0,0 +1,19 @@
+{
+  "name": "Extension Test Agent",
+  "description": "A test agent with A2A protocol extensions",
+  "version": "1.0.0",
+  "capabilities": {
+    "extensions": [
+      {
+        "uri": "urn:test:tracking",
+        "description": "Test tracking extension"
+      }
+    ]
+  },
+  "supportedInterfaces": [
+    {
+      "url": "http://localhost:8080";,
+      "protocolBinding": "JSONRPC"
+    }
+  ]
+}
diff --git 
a/integration-tests/a2a/src/main/resources/cards/full-agent-card.json 
b/integration-tests/a2a/src/main/resources/cards/full-agent-card.json
new file mode 100644
index 0000000000..78e0a67c54
--- /dev/null
+++ b/integration-tests/a2a/src/main/resources/cards/full-agent-card.json
@@ -0,0 +1,36 @@
+{
+  "name": "Full Feature Agent",
+  "description": "A Quarkus test agent with all features",
+  "version": "2.0.0",
+  "provider": {
+    "name": "Test Provider",
+    "url": "https://example.com/provider";
+  },
+  "capabilities": {
+    "streaming": true,
+    "pushNotifications": true
+  },
+  "skills": [
+    {
+      "id": "echo",
+      "name": "Echo Skill",
+      "description": "Echoes back the input message",
+      "tags": ["test", "echo"],
+      "inputModes": ["text/plain", "application/json"],
+      "outputModes": ["text/plain"]
+    },
+    {
+      "id": "transform",
+      "name": "Transform Skill",
+      "description": "Transforms input data"
+    }
+  ],
+  "supportedInterfaces": [
+    {
+      "url": "http://localhost:8080";,
+      "protocolBinding": "JSONRPC"
+    }
+  ],
+  "defaultInputModes": ["text/plain"],
+  "defaultOutputModes": ["text/plain"]
+}
diff --git 
a/integration-tests/a2a/src/main/resources/cards/oauth-agent-card.json 
b/integration-tests/a2a/src/main/resources/cards/oauth-agent-card.json
new file mode 100644
index 0000000000..1f7ee109d1
--- /dev/null
+++ b/integration-tests/a2a/src/main/resources/cards/oauth-agent-card.json
@@ -0,0 +1,27 @@
+{
+  "name": "OAuth Agent",
+  "description": "A test agent with OAuth2 authentication",
+  "version": "1.0.0",
+  "securitySchemes": {
+    "oauth2": {
+      "openIdConnectSecurityScheme": {
+        "openIdConnectUrl": 
"http://placeholder/.well-known/openid-configuration";
+      }
+    }
+  },
+  "securityRequirements": [
+    {
+      "schemes": {
+        "oauth2": {
+          "list": []
+        }
+      }
+    }
+  ],
+  "supportedInterfaces": [
+    {
+      "url": "http://localhost:8080";,
+      "protocolBinding": "JSONRPC"
+    }
+  ]
+}
diff --git 
a/integration-tests/a2a/src/main/resources/cards/push-agent-card.json 
b/integration-tests/a2a/src/main/resources/cards/push-agent-card.json
new file mode 100644
index 0000000000..41bfc307be
--- /dev/null
+++ b/integration-tests/a2a/src/main/resources/cards/push-agent-card.json
@@ -0,0 +1,14 @@
+{
+  "name": "Push Test Agent",
+  "description": "A Quarkus test agent with push notification support",
+  "version": "1.0.0",
+  "capabilities": {
+    "pushNotifications": true
+  },
+  "supportedInterfaces": [
+    {
+      "url": "http://localhost:8080";,
+      "protocolBinding": "JSONRPC"
+    }
+  ]
+}
diff --git 
a/integration-tests/a2a/src/main/resources/cards/streaming-agent-card.json 
b/integration-tests/a2a/src/main/resources/cards/streaming-agent-card.json
new file mode 100644
index 0000000000..4d44c8b2eb
--- /dev/null
+++ b/integration-tests/a2a/src/main/resources/cards/streaming-agent-card.json
@@ -0,0 +1,14 @@
+{
+  "name": "Streaming Test Agent",
+  "description": "A Quarkus test agent with streaming support",
+  "version": "1.0.0",
+  "capabilities": {
+    "streaming": true
+  },
+  "supportedInterfaces": [
+    {
+      "url": "http://localhost:8081/streaming";,
+      "protocolBinding": "JSONRPC"
+    }
+  ]
+}
diff --git 
a/integration-tests/a2a/src/test/java/org/apache/camel/quarkus/component/a2a/it/A2aIT.java
 
b/integration-tests/a2a/src/test/java/org/apache/camel/quarkus/component/a2a/it/A2aIT.java
new file mode 100644
index 0000000000..716c749b03
--- /dev/null
+++ 
b/integration-tests/a2a/src/test/java/org/apache/camel/quarkus/component/a2a/it/A2aIT.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.a2a.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+class A2aIT extends A2aTest {
+
+}
diff --git 
a/integration-tests/a2a/src/test/java/org/apache/camel/quarkus/component/a2a/it/A2aKeycloakTestResource.java
 
b/integration-tests/a2a/src/test/java/org/apache/camel/quarkus/component/a2a/it/A2aKeycloakTestResource.java
new file mode 100644
index 0000000000..783d84734f
--- /dev/null
+++ 
b/integration-tests/a2a/src/test/java/org/apache/camel/quarkus/component/a2a/it/A2aKeycloakTestResource.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.a2a.it;
+
+import java.time.Duration;
+import java.util.Collections;
+import java.util.Map;
+
+import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
+import io.quarkus.test.keycloak.server.KeycloakContainer;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
+import org.testcontainers.utility.MountableFile;
+
+public class A2aKeycloakTestResource implements 
QuarkusTestResourceLifecycleManager {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(A2aKeycloakTestResource.class);
+    private static final String REALM_NAME = "camel";
+
+    private KeycloakContainer keycloak;
+
+    @Override
+    public Map<String, String> start() {
+        System.setProperty("keycloak.docker.image",
+                
ConfigProvider.getConfig().getValue("keycloak.container.image", String.class));
+
+        keycloak = new KeycloakContainer()
+                .withStartupTimeout(Duration.ofMinutes(5))
+                .withLogConsumer(new Slf4jLogConsumer(LOG))
+                .withCopyFileToContainer(
+                        
MountableFile.forClasspathResource("/camel-realm.json"),
+                        "/opt/keycloak/data/import/camel-realm.json")
+                .withCommand("start", "--import-realm", "--verbose");
+
+        keycloak.start();
+
+        return Collections.singletonMap("cq.a2a.test.keycloak.url",
+                keycloak.getServerUrl() + "/realms/" + REALM_NAME);
+    }
+
+    @Override
+    public void stop() {
+        if (keycloak != null) {
+            keycloak.stop();
+        }
+    }
+}
diff --git 
a/integration-tests/a2a/src/test/java/org/apache/camel/quarkus/component/a2a/it/A2aTest.java
 
b/integration-tests/a2a/src/test/java/org/apache/camel/quarkus/component/a2a/it/A2aTest.java
new file mode 100644
index 0000000000..3cae2712c6
--- /dev/null
+++ 
b/integration-tests/a2a/src/test/java/org/apache/camel/quarkus/component/a2a/it/A2aTest.java
@@ -0,0 +1,538 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.a2a.it;
+
+import io.quarkus.test.common.QuarkusTestResource;
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+import org.apache.camel.component.a2a.A2AConstants;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@QuarkusTest
+@QuarkusTestResource(A2aKeycloakTestResource.class)
+class A2aTest {
+
+    @Test
+    void agentCardServed() {
+        RestAssured.get("/.well-known/agent-card.json")
+                .then()
+                .statusCode(200)
+                .body(
+                        "name", is("Test Agent"),
+                        "version", is("1.0.0"),
+                        "description", is("A Quarkus test agent"));
+    }
+
+    @Test
+    void sendMessageJsonRpc() {
+        RestAssured.given()
+                .contentType("application/json")
+                .body(jsonRpcSendMessage("msg-1", "req-1", "{\"text\":\"Hello 
A2A\"}"))
+                .post("/")
+                .then()
+                .statusCode(200)
+                .body(
+                        "jsonrpc", is("2.0"),
+                        "result.task.id", notNullValue(),
+                        "result.task.contextId", notNullValue(),
+                        "id", is("req-1"));
+    }
+
+    @Test
+    void producerSendMessagePojo() {
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("Hello from producer")
+                .post("/a2a/send")
+                .then()
+                .statusCode(200)
+                .body(
+                        "taskId", notNullValue(),
+                        "contextId", notNullValue(),
+                        "state", is("COMPLETED"));
+    }
+
+    @Test
+    void producerSendMessagePayloadDataFormat() {
+        String response = RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("Hello payload")
+                .post("/a2a/send-payload")
+                .then()
+                .statusCode(200)
+                .extract().asString();
+
+        assertTrue(
+                response.contains("Echo:"),
+                "Expected PAYLOAD response to contain echoed text, got: " + 
response);
+    }
+
+    @Test
+    void producerSendMessageRawDataFormat() {
+        String response = RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("Hello raw")
+                .post("/a2a/send-raw")
+                .then()
+                .statusCode(200)
+                .extract().asString();
+
+        assertTrue(
+                response.contains("\"task\"") || 
response.contains("\"result\""),
+                "Expected RAW response to contain JSON structure, got: " + 
response);
+    }
+
+    @Test
+    void producerGetTask() {
+        String taskId = RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("Create task for get")
+                .post("/a2a/send")
+                .then()
+                .statusCode(200)
+                .extract()
+                .jsonPath()
+                .getString("taskId");
+
+        RestAssured.given()
+                .queryParam("taskId", taskId)
+                .get("/a2a/get-task")
+                .then()
+                .statusCode(200)
+                .body(
+                        "taskId", is(taskId),
+                        "state", is("COMPLETED"));
+    }
+
+    @Test
+    void cancelCompletedTaskReturnsError() {
+        // The echo agent completes tasks immediately, so the task is already 
in COMPLETED state
+        // when we attempt to cancel it — the A2A protocol rejects canceling a 
completed task
+        String taskId = RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("Create task for cancel")
+                .post("/a2a/send")
+                .then()
+                .statusCode(200)
+                .extract()
+                .jsonPath()
+                .getString("taskId");
+
+        RestAssured.given()
+                .queryParam("taskId", taskId)
+                .post("/a2a/cancel-task")
+                .then()
+                .statusCode(200)
+                .body("error", notNullValue());
+    }
+
+    @Test
+    void sendStreamingMessageJsonRpc() {
+        String response = RestAssured.given()
+                .contentType("application/json")
+                .body(jsonRpcStreamMessage("msg-stream", "req-stream", "Stream 
this"))
+                .post("/streaming/")
+                .then()
+                .statusCode(200)
+                .header("Content-Type", "text/event-stream")
+                .extract().asString();
+
+        String[] events = response.split("\n\n");
+        assertTrue(events.length >= 3,
+                "Expected at least 3 SSE events (submitted + 2 progress + 
completed), got "
+                        + events.length + ": " + response);
+
+        for (String event : events) {
+            assertTrue(event.startsWith("data: "),
+                    "SSE event should start with 'data: ', got: " + event);
+        }
+
+        assertTrue(response.contains("Step 1 complete"),
+                "Expected progress event 'Step 1 complete' in response: " + 
response);
+        assertTrue(response.contains("Step 2 complete"),
+                "Expected progress event 'Step 2 complete' in response: " + 
response);
+    }
+
+    @Test
+    void restProtocolBindingRejected() {
+        RestAssured.get("/a2a/create-rest-endpoint")
+                .then()
+                .statusCode(200)
+                .body(containsString("REST (HTTP+JSON) protocol binding is not 
supported on Quarkus"));
+    }
+
+    @Test
+    void sendMessageWithDataPart() {
+        RestAssured.given()
+                .contentType("application/json")
+                .body(jsonRpcSendMessage("msg-data", "req-data",
+                        
"{\"kind\":\"data\",\"data\":{\"key\":\"value\",\"count\":42}}"))
+                .post("/")
+                .then()
+                .statusCode(200)
+                .body(
+                        "jsonrpc", is("2.0"),
+                        "result.task.id", notNullValue(),
+                        "result.task.status.state", is("TASK_STATE_COMPLETED"),
+                        "id", is("req-data"));
+    }
+
+    @Test
+    void sendMessageWithFilePart() {
+        RestAssured.given()
+                .contentType("application/json")
+                .body(jsonRpcSendMessage("msg-file", "req-file",
+                        
"{\"kind\":\"file\",\"raw\":\"aGVsbG8=\",\"mediaType\":\"text/plain\",\"filename\":\"test.txt\"}"))
+                .post("/")
+                .then()
+                .statusCode(200)
+                .body(
+                        "jsonrpc", is("2.0"),
+                        "result.task.id", notNullValue(),
+                        "result.task.status.state", is("TASK_STATE_COMPLETED"),
+                        "id", is("req-file"));
+    }
+
+    @Test
+    void fullAgentCardServed() {
+        RestAssured.get("/full/.well-known/agent-card.json")
+                .then()
+                .statusCode(200)
+                .body(
+                        "name", is("Full Feature Agent"),
+                        "version", is("2.0.0"),
+                        "description", is("A Quarkus test agent with all 
features"),
+                        "provider.name", is("Test Provider"),
+                        "provider.url", is("https://example.com/provider";),
+                        "capabilities.streaming", is(true),
+                        "capabilities.pushNotifications", is(true),
+                        "skills[0].id", is("echo"),
+                        "skills[0].name", is("Echo Skill"),
+                        "skills[0].tags[0]", is("test"),
+                        "skills[0].inputModes[0]", is("text/plain"),
+                        "skills[1].id", is("transform"),
+                        "defaultInputModes[0]", is("text/plain"),
+                        "defaultOutputModes[0]", is("text/plain"));
+    }
+
+    @Test
+    void producerListTasks() {
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("Task for list 1")
+                .post("/a2a/send")
+                .then()
+                .statusCode(200);
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("Task for list 2")
+                .post("/a2a/send")
+                .then()
+                .statusCode(200);
+
+        RestAssured.get("/a2a/list-tasks")
+                .then()
+                .statusCode(200)
+                .body("count", greaterThanOrEqualTo(2));
+    }
+
+    @Test
+    void multiTurnConversation() {
+        String contextId = RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("Turn 1")
+                .post("/a2a/send-context")
+                .then()
+                .statusCode(200)
+                .extract()
+                .jsonPath()
+                .getString("contextId");
+        assertNotNull(contextId, "First turn should return a contextId");
+
+        String contextId2 = RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("Turn 2")
+                .queryParam("contextId", contextId)
+                .post("/a2a/send-context")
+                .then()
+                .statusCode(200)
+                .extract()
+                .jsonPath()
+                .getString("contextId");
+
+        assertEquals(contextId, contextId2, "contextId should be preserved 
across turns");
+    }
+
+    @Test
+    void pushNotificationConfigCrud() {
+        String taskId = RestAssured.given()
+                .contentType("application/json")
+                .body(jsonRpcSendMessage("msg-push", "req-push", 
"{\"text\":\"Push test\"}"))
+                .post("/push/")
+                .then()
+                .statusCode(200)
+                .body("result.task.id", notNullValue())
+                .extract()
+                .jsonPath()
+                .getString("result.task.id");
+        assertNotNull(taskId, "Task ID should be returned");
+
+        String configId = RestAssured.given()
+                .contentType("application/json")
+                .body(jsonRpcRequest("CreateTaskPushNotificationConfig", 
"req-pc-create",
+                        "\"taskId\":\"" + taskId + 
"\",\"url\":\"http://localhost:9999/webhook\"";))
+                .post("/push/")
+                .then()
+                .statusCode(200)
+                .body("result.url", is("http://localhost:9999/webhook";))
+                .extract()
+                .jsonPath()
+                .getString("result.id");
+        assertNotNull(configId, "Push config ID should be returned");
+
+        String listRequest = jsonRpcRequest("ListTaskPushNotificationConfigs", 
"req-pc-list",
+                "\"taskId\":\"" + taskId + "\"");
+
+        RestAssured.given()
+                .contentType("application/json")
+                .body(listRequest)
+                .post("/push/")
+                .then()
+                .statusCode(200)
+                .body("result.configs.size()", is(1));
+
+        RestAssured.given()
+                .contentType("application/json")
+                .body(jsonRpcRequest("GetTaskPushNotificationConfig", 
"req-pc-get",
+                        "\"taskId\":\"" + taskId + "\",\"id\":\"" + configId + 
"\""))
+                .post("/push/")
+                .then()
+                .statusCode(200)
+                .body("result.url", is("http://localhost:9999/webhook";));
+
+        RestAssured.given()
+                .contentType("application/json")
+                .body(jsonRpcRequest("DeleteTaskPushNotificationConfig", 
"req-pc-delete",
+                        "\"taskId\":\"" + taskId + "\",\"id\":\"" + configId + 
"\""))
+                .post("/push/")
+                .then()
+                .statusCode(200);
+
+        RestAssured.given()
+                .contentType("application/json")
+                .body(listRequest)
+                .post("/push/")
+                .then()
+                .statusCode(200)
+                .body("result.configs.size()", is(0));
+    }
+
+    @Test
+    void streamingWithArtifactEmission() {
+        String response = RestAssured.given()
+                .contentType("application/json")
+                .body(jsonRpcStreamMessage("msg-art", "req-art", "Stream with 
artifact"))
+                .post("/streaming/")
+                .then()
+                .statusCode(200)
+                .header("Content-Type", "text/event-stream")
+                .extract().asString();
+
+        assertTrue(response.contains("artifactUpdate"),
+                "Expected artifact update event in SSE response: " + response);
+        assertTrue(response.contains("test-artifact"),
+                "Expected artifact name 'test-artifact' in SSE response: " + 
response);
+    }
+
+    @Test
+    void producerStreamMessage() {
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("Stream from producer")
+                .post("/a2a/send-stream")
+                .then()
+                .statusCode(200)
+                .body(
+                        "statusUpdates", greaterThanOrEqualTo(2),
+                        "artifactUpdates", greaterThanOrEqualTo(1));
+    }
+
+    @Test
+    void consumerPojoDataFormat() {
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("Hello POJO")
+                .post("/a2a/send-pojo")
+                .then()
+                .statusCode(200)
+                .body(
+                        "state", is("COMPLETED"),
+                        "response", containsString("role=ROLE_USER"));
+    }
+
+    @Test
+    void sendMessageAsync() {
+        RestAssured.given()
+                .contentType("application/json")
+                .body("{\"jsonrpc\":\"2.0\",\"method\":\"SendMessage\","
+                        + 
"\"params\":{\"message\":{\"messageId\":\"msg-async\","
+                        + "\"role\":\"user\",\"parts\":[{\"text\":\"Async 
request\"}]},"
+                        + "\"configuration\":{\"returnImmediately\":true}},"
+                        + "\"id\":\"req-async\"}")
+                .post("/")
+                .then()
+                .statusCode(200)
+                .body(
+                        "jsonrpc", is("2.0"),
+                        "result.task.id", notNullValue(),
+                        "result.task.status.state", is("TASK_STATE_SUBMITTED"),
+                        "id", is("req-async"));
+    }
+
+    @Test
+    void cardFromParametersServed() {
+        RestAssured.get("/pojo/.well-known/agent-card.json")
+                .then()
+                .statusCode(200)
+                .body(
+                        "name", is("POJO Agent"),
+                        "description", is("POJO data format test"),
+                        "version", is("1.0.0"));
+    }
+
+    @Test
+    void simpleLanguageEmitFunction() {
+        String response = RestAssured.given()
+                .contentType("application/json")
+                .body(jsonRpcStreamMessage("msg-emit", "req-emit", "Test 
emit"))
+                .post("/emit/")
+                .then()
+                .statusCode(200)
+                .header("Content-Type", "text/event-stream")
+                .extract().asString();
+
+        assertTrue(response.contains("Simple emit step 1"),
+                "Expected 'Simple emit step 1' in SSE response: " + response);
+        assertTrue(response.contains("Simple emit step 2"),
+                "Expected 'Simple emit step 2' in SSE response: " + response);
+    }
+
+    @Test
+    void apiKeyAuthenticationRequired() {
+        RestAssured.given()
+                .contentType("application/json")
+                .body(jsonRpcSendMessage("msg-noauth", "req-noauth", 
"{\"text\":\"No auth\"}"))
+                .post("/apikey/")
+                .then()
+                .statusCode(200)
+                .body("error", notNullValue());
+    }
+
+    @Test
+    void apiKeyAuthenticationSuccess() {
+        RestAssured.given()
+                .contentType("application/json")
+                .header("X-API-Key", "test-secret-key")
+                .body(jsonRpcSendMessage("msg-auth", "req-auth", 
"{\"text\":\"With auth\"}"))
+                .post("/apikey/")
+                .then()
+                .statusCode(200)
+                .body(
+                        "result.task.id", notNullValue(),
+                        "id", is("req-auth"));
+    }
+
+    @Test
+    void a2aExtensionNegotiation() {
+        RestAssured.given()
+                .contentType("application/json")
+                .header(A2AConstants.HEADER_A2A_EXTENSIONS, 
"urn:test:tracking")
+                .body(jsonRpcSendMessage("msg-ext", "req-ext", 
"{\"text\":\"Extension test\"}"))
+                .post("/ext/")
+                .then()
+                .statusCode(200)
+                .header(A2AConstants.HEADER_A2A_EXTENSIONS, 
containsString("urn:test:tracking"))
+                .body("result.task.id", notNullValue());
+    }
+
+    @Test
+    void oauthAuthenticationRequired() {
+        RestAssured.given()
+                .contentType("application/json")
+                .body(jsonRpcSendMessage("msg-notoken", "req-notoken", 
"{\"text\":\"No token\"}"))
+                .post("/oauth/")
+                .then()
+                .statusCode(200)
+                .body("error", notNullValue());
+    }
+
+    @Test
+    void oauthAuthenticationSuccess() {
+        String keycloakUrl = 
ConfigProvider.getConfig().getValue("cq.a2a.test.keycloak.url", String.class);
+        String tokenEndpoint = keycloakUrl + "/protocol/openid-connect/token";
+
+        String accessToken = RestAssured.given()
+                .formParam("grant_type", "client_credentials")
+                .formParam("client_id", "camel-client")
+                .formParam("client_secret", "camel-client-secret")
+                .post(tokenEndpoint)
+                .then()
+                .statusCode(200)
+                .extract()
+                .jsonPath()
+                .getString("access_token");
+        assertNotNull(accessToken, "Should obtain access token from Keycloak");
+
+        RestAssured.given()
+                .contentType("application/json")
+                .header("Authorization", "Bearer " + accessToken)
+                .body(jsonRpcSendMessage("msg-oauth", "req-oauth", 
"{\"text\":\"With OAuth\"}"))
+                .post("/oauth/")
+                .then()
+                .statusCode(200)
+                .body(
+                        "result.task.id", notNullValue(),
+                        "id", is("req-oauth"));
+    }
+
+    private static String jsonRpcSendMessage(String messageId, String 
requestId, String partJson) {
+        return jsonRpcRequest("SendMessage", requestId,
+                "\"message\":{\"messageId\":\"" + messageId + "\","
+                        + "\"role\":\"user\",\"parts\":[" + partJson + "]}");
+    }
+
+    private static String jsonRpcStreamMessage(String messageId, String 
requestId, String text) {
+        return jsonRpcRequest("SendStreamingMessage", requestId,
+                "\"message\":{\"messageId\":\"" + messageId + "\","
+                        + "\"role\":\"user\",\"parts\":[{\"text\":\"" + text + 
"\"}]}");
+    }
+
+    private static String jsonRpcRequest(String method, String requestId, 
String params) {
+        return "{\"jsonrpc\":\"2.0\",\"method\":\"" + method + "\","
+                + "\"params\":{" + params + "},\"id\":\"" + requestId + "\"}";
+    }
+}
diff --git a/integration-tests/a2a/src/test/resources/camel-realm.json 
b/integration-tests/a2a/src/test/resources/camel-realm.json
new file mode 100644
index 0000000000..1e2ff6d9be
--- /dev/null
+++ b/integration-tests/a2a/src/test/resources/camel-realm.json
@@ -0,0 +1,84 @@
+{
+  "realm": "camel",
+  "accessTokenLifespan": 300,
+  "ssoSessionMaxLifespan": 32140800,
+  "ssoSessionIdleTimeout": 32140800,
+  "enabled": true,
+  "sslRequired": "external",
+  "users": [
+    {
+      "username": "alice",
+      "enabled": true,
+      "firstName": "Alice",
+      "lastName": "Brown",
+      "email": "[email protected]",
+      "credentials": [
+        {
+          "type": "password",
+          "value": "alice"
+        }
+      ],
+      "realmRoles": [
+        "user"
+      ]
+    },
+    {
+      "username": "admin",
+      "enabled": true,
+      "email": "[email protected]",
+      "credentials": [
+        {
+          "type": "password",
+          "value": "admin-password"
+        }
+      ],
+      "realmRoles": [
+        "admin"
+      ],
+      "clientRoles": {
+        "realm-management": [
+          "realm-admin"
+        ]
+      }
+    }
+  ],
+  "roles": {
+    "realm": [
+      {
+        "name": "user",
+        "description": "User privileges"
+      },
+      {
+        "name": "admin",
+        "description": "Administrator privileges"
+      }
+    ],
+    "client": {}
+  },
+  "scopeMappings": [],
+  "clientScopeMappings": {},
+  "clients": [
+    {
+      "clientId": "camel-client",
+      "enabled": true,
+      "clientAuthenticatorType": "client-secret",
+      "secret": "camel-client-secret",
+      "publicClient": false,
+      "bearerOnly": false,
+      "standardFlowEnabled": true,
+      "implicitFlowEnabled": false,
+      "directAccessGrantsEnabled": false,
+      "serviceAccountsEnabled": true,
+      "consentRequired" : false,
+      "fullScopeAllowed" : false,
+      "redirectUris": [
+        "http://127.0.0.1:8080/auth";,
+        "https://example.local/auth";,
+        "https://example.k3s/auth";
+      ],
+      "attributes": {
+        "post.logout.redirect.uris": 
"http://127.0.0.1:8080/##https://example.local/##https://example.k3s/";
+      }
+    }
+  ]
+}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 9249f0365b..903d7ef9d2 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -48,6 +48,7 @@
         <module>main-yaml</module>
 
         <!-- extensions a..z; do not remove this comment, it is important when 
sorting via  mvn process-resources -Pformat -->
+        <module>a2a</module>
         <module>activemq</module>
         <module>activemq6</module>
         <module>amqp</module>
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index aa9502dcd8..90d6b700d6 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -124,6 +124,11 @@
             <!-- Dependencies a..z; do not remove this comment, it is 
important when sorting via  mvn process-resources -Pformat -->
 
             <!--$ org.apache.camel $-->
+            <dependency>
+                <groupId>org.apache.camel</groupId>
+                <artifactId>camel-a2a</artifactId>
+                <version>${camel.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.apache.camel</groupId>
                 <artifactId>camel-activemq</artifactId>
@@ -3507,6 +3512,16 @@
             </dependency>
 
             <!--$ org.apache.camel.quarkus $-->
+            <dependency>
+                <groupId>org.apache.camel.quarkus</groupId>
+                <artifactId>camel-quarkus-a2a</artifactId>
+                <version>${camel-quarkus.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.camel.quarkus</groupId>
+                <artifactId>camel-quarkus-a2a-deployment</artifactId>
+                <version>${camel-quarkus.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.apache.camel.quarkus</groupId>
                 <artifactId>camel-quarkus-activemq</artifactId>
diff --git a/poms/bom/src/main/generated/flattened-full-pom.xml 
b/poms/bom/src/main/generated/flattened-full-pom.xml
index 1295116b09..5385c2ed6f 100644
--- a/poms/bom/src/main/generated/flattened-full-pom.xml
+++ b/poms/bom/src/main/generated/flattened-full-pom.xml
@@ -47,6 +47,11 @@
   </distributionManagement>
   <dependencyManagement>
     <dependencies>
+      <dependency>
+        <groupId>org.apache.camel</groupId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-a2a</artifactId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>4.21.0</version><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
         <artifactId>camel-activemq</artifactId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
@@ -3402,6 +3407,16 @@
           </exclusion>
         </exclusions>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-quarkus-a2a</artifactId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>3.37.0-SNAPSHOT</version><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-quarkus-a2a-deployment</artifactId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>3.37.0-SNAPSHOT</version><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
       <dependency>
         <groupId>org.apache.camel.quarkus</groupId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
         <artifactId>camel-quarkus-activemq</artifactId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
diff --git a/poms/bom/src/main/generated/flattened-reduced-pom.xml 
b/poms/bom/src/main/generated/flattened-reduced-pom.xml
index a1a7519dc6..73e0632330 100644
--- a/poms/bom/src/main/generated/flattened-reduced-pom.xml
+++ b/poms/bom/src/main/generated/flattened-reduced-pom.xml
@@ -47,6 +47,11 @@
   </distributionManagement>
   <dependencyManagement>
     <dependencies>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-a2a</artifactId>
+        <version>4.21.0</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId>
         <artifactId>camel-activemq</artifactId>
@@ -3376,6 +3381,16 @@
           </exclusion>
         </exclusions>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-a2a</artifactId>
+        <version>3.37.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-a2a-deployment</artifactId>
+        <version>3.37.0-SNAPSHOT</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.camel.quarkus</groupId>
         <artifactId>camel-quarkus-activemq</artifactId>
diff --git a/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml 
b/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
index 17d0d306aa..2609463e66 100644
--- a/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
+++ b/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
@@ -47,6 +47,11 @@
   </distributionManagement>
   <dependencyManagement>
     <dependencies>
+      <dependency>
+        <groupId>org.apache.camel</groupId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-a2a</artifactId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>4.21.0</version><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
         <artifactId>camel-activemq</artifactId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
@@ -3376,6 +3381,16 @@
           </exclusion>
         </exclusions>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-quarkus-a2a</artifactId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>3.37.0-SNAPSHOT</version><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-quarkus-a2a-deployment</artifactId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>3.37.0-SNAPSHOT</version><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
       <dependency>
         <groupId>org.apache.camel.quarkus</groupId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
         <artifactId>camel-quarkus-activemq</artifactId><!-- 
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
diff --git a/tooling/scripts/test-categories.yaml 
b/tooling/scripts/test-categories.yaml
index 4ddaeb144f..d477e1b68e 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -97,6 +97,7 @@ group-04:
   - observability-services
   - sjms-artemis-client
 group-05:
+  - a2a
   - avro
   - base64
   - bindy

Reply via email to