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

robertlazarski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/axis-axis2-java-core.git

commit ef24536772c405b18cd25c0fd16446c030c2dd18
Author: Robert Lazarski <[email protected]>
AuthorDate: Sat Apr 11 05:34:30 2026 -1000

    Clean up MCP/OpenAPI docs for 2.0.1 release; fix XML parse bug
    
    - Fix unescaped '<' in BigDataH2Service services.xml mcpInputSchema
      ("<10MB" broke XML parsing on all containers)
    - Replace generic placeholder service example with
      FinancialBenchmarkService in json-rpc-mcp-guide.xml
    - Update inputSchema status from "not implemented" to "implemented"
      (mcpInputSchema in services.xml has been working since April)
    - Convert all curl examples to HTTPS/HTTP2 on port 8443
      (Tomcat mTLS, WildFly self-signed cert, both ALPN h2 verified)
    - Add container/JDK testing matrix (WildFly 32/39, Tomcat 11,
      OpenJDK 21/25 — all validated)
    - Inline full test flow in WildFly README (was cross-ref to Tomcat)
    - Add quick-start build/deploy/test instructions to mcp-examples.md
    - Reference sample READMEs from main docs (mcp-architecture.md,
      json-rpc-mcp-guide.xml) for discoverability
    - Remove stale Axis2/C next-steps (C1 complete, code committed)
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---
 .../userguide/springbootdemo-tomcat11/README.md    |  33 +++--
 .../bigdata_h2_resources/services.xml              |   2 +-
 .../src/userguide/springbootdemo-wildfly/README.md |  78 +++++++++++-
 src/site/markdown/docs/mcp-architecture.md         |  25 ++--
 src/site/markdown/docs/mcp-examples.md             | 137 ++++++++++++++++++---
 src/site/xdoc/docs/json-rpc-mcp-guide.xml          |  41 ++++--
 6 files changed, 258 insertions(+), 58 deletions(-)

diff --git 
a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/README.md 
b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/README.md
index 10e000b035..3aa9b68bd0 100644
--- a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/README.md
+++ b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/README.md
@@ -81,19 +81,30 @@ reason. Do not rename the directory before copying to 
`webapps/`.
 
 ## Test flow
 
-### 1. Verify OpenAPI docs
+All tests use **HTTPS/HTTP2 on port 8443** with mTLS client certificates. The 
Tomcat connector
+requires `certificateVerification="required"` — plain HTTP is not available.
+
+Set up the cert variables first:
+
+```bash
+CERTS=/path/to/axis-axis2-java-core/certs
+CURL_MTLS="curl -s --http2 --cert $CERTS/client.crt --key $CERTS/client.key 
--cacert $CERTS/ca.crt"
+```
+
+### 1. Verify OpenAPI and MCP endpoints
 
 ```bash
-curl http://localhost:8080/axis2-json-api/openapi.json
-curl http://localhost:8080/axis2-json-api/openapi.yaml
+$CURL_MTLS https://localhost:8443/axis2-json-api/openapi.json
+$CURL_MTLS https://localhost:8443/axis2-json-api/openapi.yaml
+$CURL_MTLS https://localhost:8443/axis2-json-api/openapi-mcp.json
 # Interactive UI:
-curl http://localhost:8080/axis2-json-api/swagger-ui
+$CURL_MTLS https://localhost:8443/axis2-json-api/swagger-ui
 ```
 
 ### 2. Login (get Bearer token)
 
 ```bash
-curl -s -X POST http://localhost:8080/axis2-json-api/services/loginService \
+$CURL_MTLS -X POST https://localhost:8443/axis2-json-api/services/loginService 
\
   -H 'Content-Type: application/json' \
   -d 
'{"doLogin":[{"arg0":{"email":"[email protected]","credentials":"userguide"}}]}'
 ```
@@ -107,7 +118,7 @@ characters).
 
 ```bash
 TOKEN="<token from step 2>"
-curl -s -X POST http://localhost:8080/axis2-json-api/services/testws \
+$CURL_MTLS -X POST https://localhost:8443/axis2-json-api/services/testws \
   -H 'Content-Type: application/json' \
   -H "Authorization: Bearer $TOKEN" \
   -d '{"doTestws":[{"arg0":{"messagein":"hello world"}}]}'
@@ -115,11 +126,11 @@ curl -s -X POST 
http://localhost:8080/axis2-json-api/services/testws \
 
 ### 4. Call BigData service
 
-`datasetSize` is in bytes. Size determines processing path: <10 MB → standard,
+`datasetSize` is in bytes. Size determines processing path: under 10 MB → 
standard,
 10–50 MB → multiplexing, >50 MB → streaming. Use at least 1 000 000 to get 
populated results.
 
 ```bash
