Skip to content

Commit 4847919

Browse files
Merge pull request #4707 from OpenLiberty/staging
Update prod
2 parents 1935644 + 5f9a2f5 commit 4847919

File tree

1 file changed

+51
-74
lines changed

1 file changed

+51
-74
lines changed

posts/2026-02-10-26.0.0.2-beta.adoc

Lines changed: 51 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ categories: blog
66
author_picture: https://avatars3.githubusercontent.com/navaneethsnair1
77
author_github: https://github.com/navaneethsnair1
88
seo-title: "Model Context Protocol Server 1.0 updates and more in 26.0.0.2-beta- OpenLiberty.io"
9-
seo-description: This beta release enhances the `mcpServer-1.0` feature with role-based authorization, request IDs, the new `_meta` field, and key bug fixes. It also adds documentation and tests for `displayCustomizedExceptionText`, allowing users to replace default Liberty error messages with clearer, custom text.
10-
blog_description: This beta release enhances the `mcpServer-1.0` feature with role-based authorization, request IDs, the new `_meta` field, and key bug fixes. It also adds documentation and tests for `displayCustomizedExceptionText`, allowing users to replace default Liberty error messages with clearer, custom text.
9+
seo-description: This beta release enhances the `mcpServer-1.0` feature with role-based authorization, the new `_meta` field, and key bug fixes. It also adds documentation and tests for `displayCustomizedExceptionText`, allowing users to replace default Liberty error messages with clearer, custom text.
10+
blog_description: This beta release enhances the `mcpServer-1.0` feature with role-based authorization, the new `_meta` field, and key bug fixes. It also adds documentation and tests for `displayCustomizedExceptionText`, allowing users to replace default Liberty error messages with clearer, custom text.
1111
open-graph-image: https://openliberty.io/img/twitter_card.jpg
1212
open-graph-image-alt: Open Liberty Logo
1313
---
@@ -18,7 +18,7 @@ Navaneeth S Nair <https://github.com/navaneethsnair1>
1818
:url-about: /
1919
//Blank line here is necessary before starting the body of the post.
2020

21-
This beta release enhances the `mcpServer-1.0` feature with role-based authorization, request IDs, the new `_meta` field, and key bug fixes. It also adds documentation and tests for `displayCustomizedExceptionText`, allowing users to replace default Liberty error messages with clearer, custom text.
21+
This beta release enhances the `mcpServer-1.0` feature with role-based authorization, the new `_meta` field, and key bug fixes. It also adds documentation and tests for `displayCustomizedExceptionText`, allowing users to replace default Liberty error messages with clearer, custom text.
2222

2323
The link:{url-about}[Open Liberty] 26.0.0.2-beta includes the following beta features (along with link:{url-prefix}/docs/latest/reference/feature/feature-overview.html[all GA features]):
2424

