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

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


The following commit(s) were added to refs/heads/main by this push:
     new abd4c4380e43 CAMEL-24333: Add structured tool output (outputSchema / 
structuredContent)
abd4c4380e43 is described below

commit abd4c4380e43359988c4943b3a1759170a9ff639
Author: Omar Atie <[email protected]>
AuthorDate: Wed Aug 12 01:21:58 2026 -0700

    CAMEL-24333: Add structured tool output (outputSchema / structuredContent)
    
    Extend ai-tool with optional outputParameter.* and outputSchema metadata,
    parse JSON route bodies into AiToolResult.Success.structuredContent, and
    map through the MCP bridge to Tool.outputSchema and
    CallToolResult.structuredContent.
    
    Closes #25398
    
    Co-authored-by: Cursor Agent <[email protected]>
---
 .../apache/camel/catalog/components/ai-tool.json   |  28 +++--
 .../camel/catalog/docs/ai-tool-component.adoc      |  44 +++++++
 .../ai/tool/AiToolComponentConfigurer.java         |  14 +++
 .../ai/tool/AiToolConfigurationConfigurer.java     |  14 +++
 .../ai/tool/AiToolEndpointConfigurer.java          |  14 +++
 .../ai/tool/AiToolEndpointUriFactory.java          |   7 +-
 .../apache/camel/component/ai/tool/ai-tool.json    |  28 +++--
 .../src/main/docs/ai-tool-component.adoc           |  44 +++++++
 .../camel/component/ai/tool/AiToolComponent.java   |   6 +
 .../component/ai/tool/AiToolConfiguration.java     |  34 +++++
 .../camel/component/ai/tool/AiToolConsumer.java    |  15 ++-
 .../camel/component/ai/tool/AiToolExecutor.java    |  19 ++-
 .../component/ai/tool/AiToolParameterHelper.java   |  95 +++++++++++++-
 .../camel/component/ai/tool/AiToolResult.java      |   9 +-
 .../apache/camel/component/ai/tool/AiToolSpec.java |  25 +++-
 .../ai/tool/AiToolEndpointLifecycleTest.java       |  53 ++++++++
 .../component/ai/tool/AiToolExecutorTest.java      |  82 +++++++++++-
 .../ai/tool/AiToolParameterHelperTest.java         |  72 +++++++++++
 .../ai/tool/AiToolRegistryListenerTest.java        |   3 +-
 .../component/ai/tool/AiToolRegistryTest.java      |  50 ++++----
 .../resources/output-schemas/weather-result.json   |   9 ++
 .../agent/AiToolSpecToLangChain4jTest.java         |  20 +--
 .../component/mcp/server/McpServerBridge.java      |   7 +-
 .../camel/component/mcp/server/McpServerTool.java  |   9 ++
 .../component/mcp/server/McpToolCallResult.java    |  13 +-
 .../component/mcp/server/McpServerBridgeTest.java  |  21 ++++
 .../mcp/server/vertx/VertxMcpServerEngine.java     |  12 +-
 .../vertx/VertxMcpServerOutputSchemaTest.java      | 138 +++++++++++++++++++++
 .../ROOT/pages/camel-4x-upgrade-guide-4_22.adoc    |  12 ++
 .../dsl/AiToolComponentBuilderFactory.java         |  43 +++++++
 .../endpoint/dsl/AiToolEndpointBuilderFactory.java |  64 ++++++++++
 31 files changed, 922 insertions(+), 82 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ai-tool.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ai-tool.json