-curl -s -X POST http://localhost:8080/axis2-json-api/services/BigDataH2Service 
\
+$CURL_MTLS -X POST 
https://localhost:8443/axis2-json-api/services/BigDataH2Service \
   -H 'Content-Type: application/json' \
   -H "Authorization: Bearer $TOKEN" \
   -d 
'{"processBigDataSet":[{"arg0":{"datasetId":"test-001","datasetSize":1000000,"processingMode":"streaming","enableMemoryOptimization":true,"analyticsType":"summary"}}]}'
@@ -132,19 +143,19 @@ Response includes `processedRecordCount`, 
`http2Optimized`, `memoryOptimized`, a
 
 ```bash
 # Portfolio variance — O(n²) covariance matrix
-curl -s -X POST 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService \
+$CURL_MTLS -X POST 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
   -H 'Content-Type: application/json' \
   -H "Authorization: Bearer $TOKEN" \
   -d 
'{"portfolioVariance":[{"arg0":{"nAssets":2,"weights":[0.6,0.4],"covarianceMatrix":[[0.04,0.006],[0.006,0.09]],"normalizeWeights":false,"nPeriodsPerYear":252}}]}'
 
 # Monte Carlo VaR — GBM simulation
-curl -s -X POST 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService \
+$CURL_MTLS -X POST 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
   -H 'Content-Type: application/json' \
   -H "Authorization: Bearer $TOKEN" \
   -d 
'{"monteCarlo":[{"arg0":{"nSimulations":10000,"nPeriods":252,"initialValue":100.0,"expectedReturn":0.08,"volatility":0.20,"nPeriodsPerYear":252,"randomSeed":42}}]}'
 
 # Scenario analysis — probability-weighted expected return
-curl -s -X POST 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService \
+$CURL_MTLS -X POST 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
   -H 'Content-Type: application/json' \
   -H "Authorization: Bearer $TOKEN" \
   -d 
'{"scenarioAnalysis":[{"arg0":{"assets":[{"assetId":1,"currentPrice":100.0,"positionSize":100,"scenarios":[{"price":120.0,"probability":0.3},{"price":100.0,"probability":0.5},{"price":75.0,"probability":0.2}]}],"useHashLookup":true,"probTolerance":0.001}}]}'
diff --git 
a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/resources-axis2/bigdata_h2_resources/services.xml
 
b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/resources-axis2/bigdata_h2_resources/services.xml
index 64508f0753..150e208892 100644
--- 
a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/resources-axis2/bigdata_h2_resources/services.xml
+++ 
b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/resources-axis2/bigdata_h2_resources/services.xml
@@ -81,7 +81,7 @@
               "required": ["datasetId", "datasetSize"],
               "properties": {
                 "datasetId":   {"type": "string",  "description": "Unique 
dataset identifier for tracking"},
-                "datasetSize": {"type": "integer", "description": "Dataset 
size in bytes (determines processing mode: streaming for 50MB+, multiplexing 
for 10-50MB, standard for <10MB)"}
+                "datasetSize": {"type": "integer", "description": "Dataset 
size in bytes (determines processing mode: streaming for 50MB+, multiplexing 
for 10-50MB, standard for under 10MB)"}
               }
             }</parameter>
 
diff --git 
a/modules/samples/userguide/src/userguide/springbootdemo-wildfly/README.md 
b/modules/samples/userguide/src/userguide/springbootdemo-wildfly/README.md
index c9b4870287..be358e434a 100644
--- a/modules/samples/userguide/src/userguide/springbootdemo-wildfly/README.md
+++ b/modules/samples/userguide/src/userguide/springbootdemo-wildfly/README.md
@@ -22,7 +22,7 @@
 Axis2 JSON-RPC services deployed as a WAR in **WildFly** (Undertow), using 
Spring Boot 3.x as
 a configuration framework only — there is no embedded container.
 
-Tested with: **WildFly 39.0.1.Final** · **OpenJDK 25** · **Spring Boot 3.4.3**
+Tested with: **WildFly 32.0.1.Final** (OpenJDK 21) · **WildFly 39.0.1.Final** 
(OpenJDK 25) · **Spring Boot 3.4.3**
 
 All Java source is shared from `../springbootdemo-tomcat11/src/main/java` via
 `build-helper-maven-plugin`. This module only adds WildFly-specific WEB-INF 
descriptors.
@@ -146,7 +146,77 @@ retried by a new WildFly instance — it must be removed.
 
 ## Test flow
 
-See `../springbootdemo-tomcat11/README.md` for the full curl-based test 
sequence; it applies
-identically to WildFly (same context path, same JSON-RPC format, same 
credentials).
+All tests use **HTTPS/HTTP2 on port 8443**. WildFly uses a self-signed 
certificate
+(`generate-self-signed-certificate-host="localhost"`), so `-k` is needed to 
skip
+certificate verification.
 
-The only difference: use port `8080` on WildFly (same default as Tomcat 11).
+```bash
+CURL_H2="curl -s --http2 -k"
+```
+
+### 1. Verify OpenAPI and MCP endpoints
+
+```bash
+$CURL_H2 https://localhost:8443/axis2-json-api/openapi.json
+$CURL_H2 https://localhost:8443/axis2-json-api/openapi.yaml
+$CURL_H2 https://localhost:8443/axis2-json-api/openapi-mcp.json
+# Interactive UI:
+$CURL_H2 https://localhost:8443/axis2-json-api/swagger-ui
+```
+
+### 2. Login (get Bearer token)
+
+```bash
+$CURL_H2 -X POST https://localhost:8443/axis2-json-api/services/loginService \
+  -H 'Content-Type: application/json' \
+  -d 
'{"doLogin":[{"arg0":{"email":"[email protected]","credentials":"userguide"}}]}'
+```
+
+Response: `{"response":{"token":"<TOKEN>","uuid":"<UUID>","status":"OK"}}`
+
+### 3. Call protected service (testws)
+
+`messagein` must pass ESAPI `SafeString` validation (`[A-Za-z0-9.,\-_ ]*` — no 
`+` or special
+characters).
+
+```bash
+TOKEN="<token from step 2>"
+$CURL_H2 -X POST https://localhost:8443/axis2-json-api/services/testws \
+  -H 'Content-Type: application/json' \
+  -H "Authorization: Bearer $TOKEN" \
+  -d '{"doTestws":[{"arg0":{"messagein":"hello world"}}]}'
+```
+
+### 4. Call BigData service
+
+`datasetSize` is in bytes. Size determines processing path: under 10 MB → 
standard,
+10–50 MB → multiplexing, >50 MB → streaming. Use at least 1 000 000 to get 
populated results.
+
+```bash
+$CURL_H2 -X POST 
https://localhost:8443/axis2-json-api/services/BigDataH2Service \
+  -H 'Content-Type: application/json' \
+  -H "Authorization: Bearer $TOKEN" \
+  -d 
'{"processBigDataSet":[{"arg0":{"datasetId":"test-001","datasetSize":1000000,"processingMode":"streaming","enableMemoryOptimization":true,"analyticsType":"summary"}}]}'
+```
+
+### 5. Financial Benchmark Service
+
+```bash
+# Portfolio variance — O(n²) covariance matrix
+$CURL_H2 -X POST 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
+  -H 'Content-Type: application/json' \
+  -H "Authorization: Bearer $TOKEN" \
+  -d 
'{"portfolioVariance":[{"arg0":{"nAssets":2,"weights":[0.6,0.4],"covarianceMatrix":[[0.04,0.006],[0.006,0.09]],"normalizeWeights":false,"nPeriodsPerYear":252}}]}'
+
+# Monte Carlo VaR — GBM simulation
+$CURL_H2 -X POST 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
+  -H 'Content-Type: application/json' \
+  -H "Authorization: Bearer $TOKEN" \
+  -d 
'{"monteCarlo":[{"arg0":{"nSimulations":10000,"nPeriods":252,"initialValue":100.0,"expectedReturn":0.08,"volatility":0.20,"nPeriodsPerYear":252,"randomSeed":42}}]}'
+
+# Scenario analysis — probability-weighted expected return
+$CURL_H2 -X POST 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
+  -H 'Content-Type: application/json' \
+  -H "Authorization: Bearer $TOKEN" \
+  -d 
'{"scenarioAnalysis":[{"arg0":{"assets":[{"assetId":1,"currentPrice":100.0,"positionSize":100,"scenarios":[{"price":120.0,"probability":0.3},{"price":100.0,"probability":0.5},{"price":75.0,"probability":0.2}]}],"useHashLookup":true,"probTolerance":0.001}}]}'
+```
diff --git a/src/site/markdown/docs/mcp-architecture.md 
b/src/site/markdown/docs/mcp-architecture.md
index e2089ee446..d6ef60edd0 100644
--- a/src/site/markdown/docs/mcp-architecture.md
+++ b/src/site/markdown/docs/mcp-architecture.md
@@ -32,12 +32,16 @@ modelcontextprotocol.io.
 
 ### Reference implementations
 
+Build, deploy, and test instructions for each container are in the sample 
READMEs:
+- **Tomcat 11**: 
`modules/samples/userguide/src/userguide/springbootdemo-tomcat11/README.md`
+- **WildFly 32/39**: 
`modules/samples/userguide/src/userguide/springbootdemo-wildfly/README.md`
+
 ```
 springbootdemo-tomcat11 base URL: https://localhost:8443/axis2-json-api
   - LoginService      (auth, port 8080 only)
   - BigDataH2Service  (streaming/multiplexing demo, accessible via mTLS on 
8443)
 
