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-jbang-examples.git
The following commit(s) were added to refs/heads/main by this push:
new e609158 chore: the examples move to Camel 4.23.0 (#126)
e609158 is described below
commit e6091584da315fb0f36c111e7b170b4da6602f19
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Oct 20 12:55:16 2026 +0200
chore: the examples move to Camel 4.23.0 (#126)
* chore: the examples move to Camel 4.23.0: CI tests with it, and
ai/mcp-server and contracts/openapi-server use what it brings
CI pins Camel 4.23.0 for the CLI and for the integrations the Citrus tests
start, as camel@apache/camel defaults to
the latest LTS release (4.22.0). ai/mcp-server sets the server title,
description and instructions, its README says
that the server serves ai-resource routes next to the tools, and the log
lines it shows are those of 4.23.0.
contracts/openapi-server keeps its /api base path, but its README no longer
says the servers entry must have a path:
on 4.23 an entry without one serves the operations at the root.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
* chore: the catalog no longer lists the tickets-out files
ai/ticket-classifier writes at runtime
The catalog was generated in a directory where the example had run, so it
listed tickets-out/*/T-*.json, which are
not in the repository; fetching them from GitHub answers 404.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
---------
Signed-off-by: Claus Ibsen <[email protected]>
Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
---
ai/mcp-server/README.md | 25 +++++++++++++++----------
ai/mcp-server/application.properties | 3 +++
camel-jbang-example-catalog.json | 3 ---
contracts/openapi-server/README.md | 4 ++--
4 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/ai/mcp-server/README.md b/ai/mcp-server/README.md
index 9eb62a7..5253818 100644
--- a/ai/mcp-server/README.md
+++ b/ai/mcp-server/README.md
@@ -9,14 +9,14 @@ that tag becomes a tool any MCP client can discover and call,
a coding agent inc
```text
$ camel run *
...
-INFO ... VertxMcpServerEngine : MCP server 'webshop' serving tools on path /mcp
+INFO ... VertxMcpServerEngine : MCP server 'webshop' serving tools and
resources on path /mcp
INFO ... Started stock-level (ai-tool://stock_level)
INFO ... Started order-status (ai-tool://order_status)
when a client calls the tools:
-INFO ... mcp-server.camel.yaml:38 : Tool stock_level(CAMEL-MUG): 42 CAMEL-MUG
in stock
-INFO ... mcp-server.camel.yaml:81 : Tool order_status(ORD-1003): Order
ORD-1003 for customer C-134 in US is pending with 3 line(s)
+INFO ... mcp-server.camel.yaml:44 : Tool stock_level(CAMEL-MUG): 42 CAMEL-MUG
in stock
+INFO ... mcp-server.camel.yaml:84 : Tool order_status(ORD-1003): Order
ORD-1003 for customer C-134 in US is pending with 3 line(s)
```
## Install Camel CLI
@@ -62,20 +62,25 @@ The MCP server is a preview feature since Camel 4.22.
and `readOnlyHint` as an advisory hint. When a client calls the tool, the
arguments arrive as headers and the
route's final body is the tool result.
- `tags: shop` groups the tools; `camel.server.mcp-tags=shop` in
`application.properties` exposes that group.
- `camel.server.mcp-enabled=true` starts the MCP server on the CLI's HTTP
server and `camel.server.mcp-server-name`
- is what the client shows; Camel 4.23 adds a title, description and
instructions next to it.
+ `camel.server.mcp-enabled=true` starts the MCP server on the CLI's HTTP
server. `camel.server.mcp-server-name`,
+ `mcp-server-title` and `mcp-server-description` are what the client shows,
and `mcp-instructions` is the text
+ the client hands its model with the tool list: when to use which tool and
what the ids look like.
- `order_status` reads the order file with `pollEnrich` and a file name built
from the id, `order-1001.json`
for `ORD-1001`, and answers a sentence; a missing file leaves the body null,
which becomes the unknown answer.
+- Next to tools, the server serves MCP resources: an `ai-resource` route with
the same tag is content the client
+ reads (`resources/list` and `resources/read`) rather than an action the
model calls. This example has tools
+ only; *Try changing* adds a resource.
- Nothing here is specific to MCP: the same `ai-tool` routes are the tools of
a Camel agent built with
`langchain4j-agent` or `openai`, selected by the same tags.
## Build it step by step
-1. One `ai-tool` route that answers a fixed text, with the four
`camel.server.mcp-*` properties; run it and see
- the server line in the log, then `initialize` and `tools/list` with `curl`.
-2. Add a parameter and use `${header.sku}` in the answer; call it with
`tools/call`.
-3. Answer from `stock.json`: unmarshal it, find the SKU with Groovy and add
the unknown case.
-4. Add the second tool and connect a real agent.
+1. One `ai-tool` route that answers a fixed text, with
`camel.server.mcp-enabled`, `mcp-tags` and
+ `mcp-server-name`; run it and see the server line in the log, then
`initialize` and `tools/list` with `curl`.
+2. Add the title, description and instructions, and see them in the
`initialize` answer.
+3. Add a parameter and use `${header.sku}` in the answer; call it with
`tools/call`.
+4. Answer from `stock.json`: unmarshal it, find the SKU with Groovy and add
the unknown case.
+5. Add the second tool and connect a real agent.
## Try changing
diff --git a/ai/mcp-server/application.properties
b/ai/mcp-server/application.properties
index 13ca646..b30dad5 100644
--- a/ai/mcp-server/application.properties
+++ b/ai/mcp-server/application.properties
@@ -20,3 +20,6 @@ camel.server.port=8080
camel.server.mcp-enabled=true
camel.server.mcp-tags=shop
camel.server.mcp-server-name=webshop
+camel.server.mcp-server-title=Web shop
+camel.server.mcp-server-description=Stock levels and order status of the web
shop
+camel.server.mcp-instructions=Use stock_level for how many of a product are in
the warehouse, and order_status for the status and lines of an order. Product
SKUs look like CAMEL-MUG, order ids like ORD-1001.
diff --git a/camel-jbang-example-catalog.json b/camel-jbang-example-catalog.json
index 20e0ba5..0b703a9 100644
--- a/camel-jbang-example-catalog.json
+++ b/camel-jbang-example-catalog.json
@@ -213,9 +213,6 @@
"README.md",
"application.properties",
"ticket-classifier.camel.yaml",
- "tickets-out/account/T-3.json",
- "tickets-out/billing/T-2.json",
- "tickets-out/shipping/T-1.json",
"tickets/T-1.json",
"tickets/T-2.json",
"tickets/T-3.json"
diff --git a/contracts/openapi-server/README.md
b/contracts/openapi-server/README.md
index 746aaa9..2fb9be6 100644
--- a/contracts/openapi-server/README.md
+++ b/contracts/openapi-server/README.md
@@ -42,8 +42,8 @@ Stop it with `ctrl` + `c`.
## How it works
- `rest` with `openApi: specification: stock-api.json` is the whole API
definition: paths, verbs and parameters
- come from the contract, not from the route file, and the base path `/api`
from its `servers` entry, which
- must have a path. `restConfiguration` switches on `clientRequestValidation`,
+ come from the contract, not from the route file, and the base path `/api`
from its `servers` entry (an entry
+ without a path serves the operations at the root). `restConfiguration`
switches on `clientRequestValidation`,
which rejects a request without the body or content type the contract
requires with 400, and
`apiContextPath: openapi` serves the contract.
- Each operation is a `direct` route named after its `operationId`:
`listStock`, `getStock`, `reserveStock`.