Skip to content

CAMEL-24333: camel-ai-tool structured tool output (outputSchema / structuredContent) - #25398

Open
atiaomar1978-hub wants to merge 5 commits into
apache:mainfrom
atiaomar1978-hub:feature/CAMEL-24333-ai-tool-output-schema
Open

CAMEL-24333: camel-ai-tool structured tool output (outputSchema / structuredContent)#25398
atiaomar1978-hub wants to merge 5 commits into
apache:mainfrom
atiaomar1978-hub:feature/CAMEL-24333-ai-tool-output-schema

Conversation

@atiaomar1978-hub

@atiaomar1978-hub atiaomar1978-hub commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

AI-generated on behalf of atiaomar1978-hub

Implements CAMEL-24333: optional structured tool output for ai-tool routes, mapped through the MCP server to Tool.outputSchema and CallToolResult.structuredContent.

Changes

  • ai-tool configuration: new outputParameter.* (flat field syntax) and outputSchema (raw JSON Schema), mutually exclusive — mirrors the input-side parameter.* / argSchema pattern.
  • AiToolResult.Success: extended with optional structuredContent; populated when an output schema is declared and the route body is JSON (String, Map, or List).
  • AiToolExecutor: parses JSON bodies into structured content; null/blank/invalid JSON returns ExecutionError when output schema is declared.
  • AiToolComponent: extracts outputParameter.* URI params (same pattern as existing parameter.* handling).
  • MCP SPI: McpToolCallResult.structuredContent, McpServerTool.outputSchemaJson() default method; bridge and Vert.x engine forward both to the MCP Java SDK.
  • LangChain4j / Spring AI adapters: unchanged — continue using string value() only (typed adapter support deferred as follow-up per JIRA scope note).

Testing

  • AiToolParameterHelperTest — output schema resolution, structured parsing, mutual exclusivity
  • AiToolEndpointLifecycleTest — endpoint registration with output schema
  • AiToolExecutorTest — structured content from JSON string/Map, null body and invalid JSON errors
  • McpServerBridgeTest — output schema and structured content passthrough
  • VertxMcpServerOutputSchemaTest — end-to-end MCP client verification

Documentation

  • ai-tool-component.adoc — new Structured Tool Output section
  • camel-4x-upgrade-guide-4_22.adoc — SPI extension notes (AiToolResult, McpToolCallResult, McpServerTool, AiToolSpec)

Review follow-ups (addressed)

  • Rebased on current main and fixed stale catalog regeneration artifacts (camel-xml-io.xsd namespace, camel-spring.xsd allowedSchemes from CAMEL-24298)
  • Regenerated catalog + endpoint DSL metadata for outputSchema/outputParameters
  • Null/blank body with declared output schema now returns ExecutionError (MCP structuredContent contract)
  • Upgrade guide expanded with McpToolCallResult, McpServerTool, AiToolSpec notes

@atiaomar1978-hub

Copy link
Copy Markdown
Contributor Author

Automated review summary

AI-generated on behalf of atiaomar1978-hub

Bugbot and Grok reviews were run on this PR. Key findings and disposition:

Addressed in latest commit

Finding Fix
Catalog/Endpoint DSL missing outputSchema/outputParameters Regenerated catalog/camel-catalog and dsl/camel-endpointdsl
Null/blank body succeeds without structuredContent when output schema declared parseStructuredOutput now throws; executor returns ExecutionError
Upgrade guide understates SPI changes Expanded with McpToolCallResult, McpServerTool, AiToolSpec notes

Acknowledged / deferred

Finding Rationale
No JSON Schema instance validation against outputSchema Advertise schema + parse JSON; clients validate (documented). Full validation is a follow-up if PMC wants it.
LangChain4j/Spring AI typed tool results Explicitly out of scope for this PR; JIRA follow-up
mcp-server.adoc cross-link Can add in a small doc follow-up
Schema validation on outputSchema shape Intentionally permissive (any JSON Schema type), unlike input argSchema

CI checks pending on the updated branch.

@atiaomar1978-hub
atiaomar1978-hub marked this pull request as ready for review August 6, 2026 23:47
@davsclaus
davsclaus force-pushed the feature/CAMEL-24333-ai-tool-output-schema branch from 54f70d7 to dca0c12 Compare August 7, 2026 06:09

@davsclaus davsclaus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution — the structured output feature itself is well-designed and follows the existing input-side patterns nicely. Good test coverage across unit, lifecycle, executor, bridge, and end-to-end MCP levels.

However, the PR carries two stale catalog regeneration artifacts that would cause serious regressions. Please rebase on current main and regenerate the catalog before this can be merged.

This review does not replace specialized AI review tools (CodeRabbit, Sourcery) or static analysis (SonarCloud).

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