-springbootdemo-wildfly base URL: http://localhost:8080/axis2-json-api
+springbootdemo-wildfly base URL: https://localhost:8443/axis2-json-api
   - LoginService                (JWT auth)
   - FinancialBenchmarkService   (portfolioVariance, monteCarlo VaR, 
scenarioAnalysis)
   - BigDataH2Service            (HTTP/2 streaming)
@@ -330,12 +334,6 @@ opt-in per-operation.
 
 ## Next Steps
 
-### C1 — complete ✅
-
-`finbench_mcp.c` + `finbench_mcp_main.c` committed to `axis-axis2-c-core`.
-Builds with `build_financial_service.sh`; installs to 
`/usr/local/axis2c/bin/financial-benchmark-mcp`.
-See `docs/MCP.md` in the `axis-axis2-c-core` repo for the full C 
implementation plan.
-
 ### Track A remaining
 
 | Step | Work | Notes |
@@ -349,11 +347,16 @@ See `docs/MCP.md` in the `axis-axis2-c-core` repo for the 
full C implementation
 2. stdio transport first (B1) — validates JSON-RPC 2.0 ↔ MessageContext 
translation
 3. HTTP/SSE transport (B2) — reuses Axis2 HTTP infrastructure
 
-### Axis2/C deployment
+### Testing matrix
+
+MCP and OpenAPI support needs validation across the full container/JDK matrix:
 
