back to all blogsSee all blog posts

Integrate your Liberty app with agentic AI using MCP server

image of author
Habib Lawal on Oct 23, 2025
Post available in languages:

What is MCP

Model Context Protocol (MCP) is an open standard that enables AI applications to interact with and utilize external systems.

The Liberty MCP Server feature allows developers to expose the business logic of their applications, making it discoverable, understandable, and usable by AI applications.

The Power of MCP

MCP has emerged as the standard for AI applications to access real-time information from external sources. This approach delivers more accurate and timely responses to users without the constant need to retrain AI models on new information.

Consider a scenario where your company provides weather forecasting services that require continuous updates from multiple data sources. It’s impractical and inefficient to constantly retrain your AI model with these frequently changing weather forecasts.

A more effective solution is to enable the AI to access current weather data through tools exposed by your Liberty application. This allows the AI to retrieve up-to-date forecast information whenever needed, ensuring responses are always based on the most current data available, without the need for AI model retraining.

How to Use the Liberty MCP Server Feature

The Liberty MCP Server feature enables a Liberty server to communicate with agentic AI workflows using the MCP protocol with streamable HTTP. Using the MCP protocol provides a standardized way for any AI application to be able to discover and utilize the business logic within your application.

Declaring an MCP Tool

To expose your business logic to authorized AI applications, you’ll need to declare it as an MCP tool. In this context, a tool is a function or operation that the AI can invoke to perform a specific task.

You can easily declare a tool with the Liberty MCP Server feature by adding the @Tool annotation to your desired Java method. This annotation makes your method automatically discoverable by the Liberty MCP Server feature to make the method available for AI applications to invoke.

For this discovery mechanism to work, your Java method must be defined within a CDI managed bean that has an appropriate scope annotation (e.g., @ApplicationScoped or @RequestScoped).

Example: Creating a Weather Forecast Tool

The following is an example of a tool for getting the weather forecast. The tool calls an external service to get the forecast based on the location coordinates provided by the AI application:

@ApplicationScoped
public class WeatherTools {

    @Inject
    private WeatherToolsClient weatherClient;

    @Tool(name = "getForecast", title = "Weather Forecast Provider", description = "Get weather forecast for a location.")
    public String getForecast(@ToolArg(name = "latitude", description = "Latitude of the location") String latitude,
                              @ToolArg(name = "longitude", description = "Longitude of the location") String longitude) {
        return weatherClient.getForecast(
                Double.parseDouble(latitude),
                Double.parseDouble(longitude),
                4,
                "temperature_2m,snowfall,rain,precipitation,precipitation_probability");
    }
}

We’ve annotated the WeatherTools class with @ApplicationScoped to make it a CDI managed bean. This is required for the @Tool-annotated method to be discovered by the server.

See the following for a breakdown of how this weather forecast tool works.

Breaking Down the @Tool Annotation

@Tool is the annotation that exposes your application functionality to an AI application.

  • Name: The name used to identify the tool when the AI application calls it. If this attribute is not specified, the method name is used as the tool name.

  • Title: An optional user-friendly title for the tool that can be displayed to the end user of the application. If not declared, then the tool name is used as the default for the title.

  • Description: This helps the AI model understand the functionality of the tool, enabling it to determine if this is the appropriate tool to use to help perform the desired action.

Breaking Down the @ToolArg Annotation

@ToolArg is the annotation to declare an argument that must be passed when calling a tool.

  • Name: The name used to identify the argument that the AI is providing a value for. Arguments are identified by name, so this attribute is required unless the class was compiled with the -parameters option.

  • Description: A description of the argument, so the AI can understand what value it should provide for the argument.

Note that the AI model will use the description to decide when to call a tool and what values to pass for the arguments. Therefore, writing descriptive text that the AI can understand is crucial for effective tool utilization.

Supported MCP Functionality