cursor Bot pushed a commit to atiaomar1978-hub/camel that referenced this pull request Aug 7, 2026
Rebase on current main and restore camel-spring.xsd allowedSchemes
(CAMEL-24298) and camel-xml-io.xsd targetNamespace from upstream main.
Regenerated ai-tool catalog metadata without touching unrelated schemas.

Addresses review feedback from davsclaus on PR apache#25398.

Co-authored-by: Cursor Agent <noreply@cursor.com>
@cursor
cursor Bot force-pushed the feature/CAMEL-24333-ai-tool-output-schema branch from dca0c12 to f544c52 Compare August 7, 2026 06:19
@atiaomar1978-hub

Copy link
Copy Markdown
Contributor Author

Review feedback addressed

AI-generated on behalf of atiaomar1978-hub

Thanks @davsclaus for the review — both critical catalog issues are fixed in commit f544c52:

  1. camel-xml-io.xsd — restored targetNamespace / xmlns:tns to http://camel.apache.org/schema/xml-io (matches current main).
  2. camel-spring.xsd — restored all five allowedSchemes attributes from CAMEL-24298 (no longer removed by stale regeneration).

What we did

  • Rebased feature/CAMEL-24333-ai-tool-output-schema onto current upstream/main
  • Regenerated ai-tool catalog / endpoint DSL metadata (-Pregen)
  • Restored unrelated catalog XSD artifacts from main so this PR only carries ai-tool changes
  • Re-ran targeted tests: AiToolParameterHelperTest, AiToolEndpointLifecycleTest, AiToolExecutorTest, McpServerBridgeTest, VertxMcpServerOutputSchemaTestBUILD SUCCESS

Please re-review when CI is green.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@davsclaus

Copy link
Copy Markdown
Contributor

There are uncommitted changes
HEAD detached at pull/25398/merge
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
modified: dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AiToolComponentBuilderFactory.java

@davsclaus davsclaus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #25398 Review: CAMEL-24333 — Structured tool output (outputSchema / structuredContent)

Clean, well-structured PR that mirrors the existing input-side parameter.* / argSchema pattern for outputs. Backwards compatibility is properly handled via convenience constructors on records and a default method on McpServerTool.

Minor suggestions (non-blocking)

  1. toPlainJsonValue in AiToolParameterHelperJsoner.deserialize already returns JsonObject/JsonArray/primitives, so this method performs identity type checks without any transformation. Consider removing it and using the parsed result directly in parseStructuredOutput.

  2. Undocumented outputParameter.* sub-options (in ai-tool-component.adoc) — The docs describe outputParameter.NAME=TYPE and outputParameter.NAME.description=TEXT, but the shared parseParameterMetadata method also supports .required and .enum. Consider either documenting these for output params or noting they're not applicable.

Positive observations

  • Proper backwards compatibility: AiToolResult.Success, McpToolCallResult records gain fields with convenience constructors; McpServerTool.outputSchemaJson() is a default method returning null
  • AiToolSpec constructor change is acceptable — @since 4.22 and 4.22 hasn't shipped; upgrade guide documents the SPI extensions
  • Comprehensive test coverage across parameter helper, endpoint lifecycle, executor, MCP bridge, and end-to-end Vert.x MCP client
  • Good documentation in component adoc and upgrade guide
  • LangChain4j and Spring AI adapters verified unaffected
  • All generated artifacts (catalog, configurers, DSL) properly regenerated
  • Project conventions followed (branch naming, commit format, PR body)

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • catalog/camel-catalog
  • components/camel-ai/camel-ai-tool
  • components/camel-ai/camel-langchain4j-agent
  • components/camel-ai/camel-mcp-server-api
  • components/camel-ai/camel-mcp-server
  • docs
  • dsl/camel-componentdsl
  • dsl/camel-endpointdsl

🔬 Scalpel shadow comparison — Scalpel: 17 tested, 25 compile-only — current: 13 all tested

Maveniverse Scalpel detected 42 affected modules (current approach: 13).