-`build_financial_service.sh` in `axis-axis2-c-core` needs to be run on the 
target
-host after Axis2/C is installed. The service is committed and compiles clean — 
the
-script is the only remaining deployment step.
+| Container | JDK | MCP | OpenAPI | Status |
+|-----------|-----|-----|---------|--------|
+| WildFly 32 | OpenJDK 21 | ✅ | ✅ | Validated |
+| WildFly 39 | OpenJDK 25 | ✅ | ✅ | Validated |
+| Tomcat 11 | OpenJDK 21 | ✅ | ✅ | Validated |
+| Tomcat 11 | OpenJDK 25 | ✅ | ✅ | Validated |
 
 ---
 
diff --git a/src/site/markdown/docs/mcp-examples.md 
b/src/site/markdown/docs/mcp-examples.md
index 9142662b65..1b3bef0fef 100644
--- a/src/site/markdown/docs/mcp-examples.md
+++ b/src/site/markdown/docs/mcp-examples.md
@@ -27,11 +27,15 @@ framing) is excluded. The computation comparison is 
apples-to-apples.
 
 ## Authentication
 
+All examples use **HTTPS/HTTP2 on port 8443**. WildFly uses a self-signed 
certificate,
+so `-k` skips certificate verification. Tomcat uses mTLS with CA-signed client 
certs
+(see `mcp-architecture.md` for PKI details).
+
 Axis2/Java requires JWT authentication via Spring Security. All financial 
service
 calls need a `Bearer` token obtained from the login endpoint:
 
 ```bash
-TOKEN=$(curl -s http://localhost:8080/axis2-json-api/services/loginService \
+TOKEN=$(curl -s --http2 -k 
https://localhost:8443/axis2-json-api/services/loginService \
   -H 'Content-Type: application/json' \
   -d 
'{"doLogin":[{"arg0":{"email":"[email protected]","credentials":"userguide"}}]}'
 \
   | python3 -c "import sys,json; 
print(json.load(sys.stdin)['response']['token'])")
@@ -71,7 +75,7 @@ client sees only standard MCP JSON-RPC.
     "axis2-java-finbench": {
       "command": "java",
       "args": ["-jar", "/path/to/axis2-mcp-bridge-2.0.1-SNAPSHOT-exe.jar",
-               "--base-url", "http://localhost:8080/axis2-json-api";]
+               "--base-url", "https://localhost:8443/axis2-json-api";]
     }
   }
 }
@@ -82,7 +86,7 @@ client sees only standard MCP JSON-RPC.
 echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{
   "name":"portfolioVariance","arguments":{...}}}' \
     | java -jar axis2-mcp-bridge-2.0.1-SNAPSHOT-exe.jar \
-        --base-url http://localhost:8080/axis2-json-api
+        --base-url https://localhost:8443/axis2-json-api
 ```
 
 All curl examples below include paired MCP stdio equivalents.
@@ -94,7 +98,7 @@ All curl examples below include paired MCP stdio equivalents.
 ### Portfolio Variance — 5 assets
 
 ```bash
-curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService \
+curl -s --http2 -k 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
   -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
   -d '{"portfolioVariance":[{"arg0":{
     "nAssets": 5,
@@ -128,7 +132,7 @@ curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService
 **MCP stdio equivalent:**
 ```bash
 echo 
