diff --git a/posts/2026-02-10-26.0.0.2-beta.adoc b/posts/2026-02-10-26.0.0.2-beta.adoc index fe6af8db8..d45889cf1 100644 --- a/posts/2026-02-10-26.0.0.2-beta.adoc +++ b/posts/2026-02-10-26.0.0.2-beta.adoc @@ -6,8 +6,8 @@ categories: blog author_picture: https://avatars3.githubusercontent.com/navaneethsnair1 author_github: https://github.com/navaneethsnair1 seo-title: "Model Context Protocol Server 1.0 updates and more in 26.0.0.2-beta- OpenLiberty.io" -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. -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. +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. +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. open-graph-image: https://openliberty.io/img/twitter_card.jpg open-graph-image-alt: Open Liberty Logo --- @@ -18,7 +18,7 @@ Navaneeth S Nair :url-about: / //Blank line here is necessary before starting the body of the post. -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. +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. 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]): @@ -38,20 +38,20 @@ The link:https://modelcontextprotocol.io/docs/getting-started/intro[Model Contex 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. === Prerequisites -To use the `mcpServer-1.0` feature, `Java 17` or later must be installed on the system. +To use the `mcpServer-1.0` feature, Java 17 or later must be installed on the system. -=== Implement Role-based authorization for MCP tools via annotations +=== Implement role-based authorization for MCP tools via annotations The following new annotations allow you to restrict tool usage through authorization policies: -. `@DenyAll` - Resource is denied. This is the strictest policy. -. `@RolesAllowed` - Resource is allowed for pre-authorised users in a role (same as a group in liberty). +. `@DenyAll` - Resource is denied. This annotation is the strictest policy. +. `@RolesAllowed` - Resource is allowed for pre-authorised users in a role (the same as a group in Liberty). . `@PermitAll` - Resource is allowed for anyone (even unauthenticated users). These security annotations are declared on two levels: -. Class level - Every method in the class inherits this class level annotation -. Method level - Overrides any class level annotations +. Class level - Every method in the class inherits this class level annotation. +. Method level - Overrides any class level annotations. For complete reference documentation, see the link:https://jakarta.ee/specifications/security/[Jakarta Security Annotations specification]. @@ -59,7 +59,7 @@ For complete reference documentation, see the link:https://jakarta.ee/specificat Consider an online bookshop that has different users each with different authorization levels: -* Users - Low Security clearance required +* Users - Minimum Security clearance required * Moderators - Medium Security clearance required * Admins - High Security clearance required @@ -124,16 +124,16 @@ public class PublicTools { ==== Steps required * Create an application with `@ApplicationScoped` and expose the tool with the required annotations. -* Create a `server.xml` with users -* Ensure that the groups map to the Roles created in the Tool -* Add users to the groups in the `server.xml` -* Create tests that test the expected functionality of the tools +* Create a `server.xml` file with the users. +* Ensure that the groups map to the roles created in the tool. +* Add users to the groups in the `server.xml` file. +* Create tests that validate the expected functionality of the tools. The following additional configuration is required in the `server.xml` (also see comments in the xml below): -* additional: appSecurity feature -* additional: transportSecurity feature +* additional: `appSecurity` feature +* additional: `transportSecurity` feature * additional: define a user registry * additional: enable TLS (Transport Layer Security) for security * additional: require TLS (Transport Layer Security) to ensure credentials aren't sent in cleartext @@ -204,20 +204,20 @@ The following additional configuration is required in the `server.xml` (also see ---- -If another role were added to the code, say `RoleDoesNotExistInServerConfig` then any user (for e.g. Sally) was trying to authenticate with `@RolesAllowed("RoleDoesNotExistInServerConfig")` would not be able to have access to the resource until that role had a group created for it in the `server.xml` file and that user was mapped to that group. +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. -In other situations we could also add multiple roles to tools: `@RolesAllowed("Admins, Moderators")`. This could make sense if the roles would have no overlapping users. +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. -_**Authorization Configuration**_ +**Authorization Configuration** -The `mcpServer-1.0` feature does not currently implement the MCP specification's link:https://spec.modelcontextprotocol.io/specification/2025-06-18/server/authorization[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. +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. -=== MCP: Tools can now access the ID of the request sent by the client +=== MCP: Tools can now access the ID of the request that is sent by the client Your tool can now have a new argument of type `io.openliberty.mcp.request.RequestID`. -As an example the requestID may be used for logging or audit purposes: +As an example the requestID can be used for logging or audit purposes: [source,java] ---- @@ -234,7 +234,7 @@ public class RequestIDLoggingExample { } ---- -=== MCP: Tools can access metadata sent by the client in the `_meta` field +=== MCP: Tools can access metadata that is sent by the client in the `_meta` field 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. @@ -247,8 +247,7 @@ The whole `_meta` key is seen as "example.com/myKey" ==== Adding a Tool Meta parameter -The code below shows an example metaKey used to retrieve the value of the metadata. -In the example below, the metakey is "api.ibmtest.org/location" +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" [source,java] ---- @@ -265,9 +264,9 @@ In the example below, the metakey is "api.ibmtest.org/location" } ---- -==== Returning meta data via a Tool Response +==== Returning metadata via a Tool Response -A method can return any meta data via the `ToolResponse` Object: +A method can return any metadata via the `ToolResponse` Object: [source,java] ---- @@ -296,16 +295,16 @@ Track API costs for expensive operations. *How it works:* -* Server adds costs to tool metadata -* Client tracks total spending across operations +* Server adds costs to tool metadata. +* Client tracks total spending across operations. ==== 2) Rate Limiting Extension Prevent resource exhaustion and ensure fair access. *How it works:* -* Metadata shows remaining quota before each call for time window -* If limit exceeded, error includes retry time in `_meta` +* Metadata shows the remaining quota before each call for time window +* If limit is exceeded, error includes retry time in `_meta` ==== 3) Caching Hints Extension Optimize performance through intelligent caching. @@ -317,7 +316,7 @@ Optimize performance through intelligent caching. ==== 4) Bringing it all together -All three of the above extensions could be built into your MCP server as extensions: +All three of the preceding extensions might be built into your MCP server as extensions: [source,json] ---- @@ -343,16 +342,15 @@ All three of the above extensions could be built into your MCP server as extensi === Notable bug fixes in MCP 1.0 -==== 1) MCP Server feature used ISO-8859-1 and did not handle non-latin characters +==== 1) MCP Server feature used ISO-8859-1 and did not handle non-Latin characters * Non-ASCII characters are now encoded correctly using UTF-8. -* When an asynchronous tool failed with a business exception, it was incorrectly treated as a non-business exception and the client would 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. +* 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. -==== 2) Fix Async MCP Tool error handling +==== 2) Fix asynchronous MCP Tool error handling -* When an async tool returned a completion stage that failed, we were not checking whether the returned exception was a business exception or not, so we always reported an internal error. -* Now we are checking whether or not it is a business or technical error and returning the error. -* Business errors are returned to the client and technical errors are returned to the technical team to resolve. +* 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. +* 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. // DO NOT MODIFY THIS LINE. @@ -362,7 +360,9 @@ All three of the above extensions could be built into your MCP server as extensi // // // // // // // // [#displayCustomizedExceptionText] == displayCustomizedExceptionText property -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. The feature is enabled through simple `server.xml` configuration, where custom messages can be mapped to specific HTTP status codes (403 and 500). 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. +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. +The feature is enabled through simple `server.xml` configuration, where custom messages can be mapped to specific HTTP status codes (403 and 500). +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. [source,xml] ----