webforJ MCP Apps
PreviewYour Java views, inside the AI conversation
An MCP-capable AI app, also called a host, opens a routed webforJ view inside its conversation. The person and the AI work with the same live UI.
One live UI
The view stays in your app. Both of them use it.
The view the host shows is the same routed view a browser shows, with the same components, services, routing and state. The AI works with it through tools, and the person keeps using the rendered components directly.
01 The AIThe host calls the
inventorytool, with input such as a warehouse code.02 webforJwebforJ renders the routed view
/inventory, and the view opens in the conversation.03 The AIThe AI calls actions such as
inventory_refresh_stockon the open view.04 The viewThe view sends messages and model context back to the conversation.
Open a view with input
A route becomes a tool. Its input sets the start.
Add @McpApp to a routed view and it is published as a tool. The description tells the AI when the tool is useful. One object type, such as an InventoryInput record, describes the arguments, and an @McpAppInput method applies them after the route renders.
@Route("/inventory")
@McpApp(
name = "inventory",
description = "Shows the current inventory for a warehouse.",
displayMode = McpAppDisplayMode.INLINE)
public class InventoryView extends Composite<FlexLayout> {
// ...
}
Tool names from routes
Without name, webforJ derives the tool name from the route: /inventory becomes inventory, /sales/inventory becomes sales_inventory, and the root route becomes app.
A requested display mode
displayMode asks the host how to present the view. The host can choose a different mode.
INLINEPIPFULLSCREEN
Actions and updates
More tools, for the view already open
These tools do not open the app. A call goes to the rendered inventory view in the same MCP session. If that view is not open, the call returns an error that directs the host to call inventory first.
inventory_refresh_stockAn action is a view method
Add @McpAppAction to a method and it becomes a tool with its own input. The method name refreshStock produces inventory_refresh_stock.
@McpAppAction(description = "Refreshes stock levels for the open warehouse.")
Map<String, Object> refreshStock() {
warehouse.setText(warehouse.getText() + " - refreshed");
return Map.of(
"warehouse", warehouse.getText(),
"refreshed", true);
}
inventory_updateOne update tool with the opening input
A view that implements McpAppUpdateObserver gets one update tool with the same input schema as inventory. The callback decides how to use the arguments and returns the tool result.
- webforJ does not apply the values to components automatically.
- Calling it does not open the route or render another view.
- The update tool has no UI resource metadata.
- A view can use both an action and the update tool.
Host interaction
The view talks back to the conversation
The same route also opens in a normal browser, so each host interaction starts by checking that a host is present. Host calls are asynchronous and return a PendingResult.
Continue the conversation from the view
The person picks a warehouse and asks the AI to review its stock. The button sends that request as the next user message. McpHost.ifPresent runs only when the view is connected to a host.
Paragraph warehouse = new Paragraph("Warehouse: BER");
Button review = new Button("Review stock");
review.addClickListener(event -> McpHost.ifPresent(host ->
host.sendMessage("Review the current stock for " + warehouse.getText())));
Keep the model informed
updateModelContextreplaces the context the view contributes to the model. Later responses can use it, and no visible message is added.Follow the conversation
Listeners such as
onToolCancelledandonHostContextChangedlet the view react when a tool call is cancelled or the conversation context changes.Leave the frame
openLinkcontinues on an external page, andrequestDisplayModeasks for a different presentation. The host decides whether it can satisfy either request.
Spring Boot or a standard servlet app
Publish with Spring AI, or assemble the server yourself
The view still works at /inventory in a browser. Publishing adds the MCP tool, the UI resource that opens the route, and the servlet setup the host needs to embed webforJ.
Spring Boot with Spring AI
The primary way to publish an MCP App. The integration discovers marked routes and adds them to the Spring AI MCP server, which serves Streamable HTTP at /mcp by default. It publishes the tool and a UI resource that opens the route, and installs the servlet filters and session settings needed to embed webforJ.
A servlet app without Spring
An initializer scans the package of the routed views, contributes their tools and UI resources to an MCP server, and mounts Streamable HTTP at /mcp. One install call adds the embed support the host needs.
Testing
Connect a host. Check the baseline.
webforJ MCP Apps run in any MCP Apps-capable host. The minimal inventory tool with no input is enough to confirm that a host can discover the tool and render the view.
A host that connects from outside the development machine cannot reach localhost. Expose the app through a tunnel, set webforj.origin to the public origin, and give the host that origin with /mcp added.
An inspector on the same machine connects to the local endpoint. Set the local webforj.origin and list the inspector's browser origin in webforj.mcp.allowed-origins.
- The client connects to the MCP endpoint.
- The
inventorytool is visible. - Invoking
inventoryrenders the Inventory heading. - The rendered UI is interactive.
How to start
One view, open in a host
webforJ is the full-stack Java framework for business web apps: you build the whole app, screens included, in Java. MCP Apps are part of it since webforJ 26.02, and Spring Boot with Spring AI is the primary way to publish one.
- 1
Add the MCP Apps module
Add the
webforj-mcp-appsmodule to a webforJ app. A Spring Boot app also adds the Spring AI MCP server starter. - 2
Mark a routed view
Add
@McpAppwith a description that tells the AI when the tool is useful. - 3
Start the app and connect a host
Start the server and add its
/mcpendpoint to an MCP Apps-capable host. - 4
Ask the host to open it
Prompt the host with "Open the inventory app." and the view appears.
- OverviewWhat MCP Apps are and where to begin
- Spring Boot setupDependencies, the endpoint and a routed app
- TestingRemote clients, a local inspector and the baseline
- Opening inputInput schemas, tool names and display modes
- Actions and updatesTools that work with the open view
- Host interactionMessages, model context and host events
- ConfigurationThe app origin, client origins and browser domains
- Standard setupAn MCP server in a servlet app without Spring