index e758755891cc..778564ec6a39 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ai-tool.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ai-tool.json
@@ -31,11 +31,13 @@
     "destructiveHint": { "index": 4, "kind": "property", "displayName": 
"Destructive Hint", "group": "consumer", "label": "consumer", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool may perform destructive 
o [...]
     "idempotentHint": { "index": 5, "kind": "property", "displayName": 
"Idempotent Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that repeating the tool call with the 
sam [...]
     "openWorldHint": { "index": 6, "kind": "property", "displayName": "Open 
World Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool interacts with external 
syst [...]
-    "parameters": { "index": 7, "kind": "property", "displayName": 
"Parameters", "group": "consumer", "label": "consumer", "required": false, 
"type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.String>", "prefix": "parameter.", "multiValue": true, "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.ai.tool.AiToolConfiguration", 
"configurationField": "configuration", "description": "Tool in [...]
-    "readOnlyHint": { "index": 8, "kind": "property", "displayName": "Read 
Only Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool only reads data and 
does not m [...]
-    "tags": { "index": 9, "kind": "property", "displayName": "Tags", "group": 
"consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of tags used to group 
tools. Producers filter the registry by these tags to [...]
-    "title": { "index": 10, "kind": "property", "displayName": "Title", 
"group": "consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Optional display title for MCP tool listings. 
Advisory hint for MCP clients only." },
-    "autowiredEnabled": { "index": 11, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching  [...]
+    "outputParameters": { "index": 7, "kind": "property", "displayName": 
"Output Parameters", "group": "consumer", "label": "consumer", "required": 
false, "type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.String>", "prefix": "outputParameter.", "multiValue": true, 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "des [...]
+    "outputSchema": { "index": 8, "kind": "property", "displayName": "Output 
Schema", "group": "consumer", "label": "consumer", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"supportFileReference": true, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Raw JSON Schema describing the tool's 
structured  [...]
+    "parameters": { "index": 9, "kind": "property", "displayName": 
"Parameters", "group": "consumer", "label": "consumer", "required": false, 
"type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.String>", "prefix": "parameter.", "multiValue": true, "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.ai.tool.AiToolConfiguration", 
"configurationField": "configuration", "description": "Tool in [...]
+    "readOnlyHint": { "index": 10, "kind": "property", "displayName": "Read 
Only Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool only reads data and 
does not  [...]
+    "tags": { "index": 11, "kind": "property", "displayName": "Tags", "group": 
"consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of tags used to group 
tools. Producers filter the registry by these tags t [...]
+    "title": { "index": 12, "kind": "property", "displayName": "Title", 
"group": "consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Optional display title for MCP tool listings. 
Advisory hint for MCP clients only." },
+    "autowiredEnabled": { "index": 13, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching  [...]
   },
   "properties": {
     "toolName": { "index": 0, "kind": "path", "displayName": "Tool Name", 
"group": "consumer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The tool name. This is the 
name the LLM sees and uses to invoke the tool." },
@@ -44,12 +46,14 @@
     "destructiveHint": { "index": 3, "kind": "parameter", "displayName": 
"Destructive Hint", "group": "consumer", "label": "consumer", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool may perform destructive 
 [...]
     "idempotentHint": { "index": 4, "kind": "parameter", "displayName": 
"Idempotent Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that repeating the tool call with the 
sa [...]
     "openWorldHint": { "index": 5, "kind": "parameter", "displayName": "Open 
World Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool interacts with external 
sys [...]
-    "parameters": { "index": 6, "kind": "parameter", "displayName": 
"Parameters", "group": "consumer", "label": "consumer", "required": false, 
"type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.String>", "prefix": "parameter.", "multiValue": true, "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.ai.tool.AiToolConfiguration", 
"configurationField": "configuration", "description": "Tool i [...]
-    "readOnlyHint": { "index": 7, "kind": "parameter", "displayName": "Read 
Only Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool only reads data and 
does not  [...]
-    "tags": { "index": 8, "kind": "parameter", "displayName": "Tags", "group": 
"consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of tags used to group 
tools. Producers filter the registry by these tags t [...]
-    "title": { "index": 9, "kind": "parameter", "displayName": "Title", 
"group": "consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Optional display title for MCP tool listings. 
Advisory hint for MCP clients only." },
-    "bridgeErrorHandler": { "index": 10, "kind": "parameter", "displayName": 
"Bridge Error Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions (if possible) occurred 
while the Camel consumer is trying to pickup incoming [...]
-    "exceptionHandler": { "index": 11, "kind": "parameter", "displayName": 
"Exception Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By de [...]
-    "exchangePattern": { "index": 12, "kind": "parameter", "displayName": 
"Exchange Pattern", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "enum", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], 
"deprecated": false, "autowired": false, "secret": false, "description": "Sets 
the exchange pattern when the consumer creates an exchange." }
+    "outputParameters": { "index": 6, "kind": "parameter", "displayName": 
"Output Parameters", "group": "consumer", "label": "consumer", "required": 
false, "type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.String>", "prefix": "outputParameter.", "multiValue": true, 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "de [...]
+    "outputSchema": { "index": 7, "kind": "parameter", "displayName": "Output 
Schema", "group": "consumer", "label": "consumer", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"supportFileReference": true, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Raw JSON Schema describing the tool's 
structured [...]
+    "parameters": { "index": 8, "kind": "parameter", "displayName": 
"Parameters", "group": "consumer", "label": "consumer", "required": false, 
"type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.String>", "prefix": "parameter.", "multiValue": true, "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.ai.tool.AiToolConfiguration", 
"configurationField": "configuration", "description": "Tool i [...]
+    "readOnlyHint": { "index": 9, "kind": "parameter", "displayName": "Read 
Only Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool only reads data and 
does not  [...]
+    "tags": { "index": 10, "kind": "parameter", "displayName": "Tags", 
"group": "consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of tags used to group 
tools. Producers filter the registry by these tags  [...]
+    "title": { "index": 11, "kind": "parameter", "displayName": "Title", 
"group": "consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Optional display title for MCP tool listings. 
Advisory hint for MCP clients only." },
+    "bridgeErrorHandler": { "index": 12, "kind": "parameter", "displayName": 
"Bridge Error Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions (if possible) occurred 
while the Camel consumer is trying to pickup incoming [...]
+    "exceptionHandler": { "index": 13, "kind": "parameter", "displayName": 
"Exception Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By de [...]
+    "exchangePattern": { "index": 14, "kind": "parameter", "displayName": 
"Exchange Pattern", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "enum", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], 
"deprecated": false, "autowired": false, "secret": false, "description": "Sets 
the exchange pattern when the consumer creates an exchange." }
   }
 }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/ai-tool-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/ai-tool-component.adoc
index defb3f0a929c..c13661511ada 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/ai-tool-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/ai-tool-component.adoc
@@ -197,6 +197,50 @@ Top-level schema properties are exposed as exchange 
headers. Nested values are p
 
 The root schema must be a JSON Schema object with a top-level `properties` 
map. Camel always allowlists top-level property names when invoking the tool 
route, even if the schema sets `additionalProperties: true`. Nested fields are 
not flattened into headers; only top-level properties become exchange headers 
(Map/List/primitive values).
 
+=== Structured Tool Output (outputSchema)
+
+MCP tools can declare an `outputSchema` and return `structuredContent` (typed 
JSON) so clients parse tool results reliably instead of re-interpreting free 
text. Use `outputParameter.*` for flat field definitions or `outputSchema` for 
raw JSON Schema (mirroring the input-side `parameter.*` / `argSchema` pattern). 
The two options are mutually exclusive.
+
+When an output schema is declared, the route body must be JSON (a JSON string, 
`Map`, or `List`). Camel parses it into structured content and forwards it 
through the MCP bridge as `CallToolResult.structuredContent`. The text 
representation remains available for LLM adapters (LangChain4j, Spring AI) that 
consume string tool results.
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("ai-tool:getWeather?tags=weather&description=Get weather"
+     + "&outputSchema=classpath:schemas/weather-result.json")
+    .process(exchange -> exchange.getMessage().setBody(
+        "{\"temperature\":21.5,\"unit\":\"celsius\"}"));
+----
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: ai-tool:getWeather
+      parameters:
+        tags: weather
+        description: "Get weather"
+        outputParameter.temperature: number
+        outputParameter.unit: string
+      steps:
+        - setBody:
+            constant: '{"temperature":21.5,"unit":"celsius"}'
+----
+====
+
+Flat `outputParameter.*` options use the same sub-option syntax as input 
`parameter.*`:
+
+* `outputParameter.NAME=TYPE` — field type (`string`, `integer`, `number`, 
`boolean`)
+* `outputParameter.NAME.description=TEXT` — field description in the generated 
JSON Schema
+* `outputParameter.NAME.required=true` — marks the field as required in the 
output schema
+* `outputParameter.NAME.enum=val1,val2` — restricts allowed values
+
+`outputSchema` supports Camel resource references such as 
`classpath:schemas/weather-result.json`.
+
 === MCP Tool Annotation Hints
 
 When exposing `ai-tool` routes through the MCP Server component, you can 
declare optional behavioral hints aligned with the MCP specification 
(`ToolAnnotations`). MCP clients may use these hints for per-tool policy (for 
example auto-approving read-only tools or requiring confirmation before 
destructive ones).
diff --git 
a/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolComponentConfigurer.java
 
b/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolComponentConfigurer.java
index f5a2d7183da4..bf7b00f520bd 100644
--- 
a/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolComponentConfigurer.java
+++ 
b/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolComponentConfigurer.java
@@ -44,6 +44,10 @@ public class AiToolComponentConfigurer extends 
PropertyConfigurerSupport impleme
         case "idempotentHint": 
getOrCreateConfiguration(target).setIdempotentHint(property(camelContext, 
java.lang.Boolean.class, value)); return true;
         case "openworldhint":
         case "openWorldHint": 
getOrCreateConfiguration(target).setOpenWorldHint(property(camelContext, 
java.lang.Boolean.class, value)); return true;
+        case "outputparameters":
+        case "outputParameters": 
getOrCreateConfiguration(target).setOutputParameters(property(camelContext, 
java.util.Map.class, value)); return true;
+        case "outputschema":
+        case "outputSchema": 
getOrCreateConfiguration(target).setOutputSchema(property(camelContext, 
java.lang.String.class, value)); return true;
         case "parameters": 
getOrCreateConfiguration(target).setParameters(property(camelContext, 
java.util.Map.class, value)); return true;
         case "readonlyhint":
         case "readOnlyHint": 
getOrCreateConfiguration(target).setReadOnlyHint(property(camelContext, 
java.lang.Boolean.class, value)); return true;
@@ -70,6 +74,10 @@ public class AiToolComponentConfigurer extends 
PropertyConfigurerSupport impleme
         case "idempotentHint": return java.lang.Boolean.class;
         case "openworldhint":
         case "openWorldHint": return java.lang.Boolean.class;
+        case "outputparameters":
+        case "outputParameters": return java.util.Map.class;
+        case "outputschema":
+        case "outputSchema": return java.lang.String.class;
         case "parameters": return java.util.Map.class;
         case "readonlyhint":
         case "readOnlyHint": return java.lang.Boolean.class;
@@ -97,6 +105,10 @@ public class AiToolComponentConfigurer extends 
PropertyConfigurerSupport impleme
         case "idempotentHint": return 
getOrCreateConfiguration(target).getIdempotentHint();
         case "openworldhint":
         case "openWorldHint": return 
getOrCreateConfiguration(target).getOpenWorldHint();
+        case "outputparameters":
+        case "outputParameters": return 
getOrCreateConfiguration(target).getOutputParameters();
+        case "outputschema":
+        case "outputSchema": return 
getOrCreateConfiguration(target).getOutputSchema();
         case "parameters": return 
getOrCreateConfiguration(target).getParameters();
         case "readonlyhint":
         case "readOnlyHint": return 
getOrCreateConfiguration(target).getReadOnlyHint();
@@ -109,6 +121,8 @@ public class AiToolComponentConfigurer extends 
PropertyConfigurerSupport impleme
     @Override
     public Object getCollectionValueType(Object target, String name, boolean 
ignoreCase) {
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "outputparameters":
+        case "outputParameters": return java.lang.String.class;
         case "parameters": return java.lang.String.class;
         default: return null;
         }
diff --git 
a/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolConfigurationConfigurer.java
 
b/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolConfigurationConfigurer.java
index d20e0c4742a1..487f382afa7a 100644
--- 
a/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolConfigurationConfigurer.java
+++ 
b/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolConfigurationConfigurer.java
@@ -32,6 +32,10 @@ public class AiToolConfigurationConfigurer extends 
org.apache.camel.support.comp
         case "idempotentHint": target.setIdempotentHint(property(camelContext, 
java.lang.Boolean.class, value)); return true;
         case "openworldhint":
         case "openWorldHint": target.setOpenWorldHint(property(camelContext, 
java.lang.Boolean.class, value)); return true;
+        case "outputparameters":
+        case "outputParameters": 
target.setOutputParameters(property(camelContext, java.util.Map.class, value)); 
return true;
+        case "outputschema":
+        case "outputSchema": target.setOutputSchema(property(camelContext, 
java.lang.String.class, value)); return true;
         case "parameters": target.setParameters(property(camelContext, 
java.util.Map.class, value)); return true;
         case "readonlyhint":
         case "readOnlyHint": target.setReadOnlyHint(property(camelContext, 
java.lang.Boolean.class, value)); return true;
@@ -53,6 +57,10 @@ public class AiToolConfigurationConfigurer extends 
org.apache.camel.support.comp
         case "idempotentHint": return java.lang.Boolean.class;
         case "openworldhint":
         case "openWorldHint": return java.lang.Boolean.class;
+        case "outputparameters":
+        case "outputParameters": return java.util.Map.class;
+        case "outputschema":
+        case "outputSchema": return java.lang.String.class;
         case "parameters": return java.util.Map.class;
         case "readonlyhint":
         case "readOnlyHint": return java.lang.Boolean.class;
@@ -75,6 +83,10 @@ public class AiToolConfigurationConfigurer extends 
org.apache.camel.support.comp
         case "idempotentHint": return target.getIdempotentHint();
         case "openworldhint":
         case "openWorldHint": return target.getOpenWorldHint();
+        case "outputparameters":
+        case "outputParameters": return target.getOutputParameters();
+        case "outputschema":
+        case "outputSchema": return target.getOutputSchema();
         case "parameters": return target.getParameters();
         case "readonlyhint":
         case "readOnlyHint": return target.getReadOnlyHint();
@@ -87,6 +99,8 @@ public class AiToolConfigurationConfigurer extends 
org.apache.camel.support.comp
     @Override
     public Object getCollectionValueType(Object target, String name, boolean 
ignoreCase) {
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "outputparameters":
+        case "outputParameters": return java.lang.String.class;
         case "parameters": return java.lang.String.class;
         default: return null;
         }
diff --git 
a/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolEndpointConfigurer.java
 
b/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolEndpointConfigurer.java
index d369d659852a..51216e1a274b 100644
--- 
a/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolEndpointConfigurer.java
+++ 
b/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolEndpointConfigurer.java
@@ -38,6 +38,10 @@ public class AiToolEndpointConfigurer extends 
PropertyConfigurerSupport implemen
         case "idempotentHint": 
target.getConfiguration().setIdempotentHint(property(camelContext, 
java.lang.Boolean.class, value)); return true;
         case "openworldhint":
         case "openWorldHint": 
target.getConfiguration().setOpenWorldHint(property(camelContext, 
java.lang.Boolean.class, value)); return true;
+        case "outputparameters":
+        case "outputParameters": 
target.getConfiguration().setOutputParameters(property(camelContext, 
java.util.Map.class, value)); return true;
+        case "outputschema":
+        case "outputSchema": 
target.getConfiguration().setOutputSchema(property(camelContext, 
java.lang.String.class, value)); return true;
         case "parameters": 
target.getConfiguration().setParameters(property(camelContext, 
java.util.Map.class, value)); return true;
         case "readonlyhint":
         case "readOnlyHint": 
target.getConfiguration().setReadOnlyHint(property(camelContext, 
java.lang.Boolean.class, value)); return true;
@@ -65,6 +69,10 @@ public class AiToolEndpointConfigurer extends 
PropertyConfigurerSupport implemen
         case "idempotentHint": return java.lang.Boolean.class;
         case "openworldhint":
         case "openWorldHint": return java.lang.Boolean.class;
+        case "outputparameters":
+        case "outputParameters": return java.util.Map.class;
+        case "outputschema":
+        case "outputSchema": return java.lang.String.class;
         case "parameters": return java.util.Map.class;
         case "readonlyhint":
         case "readOnlyHint": return java.lang.Boolean.class;
@@ -93,6 +101,10 @@ public class AiToolEndpointConfigurer extends 
PropertyConfigurerSupport implemen
         case "idempotentHint": return 
target.getConfiguration().getIdempotentHint();
         case "openworldhint":
         case "openWorldHint": return 
target.getConfiguration().getOpenWorldHint();
+        case "outputparameters":
+        case "outputParameters": return 
target.getConfiguration().getOutputParameters();
+        case "outputschema":
+        case "outputSchema": return 
target.getConfiguration().getOutputSchema();
         case "parameters": return target.getConfiguration().getParameters();
         case "readonlyhint":
         case "readOnlyHint": return 
target.getConfiguration().getReadOnlyHint();
@@ -105,6 +117,8 @@ public class AiToolEndpointConfigurer extends 
PropertyConfigurerSupport implemen
     @Override
     public Object getCollectionValueType(Object target, String name, boolean 
ignoreCase) {
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "outputparameters":
+        case "outputParameters": return java.lang.String.class;
         case "parameters": return java.lang.String.class;
         default: return null;
         }
diff --git 
a/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolEndpointUriFactory.java
 
b/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolEndpointUriFactory.java
index 0a4c6a4f9e2c..0b573f3a064a 100644
--- 
a/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolEndpointUriFactory.java
+++ 
b/components/camel-ai/camel-ai-tool/src/generated/java/org/apache/camel/component/ai/tool/AiToolEndpointUriFactory.java
@@ -24,7 +24,7 @@ public class AiToolEndpointUriFactory extends 
org.apache.camel.support.component
     private static final Set<String> ENDPOINT_IDENTITY_PROPERTY_NAMES;
     private static final Map<String, String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(13);
+        Set<String> props = new HashSet<>(15);
         props.add("argSchema");
         props.add("bridgeErrorHandler");
         props.add("description");
@@ -33,6 +33,8 @@ public class AiToolEndpointUriFactory extends 
org.apache.camel.support.component
         props.add("exchangePattern");
         props.add("idempotentHint");
         props.add("openWorldHint");
+        props.add("outputParameters");
+        props.add("outputSchema");
         props.add("parameters");
         props.add("readOnlyHint");
         props.add("tags");
@@ -41,7 +43,8 @@ public class AiToolEndpointUriFactory extends 
org.apache.camel.support.component
         PROPERTY_NAMES = Collections.unmodifiableSet(props);
         SECRET_PROPERTY_NAMES = Collections.emptySet();
         ENDPOINT_IDENTITY_PROPERTY_NAMES = Collections.emptySet();
-        Map<String, String> prefixes = new HashMap<>(1);
+        Map<String, String> prefixes = new HashMap<>(2);
+        prefixes.put("outputParameters", "outputParameter.");
         prefixes.put("parameters", "parameter.");
         MULTI_VALUE_PREFIXES = Collections.unmodifiableMap(prefixes);
     }
diff --git 
a/components/camel-ai/camel-ai-tool/src/generated/resources/META-INF/org/apache/camel/component/ai/tool/ai-tool.json
 
b/components/camel-ai/camel-ai-tool/src/generated/resources/META-INF/org/apache/camel/component/ai/tool/ai-tool.json
index e758755891cc..778564ec6a39 100644
--- 
a/components/camel-ai/camel-ai-tool/src/generated/resources/META-INF/org/apache/camel/component/ai/tool/ai-tool.json
+++ 
b/components/camel-ai/camel-ai-tool/src/generated/resources/META-INF/org/apache/camel/component/ai/tool/ai-tool.json
@@ -31,11 +31,13 @@
     "destructiveHint": { "index": 4, "kind": "property", "displayName": 
"Destructive Hint", "group": "consumer", "label": "consumer", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool may perform destructive 
o [...]
     "idempotentHint": { "index": 5, "kind": "property", "displayName": 
"Idempotent Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that repeating the tool call with the 
sam [...]
     "openWorldHint": { "index": 6, "kind": "property", "displayName": "Open 
World Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool interacts with external 
syst [...]
-    "parameters": { "index": 7, "kind": "property", "displayName": 
"Parameters", "group": "consumer", "label": "consumer", "required": false, 
"type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.String>", "prefix": "parameter.", "multiValue": true, "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.ai.tool.AiToolConfiguration", 
"configurationField": "configuration", "description": "Tool in [...]
-    "readOnlyHint": { "index": 8, "kind": "property", "displayName": "Read 
Only Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool only reads data and 
does not m [...]
-    "tags": { "index": 9, "kind": "property", "displayName": "Tags", "group": 
"consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of tags used to group 
tools. Producers filter the registry by these tags to [...]
-    "title": { "index": 10, "kind": "property", "displayName": "Title", 
"group": "consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Optional display title for MCP tool listings. 
Advisory hint for MCP clients only." },
-    "autowiredEnabled": { "index": 11, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching  [...]
+    "outputParameters": { "index": 7, "kind": "property", "displayName": 
"Output Parameters", "group": "consumer", "label": "consumer", "required": 
false, "type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.String>", "prefix": "outputParameter.", "multiValue": true, 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "des [...]
+    "outputSchema": { "index": 8, "kind": "property", "displayName": "Output 
Schema", "group": "consumer", "label": "consumer", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"supportFileReference": true, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Raw JSON Schema describing the tool's 
structured  [...]
+    "parameters": { "index": 9, "kind": "property", "displayName": 
"Parameters", "group": "consumer", "label": "consumer", "required": false, 
"type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.String>", "prefix": "parameter.", "multiValue": true, "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.ai.tool.AiToolConfiguration", 
"configurationField": "configuration", "description": "Tool in [...]
+    "readOnlyHint": { "index": 10, "kind": "property", "displayName": "Read 
Only Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool only reads data and 
does not  [...]
+    "tags": { "index": 11, "kind": "property", "displayName": "Tags", "group": 
"consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of tags used to group 
tools. Producers filter the registry by these tags t [...]
+    "title": { "index": 12, "kind": "property", "displayName": "Title", 
"group": "consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Optional display title for MCP tool listings. 
Advisory hint for MCP clients only." },
+    "autowiredEnabled": { "index": 13, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching  [...]
   },
   "properties": {
     "toolName": { "index": 0, "kind": "path", "displayName": "Tool Name", 
"group": "consumer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The tool name. This is the 
name the LLM sees and uses to invoke the tool." },
@@ -44,12 +46,14 @@
     "destructiveHint": { "index": 3, "kind": "parameter", "displayName": 
"Destructive Hint", "group": "consumer", "label": "consumer", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool may perform destructive 
 [...]
     "idempotentHint": { "index": 4, "kind": "parameter", "displayName": 
"Idempotent Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that repeating the tool call with the 
sa [...]
     "openWorldHint": { "index": 5, "kind": "parameter", "displayName": "Open 
World Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool interacts with external 
sys [...]
-    "parameters": { "index": 6, "kind": "parameter", "displayName": 
"Parameters", "group": "consumer", "label": "consumer", "required": false, 
"type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.String>", "prefix": "parameter.", "multiValue": true, "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.ai.tool.AiToolConfiguration", 
"configurationField": "configuration", "description": "Tool i [...]
-    "readOnlyHint": { "index": 7, "kind": "parameter", "displayName": "Read 
Only Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool only reads data and 
does not  [...]
-    "tags": { "index": 8, "kind": "parameter", "displayName": "Tags", "group": 
"consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of tags used to group 
tools. Producers filter the registry by these tags t [...]
-    "title": { "index": 9, "kind": "parameter", "displayName": "Title", 
"group": "consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Optional display title for MCP tool listings. 
Advisory hint for MCP clients only." },
-    "bridgeErrorHandler": { "index": 10, "kind": "parameter", "displayName": 
"Bridge Error Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions (if possible) occurred 
while the Camel consumer is trying to pickup incoming [...]
-    "exceptionHandler": { "index": 11, "kind": "parameter", "displayName": 
"Exception Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By de [...]
-    "exchangePattern": { "index": 12, "kind": "parameter", "displayName": 
"Exchange Pattern", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "enum", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], 
"deprecated": false, "autowired": false, "secret": false, "description": "Sets 
the exchange pattern when the consumer creates an exchange." }
+    "outputParameters": { "index": 6, "kind": "parameter", "displayName": 
"Output Parameters", "group": "consumer", "label": "consumer", "required": 
false, "type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.String>", "prefix": "outputParameter.", "multiValue": true, 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "de [...]
+    "outputSchema": { "index": 7, "kind": "parameter", "displayName": "Output 
Schema", "group": "consumer", "label": "consumer", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"supportFileReference": true, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Raw JSON Schema describing the tool's 
structured [...]
+    "parameters": { "index": 8, "kind": "parameter", "displayName": 
"Parameters", "group": "consumer", "label": "consumer", "required": false, 
"type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.String>", "prefix": "parameter.", "multiValue": true, "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.ai.tool.AiToolConfiguration", 
"configurationField": "configuration", "description": "Tool i [...]
+    "readOnlyHint": { "index": 9, "kind": "parameter", "displayName": "Read 
Only Hint", "group": "consumer", "label": "consumer", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "MCP hint that the tool only reads data and 
does not  [...]
+    "tags": { "index": 10, "kind": "parameter", "displayName": "Tags", 
"group": "consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of tags used to group 
tools. Producers filter the registry by these tags  [...]
+    "title": { "index": 11, "kind": "parameter", "displayName": "Title", 
"group": "consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.tool.AiToolConfiguration", "configurationField": 
"configuration", "description": "Optional display title for MCP tool listings. 
Advisory hint for MCP clients only." },
+    "bridgeErrorHandler": { "index": 12, "kind": "parameter", "displayName": 
"Bridge Error Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions (if possible) occurred 
while the Camel consumer is trying to pickup incoming [...]
+    "exceptionHandler": { "index": 13, "kind": "parameter", "displayName": 
"Exception Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By de [...]
+    "exchangePattern": { "index": 14, "kind": "parameter", "displayName": 
"Exchange Pattern", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "enum", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], 
"deprecated": false, "autowired": false, "secret": false, "description": "Sets 
the exchange pattern when the consumer creates an exchange." }
   }
 }
diff --git 
a/components/camel-ai/camel-ai-tool/src/main/docs/ai-tool-component.adoc 
b/components/camel-ai/camel-ai-tool/src/main/docs/ai-tool-component.adoc
index defb3f0a929c..c13661511ada 100644
--- a/components/camel-ai/camel-ai-tool/src/main/docs/ai-tool-component.adoc
+++ b/components/camel-ai/camel-ai-tool/src/main/docs/ai-tool-component.adoc
@@ -197,6 +197,50 @@ Top-level schema properties are exposed as exchange 
headers. Nested values are p
 
 The root schema must be a JSON Schema object with a top-level `properties` 
map. Camel always allowlists top-level property names when invoking the tool 
route, even if the schema sets `additionalProperties: true`. Nested fields are 
not flattened into headers; only top-level properties become exchange headers 
(Map/List/primitive values).
 
+=== Structured Tool Output (outputSchema)
+
+MCP tools can declare an `outputSchema` and return `structuredContent` (typed 
JSON) so clients parse tool results reliably instead of re-interpreting free 
text. Use `outputParameter.*` for flat field definitions or `outputSchema` for 
raw JSON Schema (mirroring the input-side `parameter.*` / `argSchema` pattern). 
The two options are mutually exclusive.
+
+When an output schema is declared, the route body must be JSON (a JSON string, 
`Map`, or `List`). Camel parses it into structured content and forwards it 
through the MCP bridge as `CallToolResult.structuredContent`. The text 
representation remains available for LLM adapters (LangChain4j, Spring AI) that 
consume string tool results.
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("ai-tool:getWeather?tags=weather&description=Get weather"
+     + "&outputSchema=classpath:schemas/weather-result.json")
+    .process(exchange -> exchange.getMessage().setBody(
+        "{\"temperature\":21.5,\"unit\":\"celsius\"}"));
+----
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: ai-tool:getWeather
+      parameters:
+        tags: weather
+        description: "Get weather"
+        outputParameter.temperature: number
+        outputParameter.unit: string
+      steps:
+        - setBody:
+            constant: '{"temperature":21.5,"unit":"celsius"}'
+----
+====
+
+Flat `outputParameter.*` options use the same sub-option syntax as input 
`parameter.*`:
+
+* `outputParameter.NAME=TYPE` — field type (`string`, `integer`, `number`, 
`boolean`)
+* `outputParameter.NAME.description=TEXT` — field description in the generated 
JSON Schema
+* `outputParameter.NAME.required=true` — marks the field as required in the 
output schema
+* `outputParameter.NAME.enum=val1,val2` — restricts allowed values
+
+`outputSchema` supports Camel resource references such as 
`classpath:schemas/weather-result.json`.
+
 === MCP Tool Annotation Hints
 
 When exposing `ai-tool` routes through the MCP Server component, you can 
declare optional behavioral hints aligned with the MCP specification 
(`ToolAnnotations`). MCP clients may use these hints for per-tool policy (for 
example auto-approving read-only tools or requiring confirmation before 
destructive ones).
diff --git 
a/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolComponent.java
 
b/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolComponent.java
index da179d5f0341..007bcc115696 100644
--- 
a/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolComponent.java
+++ 
b/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolComponent.java
@@ -70,6 +70,12 @@ public class AiToolComponent extends DefaultComponent {
                     .collect(Collectors.toMap(Map.Entry::getKey, e -> 
e.getValue().toString())));
         }
 
+        Map<String, Object> outputToolParameters = 
PropertiesHelper.extractProperties(parameters, "outputParameter.");
+        if (!outputToolParameters.isEmpty()) {
+            config.setOutputParameters(outputToolParameters.entrySet().stream()
+                    .collect(Collectors.toMap(Map.Entry::getKey, e -> 
e.getValue().toString())));
+        }
+
         AiToolEndpoint endpoint = new AiToolEndpoint(uri, this, toolName, 
config);
 
         setProperties(endpoint, parameters);
diff --git 
a/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolConfiguration.java
 
b/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolConfiguration.java
index 715ef848e10a..6fcfbb326e0e 100644
--- 
a/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolConfiguration.java
+++ 
b/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolConfiguration.java
@@ -61,6 +61,21 @@ public class AiToolConfiguration implements Cloneable {
     @Metadata(label = "consumer", supportFileReference = true, largeInput = 
true, inputLanguage = "json")
     private String argSchema;
 
+    @Metadata(label = "consumer")
+    @UriParam(description = "Tool output schema fields. "
+                            + "Format: outputParameter.NAME=TYPE, 
outputParameter.NAME.description=TEXT. "
+                            + "Supported types: string, integer, number, 
boolean. "
+                            + "Mutually exclusive with outputSchema.",
+              prefix = "outputParameter.", multiValue = true)
+    private Map<String, String> outputParameters;
+
+    @UriParam(description = "Raw JSON Schema describing the tool's structured 
output. Supports inline JSON and "
+                            + "resource references (classpath:, file:, 
resource:). Mutually exclusive with the "
+                            + "outputParameter multi-value options. When 
declared, the route body is parsed as JSON "
+                            + "and exposed as structured content to MCP 
clients.")
+    @Metadata(label = "consumer", supportFileReference = true, largeInput = 
true, inputLanguage = "json")
+    private String outputSchema;
+
     @Metadata(label = "consumer")
     @UriParam(description = "Optional display title for MCP tool listings. 
Advisory hint for MCP clients only.")
     private String title;
@@ -120,6 +135,22 @@ public class AiToolConfiguration implements Cloneable {
         this.argSchema = argSchema;
     }
 
+    public Map<String, String> getOutputParameters() {
+        return outputParameters;
+    }
+
+    public void setOutputParameters(Map<String, String> outputParameters) {
+        this.outputParameters = outputParameters;
+    }
+
+    public String getOutputSchema() {
+        return outputSchema;
+    }
+
+    public void setOutputSchema(String outputSchema) {
+        this.outputSchema = outputSchema;
+    }
+
     public String getTitle() {
         return title;
     }
@@ -166,6 +197,9 @@ public class AiToolConfiguration implements Cloneable {
             if (this.parameters != null) {
                 copy.parameters = new HashMap<>(this.parameters);
             }
+            if (this.outputParameters != null) {
+                copy.outputParameters = new HashMap<>(this.outputParameters);
+            }
             return copy;
         } catch (CloneNotSupportedException e) {
             throw new RuntimeCamelException(e);
diff --git 
a/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolConsumer.java
 
b/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolConsumer.java
index 1f9c587bb7f4..9309dfe6241a 100644
--- 
a/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolConsumer.java
+++ 
b/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolConsumer.java
@@ -52,8 +52,14 @@ public class AiToolConsumer extends DefaultConsumer {
         String argSchema = configuration.getArgSchema();
         AiToolParameterHelper.validateParameterSourceExclusive(params, 
argSchema);
 
+        Map<String, String> outputParams = configuration.getOutputParameters();
+        String outputSchema = configuration.getOutputSchema();
+        AiToolParameterHelper.validateOutputSourceExclusive(outputParams, 
outputSchema);
+
         Map<String, AiToolParameterHelper.ParameterDef> parameterDefs = 
Map.of();
         String jsonSchema = null;
+        Map<String, AiToolParameterHelper.ParameterDef> outputParameterDefs = 
Map.of();
+        String outputJsonSchema = null;
 
         if (params != null && !params.isEmpty()) {
             parameterDefs = 
AiToolParameterHelper.parseParameterMetadata(params);
@@ -62,6 +68,13 @@ public class AiToolConsumer extends DefaultConsumer {
             jsonSchema = 
AiToolParameterHelper.resolveArgSchema(getEndpoint().getCamelContext(), 
argSchema);
         }
 
+        if (outputParams != null && !outputParams.isEmpty()) {
+            outputParameterDefs = 
AiToolParameterHelper.parseParameterMetadata(outputParams);
+            outputJsonSchema = 
AiToolParameterHelper.buildJsonSchemaFromDefs(outputParameterDefs);
+        } else if (outputSchema != null && !outputSchema.isBlank()) {
+            outputJsonSchema = 
AiToolParameterHelper.resolveOutputSchema(getEndpoint().getCamelContext(), 
outputSchema);
+        }
+
         String desc = configuration.getDescription();
         if (desc == null || desc.isBlank()) {
             desc = toolName;
@@ -69,7 +82,7 @@ public class AiToolConsumer extends DefaultConsumer {
 
         AiToolAnnotations annotations = 
AiToolAnnotations.fromConfiguration(configuration);
         registeredSpec = new AiToolSpec(
-                toolName, desc, parameterDefs, jsonSchema, annotations, this);
+                toolName, desc, parameterDefs, jsonSchema, 
outputParameterDefs, outputJsonSchema, annotations, this);
 
         String tags = configuration.getTags();
         String[] parsedTags = (tags != null && !tags.isBlank())
diff --git 
a/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolExecutor.java
 
b/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolExecutor.java
index 8f918232d77a..850af4aebc4a 100644
--- 
a/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolExecutor.java
+++ 
b/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolExecutor.java
@@ -151,11 +151,28 @@ public final class AiToolExecutor {
 
             String result = exchange.getMessage().getBody(String.class);
             LOG.debug("Tool '{}' execution completed successfully", toolName);
-            return new AiToolResult.Success(result != null ? result : "No 
result");
+            return buildSuccessResult(spec, exchange, result);
         } catch (Exception e) {
             LOG.error("Error executing tool '{}': {}", toolName, 
e.getMessage(), e);
             return new AiToolResult.ExecutionError(
                     String.format("Error executing tool '%s': %s", toolName, 
e.getMessage()), e);
         }
     }
+
+    private static AiToolResult buildSuccessResult(AiToolSpec spec, Exchange 
exchange, String stringBody) {
+        String outputSchema = spec.getOutputJsonSchema();
+        if (outputSchema == null || outputSchema.isBlank()) {
+            return new AiToolResult.Success(stringBody != null ? stringBody : 
"No result");
+        }
+
+        Object body = exchange.getMessage().getBody();
+        try {
+            Object structured = 
AiToolParameterHelper.parseStructuredOutput(body);
+            String text = 
AiToolParameterHelper.structuredContentToText(structured, body);
+            return new AiToolResult.Success(text, structured);
+        } catch (IllegalArgumentException e) {
+            return new AiToolResult.ExecutionError(
+                    String.format("Error executing tool '%s': %s", 
spec.getName(), e.getMessage()), e);
+        }
+    }
 }
diff --git 
a/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolParameterHelper.java
 
b/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolParameterHelper.java
index 2be215949b48..f80b906305e3 100644
--- 
a/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolParameterHelper.java
+++ 
b/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolParameterHelper.java
@@ -171,6 +171,18 @@ public final class AiToolParameterHelper {
         }
     }
 
+    /**
+     * Validates that flat {@code outputParameter.*} metadata and {@code 
outputSchema} are not both configured.
+     */
+    public static void validateOutputSourceExclusive(Map<String, String> 
outputParameters, String outputSchema) {
+        boolean hasOutputParameters = outputParameters != null && 
!outputParameters.isEmpty();
+        boolean hasOutputSchema = outputSchema != null && 
!outputSchema.isBlank();
+        if (hasOutputParameters && hasOutputSchema) {
+            throw new IllegalArgumentException(
+                    "outputSchema and outputParameter.* are mutually exclusive 
on ai-tool endpoints");
+        }
+    }
+
     /**
      * Resolves, validates, and normalizes a raw JSON Schema for tool input.
      */
@@ -190,6 +202,73 @@ public final class AiToolParameterHelper {
         return root.toJson();
     }
 
+    /**
+     * Resolves and normalizes a raw JSON Schema describing tool output. Unlike
+     * {@link #resolveArgSchema(CamelContext, String)}, the schema may 
describe any JSON type (object, array, string,
+     * etc.).
+     */
+    public static String resolveOutputSchema(CamelContext camelContext, String 
outputSchema) {
+        if (outputSchema == null || outputSchema.isBlank()) {
+            throw new IllegalArgumentException("outputSchema must not be 
blank");
+        }
+
+        String resolved = 
camelContext.resolvePropertyPlaceholders(outputSchema);
+        String content = resolveResourceContent(camelContext, resolved, 
"outputSchema");
+        if (content != null) {
+            resolved = content;
+        }
+
+        JsonObject root = parseJsonObject(resolved, outputSchema, 
"outputSchema");
+        return root.toJson();
+    }
+
+    /**
+     * Parses a route body into structured JSON content when an output schema 
is declared.
+     */
+    public static Object parseStructuredOutput(Object body) {
+        if (body == null) {
+            throw new IllegalArgumentException(
+                    "Route body must not be null when an output schema is 
declared");
+        }
+        if (body instanceof Map<?, ?> || body instanceof List<?> || body 
instanceof Number || body instanceof Boolean) {
+            return body;
+        }
+        if (body instanceof String text) {
+            if (text.isBlank()) {
+                throw new IllegalArgumentException(
+                        "Route body must not be blank when an output schema is 
declared");
+            }
+            try {
+                return Jsoner.deserialize(text);
+            } catch (DeserializationException e) {
+                throw new IllegalArgumentException(
+                        "Route body must be valid JSON when an output schema 
is declared", e);
+            }
+        }
+        throw new IllegalArgumentException(
+                "Route body must be JSON (String, Map, or List) when an output 
schema is declared, but was: "
+                                           + body.getClass().getSimpleName());
+    }
+
+    /**
+     * Serializes structured JSON content to a text representation for LLM 
adapters.
+     */
+    public static String structuredContentToText(Object structuredContent, 
Object originalBody) {
+        if (structuredContent == null) {
+            return "No result";
+        }
+        if (originalBody instanceof String text && !text.isBlank()) {
+            return text.trim();
+        }
+        if (structuredContent instanceof JsonObject jsonObject) {
+            return jsonObject.toJson();
+        }
+        if (structuredContent instanceof JsonArray jsonArray) {
+            return jsonArray.toJson();
+        }
+        return Jsoner.serialize(structuredContent);
+    }
+
     /**
      * Returns top-level property names declared in a JSON Schema object.
      */
@@ -227,19 +306,23 @@ public final class AiToolParameterHelper {
     }
 
     private static JsonObject parseJsonObject(String json, String 
originalValue) {
+        return parseJsonObject(json, originalValue, "argSchema");
+    }
+
+    private static JsonObject parseJsonObject(String json, String 
originalValue, String context) {
         try {
             Object parsed = Jsoner.deserialize(json);
             if (parsed == null) {
-                throw new IllegalArgumentException("argSchema must be a JSON 
object, but was: null");
+                throw new IllegalArgumentException(context + " must be a JSON 
object, but was: null");
             }
             if (!(parsed instanceof JsonObject root)) {
                 throw new IllegalArgumentException(
-                        "argSchema must be a JSON object, but was: " + 
parsed.getClass().getSimpleName());
+                        context + " must be a JSON object, but was: " + 
parsed.getClass().getSimpleName());
             }
             return root;
         } catch (DeserializationException e) {
             throw new IllegalArgumentException(
-                    "argSchema does not contain valid JSON. Provided value: " 
+ originalValue, e);
+                    context + " does not contain valid JSON. Provided value: " 
+ originalValue, e);
         }
     }
 
@@ -295,6 +378,10 @@ public final class AiToolParameterHelper {
     }
 
     private static String resolveResourceContent(CamelContext camelContext, 
String property) {
+        return resolveResourceContent(camelContext, property, "argSchema");
+    }
+
+    private static String resolveResourceContent(CamelContext camelContext, 
String property, String context) {
         try {
             if (ResourceHelper.hasScheme(property)) {
                 try (InputStream is = 
ResourceHelper.resolveMandatoryResourceAsInputStream(camelContext, property)) {
@@ -307,7 +394,7 @@ public final class AiToolParameterHelper {
                 }
             }
         } catch (IOException e) {
-            throw new IllegalArgumentException("Failed to load argSchema 
resource: " + property, e);
+            throw new IllegalArgumentException("Failed to load " + context + " 
resource: " + property, e);
         } catch (Exception e) {
             // not a resolvable resource URI — fall through and treat as 
inline JSON content
         }
diff --git 
a/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolResult.java
 
b/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolResult.java
index 0eb750db9dfb..0345db189efb 100644
--- 
a/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolResult.java
+++ 
b/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolResult.java
@@ -34,9 +34,14 @@ public sealed interface AiToolResult {
     /**
      * The route executed successfully and produced a result.
      *
-     * @param value the route result as a string
+     * @param value             the route result as a string (JSON text when 
structured output is configured)
+     * @param structuredContent typed JSON value when an output schema is 
declared, otherwise {@code null}
      */
-    record Success(String value) implements AiToolResult {
+    record Success(String value, Object structuredContent) implements 
AiToolResult {
+
+        public Success(String value) {
+            this(value, null);
+        }
     }
 
     /**
diff --git 
a/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolSpec.java
 
b/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolSpec.java
index 3a21fb3bbe4a..2ee712b52c62 100644
--- 
a/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolSpec.java
+++ 
b/components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolSpec.java
@@ -38,6 +38,8 @@ public final class AiToolSpec {
     private final String description;
     private final Map<String, AiToolParameterHelper.ParameterDef> 
parameterDefs;
     private final String parametersJsonSchema;
+    private final Map<String, AiToolParameterHelper.ParameterDef> 
outputParameterDefs;
+    private final String outputJsonSchema;
     private final Set<String> declaredArgumentNames;
     private final Set<String> requiredArgumentNames;
     private final AiToolAnnotations annotations;
@@ -48,12 +50,16 @@ public final class AiToolSpec {
                       String description,
                       Map<String, AiToolParameterHelper.ParameterDef> 
parameterDefs,
                       String parametersJsonSchema,
+                      Map<String, AiToolParameterHelper.ParameterDef> 
outputParameterDefs,
+                      String outputJsonSchema,
                       AiToolAnnotations annotations,
                       DefaultConsumer consumer) {
         this.name = name;
         this.description = description;
         this.parameterDefs = parameterDefs != null ? 
Collections.unmodifiableMap(parameterDefs) : Map.of();
         this.parametersJsonSchema = parametersJsonSchema;
+        this.outputParameterDefs = outputParameterDefs != null ? 
Collections.unmodifiableMap(outputParameterDefs) : Map.of();
+        this.outputJsonSchema = outputJsonSchema;
         if (!this.parameterDefs.isEmpty()) {
             this.declaredArgumentNames = 
Set.copyOf(this.parameterDefs.keySet());
             this.requiredArgumentNames = this.parameterDefs.entrySet().stream()
@@ -95,6 +101,20 @@ public final class AiToolSpec {
         return parametersJsonSchema;
     }
 
+    /**
+     * Structured output field definitions declared via flat {@code 
outputParameter.*} metadata.
+     */
+    public Map<String, AiToolParameterHelper.ParameterDef> 
getOutputParameterDefs() {
+        return outputParameterDefs;
+    }
+
+    /**
+     * Pre-built JSON Schema string describing the tool's structured output, 
or {@code null} when none is declared.
+     */
+    public String getOutputJsonSchema() {
+        return outputJsonSchema;
+    }
+
     /**
      * Top-level argument names accepted by this tool. Derived from flat 
parameter definitions or from a raw
      * {@code argSchema}'s top-level {@code properties} map.
@@ -140,6 +160,8 @@ public final class AiToolSpec {
                 && Objects.equals(description, that.description)
                 && Objects.equals(parameterDefs, that.parameterDefs)
                 && Objects.equals(parametersJsonSchema, 
that.parametersJsonSchema)
+                && Objects.equals(outputParameterDefs, 
that.outputParameterDefs)
+                && Objects.equals(outputJsonSchema, that.outputJsonSchema)
                 && Objects.equals(declaredArgumentNames, 
that.declaredArgumentNames)
                 && Objects.equals(requiredArgumentNames, 
that.requiredArgumentNames)
                 && Objects.equals(annotations, that.annotations)
@@ -148,7 +170,8 @@ public final class AiToolSpec {
 
     @Override
     public int hashCode() {
-        return Objects.hash(name, description, parameterDefs, 
parametersJsonSchema, declaredArgumentNames,
+        return Objects.hash(name, description, parameterDefs, 
parametersJsonSchema, outputParameterDefs,
+                outputJsonSchema, declaredArgumentNames,
                 requiredArgumentNames, annotations, consumer);
     }
 
diff --git 
a/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolEndpointLifecycleTest.java
 
b/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolEndpointLifecycleTest.java
index e9b1aa829455..0238416bc352 100644
--- 
a/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolEndpointLifecycleTest.java
+++ 
b/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolEndpointLifecycleTest.java
@@ -383,6 +383,59 @@ public class AiToolEndpointLifecycleTest extends 
CamelTestSupport {
         assertThat(annotations.openWorldHint()).isTrue();
     }
 
+    @Test
+    void testOutputSchemaToolRegisteredOnStart() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            public void configure() {
+                from("ai-tool:getWeatherStructured"
+                     + "?tags=weather-structured"
+                     + "&description=Get weather"
+                     + 
"&outputSchema=classpath:output-schemas/weather-result.json")
+                        
.setBody(constant("{\"temperature\":21.5,\"unit\":\"celsius\"}"));
+            }
+        });
+
+        AiToolSpec spec = 
AiToolRegistry.getOrCreate(context).getToolsByTag("weather-structured").iterator().next();
+
+        assertThat(spec.getName()).isEqualTo("getWeatherStructured");
+
+        assertThat(spec.getOutputParameterDefs()).isEmpty();
+        
assertThat(spec.getOutputJsonSchema()).isNotNull().contains("\"temperature\"");
+    }
+
+    @Test
+    void testOutputParameterToolRegisteredOnStart() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            public void configure() {
+                from("ai-tool:getTemperature"
+                     + "?tags=weather-output"
+                     + "&description=Get temperature"
+                     + "&outputParameter.temperature=number"
+                     + "&outputParameter.unit=string")
+                        
.setBody(constant("{\"temperature\":18,\"unit\":\"celsius\"}"));
+            }
+        });
+
+        AiToolSpec spec = 
AiToolRegistry.getOrCreate(context).getToolsByTag("weather-output").iterator().next();
+
+        assertThat(spec.getOutputParameterDefs()).containsKeys("temperature", 
"unit");
+        
assertThat(spec.getOutputJsonSchema()).contains("\"temperature\"").contains("\"unit\"");
+    }
+
+    @Test
+    void testOutputSchemaAndOutputParametersAreMutuallyExclusive() {
+        assertThatThrownBy(() -> context.addRoutes(new RouteBuilder() {
+            public void configure() {
+                from("ai-tool:invalidOutput"
+                     + "?tags=test"
+                     + "&outputParameter.temperature=number"
+                     + "&outputSchema={\"type\":\"object\"}")
+                        .setBody(constant("invalid"));
+            }
+        })).isInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("mutually exclusive");
+    }
+
     @Test
     void testGetAllToolsReturnsAllPools() throws Exception {
         context.addRoutes(new RouteBuilder() {
diff --git 
a/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolExecutorTest.java
 
b/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolExecutorTest.java
index 028be078bd31..34c71452100f 100644
--- 
a/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolExecutorTest.java
+++ 
b/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolExecutorTest.java
@@ -85,6 +85,32 @@ public class AiToolExecutorTest extends CamelTestSupport {
                             List<?> items = 
exchange.getMessage().getHeader("items", List.class);
                             exchange.getMessage().setBody("order:" + 
customer.get("id") + ":" + items.size());
                         });
+
+                from("ai-tool:getWeather"
+                     + "?tags=test"
+                     + "&description=Get weather"
+                     + 
"&outputSchema=classpath:output-schemas/weather-result.json")
+                        
.setBody(constant("{\"temperature\":21.5,\"unit\":\"celsius\"}"));
+
+                from("ai-tool:getWeatherMap"
+                     + "?tags=test"
+                     + "&description=Get weather as map"
+                     + "&outputParameter.temperature=number"
+                     + "&outputParameter.unit=string")
+                        .process(exchange -> exchange.getMessage().setBody(
+                                Map.of("temperature", 18, "unit", "celsius")));
+
+                from("ai-tool:badStructuredOutput"
+                     + "?tags=test"
+                     + "&description=Returns invalid JSON"
+                     + 
"&outputSchema=classpath:output-schemas/weather-result.json")
+                        .setBody(constant("not-json"));
+
+                from("ai-tool:nullStructuredOutput"
+                     + "?tags=test"
+                     + "&description=Returns null body with output schema"
+                     + 
"&outputSchema=classpath:output-schemas/weather-result.json")
+                        .setBody(constant((Object) null));
             }
         };
     }
@@ -217,7 +243,7 @@ public class AiToolExecutorTest extends CamelTestSupport {
 
     @Test
     public void testExecuteReturnsExecutionErrorForNullConsumer() {
-        AiToolSpec spec = new AiToolSpec("ghostTool", "A tool with no 
consumer", Map.of(), null, null, null);
+        AiToolSpec spec = new AiToolSpec("ghostTool", "A tool with no 
consumer", Map.of(), null, Map.of(), null, null, null);
         Exchange exchange = new DefaultExchange(context);
 
         AiToolResult result = AiToolExecutor.execute(spec, null, exchange);
@@ -235,7 +261,7 @@ public class AiToolExecutorTest extends CamelTestSupport {
         DefaultConsumer consumerWithNullProcessor = new 
DefaultConsumer(endpoint, null);
 
         AiToolSpec spec = new AiToolSpec(
-                "nullProc", "test", Map.of(), null, null, 
consumerWithNullProcessor);
+                "nullProc", "test", Map.of(), null, Map.of(), null, null, 
consumerWithNullProcessor);
         Exchange exchange = new DefaultExchange(context);
 
         AiToolResult result = AiToolExecutor.execute(spec, null, exchange);
@@ -370,7 +396,9 @@ public class AiToolExecutorTest extends CamelTestSupport {
                   "required": ["country"]
                 }
                 """;
-        AiToolSpec spec = new AiToolSpec("badRequired", "test", Map.of(), 
schema, null, findSpec("greetUser").getConsumer());
+        AiToolSpec spec = new AiToolSpec(
+                "badRequired", "test", Map.of(), schema, Map.of(), null, null,
+                findSpec("greetUser").getConsumer());
         Exchange exchange = new DefaultExchange(context);
 
         Map<String, Object> arguments = Map.of("country", "Paris");
@@ -381,6 +409,54 @@ public class AiToolExecutorTest extends CamelTestSupport {
         assertThat(((AiToolResult.ArgumentError) 
result).message()).contains("Missing required argument 'country'");
     }
 
+    @Test
+    public void testExecuteReturnsStructuredContentFromJsonString() {
+        AiToolSpec spec = findSpec("getWeather");
+        Exchange exchange = new DefaultExchange(context);
+
+        AiToolResult result = AiToolExecutor.execute(spec, Map.of(), exchange);
+
+        assertThat(result).isInstanceOf(AiToolResult.Success.class);
+        AiToolResult.Success success = (AiToolResult.Success) result;
+        assertThat(success.value()).contains("\"temperature\":21.5");
+        assertThat(success.structuredContent()).isNotNull();
+    }
+
+    @Test
+    public void testExecuteReturnsStructuredContentFromMapBody() {
+        AiToolSpec spec = findSpec("getWeatherMap");
+        Exchange exchange = new DefaultExchange(context);
+
+        AiToolResult result = AiToolExecutor.execute(spec, Map.of(), exchange);
+
+        assertThat(result).isInstanceOf(AiToolResult.Success.class);
+        AiToolResult.Success success = (AiToolResult.Success) result;
+        assertThat(success.structuredContent()).isInstanceOf(Map.class);
+        assertThat(success.value()).contains("\"temperature\":18");
+    }
+
+    @Test
+    public void testExecuteReturnsExecutionErrorForInvalidStructuredOutput() {
+        AiToolSpec spec = findSpec("badStructuredOutput");
+        Exchange exchange = new DefaultExchange(context);
+
+        AiToolResult result = AiToolExecutor.execute(spec, Map.of(), exchange);
+
+        assertThat(result).isInstanceOf(AiToolResult.ExecutionError.class);
+        assertThat(((AiToolResult.ExecutionError) 
result).message()).contains("valid JSON");
+    }
+
+    @Test
+    public void testExecuteReturnsExecutionErrorForNullBodyWithOutputSchema() {
+        AiToolSpec spec = findSpec("nullStructuredOutput");
+        Exchange exchange = new DefaultExchange(context);
+
+        AiToolResult result = AiToolExecutor.execute(spec, Map.of(), exchange);
+
+        assertThat(result).isInstanceOf(AiToolResult.ExecutionError.class);
+        assertThat(((AiToolResult.ExecutionError) 
result).message()).contains("must not be null");
+    }
+
     private AiToolSpec findSpec(String toolName) {
         return 
AiToolRegistry.getOrCreate(context).getToolsByTag("test").stream()
                 .filter(s -> toolName.equals(s.getName()))
diff --git 
a/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolParameterHelperTest.java
 
b/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolParameterHelperTest.java
index 81068d72ba90..aa4c8ddbea79 100644
--- 
a/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolParameterHelperTest.java
+++ 
b/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolParameterHelperTest.java
@@ -371,4 +371,76 @@ public class AiToolParameterHelperTest {
                 .isInstanceOf(IllegalArgumentException.class)
                 .hasMessageContaining("properties must be a JSON object");
     }
+
+    @Test
+    void testValidateOutputSourceExclusive() {
+        assertThatThrownBy(() -> 
AiToolParameterHelper.validateOutputSourceExclusive(
+                Map.of("temperature", "number"), "{\"type\":\"object\"}"))
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("mutually exclusive");
+    }
+
+    @Test
+    void testResolveOutputSchemaFromInlineJson() {
+        String schema = 
AiToolParameterHelper.resolveOutputSchema(camelContext, """
+                {
+                  "type": "object",
+                  "properties": {
+                    "temperature": { "type": "number" }
+                  }
+                }
+                """);
+
+        assertThat(schema).contains("\"temperature\"");
+    }
+
+    @Test
+    void testResolveOutputSchemaAllowsNonObjectRootType() {
+        String schema = 
AiToolParameterHelper.resolveOutputSchema(camelContext, 
"{\"type\":\"string\"}");
+
+        assertThat(schema).contains("\"type\":\"string\"");
+    }
+
+    @Test
+    void testResolveOutputSchemaFromClasspath() {
+        String schema = AiToolParameterHelper.resolveOutputSchema(camelContext,
+                "classpath:output-schemas/weather-result.json");
+
+        assertThat(schema).contains("\"temperature\"").contains("\"unit\"");
+    }
+
+    @Test
+    void testParseStructuredOutputFromJsonString() {
+        Object structured = AiToolParameterHelper.parseStructuredOutput("""
+                {"temperature":21.5,"unit":"celsius"}
+                """);
+
+        assertThat(structured).isInstanceOf(JsonObject.class);
+        assertThat(((JsonObject) 
structured).get("temperature").toString()).isEqualTo("21.5");
+        assertThat(((JsonObject) 
structured).getString("unit")).isEqualTo("celsius");
+    }
+
+    @Test
+    void testParseStructuredOutputFromMap() {
+        Map<String, Object> body = Map.of("temperature", 21.5, "unit", 
"celsius");
+
+        Object structured = AiToolParameterHelper.parseStructuredOutput(body);
+
+        assertThat(structured).isSameAs(body);
+    }
+
+    @Test
+    void testParseStructuredOutputRejectsInvalidJsonString() {
+        assertThatThrownBy(() -> 
AiToolParameterHelper.parseStructuredOutput("{not-json"))
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("valid JSON");
+    }
+
+    @Test
+    void testStructuredContentToTextUsesOriginalJsonString() {
+        String json = "{\"temperature\":21.5,\"unit\":\"celsius\"}";
+        JsonObject structured = (JsonObject) 
AiToolParameterHelper.parseStructuredOutput(json);
+
+        assertThat(AiToolParameterHelper.structuredContentToText(structured, 
json)).isEqualTo(json);
+    }
 }
diff --git 
a/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolRegistryListenerTest.java
 
b/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolRegistryListenerTest.java
index 5244083f452d..25ea81659250 100644
--- 
a/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolRegistryListenerTest.java
+++ 
b/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolRegistryListenerTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.component.ai.tool;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -136,7 +137,7 @@ class AiToolRegistryListenerTest {
     }
 
     private static AiToolSpec spec(String name) {
-        return new AiToolSpec(name, name + " description", null, null, null, 
null);
+        return new AiToolSpec(name, name + " description", null, null, 
Map.of(), null, null, null);
     }
 
     private record Event(String type, String tag, AiToolSpec spec) {
diff --git 
a/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolRegistryTest.java
 
b/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolRegistryTest.java
index d65a153a5c8f..78fabd961758 100644
--- 
a/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolRegistryTest.java
+++ 
b/components/camel-ai/camel-ai-tool/src/test/java/org/apache/camel/component/ai/tool/AiToolRegistryTest.java
@@ -43,7 +43,7 @@ public class AiToolRegistryTest {
 
     @Test
     public void testPutAndGetTool() {
-        AiToolSpec spec = new AiToolSpec("getTool", "A test tool", Map.of(), 
null, null, null);
+        AiToolSpec spec = new AiToolSpec("getTool", "A test tool", Map.of(), 
null, Map.of(), null, null, null);
 
         registry.put("weather", spec);
 
@@ -56,7 +56,7 @@ public class AiToolRegistryTest {
 
     @Test
     public void testRemoveTool() {
-        AiToolSpec spec = new AiToolSpec("getTool", "A test tool", Map.of(), 
null, null, null);
+        AiToolSpec spec = new AiToolSpec("getTool", "A test tool", Map.of(), 
null, Map.of(), null, null, null);
 
         registry.put("weather", spec);
         assertThat(registry.getTools().get("weather"))
@@ -71,8 +71,8 @@ public class AiToolRegistryTest {
 
     @Test
     public void testMultipleToolsWithSameTag() {
-        AiToolSpec spec1 = new AiToolSpec("tool1", "Tool 1", Map.of(), null, 
null, null);
-        AiToolSpec spec2 = new AiToolSpec("tool2", "Tool 2", Map.of(), null, 
null, null);
+        AiToolSpec spec1 = new AiToolSpec("tool1", "Tool 1", Map.of(), null, 
Map.of(), null, null, null);
+        AiToolSpec spec2 = new AiToolSpec("tool2", "Tool 2", Map.of(), null, 
Map.of(), null, null, null);
 
         registry.put("assistant", spec1);
         registry.put("assistant", spec2);
@@ -84,8 +84,8 @@ public class AiToolRegistryTest {
 
     @Test
     public void testRemoveOneOfMultipleTools() {
-        AiToolSpec spec1 = new AiToolSpec("tool1", "Tool 1", Map.of(), null, 
null, null);
-        AiToolSpec spec2 = new AiToolSpec("tool2", "Tool 2", Map.of(), null, 
null, null);
+        AiToolSpec spec1 = new AiToolSpec("tool1", "Tool 1", Map.of(), null, 
Map.of(), null, null, null);
+        AiToolSpec spec2 = new AiToolSpec("tool2", "Tool 2", Map.of(), null, 
Map.of(), null, null, null);
 
         registry.put("assistant", spec1);
         registry.put("assistant", spec2);
@@ -101,8 +101,8 @@ public class AiToolRegistryTest {
 
     @Test
     public void testTagIsolation() {
-        AiToolSpec weatherSpec = new AiToolSpec("weather", "Weather", 
Map.of(), null, null, null);
-        AiToolSpec emailSpec = new AiToolSpec("email", "Email", Map.of(), 
null, null, null);
+        AiToolSpec weatherSpec = new AiToolSpec("weather", "Weather", 
Map.of(), null, Map.of(), null, null, null);
+        AiToolSpec emailSpec = new AiToolSpec("email", "Email", Map.of(), 
null, Map.of(), null, null, null);
 
         registry.put("weather", weatherSpec);
         registry.put("email", emailSpec);
@@ -120,7 +120,7 @@ public class AiToolRegistryTest {
 
     @Test
     public void testRemoveFromNonExistentTag() {
-        AiToolSpec spec = new AiToolSpec("tool", "A tool", Map.of(), null, 
null, null);
+        AiToolSpec spec = new AiToolSpec("tool", "A tool", Map.of(), null, 
Map.of(), null, null, null);
         registry.remove("nonexistent", spec);
 
         assertThat(registry.getTools())
@@ -133,7 +133,7 @@ public class AiToolRegistryTest {
 
     @Test
     public void testDefaultPoolPutAndRemove() {
-        AiToolSpec spec = new AiToolSpec("defaultTool", "Default", Map.of(), 
null, null, null);
+        AiToolSpec spec = new AiToolSpec("defaultTool", "Default", Map.of(), 
null, Map.of(), null, null, null);
 
         registry.putDefault(spec);
         assertThat(registry.getDefaultTools())
@@ -149,8 +149,8 @@ public class AiToolRegistryTest {
 
     @Test
     public void testGetToolsByTagIncludesDefaultPool() {
-        AiToolSpec taggedTool = new AiToolSpec("tagged", "Tagged", Map.of(), 
null, null, null);
-        AiToolSpec defaultTool = new AiToolSpec("default", "Default", 
Map.of(), null, null, null);
+        AiToolSpec taggedTool = new AiToolSpec("tagged", "Tagged", Map.of(), 
null, Map.of(), null, null, null);
+        AiToolSpec defaultTool = new AiToolSpec("default", "Default", 
Map.of(), null, Map.of(), null, null, null);
 
         registry.put("weather", taggedTool);
         registry.putDefault(defaultTool);
@@ -164,7 +164,7 @@ public class AiToolRegistryTest {
 
     @Test
     public void testGetToolsByTagWithNoMatchReturnsDefaultOnly() {
-        AiToolSpec defaultTool = new AiToolSpec("default", "Default", 
Map.of(), null, null, null);
+        AiToolSpec defaultTool = new AiToolSpec("default", "Default", 
Map.of(), null, Map.of(), null, null, null);
         registry.putDefault(defaultTool);
 
         assertThat(registry.getToolsByTag("nonexistent"))
@@ -192,7 +192,7 @@ public class AiToolRegistryTest {
                 }
                 for (int i = 0; i < opsPerThread; i++) {
                     AiToolSpec spec = new AiToolSpec(
-                            "tool-" + threadId + "-" + i, "desc", Map.of(), 
null, null, null);
+                            "tool-" + threadId + "-" + i, "desc", Map.of(), 
null, Map.of(), null, null, null);
                     registry.put("concurrent", spec);
                     registry.getToolsByTag("concurrent");
                     registry.getAllTools();
@@ -215,8 +215,8 @@ public class AiToolRegistryTest {
 
     @Test
     public void testDuplicateToolNameUnderSameTagThrows() {
-        AiToolSpec spec1 = new AiToolSpec("sameName", "First", Map.of(), null, 
null, null);
-        AiToolSpec spec2 = new AiToolSpec("sameName", "Second", Map.of(), 
null, null, null);
+        AiToolSpec spec1 = new AiToolSpec("sameName", "First", Map.of(), null, 
Map.of(), null, null, null);
+        AiToolSpec spec2 = new AiToolSpec("sameName", "Second", Map.of(), 
null, Map.of(), null, null, null);
 
         registry.put("weather", spec1);
 
@@ -233,8 +233,8 @@ public class AiToolRegistryTest {
 
     @Test
     public void testDuplicateToolNameInDefaultPoolThrows() {
-        AiToolSpec spec1 = new AiToolSpec("sameName", "First", Map.of(), null, 
null, null);
-        AiToolSpec spec2 = new AiToolSpec("sameName", "Second", Map.of(), 
null, null, null);
+        AiToolSpec spec1 = new AiToolSpec("sameName", "First", Map.of(), null, 
Map.of(), null, null, null);
+        AiToolSpec spec2 = new AiToolSpec("sameName", "Second", Map.of(), 
null, Map.of(), null, null, null);
 
         registry.putDefault(spec1);
 
@@ -251,8 +251,8 @@ public class AiToolRegistryTest {
 
     @Test
     public void testSameToolNameDifferentTagsIsAllowed() {
-        AiToolSpec spec1 = new AiToolSpec("sameName", "Weather version", 
Map.of(), null, null, null);
-        AiToolSpec spec2 = new AiToolSpec("sameName", "Email version", 
Map.of(), null, null, null);
+        AiToolSpec spec1 = new AiToolSpec("sameName", "Weather version", 
Map.of(), null, Map.of(), null, null, null);
+        AiToolSpec spec2 = new AiToolSpec("sameName", "Email version", 
Map.of(), null, Map.of(), null, null, null);
 
         registry.put("weather", spec1);
         registry.put("email", spec2);
@@ -263,8 +263,8 @@ public class AiToolRegistryTest {
 
     @Test
     public void testReRegisterAfterRemoveIsAllowed() {
-        AiToolSpec spec1 = new AiToolSpec("tool", "First", Map.of(), null, 
null, null);
-        AiToolSpec spec2 = new AiToolSpec("tool", "Second", Map.of(), null, 
null, null);
+        AiToolSpec spec1 = new AiToolSpec("tool", "First", Map.of(), null, 
Map.of(), null, null, null);
+        AiToolSpec spec2 = new AiToolSpec("tool", "Second", Map.of(), null, 
Map.of(), null, null, null);
 
         registry.put("weather", spec1);
         registry.remove("weather", spec1);
@@ -277,9 +277,9 @@ public class AiToolRegistryTest {
 
     @Test
     public void testGetAllToolsMergesTaggedAndDefault() {
-        AiToolSpec tool1 = new AiToolSpec("tool1", "Tool 1", Map.of(), null, 
null, null);
-        AiToolSpec tool2 = new AiToolSpec("tool2", "Tool 2", Map.of(), null, 
null, null);
-        AiToolSpec defaultTool = new AiToolSpec("default", "Default", 
Map.of(), null, null, null);
+        AiToolSpec tool1 = new AiToolSpec("tool1", "Tool 1", Map.of(), null, 
Map.of(), null, null, null);
+        AiToolSpec tool2 = new AiToolSpec("tool2", "Tool 2", Map.of(), null, 
Map.of(), null, null, null);
+        AiToolSpec defaultTool = new AiToolSpec("default", "Default", 
Map.of(), null, Map.of(), null, null, null);
 
         registry.put("weather", tool1);
         registry.put("email", tool2);
diff --git 
a/components/camel-ai/camel-ai-tool/src/test/resources/output-schemas/weather-result.json
 
b/components/camel-ai/camel-ai-tool/src/test/resources/output-schemas/weather-result.json
new file mode 100644
index 000000000000..ccc90493aa04
--- /dev/null
+++ 
b/components/camel-ai/camel-ai-tool/src/test/resources/output-schemas/weather-result.json
@@ -0,0 +1,9 @@
+{
+  "type": "object",
+  "properties": {
+    "temperature": { "type": "number" },
+    "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] }
+  },
+  "required": ["temperature", "unit"],
+  "additionalProperties": false
+}
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/AiToolSpecToLangChain4jTest.java
 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/AiToolSpecToLangChain4jTest.java
index e8904027d1ac..8a1f382b4f45 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/AiToolSpecToLangChain4jTest.java
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/AiToolSpecToLangChain4jTest.java
@@ -41,7 +41,7 @@ class AiToolSpecToLangChain4jTest {
 
     @Test
     void testBasicToolSpecConversion() {
-        AiToolSpec spec = new AiToolSpec("myTool", "A test tool", Map.of(), 
null, null, null);
+        AiToolSpec spec = new AiToolSpec("myTool", "A test tool", Map.of(), 
null, Map.of(), null, null, null);
 
         ToolSpecification result = 
AiToolSpecToLangChain4j.toToolSpecification(spec);
 
@@ -56,7 +56,7 @@ class AiToolSpecToLangChain4jTest {
         rawParams.put("city", "string");
 
         Map<String, AiToolParameterHelper.ParameterDef> defs = 
AiToolParameterHelper.parseParameterMetadata(rawParams);
-        AiToolSpec spec = new AiToolSpec("weather", "Get weather", defs, null, 
null, null);
+        AiToolSpec spec = new AiToolSpec("weather", "Get weather", defs, null, 
Map.of(), null, null, null);
 
         ToolSpecification result = 
AiToolSpecToLangChain4j.toToolSpecification(spec);
 
@@ -71,7 +71,7 @@ class AiToolSpecToLangChain4jTest {
         rawParams.put("count", "integer");
 
         Map<String, AiToolParameterHelper.ParameterDef> defs = 
AiToolParameterHelper.parseParameterMetadata(rawParams);
-        AiToolSpec spec = new AiToolSpec("counter", "Count items", defs, null, 
null, null);
+        AiToolSpec spec = new AiToolSpec("counter", "Count items", defs, null, 
Map.of(), null, null, null);
 
         ToolSpecification result = 
AiToolSpecToLangChain4j.toToolSpecification(spec);
 
@@ -84,7 +84,7 @@ class AiToolSpecToLangChain4jTest {
         rawParams.put("price", "number");
 
         Map<String, AiToolParameterHelper.ParameterDef> defs = 
AiToolParameterHelper.parseParameterMetadata(rawParams);
-        AiToolSpec spec = new AiToolSpec("pricer", "Get price", defs, null, 
null, null);
+        AiToolSpec spec = new AiToolSpec("pricer", "Get price", defs, null, 
Map.of(), null, null, null);
 
         ToolSpecification result = 
AiToolSpecToLangChain4j.toToolSpecification(spec);
 
@@ -97,7 +97,7 @@ class AiToolSpecToLangChain4jTest {
         rawParams.put("active", "boolean");
 
         Map<String, AiToolParameterHelper.ParameterDef> defs = 
AiToolParameterHelper.parseParameterMetadata(rawParams);
-        AiToolSpec spec = new AiToolSpec("checker", "Check status", defs, 
null, null, null);
+        AiToolSpec spec = new AiToolSpec("checker", "Check status", defs, 
null, Map.of(), null, null, null);
 
         ToolSpecification result = 
AiToolSpecToLangChain4j.toToolSpecification(spec);
 
@@ -111,7 +111,7 @@ class AiToolSpecToLangChain4jTest {
         rawParams.put("color.enum", "red,green,blue");
 
         Map<String, AiToolParameterHelper.ParameterDef> defs = 
AiToolParameterHelper.parseParameterMetadata(rawParams);
-        AiToolSpec spec = new AiToolSpec("colorPicker", "Pick a color", defs, 
null, null, null);
+        AiToolSpec spec = new AiToolSpec("colorPicker", "Pick a color", defs, 
null, Map.of(), null, null, null);
 
         ToolSpecification result = 
AiToolSpecToLangChain4j.toToolSpecification(spec);
 
@@ -129,7 +129,7 @@ class AiToolSpecToLangChain4jTest {
         rawParams.put("userId.required", "true");
 
         Map<String, AiToolParameterHelper.ParameterDef> defs = 
AiToolParameterHelper.parseParameterMetadata(rawParams);
-        AiToolSpec spec = new AiToolSpec("userLookup", "Look up user", defs, 
null, null, null);
+        AiToolSpec spec = new AiToolSpec("userLookup", "Look up user", defs, 
null, Map.of(), null, null, null);
 
         ToolSpecification result = 
AiToolSpecToLangChain4j.toToolSpecification(spec);
 
@@ -147,7 +147,7 @@ class AiToolSpecToLangChain4jTest {
         rawParams.put("active", "boolean");
 
         Map<String, AiToolParameterHelper.ParameterDef> defs = 
AiToolParameterHelper.parseParameterMetadata(rawParams);
-        AiToolSpec spec = new AiToolSpec("multiTool", "Multi-param tool", 
defs, null, null, null);
+        AiToolSpec spec = new AiToolSpec("multiTool", "Multi-param tool", 
defs, null, Map.of(), null, null, null);
 
         ToolSpecification result = 
AiToolSpecToLangChain4j.toToolSpecification(spec);
 
@@ -189,7 +189,7 @@ class AiToolSpecToLangChain4jTest {
                 }
                 """;
 
-        AiToolSpec spec = new AiToolSpec("createOrder", "Create order", 
Map.of(), schema, null, null);
+        AiToolSpec spec = new AiToolSpec("createOrder", "Create order", 
Map.of(), schema, Map.of(), null, null, null);
         ToolSpecification result = 
AiToolSpecToLangChain4j.toToolSpecification(spec);
 
         assertThat(result.parameters()).isNotNull();
@@ -199,7 +199,7 @@ class AiToolSpecToLangChain4jTest {
 
     @Test
     void testEmptyParameters() {
-        AiToolSpec spec = new AiToolSpec("noParams", "Tool with no params", 
Map.of(), null, null, null);
+        AiToolSpec spec = new AiToolSpec("noParams", "Tool with no params", 
Map.of(), null, Map.of(), null, null, null);
 
         ToolSpecification result = 
AiToolSpecToLangChain4j.toToolSpecification(spec);
 
diff --git 
a/components/camel-ai/camel-mcp-server-api/src/main/java/org/apache/camel/component/mcp/server/McpServerBridge.java
 
b/components/camel-ai/camel-mcp-server-api/src/main/java/org/apache/camel/component/mcp/server/McpServerBridge.java
index 1c478aed0b1c..70caf40f3570 100644
--- 
a/components/camel-ai/camel-mcp-server-api/src/main/java/org/apache/camel/component/mcp/server/McpServerBridge.java
+++ 
b/components/camel-ai/camel-mcp-server-api/src/main/java/org/apache/camel/component/mcp/server/McpServerBridge.java
@@ -255,6 +255,11 @@ public class McpServerBridge extends ServiceSupport 
implements CamelContextAware
             public AiToolAnnotations annotations() {
                 return spec.getAnnotations();
             }
+
+            @Override
+            public String outputSchemaJson() {
+                return spec.getOutputJsonSchema();
+            }
         };
     }
 
@@ -284,7 +289,7 @@ public class McpServerBridge extends ServiceSupport 
implements CamelContextAware
                 return new McpToolCallResult(GENERIC_EXECUTION_ERROR, true);
             }
             if (result instanceof AiToolResult.Success success) {
-                return new McpToolCallResult(success.value(), false);
+                return new McpToolCallResult(success.value(), false, 
success.structuredContent());
             } else if (result instanceof AiToolResult.ArgumentError error) {
                 return new McpToolCallResult(error.message(), true);
             } else {
diff --git 
a/components/camel-ai/camel-mcp-server-api/src/main/java/org/apache/camel/component/mcp/server/McpServerTool.java
 
b/components/camel-ai/camel-mcp-server-api/src/main/java/org/apache/camel/component/mcp/server/McpServerTool.java
index f348c6059d2a..3ba36396f5ab 100644
--- 
a/components/camel-ai/camel-mcp-server-api/src/main/java/org/apache/camel/component/mcp/server/McpServerTool.java
+++ 
b/components/camel-ai/camel-mcp-server-api/src/main/java/org/apache/camel/component/mcp/server/McpServerTool.java
@@ -60,4 +60,13 @@ public interface McpServerTool {
     default AiToolAnnotations annotations() {
         return null;
     }
+
+    /**
+     * The tool output as a JSON Schema object string, or {@code null} when 
the tool declares no structured output.
+     *
+     * @since 4.22
+     */
+    default String outputSchemaJson() {
+        return null;
+    }
 }
diff --git 
a/components/camel-ai/camel-mcp-server-api/src/main/java/org/apache/camel/component/mcp/server/McpToolCallResult.java
 
b/components/camel-ai/camel-mcp-server-api/src/main/java/org/apache/camel/component/mcp/server/McpToolCallResult.java
index 526236d5a11b..a57bead1e003 100644
--- 
a/components/camel-ai/camel-mcp-server-api/src/main/java/org/apache/camel/component/mcp/server/McpToolCallResult.java
+++ 
b/components/camel-ai/camel-mcp-server-api/src/main/java/org/apache/camel/component/mcp/server/McpToolCallResult.java
@@ -20,10 +20,15 @@ package org.apache.camel.component.mcp.server;
  * Result of an MCP tool invocation, pre-sanitized by the bridge: the text is 
safe to return to a remote MCP client and
  * never contains raw route exception messages.
  *
- * @param text    the tool output, or a safe error message when {@code 
isError} is true
- * @param isError whether the invocation failed
+ * @param text              the tool output, or a safe error message when 
{@code isError} is true
+ * @param isError           whether the invocation failed
+ * @param structuredContent typed JSON output when the tool declares an output 
schema, otherwise {@code null}
  *
- * @since         4.22
+ * @since                   4.22
  */
-public record McpToolCallResult(String text, boolean isError) {
+public record McpToolCallResult(String text, boolean isError, Object 
structuredContent) {
+
+    public McpToolCallResult(String text, boolean isError) {
+        this(text, isError, null);
+    }
 }
diff --git 
a/components/camel-ai/camel-mcp-server-api/src/test/java/org/apache/camel/component/mcp/server/McpServerBridgeTest.java
 
b/components/camel-ai/camel-mcp-server-api/src/test/java/org/apache/camel/component/mcp/server/McpServerBridgeTest.java
index 6d9db5c79793..26c927ba5f36 100644
--- 
a/components/camel-ai/camel-mcp-server-api/src/test/java/org/apache/camel/component/mcp/server/McpServerBridgeTest.java
+++ 
b/components/camel-ai/camel-mcp-server-api/src/test/java/org/apache/camel/component/mcp/server/McpServerBridgeTest.java
@@ -78,6 +78,11 @@ class McpServerBridgeTest extends CamelTestSupport {
 
                 from("ai-tool:other_tool?tags=untrusted&description=Other tag")
                         .setBody(constant("other"));
+
+                from("ai-tool:getWeather?tags=crm&description=Get weather"
+                     + 
"&outputSchema={\"type\":\"object\",\"properties\":{\"temperature\":{\"type\":\"number\"},\"unit\":{\"type\":\"string\"}},\"required\":[\"temperature\",\"unit\"]}")
+                        .routeId("weather-route")
+                        
.setBody(constant("{\"temperature\":21.5,\"unit\":\"celsius\"}"));
             }
         };
     }
@@ -162,6 +167,22 @@ class McpServerBridgeTest extends CamelTestSupport {
         assertThat(engine.removed()).containsOnlyOnce("send_email");
     }
 
+    @Test
+    void testToolOutputSchemaPassedThroughBridge() {
+        McpServerTool tool = engine.tools().get("getWeather");
+
+        
assertThat(tool.outputSchemaJson()).isNotNull().contains("\"temperature\"");
+    }
+
+    @Test
+    void testCallToolReturnsStructuredContent() {
+        McpToolCallResult result = 
engine.tools().get("getWeather").handler().call(Map.of());
+
+        assertThat(result.isError()).isFalse();
+        assertThat(result.text()).contains("\"temperature\":21.5");
+        assertThat(result.structuredContent()).isNotNull();
+    }
+
     @Test
     void testNameCollisionIsRefused() throws Exception {
         McpServerTool published = engine.tools().get("query_db");
diff --git 
a/components/camel-ai/camel-mcp-server/src/main/java/org/apache/camel/component/mcp/server/vertx/VertxMcpServerEngine.java
 
b/components/camel-ai/camel-mcp-server/src/main/java/org/apache/camel/component/mcp/server/vertx/VertxMcpServerEngine.java
index a0435525722c..63ed18dfc355 100644
--- 
a/components/camel-ai/camel-mcp-server/src/main/java/org/apache/camel/component/mcp/server/vertx/VertxMcpServerEngine.java
+++ 
b/components/camel-ai/camel-mcp-server/src/main/java/org/apache/camel/component/mcp/server/vertx/VertxMcpServerEngine.java
@@ -149,10 +149,13 @@ public class VertxMcpServerEngine extends ServiceSupport 
implements McpServerEng
                 .callHandler((exchange, request) -> {
                     Map<String, Object> arguments = request.arguments() != 
null ? request.arguments() : Map.of();
                     McpToolCallResult result = tool.handler().call(arguments);
-                    return McpSchema.CallToolResult.builder()
+                    McpSchema.CallToolResult.Builder builder = 
McpSchema.CallToolResult.builder()
                             .addTextContent(result.text())
-                            .isError(result.isError())
-                            .build();
+                            .isError(result.isError());
+                    if (result.structuredContent() != null) {
+                        builder.structuredContent(result.structuredContent());
+                    }
+                    return builder.build();
                 })
                 .build();
         server.addTool(spec);
@@ -177,6 +180,9 @@ public class VertxMcpServerEngine extends ServiceSupport 
implements McpServerEng
         String schema = tool.inputSchemaJson() != null ? 
tool.inputSchemaJson() : EMPTY_OBJECT_SCHEMA;
         McpSchema.Tool.Builder builder = McpSchema.Tool.builder(tool.name(), 
jsonMapper, schema)
                 .description(tool.description());
+        if (tool.outputSchemaJson() != null && 
!tool.outputSchemaJson().isBlank()) {
+            builder.outputSchema(jsonMapper, tool.outputSchemaJson());
+        }
         applyAnnotations(builder, tool.annotations());
         return builder.build();
     }
diff --git 
a/components/camel-ai/camel-mcp-server/src/test/java/org/apache/camel/component/mcp/server/vertx/VertxMcpServerOutputSchemaTest.java
 
b/components/camel-ai/camel-mcp-server/src/test/java/org/apache/camel/component/mcp/server/vertx/VertxMcpServerOutputSchemaTest.java
new file mode 100644
index 000000000000..95553c81d9a7
--- /dev/null
+++ 
b/components/camel-ai/camel-mcp-server/src/test/java/org/apache/camel/component/mcp/server/vertx/VertxMcpServerOutputSchemaTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.component.mcp.server.vertx;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.Map;
+
+import io.modelcontextprotocol.client.McpClient;
+import io.modelcontextprotocol.client.McpSyncClient;
+import 
io.modelcontextprotocol.client.transport.HttpClientStreamableHttpTransport;
+import io.modelcontextprotocol.spec.McpSchema;
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.mcp.server.McpServerInfo;
+import org.apache.camel.component.mcp.server.McpServerTool;
+import org.apache.camel.component.mcp.server.McpToolCallHandler;
+import org.apache.camel.component.mcp.server.McpToolCallResult;
+import org.apache.camel.component.platform.http.main.MainHttpServer;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.test.AvailablePortFinder;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class VertxMcpServerOutputSchemaTest {
+
+    private static final String OUTPUT_SCHEMA = """
+            {
+              "type": "object",
+              "properties": {
+                "temperature": { "type": "number" },
+                "unit": { "type": "string" }
+              },
+              "required": ["temperature", "unit"]
+            }
+            """;
+
+    @Test
+    void testEnginePublishesOutputSchemaAndStructuredContent() throws 
Exception {
+        int port = AvailablePortFinder.getNextAvailable();
+        CamelContext camelContext = new DefaultCamelContext();
+        VertxMcpServerEngine engine = new VertxMcpServerEngine();
+        McpSyncClient client = null;
+        try {
+            MainHttpServer main = new MainHttpServer();
+            main.setCamelContext(camelContext);
+            main.setHost("0.0.0.0");
+            main.setPort(port);
+            camelContext.addService(main);
+            camelContext.start();
+
+            engine.setCamelContext(camelContext);
+            engine.initialize(new McpServerInfo("output-schema", "1.0", 
"/mcp"));
+            engine.start();
+
+            JsonObject structured = new JsonObject();
+            structured.put("temperature", 21.5);
+            structured.put("unit", "celsius");
+            engine.toolAdded(tool("getWeather", "Get weather", OUTPUT_SCHEMA,
+                    arguments -> new McpToolCallResult(structured.toJson(), 
false, structured)));
+
+            client = 
McpClient.sync(HttpClientStreamableHttpTransport.builder("http://localhost:"; + 
port).build())
+                    .requestTimeout(Duration.ofSeconds(10))
+                    .initializationTimeout(Duration.ofSeconds(10))
+                    .build();
+            client.initialize();
+
+            List<McpSchema.Tool> tools = client.listTools().tools();
+            McpSchema.Tool weather = tools.stream().filter(t -> 
"getWeather".equals(t.name())).findFirst().orElseThrow();
+
+            assertThat(weather.outputSchema()).isNotNull();
+            assertThat(weather.outputSchema()).containsKey("properties");
+
+            McpSchema.CallToolResult result = client.callTool(new 
McpSchema.CallToolRequest("getWeather", Map.of()));
+
+            assertThat(result.isError()).isFalse();
+            assertThat(result.structuredContent()).isNotNull();
+            assertThat(result.structuredContent()).isInstanceOf(Map.class);
+            assertThat(((Map<?, ?>) 
result.structuredContent()).get("temperature")).isEqualTo(21.5);
+        } finally {
+            if (client != null) {
+                client.closeGracefully();
+            }
+            engine.stop();
+            camelContext.stop();
+        }
+    }
+
+    private static McpServerTool tool(
+            String name, String description, String outputSchemaJson, 
McpToolCallHandler handler) {
+        return new McpServerTool() {
+            @Override
+            public String name() {
+                return name;
+            }
+
+            @Override
+            public String description() {
+                return description;
+            }
+
+            @Override
+            public String inputSchemaJson() {
+                return null;
+            }
+
+            @Override
+            public Map<String, 
org.apache.camel.component.ai.tool.AiToolParameterHelper.ParameterDef> 
parameters() {
+                return Map.of();
+            }
+
+            @Override
+            public McpToolCallHandler handler() {
+                return handler;
+            }
+
+            @Override
+            public String outputSchemaJson() {
+                return outputSchemaJson;
+            }
+        };
+    }
+}
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc
index 1c4c03497e19..da5d4261420f 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc
@@ -31,6 +31,18 @@ TTL of 5 minutes (evict sessions with no POST/GET activity). 
Configure with
 `camel.server.mcp-session-keep-alive-interval` and 
`camel.server.mcp-session-idle-ttl`; set either
 option to `0` to disable that mechanism.
 
+=== camel-ai-tool
+
+`AiToolResult.Success` now carries an optional `structuredContent` field when 
the tool declares an
+output schema (`outputParameter.*` or `outputSchema`). The MCP bridge maps 
this to
+`CallToolResult.structuredContent` and publishes `Tool.outputSchema` to MCP 
clients. LangChain4j
+and Spring AI adapters continue to use the string `value()` only.
+
+SPI extensions in this release (before 4.22 ships): `McpToolCallResult` gains 
a third
+`structuredContent` component; `McpServerTool` adds `outputSchemaJson()`; 
`AiToolSpec` constructor
+accepts output schema fields. Custom `McpServerEngine` implementations should 
forward structured
+content when present.
+
 === camel-core
 
 ==== Property placeholders in toD and enrich dynamic endpoint URIs
diff --git 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AiToolComponentBuilderFactory.java
 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AiToolComponentBuilderFactory.java
index 21ab68bca404..f74b4a8b9a0d 100644
--- 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AiToolComponentBuilderFactory.java
+++ 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AiToolComponentBuilderFactory.java
@@ -189,6 +189,47 @@ public interface AiToolComponentBuilderFactory {
             return this;
         }
     
+        /**
+         * Tool output schema fields. Format: outputParameter.NAME=TYPE,
+         * outputParameter.NAME.description=TEXT. Supported types: string,
+         * integer, number, boolean. Mutually exclusive with outputSchema. This
+         * is a multi-value option with prefix: outputParameter.
+         * 
+         * The option is a: &lt;code&gt;java.util.Map&amp;lt;java.lang.String,
+         * java.lang.String&amp;gt;&lt;/code&gt; type.
+         * 
+         * Group: consumer
+         * 
+         * @param outputParameters the value to set
+         * @return the dsl builder
+         */
+        default AiToolComponentBuilder 
outputParameters(java.util.Map<java.lang.String, java.lang.String> 
outputParameters) {
+            doSetProperty("outputParameters", outputParameters);
+            return this;
+        }
+    
+        /**
+         * Raw JSON Schema describing the tool's structured output. Supports
+         * inline JSON and resource references (classpath:, file:, resource:).
+         * Mutually exclusive with the outputParameter multi-value options. 
When
+         * declared, the route body is parsed as JSON and exposed as structured
+         * content to MCP clients.
+         * 
+         * This option can also be loaded from an existing file, by prefixing
+         * with file: or classpath: followed by the location of the file.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: consumer
+         * 
+         * @param outputSchema the value to set
+         * @return the dsl builder
+         */
+        default AiToolComponentBuilder outputSchema(java.lang.String 
outputSchema) {
+            doSetProperty("outputSchema", outputSchema);
+            return this;
+        }
+    
         /**
          * Tool input parameters. Format: parameter.NAME=TYPE,
          * parameter.NAME.description=TEXT, parameter.NAME.required=true or
@@ -310,6 +351,8 @@ public interface AiToolComponentBuilderFactory {
             case "destructiveHint": getOrCreateConfiguration((AiToolComponent) 
component).setDestructiveHint((java.lang.Boolean) value); return true;
             case "idempotentHint": getOrCreateConfiguration((AiToolComponent) 
component).setIdempotentHint((java.lang.Boolean) value); return true;
             case "openWorldHint": getOrCreateConfiguration((AiToolComponent) 
component).setOpenWorldHint((java.lang.Boolean) value); return true;
+            case "outputParameters": 
getOrCreateConfiguration((AiToolComponent) 
component).setOutputParameters((java.util.Map) value); return true;
+            case "outputSchema": getOrCreateConfiguration((AiToolComponent) 
component).setOutputSchema((java.lang.String) value); return true;
             case "parameters": getOrCreateConfiguration((AiToolComponent) 
component).setParameters((java.util.Map) value); return true;
             case "readOnlyHint": getOrCreateConfiguration((AiToolComponent) 
component).setReadOnlyHint((java.lang.Boolean) value); return true;
             case "tags": getOrCreateConfiguration((AiToolComponent) 
component).setTags((java.lang.String) value); return true;
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AiToolEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AiToolEndpointBuilderFactory.java
index 74e7abf42bfd..9d3e7cb45aab 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AiToolEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AiToolEndpointBuilderFactory.java
@@ -182,6 +182,70 @@ public interface AiToolEndpointBuilderFactory {
             doSetProperty("openWorldHint", openWorldHint);
             return this;
         }
+        /**
+         * Tool output schema fields. Format: outputParameter.NAME=TYPE,
+         * outputParameter.NAME.description=TEXT. Supported types: string,
+         * integer, number, boolean. Mutually exclusive with outputSchema. This
+         * is a multi-value option with prefix: outputParameter.
+         * 
+         * The option is a: <code>java.util.Map&lt;java.lang.String,
+         * java.lang.String&gt;</code> type.
+         * The option is multivalued, and you can use the
+         * outputParameters(String, Object) method to add a value (call the
+         * method multiple times to set more values).
+         * 
+         * Group: consumer
+         * 
+         * @param key the option key
+         * @param value the option value
+         * @return the dsl builder
+         */
+        default AiToolEndpointBuilder outputParameters(String key, Object 
value) {
+            doSetMultiValueProperty("outputParameters", "outputParameter." + 
key, value);
+            return this;
+        }
+        /**
+         * Tool output schema fields. Format: outputParameter.NAME=TYPE,
+         * outputParameter.NAME.description=TEXT. Supported types: string,
+         * integer, number, boolean. Mutually exclusive with outputSchema. This
+         * is a multi-value option with prefix: outputParameter.
+         * 
+         * The option is a: <code>java.util.Map&lt;java.lang.String,
+         * java.lang.String&gt;</code> type.
+         * The option is multivalued, and you can use the
+         * outputParameters(String, Object) method to add a value (call the
+         * method multiple times to set more values).
+         * 
+         * Group: consumer
+         * 
+         * @param values the values
+         * @return the dsl builder
+         */
+        default AiToolEndpointBuilder outputParameters(Map values) {
+            doSetMultiValueProperties("outputParameters", "outputParameter.", 
values);
+            return this;
+        }
+        /**
+         * Raw JSON Schema describing the tool's structured output. Supports
+         * inline JSON and resource references (classpath:, file:, resource:).
+         * Mutually exclusive with the outputParameter multi-value options. 
When
+         * declared, the route body is parsed as JSON and exposed as structured
+         * content to MCP clients.
+         * 
+         * This option can also be loaded from an existing file, by prefixing
+         * with file: or classpath: followed by the location of the file.
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: consumer
+         * 
+         * @param outputSchema the value to set
+         * @return the dsl builder
+         */
+        default AiToolEndpointBuilder outputSchema(String outputSchema) {
+            doSetProperty("outputSchema", outputSchema);
+            return this;
+        }
         /**
          * Tool input parameters. Format: parameter.NAME=TYPE,
          * parameter.NAME.description=TEXT, parameter.NAME.required=true or

Reply via email to