'{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"portfolioVariance","arguments":{"nAssets":5,"weights":[0.25,0.25,0.20,0.15,0.15],"covarianceMatrix":[[0.0691,0.0313,0.0457,0.0272,-0.0035],[0.0313,0.0976,0.0591,0.0408,0.0058],[0.0457,0.0591,0.1207,0.0437,-0.0086],[0.0272,0.0408,0.0437,0.0638,0.0015],[-0.0035,0.0058,-0.0086,0.0015,0.0303]],"normalizeWeights":true}}}'
 \
-    | java -jar axis2-mcp-bridge-2.0.1-SNAPSHOT-exe.jar --base-url 
http://localhost:8080/axis2-json-api
+    | java -jar axis2-mcp-bridge-2.0.1-SNAPSHOT-exe.jar --base-url 
https://localhost:8443/axis2-json-api
 ```
 
 ### Portfolio Variance — 500 assets
@@ -147,7 +151,7 @@ for i in range(n):
 
print(json.dumps({'portfolioVariance':[{'arg0':{'nAssets':n,'weights':w,'covarianceMatrix':c}}]}))"
 \
   > /tmp/pv500.json
 
-curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService \
+curl -s --http2 -k 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
   -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
   -d @/tmp/pv500.json
 ```
@@ -178,7 +182,7 @@ Z ~ N(0,1). Run 100,000 paths, sort the terminal values, 
read off the
 this nightly for regulatory capital calculations.
 
 ```bash
-curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService \
+curl -s --http2 -k 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
   -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
   -d '{"monteCarlo":[{"arg0":{
     "nSimulations": 100000,
@@ -210,7 +214,7 @@ curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService
 **MCP stdio equivalent:**
 ```bash
 echo 
'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"monteCarlo","arguments":{"nSimulations":100000,"nPeriods":252,"initialValue":1000000,"expectedReturn":0.10,"volatility":0.198,"nPeriodsPerYear":252}}}'
 \
-    | java -jar axis2-mcp-bridge-2.0.1-SNAPSHOT-exe.jar --base-url 
http://localhost:8080/axis2-json-api
+    | java -jar axis2-mcp-bridge-2.0.1-SNAPSHOT-exe.jar --base-url 
https://localhost:8443/axis2-json-api
 ```
 
 ---
@@ -228,7 +232,7 @@ payload. The bridge handles the Axis2 JSON-RPC wrapping 
transparently.
 **Step 1 — Baseline:**
 
 ```bash
-curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService \
+curl -s --http2 -k 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
   -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
   -d '{"portfolioVariance":[{"arg0":{
     "nAssets": 5,
@@ -259,7 +263,7 @@ curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService
 **Step 2 — Stressed (all pairwise correlations → 0.8):**
 
 ```bash
-curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService \
+curl -s --http2 -k 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
   -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
   -d '{"portfolioVariance":[{"arg0":{
     "nAssets": 5,
@@ -290,7 +294,7 @@ curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService
 **Step 3 — Monte Carlo on stressed portfolio (100K paths):**
 
 ```bash
-curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService \
+curl -s --http2 -k 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
   -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
   -d '{"monteCarlo":[{"arg0":{
     "nSimulations": 100000,
@@ -321,7 +325,7 @@ curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService
 **MCP stdio equivalent (stressed MC):**
 ```bash
 echo 
'{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"monteCarlo","arguments":{"nSimulations":100000,"nPeriods":252,"initialValue":1000000,"expectedReturn":0.10,"volatility":0.255,"nPeriodsPerYear":252}}}'
 \
-    | java -jar axis2-mcp-bridge-2.0.1-SNAPSHOT-exe.jar --base-url 
http://localhost:8080/axis2-json-api
+    | java -jar axis2-mcp-bridge-2.0.1-SNAPSHOT-exe.jar --base-url 
https://localhost:8443/axis2-json-api
 ```
 
 **Comparison — Axis2/C vs Axis2/Java (same inputs, same day):**
@@ -355,7 +359,7 @@ as Live Examples).
 **Candidate A — European semi (vol 44%, ρ = 0.68 to tech):**
 
 ```bash
-curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService \
+curl -s --http2 -k 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
   -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
   -d '{"portfolioVariance":[{"arg0":{
     "nAssets": 6,
@@ -379,7 +383,7 @@ curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService
 **Candidate B — Japanese peer (vol 38%, ρ = 0.31 to US tech):**
 
 ```bash
-curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService \
+curl -s --http2 -k 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
   -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
   -d '{"portfolioVariance":[{"arg0":{
     "nAssets": 6,
@@ -404,14 +408,14 @@ curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService
 
 ```bash
 # European candidate (vol 21.1%)
-curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService \
+curl -s --http2 -k 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
   -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
   -d '{"monteCarlo":[{"arg0":{"nSimulations":100000,"nPeriods":252,
        "initialValue":1000000,"expectedReturn":0.10,"volatility":0.211,
        "nPeriodsPerYear":252}}]}'
 
 # Japanese candidate (vol 20.1%)
-curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService \
+curl -s --http2 -k 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
   -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
   -d '{"monteCarlo":[{"arg0":{"nSimulations":100000,"nPeriods":252,
        "initialValue":1000000,"expectedReturn":0.10,"volatility":0.201,
@@ -459,7 +463,7 @@ Run `monteCarlo` at 1K, 10K, 100K, and 1M paths:
 
 ```bash
 for N in 1000 10000 100000 1000000; do
-  curl -s 
http://localhost:8080/axis2-json-api/services/FinancialBenchmarkService \
+  curl -s --http2 -k 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
     -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
     -d "{\"monteCarlo\":[{\"arg0\":{\"nSimulations\":$N,\"nPeriods\":252,
          \"initialValue\":1000000,\"expectedReturn\":0.10,\"volatility\":0.198,
@@ -470,7 +474,7 @@ done
 **MCP stdio equivalent (example for 100K):**
 ```bash
 echo 
'{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"monteCarlo","arguments":{"nSimulations":100000,"nPeriods":252,"initialValue":1000000,"expectedReturn":0.10,"volatility":0.198,"nPeriodsPerYear":252}}}'
 \
-    | java -jar axis2-mcp-bridge-2.0.1-SNAPSHOT-exe.jar --base-url 
http://localhost:8080/axis2-json-api
+    | java -jar axis2-mcp-bridge-2.0.1-SNAPSHOT-exe.jar --base-url 
https://localhost:8443/axis2-json-api
 ```
 
 **Axis2/Java results (2026-04-08):**
@@ -575,7 +579,7 @@ produce the same answers. The choice is deployment context, 
not functionality.
 Axis2/Java exposes an MCP tool catalog at:
 
 ```
-GET http://localhost:8080/axis2-json-api/openapi-mcp.json
+GET https://localhost:8443/axis2-json-api/openapi-mcp.json
 ```
 
 This endpoint returns the same tool schema structure that Claude Desktop
@@ -586,6 +590,101 @@ Axis2/C MCP stdio server.
 
 ---
 
+## Container/JDK Testing Matrix
+
+MCP bridge and OpenAPI endpoints need validation across all supported 
containers
+and JDK versions before the 2.0.1 release:
+
+| Container | JDK | MCP Bridge | OpenAPI/Swagger UI | Status |
+|-----------|-----|------------|-------------------|--------|
+| WildFly 32 | OpenJDK 21 | ✅ Tested | ✅ Tested | Validated |
+| WildFly 39 | OpenJDK 25 | ✅ Tested | ✅ Tested | Validated |
+| Tomcat 11 | OpenJDK 21 | ✅ Tested | ✅ Tested | Validated |
+| Tomcat 11 | OpenJDK 25 | ✅ Tested | ✅ Tested | Validated |
+
+All four container/JDK combinations negotiate HTTP/2 via ALPN over TLS.
+
+---
+
+## Build and Deploy
+
+### WildFly
+
+Full build, deploy, and test instructions are in
+`modules/samples/userguide/src/userguide/springbootdemo-wildfly/README.md`.
+Quick start:
+
+```bash
+cd modules/samples/userguide/src/userguide/springbootdemo-wildfly
+mvn -Dmaven.test.skip.exec clean install
+
+# Deploy exploded WAR to WildFly
+rsync -a --delete target/deploy/axis2-json-api/ 
~/wildfly/standalone/deployments/axis2-json-api.war/
+touch ~/wildfly/standalone/deployments/axis2-json-api.war.dodeploy
+```
+
+### Tomcat 11
+
+Full build, deploy, and test instructions are in
+`modules/samples/userguide/src/userguide/springbootdemo-tomcat11/README.md`.
+Quick start:
+
+```bash
+cd modules/samples/userguide/src/userguide/springbootdemo-tomcat11
+mvn -Dmaven.test.skip.exec clean install
+
+# Deploy exploded WAR to Tomcat
+cp -r target/deploy/axis2-json-api /path/to/tomcat/webapps/
+```
+
+### Verify all endpoints after deploy
+
+**Tomcat 11** (HTTPS/HTTP2 on port 8443 with mTLS):
+
+```bash
+CERTS=/path/to/axis-axis2-java-core/certs
+CURL_MTLS="curl -s --http2 --cert $CERTS/client.crt --key $CERTS/client.key 
--cacert $CERTS/ca.crt"
+
+# OpenAPI and MCP (no auth required, but mTLS handshake still needed)
+$CURL_MTLS https://localhost:8443/axis2-json-api/openapi.json
+$CURL_MTLS https://localhost:8443/axis2-json-api/openapi.yaml
+$CURL_MTLS https://localhost:8443/axis2-json-api/openapi-mcp.json
+$CURL_MTLS https://localhost:8443/axis2-json-api/swagger-ui
+
+# Login
+TOKEN=$($CURL_MTLS -X POST 
https://localhost:8443/axis2-json-api/services/loginService \
+  -H 'Content-Type: application/json' \
+  -d 
'{"doLogin":[{"arg0":{"email":"[email protected]","credentials":"userguide"}}]}'
 \
+  | python3 -c "import sys,json; 
print(json.load(sys.stdin)['response']['token'])")
+
+# Financial benchmark
+$CURL_MTLS -X POST 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
+  -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
+  -d 
'{"portfolioVariance":[{"arg0":{"nAssets":2,"weights":[0.6,0.4],"covarianceMatrix":[[0.04,0.006],[0.006,0.09]]}}]}'
+```
+
+**WildFly 32/39** (HTTPS/HTTP2 on port 8443 with self-signed cert, JWT auth):
+
+```bash
+# OpenAPI and MCP
+curl -s --http2 -k https://localhost:8443/axis2-json-api/openapi.json
+curl -s --http2 -k https://localhost:8443/axis2-json-api/openapi-mcp.json
+
+# Login + financial benchmark
+TOKEN=$(curl -s --http2 -k 
https://localhost:8443/axis2-json-api/services/loginService \
+  -H 'Content-Type: application/json' \
+  -d 
'{"doLogin":[{"arg0":{"email":"[email protected]","credentials":"userguide"}}]}'
 \
+  | python3 -c "import sys,json; 
print(json.load(sys.stdin)['response']['token'])")
+
+curl -s --http2 -k 
https://localhost:8443/axis2-json-api/services/FinancialBenchmarkService \
+  -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
+  -d 
'{"portfolioVariance":[{"arg0":{"nAssets":2,"weights":[0.6,0.4],"covarianceMatrix":[[0.04,0.006],[0.006,0.09]]}}]}'
+```
+
+See the sample READMEs for the complete test flow covering all services.
+
+---
+
 ## WildFly 32 Deployment Notes
 
 See `WILDFLY32_DEPLOY_STATE.md` in the Axis2/C repo for the full deployment
diff --git a/src/site/xdoc/docs/json-rpc-mcp-guide.xml 
b/src/site/xdoc/docs/json-rpc-mcp-guide.xml
index b768449eb6..9b2d46688a 100644
--- a/src/site/xdoc/docs/json-rpc-mcp-guide.xml
+++ b/src/site/xdoc/docs/json-rpc-mcp-guide.xml
@@ -33,6 +33,12 @@
 that target Axis2 JSON-RPC services and need to understand the auto-generated 
MCP tool
 catalog, the required envelope format, authentication flow, and current 
limitations.</p>
 
+<p><strong>Quick start:</strong> For step-by-step build, deploy, and test 
instructions
+(including curl commands for every endpoint), see the sample READMEs:
+<code>modules/samples/userguide/src/userguide/springbootdemo-tomcat11/README.md</code>
 (Tomcat 11)
+and 
<code>modules/samples/userguide/src/userguide/springbootdemo-wildfly/README.md</code>
+(WildFly 32/39).</p>
+
 <p><strong>In one sentence:</strong> Axis2 auto-generates an MCP tool catalog 
from its
 deployed services, accessible at <code>/openapi-mcp.json</code>, that tells 
MCP clients
 the exact JSON-RPC envelope format, auth requirements, and endpoint URL for 
every
@@ -138,16 +144,26 @@ before calling any tool:</p>
       }
     },
     {
-      "name":        "getCalculations",
-      "description": "CalculationService: getCalculations",
-      "inputSchema": { "type": "object", "properties": {}, "required": [] },
-      "endpoint":                "POST 
/services/CalculationService/getCalculations",
-      "x-axis2-payloadTemplate": "{\"getCalculations\":[{\"arg0\":{}}]}",
+      "name":        "portfolioVariance",
+      "description": "Calculate portfolio variance using O(n^2) covariance 
matrix multiplication",
+      "inputSchema": {
+        "type": "object",
+        "required": ["nAssets", "weights", "covarianceMatrix"],
+        "properties": {
+          "nAssets":          {"type": "integer", "minimum": 2, "maximum": 
2000},
+          "weights":          {"type": "array", "items": {"type": "number"}},
+          "covarianceMatrix": {"type": "array", "items": {"type": "array", 
"items": {"type": "number"}}},
+          "normalizeWeights": {"type": "boolean", "default": false},
+          "nPeriodsPerYear":  {"type": "integer", "default": 252}
+        }
+      },
+      "endpoint":                "POST 
/services/FinancialBenchmarkService/portfolioVariance",
+      "x-axis2-payloadTemplate": "{\"portfolioVariance\":[{\"arg0\":{}}]}",
       "x-requiresAuth":          true,
       "annotations": {
-        "readOnlyHint":    false,
+        "readOnlyHint":    true,
         "destructiveHint": false,
-        "idempotentHint":  false,
+        "idempotentHint":  true,
         "openWorldHint":   false
       }
     }