@@ -33,9 +33,9 @@ See also link:{url-prefix}/blog/?search=beta&key=tag[previous Open Liberty beta
3333
// // // // // // // //
3434
[#mcp]
3535
== Model Context Protocol Server 1.0 updates
36-
The link:https://modelcontextprotocol.io/docs/getting-started/intro[Model Context Protocol (MCP)] is an open standard that enables AI applications to access real-time information from external sources. The Liberty MCP Server feature `mcpServer-1.0` allows developers to expose the business logic of their applications, allowing it to be integrated into agentic AI workflows.
36+
The link:https://modelcontextprotocol.io/docs/getting-started/intro[Model Context Protocol (MCP)] is an open standard that enables AI applications to access real-time information from external sources. The Liberty MCP Server feature (`mcpServer-1.0`) allows developers to expose the business logic of their applications, allowing it to be integrated into agentic AI workflows.
3737

38-
This beta release of Open Liberty includes important updates to the `mcpServer-1.0` feature including role-based authorization, request IDs, the `_meta` field, and a few bug fixes.
38+
This beta release of Open Liberty includes important updates to the `mcpServer-1.0` feature including role-based authorization, the `_meta` field, and a few bug fixes.
3939

4040
=== Prerequisites
4141
To use the `mcpServer-1.0` feature, Java 17 or later must be installed on the system.
@@ -55,13 +55,19 @@ These security annotations are declared on two levels:
5555

5656
For complete reference documentation, see the link:https://jakarta.ee/specifications/security/[Jakarta Security Annotations specification].
5757

58-
==== Basic Authorization policy
58+
The `mcpServer-1.0` feature does not currently implement all of the link:https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#authorization-server-metadata-discovery[authorization-server-metadata-discovery requirements] specified in the MCP specification. However, you can use any of Liberty's link:https://openliberty.io/docs/latest/authentication.html[authentication and authorization mechanisms] to authenticate users and assign roles. The `mcpServer-1.0` feature can then ensure that users can access only the tools that are permitted for their assigned roles.
59+
60+
==== Basic authorization example
61+
62+
The following example shows how to configure MCP tools to require authentication and to ensure that users have the appropriate roles to access specific tools. Users authenticate using Basic Authentication, and the list of users and their roles are configured in a basicRegistry in the `server.xml` file.
5963

6064
Consider an online bookshop that has different users each with different authorization levels:
6165

62-
* Users - Minimum Security clearance required
63-
* Moderators - Medium Security clearance required
64-
* Admins - High Security clearance required
66+
* Users - can buy books and track prices
67+
* Moderators - can manage the books available
68+
* Admins - can manually ban users
69+
70+
Clients who connect without authenticating can only display the available books or register as a new user.
6571

6672
[source,java]
6773
----
@@ -74,7 +80,7 @@ import jakarta.annotation.security.RolesAllowed;
7480
import jakarta.enterprise.context.ApplicationScoped;
7581
----
7682

77-
=== Security Annotation Demo Classes
83+
==== Security Annotation example classes
7884

7985
[source,java]
8086
----
@@ -123,20 +129,18 @@ public class PublicTools {
123129

124130
==== Steps required
125131

126-
* Create an application with `@ApplicationScoped` and expose the tool with the required annotations.
132+
* Create an application with `@ApplicationScoped` and expose the tools with the required annotations.
127133
* Create a `server.xml` file with the users.
128134
* Ensure that the groups map to the roles created in the tool.
129135
* Add users to the groups in the `server.xml` file.
130-
* Create tests that validate the expected functionality of the tools.
131136

137+
The following additional configuration is required in the `server.xml` (See the comments in the XML example for details.):
132138

133-
The following additional configuration is required in the `server.xml` (also see comments in the xml below):
134-
135-
* additional: `appSecurity` feature
136-
* additional: `transportSecurity` feature
137-
* additional: define a user registry
138-
* additional: enable TLS (Transport Layer Security) for security
139-
* additional: require TLS (Transport Layer Security) to ensure credentials aren't sent in cleartext
139+
* The `appSecurity` feature
140+
* The `transportSecurity` feature
141+
* Define a user registry
142+
* Enable TLS (Transport Layer Security) for security
143+
* Require TLS (Transport Layer Security) to ensure that credentials aren't sent in cleartext
140144

141145
[source,xml]
142146
----
@@ -156,11 +160,11 @@ The following additional configuration is required in the `server.xml` (also see
156160
<!-- Required for passwords to be encrypted using HTTPS -->
157161
<keyStore id="defaultKeyStore" password="Liberty" />
158162
159-
<!-- Required to define https port for TLS (Transport Layer Security) -->
160-
<httpEndpoint id="defaultHttpEndpoint"
161-
httpPort="-1"
162-
httpsPort="9443">
163-
</httpEndpoint>
163+
<!-- Required to define https port for TLS (Transport Layer Security) -->
164+
<httpEndpoint id="defaultHttpEndpoint"
165+
httpPort="-1"
166+
httpsPort="9443">
167+
</httpEndpoint>
164168
165169
<basicRegistry id="basic" realm="BasicRealm">
166170
@@ -204,50 +208,22 @@ The following additional configuration is required in the `server.xml` (also see
204208
</server>
205209
----
206210

207-
If a new role like `RoleDoesNotExistInServerConfig` were added to the code, any user (e.g., Sally) attempting to authenticate with a resource annotated with `@RolesAllowed("RoleDoesNotExistInServerConfig")` would be denied access to the resource. Access would only be granted after creating a corresponding group for that role in the server.xml file and mapping the user to that group.
208-
209-
In other situations we could also add multiple roles to tools: `@RolesAllowed("Admins, Moderators")`. This approach might make sense if the roles had no overlapping users.
210-
211-
**Authorization Configuration**
212-
213-
The `mcpServer-1.0` feature does not currently implement the MCP specification's authorization-server-metadata-discovery requirements. However, you can use any of Liberty's link:https://openliberty.io/docs/latest/authentication.html[standard authorization methods], including custom implementations.
214-
215-
216-
=== MCP: Tools can now access the ID of the request that is sent by the client
217-
218-
Your tool can now have a new argument of type `io.openliberty.mcp.request.RequestID`.
219-
220-
As an example the requestID can be used for logging or audit purposes:
221-
222-
[source,java]
223-
----
224-
public class RequestIDLoggingExample {
225-
226-
private static final Logger logger = Logger.getLogger(McpToolExample.class.getName());
211+
It is also possible to add multiple roles to tools: `@RolesAllowed("Admins, Moderators")`. Doing so grants access to users who have either role.
227212

228-
@Tool(name = "exampleTool")
229-
public String exampleTool(RequestId requestId) {
230-
// Log with request ID using asString() method
231-
logger.info("Processing request [" + requestId.asString() + "] with input: ");
232-
...
233-
}
234-
}
235-
----
236-
237-
=== MCP: Tools can access metadata that is sent by the client in the `_meta` field
238-
239-
The link:https://modelcontextprotocol.io/specification/2025-06-18/basic/index#meta[MCP specification] specifies that the `_meta` property/parameter is reserved by MCP to allow clients and servers to attach additional metadata to their interactions.
213+
If a role that is used in `@RolesAllowed` annotation is not mentioned in the `server.xml` file, that just means that no user has that role. If it is the only role that is allowed to call the tool, then no users can call the tool.
240214

215+
=== MCP: Tools can access metadata that the client sends in the _meta field.
216+
The link:https://modelcontextprotocol.io/specification/2025-06-18/basic/index#meta[MCP specification] reserves the `_meta` property or parameter so clients and servers can attach additional metadata to their interactions.
241217
Key name format: valid `_meta` key names have two segments:
242218

243-
* an optional prefix (e.g. "example.com/") and
244-
* a name ("myKey")
219+
* An optional prefix (e.g. "example.com/") and
220+
* A name ("myKey")
245221

246222
The whole `_meta` key is seen as "example.com/myKey"
247223

248224
==== Adding a Tool Meta parameter
249225

250-
The following code shows an example metaKey used to retrieve the value of the metadata. In the example, the metakey is "api.ibmtest.org/location"
226+
The following code shows an example metaKey used to retrieve the value of the metadata. In the example, the metakey is "example.org/location"
251227

252228
[source,java]
253229
----
@@ -257,16 +233,16 @@ The following code shows an example metaKey used to retrieve the value of the me
257233
structuredContent = false)
258234
public String noArgsRequest(Meta meta) {
259235
Jsonb jsonb = JsonbBuilder.create();
260-
String location = (String) meta.getValue(MetaKey.from("api.ibmtest.org/location"));
236+
String location = (String) meta.getValue(MetaKey.from("example.org/location"));
261237
BigDecimal timestamp = (BigDecimal) meta.getValue(MetaKey.from("timestamp"));
262238
String result = "You have called this tool from " + location + " at timestamp " + timestamp.toString();
263239
return result;
264240
}
265241
----
266242

267-
==== Returning metadata via a Tool Response
243+
==== Returning metadata in a tool response
268244

269-
A method can return any metadata via the `ToolResponse` Object:
245+
A method can return any metadata by using the `ToolResponse` object:
270246

271247
[source,java]
272248
----
@@ -282,20 +258,20 @@ A method can return any metadata via the `ToolResponse` Object:
282258
Jsonb jsonb = JsonbBuilder.create();
283259
Map<MetaKey, Object> _meta = new HashMap<>();
284260
_meta.put(MetaKey.from("timestamp"), 1762860699);
285-
_meta.put(MetaKey.from("api.ibmtest.org/location"), "Hursley");
286-
_meta.put(MetaKey.from("api.libertytest.org/person"), personInstance);
261+
_meta.put(MetaKey.from("example.org/location"), "Hursley");
262+
_meta.put(MetaKey.from("example.org/person"), personInstance);
287263
return new ToolResponse(false, List.of(new TextContent(jsonb.toJson(employeeList))), employeeList, _meta);
288264
}
289265
----
290266

291-
The `_meta` field enables protocol extensions without breaking compatibility. Here are practical examples:
267+
The `_meta` field enables protocol extensions without breaking compatibility. The following examples illustrate common use cases:
292268

293269
==== 1) Cost Tracking Extension
294270
Track API costs for expensive operations.
295271

296272
*How it works:*
297273

298-
* Server adds costs to tool metadata.
274+
* Server reports the cost of executing a tool in the result metadata.
299275
* Client tracks total spending across operations.
300276

301277
==== 2) Rate Limiting Extension
@@ -304,14 +280,14 @@ Prevent resource exhaustion and ensure fair access.
304280
*How it works:*
305281

306282
* Metadata shows the remaining quota before each call for time window
307-
* If limit is exceeded, error includes retry time in `_meta`
283+
* If limit is exceeded, the error includes retry time in `_meta`
308284

309285
==== 3) Caching Hints Extension
310286
Optimize performance through intelligent caching.
311287

312288
*How it works:*
313289

314-
* Server implements caching strategy
290+
* Server includes caching information in the tool call result
315291
* Client can implement client-side caching
316292

317293
==== 4) Bringing it all together
@@ -344,13 +320,12 @@ All three of the preceding extensions might be built into your MCP server as ext
344320

345321
==== 1) MCP Server feature used ISO-8859-1 and did not handle non-Latin characters
346322

347-
* Non-ASCII characters are now encoded correctly using UTF-8.
348-
* When an asynchronous tool failed with a business exception, it was incorrectly treated as a non-business exception and the client might receive an "Internal server error" response. Now, the business exception message is correctly returned to the user in the same way that it is for synchronous tools.
323+
* MCP requests and responses are now encoded correctly using UTF-8.
349324

350325
==== 2) Fix asynchronous MCP Tool error handling
351326

352-
* Previously, when an asynchronous tool returned a failed completion stage, the system did not verify if the exception was a business or technical error. This oversight resulted in all failures being reported as internal errors.
353-
* The system now differentiates between exception types. This categorization ensures that business errors are returned to the client, while technical errors are directed to the technical team for resolution.
327+
* Previously, when an asynchronous tool returned a failed completion stage, the system did not verify whether the exception was a business or technical error. This resulted in all failures being reported as internal errors.
328+
* The system now differentiates between exception types. This categorization ensures that business errors are returned to the client, while technical errors are reported in the Liberty server log.
354329

355330
// DO NOT MODIFY THIS LINE. </GHA-BLOG-TOPIC>
356331

@@ -361,7 +336,9 @@ All three of the preceding extensions might be built into your MCP server as ext
361336
[#displayCustomizedExceptionText]
362337
== displayCustomizedExceptionText property
363338
This beta release adds documentation and tests for the `displayCustomizedExceptionText` configuration, which allows users to override Liberty’s default error messages (such as SRVE0218E: Forbidden and SRVE0232E: An exception occurred) with clearer, user-defined messages.
364-
The feature is enabled through simple `server.xml` configuration, where custom messages can be mapped to specific HTTP status codes (403 and 500).
339+
340+
The feature is enabled through simple `server.xml` file configuration, where custom messages can be mapped to specific HTTP status codes (403 and 500).
341+
365342
Testing ensures that these custom messages correctly replace Liberty’s defaults across all supported platforms, confirming that the configured text is returned consistently in all scenarios.
366343

367344
[source,xml]
@@ -455,4 +432,4 @@ For more information on using a beta release, refer to the link:{url-prefix}docs
455432
[#feedback]
456433
== We welcome your feedback
457434

458-
Let us know what you think on link:https://groups.io/g/openliberty[our mailing list]. If you hit a problem, link:https://stackoverflow.com/questions/tagged/open-liberty[post a question on StackOverflow]. If you hit a bug, link:https://github.com/OpenLiberty/open-liberty/issues[please raise an issue].
435+
Let us know what you think on link:https://groups.io/g/openliberty[our mailing list]. If you hit a problem, link:https://stackoverflow.com/questions/tagged/open-liberty[post a question on StackOverflow]. If you hit a bug, link:https://github.com/OpenLiberty/open-liberty/issues[please raise an issue].

0 commit comments

Comments
 (0)