Much of the MCP specification’s functionality is optional to implement, allowing for gradual adoption while maintaining compatibility. The mcpServer-1.0 feature has implemented support for the tool feature of the MCP Server specification, along with the tool related capabilities listed below.

The mcpServer-1.0 feature supports communicating using both version 2025-06-18 and version 2025-03-26 of the MCP protocol.

Tool Metadata hints (Annotations)

You can provide hints about the scope and range of your tool to give the AI application an indication of how safe the tool is to call. For example, you can indicate whether calling your tool may modify data. Note that although the MCP specification refers to these hints as "Tool Annotations", they are unrelated to Java annotations.

You can add these hints within your @Tool annotation. Below is an example:

@Tool(annotations = @Annotations(readOnlyHint = true, openWorldHint = false)

The hints you can currently add to your tool include:

  • readOnlyHint - If true, indicates the tool will not modify any data. (Default: false)

  • destructiveHint - If true, for tools which are not readOnly, indicates the tool may destroy data. (Default: true)

  • idempotentHint - If true, for tools which are not readOnly, indicates calling the tool repeatedly with the same arguments will have no additional effect on data. (Default: false)

  • openWorldHint - If true, indicates the tool may interact with external systems. (Default: true)

Note: The destructiveHint and idempotentHint are only meaningful when readOnlyHint is set to false, as read-only tools by definition neither destroy data nor need to be idempotent.

Cancellation

A tool can sometimes take a long time to run, such as when fetching data from a slow external service. In these situations, clients should have the ability to cancel their request to the running tool.

The Liberty MCP Server feature supports cancellation, allowing clients to send cancellation requests at any time during tool execution.

To enable cancellation for your tool, you must accept a Cancellation parameter. When your tool is running, you should periodically call Cancellation.skipProcessingIfCancelled() which will throw an OperationCancellationException if the client has requested cancellation.

@Tool
public String bigComputationTool(Cancellation cancellation) {
    ArrayList<Data> result = new ArrayList<>();
    for (Data someData : getData()) {
        cancellation.skipProcessingIfCancelled();
        result.add(process(someData));
    }
    return result;
}

How to Try the MCP Server Feature

Here are the simple steps to follow to try out the MCP Server feature mcpServer-1.0:

  1. Download the Open Liberty All Beta Features package from here

  2. Unzip the archive. You should have a wlp folder

  3. Find the version number of the io.openliberty.mcp jar, which is located within the lib folder inside the wlp folder. For example, if the io.openliberty.mcp jar is named io.openliberty.mcp_1.0.106.jar, then it means the version number is 1.0.106.

  4. Inside your pom.xml file, add the version number from step 3 and the path to your wlp folder as variables named mcp-jar-version and wlp-dir-path within the <properties> block:

    <properties>
        <wlp-dir-path>replace-with-path-to-wlp-dir</wlp-dir-path>
        <mcp-jar-version>replace-with-version-number</mcp-jar-version>
    </properties>
  5. Inside your pom.xml file, to add the MCP jar as a dependency, add the following dependency within the <dependencies> block:

    <!-- Liberty MCP API -->
    <dependency>
        <groupId>io.openliberty.mcp</groupId>
        <artifactId>mcp-core</artifactId>
        <version>${mcp-jar-version}</version>
        <scope>system</scope>
        <systemPath>${wlp-dir-path}/lib/io.openliberty.mcp_${mcp-jar-version}.jar</systemPath>
    </dependency>
  6. Inside your pom.xml file, add the following plugin within the plugins block:

    <plugin>
        <groupId>io.openliberty.tools</groupId>
        <artifactId>liberty-maven-plugin</artifactId>
        <configuration>
            <installDirectory>${wlp-dir-path}</installDirectory>
        </configuration>
    </plugin>

We are actively developing support for additional MCP Server features and would greatly appreciate your feedback on which functionality would be most valuable for your use case. You can raise an issue for a feature request here.

For more information about MCP, you can read the official MCP documentation here.