⚠️ Modules only in Scalpel (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

Skip-tests mode would test 17 modules (8 direct + 9 downstream), skip tests for 25 (generated code, meta-modules)

Modules Scalpel would test (17)
  • camel-ai-tool
  • camel-catalog
  • camel-componentdsl
  • camel-endpointdsl
  • camel-jbang-mcp
  • camel-jbang-plugin-mcp
  • camel-jbang-plugin-route-parser
  • camel-jbang-plugin-tui
  • camel-jbang-plugin-validate
  • camel-langchain4j-agent
  • camel-launcher-container
  • camel-mcp-server
  • camel-mcp-server-api
  • camel-spring-ai-chat
  • camel-yaml-dsl-validator
  • camel-yaml-dsl-validator-maven-plugin
  • docs
Modules with tests skipped (25)
  • apache-camel
  • camel-allcomponents
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-csimple-maven-plugin
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • dummy-component

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

⚠️ Some tests are disabled on GitHub Actions (@DisabledIfSystemProperty(named = "ci.env.name")) and require manual verification:

  • components/camel-ai/camel-langchain4j-agent: 16 test(s) disabled on GitHub Actions
  • components/camel-ai/camel-mcp-server: 1 test(s) disabled on GitHub Actions
All tested modules (42 modules)
  • Camel :: AI :: LangChain4j :: Agent
  • Camel :: AI :: MCP Server
  • Camel :: AI :: MCP Server API
  • Camel :: AI :: Tool
  • Camel :: All Components Sync point
  • Camel :: Assembly
  • Camel :: Catalog :: CSimple Maven Plugin (deprecated)
  • Camel :: Catalog :: Camel Catalog
  • Camel :: Catalog :: Camel Report Maven Plugin
  • Camel :: Catalog :: Camel Route Parser
  • Camel :: Catalog :: Console
  • Camel :: Catalog :: Dummy Component
  • Camel :: Catalog :: Lucene (deprecated)
  • Camel :: Catalog :: Maven
  • Camel :: Catalog :: Suggest
  • Camel :: Component DSL
  • Camel :: Coverage
  • Camel :: Docs
  • Camel :: Endpoint DSL
  • Camel :: Endpoint DSL :: Support
  • Camel :: Integration Tests
  • Camel :: JBang :: Core
  • Camel :: JBang :: Integration tests
  • Camel :: JBang :: MCP
  • Camel :: JBang :: Main
  • Camel :: JBang :: Plugin :: Edit
  • Camel :: JBang :: Plugin :: Generate
  • Camel :: JBang :: Plugin :: Kubernetes
  • Camel :: JBang :: Plugin :: MCP
  • Camel :: JBang :: Plugin :: Route Parser
  • Camel :: JBang :: Plugin :: TUI
  • Camel :: JBang :: Plugin :: Testing
  • Camel :: JBang :: Plugin :: Validate
  • Camel :: Kamelet Main
  • Camel :: Launcher
  • Camel :: Launcher :: Container
  • Camel :: Spring AI :: Chat
  • Camel :: YAML DSL
  • Camel :: YAML DSL :: Deserializers
  • Camel :: YAML DSL :: Maven Plugins
  • Camel :: YAML DSL :: Validator
  • Camel :: YAML DSL :: Validator Maven Plugin

⚙️ View full build and test results

cursoragent and others added 5 commits August 7, 2026 17:47
…tent)

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.

Co-authored-by: Cursor <cursoragent@cursor.com>
Reject null/blank route bodies when output schema is declared, regenerate
catalog and endpoint DSL metadata, expand upgrade guide SPI notes, and add
null-body test coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
Rebase on current main and restore camel-spring.xsd allowedSchemes
(CAMEL-24298) and camel-xml-io.xsd targetNamespace from upstream main.
Regenerated ai-tool catalog metadata without touching unrelated schemas.

Addresses review feedback from davsclaus on PR apache#25398.

Co-authored-by: Cursor Agent <noreply@cursor.com>
Commit missing AiToolComponentBuilderFactory generated outputParameters
and outputSchema builder methods so CI regen check passes.

Co-authored-by: Cursor Agent <noreply@cursor.com>
…, document outputParameter sub-options

- Remove redundant toPlainJsonValue() wrapper; Jsoner.deserialize already returns plain types
- Document outputParameter.* sub-options (.description, .required, .enum) in component docs
- Revert spurious regen of camel-spring.xsd and jbang metadata after rebase onto main

Co-authored-by: Omar Atie <atiaomar1978-hub@users.noreply.github.com>
@cursor
cursor Bot force-pushed the feature/CAMEL-24333-ai-tool-output-schema branch from 1e8f732 to d65babb Compare August 7, 2026 17:48
@atiaomar1978-hub

Copy link
Copy Markdown
Contributor Author

Addressed remaining review feedback in commit d65babb:

  1. Simplified parseStructuredOutput() — removed redundant toPlainJsonValue() wrapper; Jsoner.deserialize() already returns plain Java types suitable for MCP structured content.
  2. Documented outputParameter.* sub-options — added .description, .required, and .enum in component docs (mirroring input parameter.*).
  3. Rebased onto current main — reverted spurious regen of camel-spring.xsd and jbang metadata.

The two critical XSD review threads (stale camel-xml-io.xsd namespace and missing allowedSchemes in camel-spring.xsd) were fixed in commit 06eb4c3 and are now resolved.

All related unit tests pass locally:

  • AiToolParameterHelperTest
  • AiToolEndpointLifecycleTest
  • AiToolExecutorTest
  • AiToolRegistryTest
  • McpServerBridgeTest
  • VertxMcpServerOutputSchemaTest

AI-generated on behalf of atiaomar1978-hub

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants