Zum Hauptinhalt springen

webforJ MCP Apps

Preview

Your 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.

An inventory view, open in the conversation

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.

  1. 01 The AIThe host calls the inventory tool, with input such as a warehouse code.

  2. 02 webforJwebforJ renders the routed view /inventory, and the view opens in the conversation.

  3. 03 The AIThe AI calls actions such as inventory_refresh_stock on the open view.

  4. 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.

Read about opening input
InventoryView.java
@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.

  • INLINE
  • PIP
  • FULLSCREEN

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.

Read about actions and updates
inventory_refresh_stock

An 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.

InventoryView.java
@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_update

One 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.

Read about host interaction

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.

InventoryView.java
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

    updateModelContext replaces 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 onToolCancelled and onHostContextChanged let the view react when a tool call is cancelled or the conversation context changes.

  • Leave the frame

    openLink continues on an external page, and requestDisplayMode asks 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

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.

Spring Boot setup
Standard servlet

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.

Standard setup

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.

Read the testing guide
Remote hosts

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.

Local inspector

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 baseline, for each host
  • The client connects to the MCP endpoint.
  • The inventory tool is visible.
  • Invoking inventory renders 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. 1

    Add the MCP Apps module

    Add the webforj-mcp-apps module to a webforJ app. A Spring Boot app also adds the Spring AI MCP server starter.

  2. 2

    Mark a routed view

    Add @McpApp with a description that tells the AI when the tool is useful.

  3. 3

    Start the app and connect a host

    Start the server and add its /mcp endpoint to an MCP Apps-capable host.

  4. 4

    Ask the host to open it

    Prompt the host with "Open the inventory app." and the view appears.