public final class MCP

  1. Object
  2. MCP

Public entry point for the Codename One MCP headless API. Invoking a starter here is the enablement; there is no build hint or property to toggle. A single server instance exists per process.

The stdio transport is supported by the Codename One JavaSE port, which powers the simulator and the desktop tooling. The socket transport also serves a build running on a device, on any port that can bind the loopback interface. It is blocked on a release build - see setAllowOnReleaseBuilds(boolean).

Typical usage

// Let a running tool or the simulator accept an attaching agent on a local port:
MCP.startSocketServer(8642);

// Or serve over stdio when a host launches the tool as a subprocess:
MCP.startStdioServer();

// Publish domain tools alongside the automatic UI driving tools:
MCP.addTool(myTool);

Nested types

interface MCP.StdioTransportFactorySupplies the platform stdio transport.
interface MCP.SocketTransportFactorySupplies the platform loopback socket transport.

Methods

public static synchronized void setStdioTransportFactory(MCP.StdioTransportFactory factory)Registers the platform stdio transport factory.
public static synchronized void setSocketTransportFactory(MCP.SocketTransportFactory factory)Registers the platform socket transport factory.
public static synchronized boolean isStdioSupported()Whether an stdio transport is available on this platform.
public static synchronized boolean isSocketSupported()Whether a loopback socket transport is available on this platform - either one the port registered itself, or the portable one, which needs Socket.isLoopbackServerSocketSupported().
public static synchronized MCPServer getServer()Returns the shared server, creating it on first use.
public static synchronized boolean isRunning()
public static synchronized MCPServer startStdioServer()Starts the stdio transport server (the standard MCP local transport).
public static synchronized MCPServer startSocketServer(int port)Starts a loopback socket server so an agent can attach to this running process.
public static synchronized void setAllowOnReleaseBuilds(boolean allow)Permits the socket server to bind on a RELEASE build.
public static synchronized boolean isAllowedOnReleaseBuilds()Whether the socket server may bind on a release build.
public static synchronized boolean isSocketServerAllowedOnThisBuild()Whether the socket server is allowed to run on THIS build, which is the other half of the question isSocketSupported() answers: that one asks whether the platform can bind a loopback server socket, this one whether it is permitted to serve.
public static synchronized void stop()Stops the shared server if it is running.
public static void addTool(Tool tool)Registers a developer defined tool with the shared server.
public static void setVerbosity(MCPVerbosity verbosity)Sets how much of the MCP conversation is echoed to the Codename One log so a developer can watch and debug what an agent is doing.
public static MCPVerbosity getVerbosity()

Inherited methods

Method details

setStdioTransportFactory

public static synchronized void setStdioTransportFactory(MCP.StdioTransportFactory factory)
Registers the platform stdio transport factory. Called by the JavaSE port.

setSocketTransportFactory

public static synchronized void setSocketTransportFactory(MCP.SocketTransportFactory factory)
Registers the platform socket transport factory. Called by the JavaSE port.

isStdioSupported

public static synchronized boolean isStdioSupported()
Whether an stdio transport is available on this platform.

isSocketSupported

public static synchronized boolean isSocketSupported()

Whether a loopback socket transport is available on this platform - either one the port registered itself, or the portable one, which needs Socket.isLoopbackServerSocketSupported().

This is a question about CAPABILITY and deliberately ignores the release build gate, so it is not a complete preflight for startSocketServer(int) on its own - a platform that can bind may still refuse to serve. Ask isSocketServerAllowedOnThisBuild() for the other half.

getServer

public static synchronized MCPServer getServer()
Returns the shared server, creating it on first use.

isRunning

public static synchronized boolean isRunning()

startStdioServer

public static synchronized MCPServer startStdioServer()
Starts the stdio transport server (the standard MCP local transport). Requires a platform stdio transport factory (registered by the JavaSE port).

startSocketServer

public static synchronized MCPServer startSocketServer(int port)

Starts a loopback socket server so an agent can attach to this running process.

Uses the transport the port registered, if it has one - the JavaSE port registers a java.net implementation. Any other port falls back to the portable transport, which binds through Socket, so this works on a device too. It fails, on this thread, when the platform cannot bind a loopback server socket at all.

Refuses to bind on a RELEASE build, throwing IllegalStateException - see setAllowOnReleaseBuilds(boolean) for why, and for the deliberate override.

setAllowOnReleaseBuilds

public static synchronized void setAllowOnReleaseBuilds(boolean allow)

Permits the socket server to bind on a RELEASE build. Off by default, and turning it on should be a deliberate, reviewed decision.

The reason for the default: an attached agent can read the screen and drive the user interface, and the loopback interface is shared by everything on the device, not private to one application. On a phone that means any OTHER app installed alongside yours can connect to the port and drive your application. That is a fine trade while developing - it is how an agent attaches to a running app - and a poor one in an app a user installs.

A development build is detected as a debuggable Android package or a development provisioned iOS build. Any other target is treated as a release build, so a port that cannot tell withholds the server rather than exposing it.

The JavaSE port is the exception, and it matters here: it reports a development build in every case, because it cannot distinguish the simulator, the designer and the desktop tooling from a desktop application packaged for distribution. So this gate does NOT protect a shipped desktop build, and a desktop application that wants the server withheld from its own release has to decide that for itself. See Display.isDebuggableBuild().

Set this only for a build that ships to a controlled fleet - a kiosk, a test lab, an enterprise deployment - where the device itself is trusted.

Parameters

allow boolean
true to permit the socket server on a release build

isAllowedOnReleaseBuilds

public static synchronized boolean isAllowedOnReleaseBuilds()
Whether the socket server may bind on a release build.

isSocketServerAllowedOnThisBuild

public static synchronized boolean isSocketServerAllowedOnThisBuild()

Whether the socket server is allowed to run on THIS build, which is the other half of the question isSocketSupported() answers: that one asks whether the platform can bind a loopback server socket, this one whether it is permitted to serve. startSocketServer(int) needs both, and refuses on the first that says no.

True on a development build, or on any build where setAllowOnReleaseBuilds(boolean) has been used.

stop

public static synchronized void stop()
Stops the shared server if it is running.

addTool

public static void addTool(Tool tool)
Registers a developer defined tool with the shared server.

setVerbosity

public static void setVerbosity(MCPVerbosity verbosity)
Sets how much of the MCP conversation is echoed to the Codename One log so a developer can watch and debug what an agent is doing.

getVerbosity

public static MCPVerbosity getVerbosity()