@@ -161,7 +177,7 @@ before calling any tool:</p>
 <tr><th>Field</th><th>Type</th><th>Notes</th></tr>
 <tr><td><code>name</code></td><td>string</td><td>Axis2 operation name (local 
part of QName); use as tool name in MCP</td></tr>
 <tr><td><code>description</code></td><td>string</td><td>Auto-generated 
"ServiceName: operationName" — not a rich natural language description</td></tr>
-<tr><td><code>inputSchema</code></td><td>object</td><td>MCP-compliant JSON 
Schema wrapper; <strong>properties is always empty</strong> (see Section 
7)</td></tr>
+<tr><td><code>inputSchema</code></td><td>object</td><td>MCP-compliant JSON 
Schema; populated from <code>mcpInputSchema</code> parameter in services.xml 
when set, otherwise empty <code>{}</code></td></tr>
 <tr><td><code>endpoint</code></td><td>string</td><td>Full POST path for this 
operation</td></tr>
 <tr><td><code>x-axis2-payloadTemplate</code></td><td>string (JSON)</td><td>The 
exact body to send, with the operation's wrapper already filled in</td></tr>
 <tr><td><code>x-requiresAuth</code></td><td>boolean</td><td><code>false</code> 
only for <code>loginService</code> (case-insensitive); <code>true</code> for 
everything else</td></tr>
@@ -470,8 +486,8 @@ Each item notes whether the gap is architectural (won't be 
added to Axis2) or de
 <tr><th>Feature</th><th>Status</th><th>Notes</th></tr>
 <tr>
   <td>Rich <code>inputSchema</code> properties</td>
-  <td>Not implemented — architectural gap</td>
-  <td><code>inputSchema.properties</code> is always <code>{}</code>. Axis2 
does not introspect Java parameter types into JSON Schema. MCP clients that 
need parameter validation must define their own schemas (e.g., via Pydantic 
models in a Python MCP server layer).</td>
+  <td><strong>Implemented</strong> — set <code>mcpInputSchema</code> parameter 
on <code>&lt;operation&gt;</code> in services.xml</td>
+  <td>When <code>mcpInputSchema</code> is set, the catalog embeds the full 
JSON Schema (types, constraints, required fields). Falls back to empty 
<code>{}</code> when not set. All financial benchmark operations have full 
schemas. Automatic introspection from Java types is not yet implemented — 
schemas are hand-authored in services.xml.</td>
 </tr>
 <tr>
   <td>Natural language tool descriptions</td>
@@ -546,7 +562,7 @@ uses determines what limitations apply:</p>
 <tr><td>Query semantics</td><td>Per-operation parameters in 
arg0</td><td>Uniform filter/sort/fields on every resource</td></tr>
 <tr><td>Error format</td><td>SOAP fault with correlation ID UUID</td><td>RFC 
7807 Problem Details (JSON, per-field)</td></tr>
 <tr><td>Pagination</td><td>Full result sets only</td><td>Cursor-based</td></tr>
-<tr><td>inputSchema</td><td>Always empty properties</td><td>Full JSON Schema 
from OpenAPI annotations</td></tr>
+<tr><td>inputSchema</td><td>Full JSON Schema via <code>mcpInputSchema</code> 
in services.xml (hand-authored)</td><td>Full JSON Schema from OpenAPI 
annotations (auto-generated)</td></tr>
 </table>
 
 <p>The Axis2 MCP catalog at <code>/openapi-mcp.json</code> provides MCP-ready 
tool
@@ -561,7 +577,8 @@ tool discovery during the transition period.</p>
 <p>When building a Python MCP server that targets Axis2 services, keep these 
points in mind:</p>
 
 <ul>
-<li>The Axis2 catalog's <code>inputSchema.properties</code> is always empty — 
define full
+<li>When <code>mcpInputSchema</code> is set in services.xml, the catalog 
provides full
+    JSON Schema for each tool. For services without 
<code>mcpInputSchema</code>, define
     Pydantic <code>inputSchema</code> per tool in your Python MCP server 
layer.</li>
 <li>Use curated natural language descriptions in your MCP server rather than 
relying on
     the auto-generated "ServiceName: opName" default (or set 
<code>mcpDescription</code>


Reply via email to