# Dev MCP

| Experimental This feature is currently experimental. To enable it, set `quarkus.dev-mcp.enabled=true` in your application properties.

## Overview

When you run a Quarkus application in dev mode, you can expose a Model Context Protocol (MCP) server. It presents the methods used by the DevUI MCP tools (methods you can call) and the data exposed by MCP resources.

### Connecting an MCP client

Open the Dev MCP menu in the Dev UI to see the MCP server’s URL. (Default `http://localhost:8080/q/dev-mcp`). Any MCP client that supports the Streamable Protocol, version 2025‑03‑26 can connect using that URL. After a client connects, it appears on the MCP Info page of the Dev UI.

## Guide for extension developers

Extensions can contribute additional tools and resources to the Dev MCP server. The integration is similar to contributing to the Dev UI, but descriptions are mandatory. A single JSON‑RPC service can be used for both Dev UI and Dev MCP; methods without a description only show up in Dev UI, while methods with a description appear in both.

### MCP resources

A resource is data exposed by your extension. There are two ways to create a resource.

#### MCP Resources against build time data

Build‑time data that is already exposed to the Dev UI can also be made available to Dev MCP. Provide a description when calling `addBuildTimeData()`:

    footerPageBuildItem.addBuildTimeData(
        "jokes",
        jokesBuildItem.getJokes(),
        "Some funny jokes that the user might enjoy"
    );

The extra `description` argument is new: without it the data only appears in the Dev UI. Once supplied, the `jokes` data becomes an MCP resource.

#### MCP Resources against a recorded value

To expose recorded values (data produced at runtime by a recorder) as an MCP resource, define a build‑time action in the deployment module. The action must include a description:

    @BuildStep(onlyIf = IsLocalDevelopment.class)
    BuildTimeActionBuildItem createBuildTimeActions() {
        BuildTimeActionBuildItem item = new BuildTimeActionBuildItem(); (1)
        item.actionBuilder() (2)
                .methodName("getMyRecordedValue")
                .description("A well‑thought‑out description") (3)
                .runtime(runtimeValue) (4)
                .build();
        return item;
    }

1 | Return or produce a `BuildTimeActionBuildItem`.
2 | Use the builder to configure the action.
3 | Set a human‑readable description.
4 | Provide the runtime value returned by your recorder.

### MCP tools

A tool corresponds to a method that a client can call. Any JSON‑RPC method can be exposed as a tool by supplying descriptions on the method and its parameters. Tools can run on either the runtime or deployment classpath.

#### MCP Tools against the Runtime classpath

To expose runtime information or actions (for example, changing log levels), define a JSON‑RPC service in your runtime or runtime‑dev module and annotate the methods and parameters with `@JsonRpcDescription`:

    public class MyExtensionRPCService {

        @JsonRpcDescription("Update a specific logger's level in this Quarkus application") (1)
        public JsonObject updateLogLevel(
                @JsonRpcDescription("The logger name as defined in the logging implementation") String loggerName,
                @JsonRpcDescription("The new log level") String levelValue) { (2)
            // implementation…
        }
    }

1 | Description of the method.
2 | Description of each parameter.

You must register the JSON‑RPC service in the deployment module:

    @BuildStep
    JsonRPCProvidersBuildItem registerRpcService() { (1)
        return new JsonRPCProvidersBuildItem(MyExtensionRPCService.class); (2)
    }

1 | Produce a `JsonRPCProvidersBuildItem`.
2 | Specify the class in your runtime or runtime‑dev module that contains the methods.

`@JsonRpcDescription` is mandatory for Dev MCP; without it the method is only available in the Dev UI. The method can return primitives, `String`, `JsonObject`, `JsonArray`, or any POJO that can be serialised to JSON. Asynchronous methods (`Uni`, `CompletionStage` or methods annotated with `@NonBlocking`) are also supported.

#### MCP Tools against the Deployment classpath

Sometimes you need to run actions on the deployment classpath (for example, writing configuration files). In that case you do not create a JSON‑RPC service; instead you provide a supplier via a `BuildTimeActionBuildItem`:

    @BuildStep(onlyIf = IsLocalDevelopment.class)
    BuildTimeActionBuildItem createBuildTimeActions() {
        BuildTimeActionBuildItem actions = new BuildTimeActionBuildItem();
        actions.actionBuilder()
                .methodName("updateProperty")
                .description("Update a configuration/property in the Quarkus application")   (1)
                .parameter("name", "The name of the configuration/property to update")       (2)
                .parameter("value", "The new value for the configuration/property")
                .function(map -> {
                    Map<String, String> values = Collections.singletonMap(
                            map.get("name"), map.get("value"));
                    updateConfig(values);
                    return true;
                })
                .build();
        return actions;
    }

1 | Description of the method.
2 | Description of each parameter.

The code in the `function` runs on the deployment classpath. The function can return a plain value, a `CompletionStage` or `CompletableFuture` for asynchronous work.

### JSON‑RPC usage

By default all JSON‑RPC methods are visible in the Dev UI. Only methods with descriptions are exposed via Dev MCP. You can override this behaviour with the `@JsonRpcUsage` annotation. Pass one or both of the `Usage` enums (`DEV_UI`, `DEV_MCP`) to control where a method is exposed.