MCP server
The Jetty MCP server is the npm package jetty-mcp-server. This page describes version 1.1.0. The server implements the Model Context Protocol (MCP). It gives an agent 27 tools that create, run, schedule, and inspect Jetty workloads.
The server is a local process. Your MCP client starts it with npx and speaks to it over standard input and output (stdio). The server calls flows-api.jetty.io with your API token. Jetty does not host an MCP endpoint.
The Jetty plugin for Claude Code, Codex, and OpenCode includes this server. The tool set is the same in every editor.
Requirements
- Node.js 18 or later.
- A Jetty API token. Create one at Settings → API keys. A token starts with
mlc_.
Configuration
The server reads two environment variables.
| Variable | Required | Default | Function |
|---|---|---|---|
JETTY_API_TOKEN | Yes | None | The API token the server sends with each request. |
JETTY_API_URL | No | https://flows-api.jetty.io | The base URL of the Jetty API. Set it only for a non-default backend. |
If JETTY_API_TOKEN is not set, the server reads the token from ~/.config/jetty/token. The jetty login command writes this file. The environment variable has priority over the file.
Add the server to your editor
The command is the same for every MCP client: npx -y jetty-mcp-server. Only the configuration file is different.
Claude Code
Run this command in the terminal:
claude mcp add jetty -- npx -y jetty-mcp-serverOr add the server to .mcp.json in the project:
{
"mcpServers": {
"jetty": {
"command": "npx",
"args": ["-y", "jetty-mcp-server"],
"env": { "JETTY_API_TOKEN": "mlc_your_token_here" }
}
}
}Cursor
Add the same object to .cursor/mcp.json. Windsurf reads the same structure from ~/.codeium/windsurf/mcp_config.json.
VS Code
Add the server to .vscode/mcp.json. VS Code uses the key servers, not mcpServers:
{
"servers": {
"jetty": {
"command": "npx",
"args": ["-y", "jetty-mcp-server"],
"env": { "JETTY_API_TOKEN": "mlc_your_token_here" }
}
}
}Codex CLI
Add the server to ~/.codex/config.toml:
[mcp_servers.jetty]
command = "npx"
args = ["-y", "jetty-mcp-server"]
env = { JETTY_API_TOKEN = "mlc_your_token_here" }Zed and other MCP clients
Register a stdio server with the command npx, the arguments -y jetty-mcp-server, and the environment variable JETTY_API_TOKEN. Zed reads servers from the context_servers object in settings.json. Refer to the documentation of your client for the field names.
Tools
The server registers 27 tools. The names below are the names an agent calls. The API calls a run a trajectory and a schedule a routine; the tool names keep the API terms.
Each tool carries MCP annotations. 14 tools set readOnlyHint: true. They read data and change nothing. The other tools create or change data. Only delete-routine sets destructiveHint: true.
| Group | Tool | Function | Read-only |
|---|---|---|---|
| Collections | list-collections | Lists all collections. | Yes |
| Collections | get-collection | Gets one collection and the names of its environment variables. | Yes |
| Tasks | list-tasks | Lists the tasks in a collection. | Yes |
| Tasks | get-task | Gets one task and its workflow definition. | Yes |
| Tasks | create-task | Creates a task from a workflow definition. | No |
| Tasks | update-task | Changes the workflow or description of a task. | No |
| Trial keys | get-trial-status | Gets the trial-key status of a collection. | Yes |
| Trial keys | activate-trial | Activates trial keys for a collection. | No |
| Runs | run-workflow | Starts a run and returns its workflow_id immediately. | No |
| Runs | run-workflow-sync | Starts a run and waits for the result (30 to 60 seconds is typical). | No |
| Run inspection | list-trajectories | Lists the recent runs of a task. | Yes |
| Run inspection | get-trajectory | Gets the full record of one run. | Yes |
| Run inspection | get-stats | Gets the run statistics of a task. | Yes |
| Run inspection | add-label | Adds a key=value label to a run. | No |
| Step templates | list-step-templates | Lists the available workflow step templates. | Yes |
| Step templates | get-step-template | Gets the details and input schema of one step template. | Yes |
| Configuration | check-secrets | Compares the environment variables of a collection with the variables a runbook needs. | Yes |
| Configuration | set-environment-vars | Sets environment variables on a collection. Existing keys are kept. A null value deletes a key. | No |
| Schedules | list-routines | Lists the schedules of a collection, or of one task. | Yes |
| Schedules | get-routine | Gets one schedule, including its next fire time. | Yes |
| Schedules | create-routine | Creates a schedule for an existing task. | No |
| Schedules | update-routine | Changes the cadence, overrides, secrets, paused state, or webhook of a schedule. | No |
| Schedules | delete-routine | Deletes a schedule. This cannot be undone. | No |
| Schedules | pause-routine | Stops a schedule until it is resumed. | No |
| Schedules | resume-routine | Resumes a paused schedule. | No |
| Schedules | run-routine-now | Fires a schedule immediately and returns the workflow_id of the run. | No |
| Schedules | list-routine-runs | Lists the recent runs that a schedule started. | Yes |
Note: run-workflow-sync holds the tool call open until the run completes. For a run that takes more than one minute, use run-workflow, then find the run with list-trajectories and read it with get-trajectory.
Use the package as a library
Version 1.1.0 adds importable entry points. All entry points are ES modules. The npx jetty-mcp-server command still starts the stdio server; editor configurations do not change.
| Import | Runs in | Exports |
|---|---|---|
jetty-mcp-server | Node.js | Everything below, plus JettyClient: the API client that resolves the token from the environment or the token file. |
jetty-mcp-server/api-client | Browser and Node.js | JettyApiClient: the API client. You pass in the token, the API origin, and an optional URL builder. |
jetty-mcp-server/tool-definitions | Browser and Node.js | JETTY_TOOLS: each tool as data (name, description, zod input shape, annotations, handler). JETTY_WEBMCP_TOOLS: the subset that WebMCP exposes. |
jetty-mcp-server/tools | Node.js | registerTools(server, client): registers the catalog on an McpServer from the MCP SDK. |
jetty-mcp-server/webmcp | Browser and Node.js | findModelContext, registerJettyWebMcpTools, jettyWebMcpTools, toWebMcpTool, and toolInputJsonSchema. See the next section. |
WebMCP: the same tools in the browser
WebMCP lets a web page give tools to an agent that runs in the browser. The page registers the tools on the model context of the document (document.modelContext or navigator.modelContext).
On jetty.io, each signed-in app page registers the Jetty tools with the session of the signed-in user. There is nothing to install and no token to copy. A WebMCP-capable browser or extension can list tasks, start a run, or read a result on the page you have open.
2 tools are not available over WebMCP: get-trial-status and activate-trial. Trial keys are an account-level setting for the local agent that set up the workspace. The package never exposes these two tools to a browser agent, even when include names them.
Register the tools on your own site
Any site can register the catalog. Give JettyApiClient a function that returns the session token of the visitor, and a buildUrl function that maps each API path to a proxy on your own origin:
import { JettyApiClient } from "jetty-mcp-server/api-client";
import { findModelContext, registerJettyWebMcpTools } from "jetty-mcp-server/webmcp";
const modelContext = findModelContext();
if (modelContext) {
const client = new JettyApiClient({
token: () => session.getToken(),
buildUrl: (path) => "/api/mise" + path.slice("/api/v1".length),
});
const controller = new AbortController();
registerJettyWebMcpTools(modelContext, client, {
signal: controller.signal,
readOnly: false,
include: ["list-tasks", "run-workflow", "get-trajectory"],
});
}Note: flows-api.jetty.io sends no CORS headers. A browser cannot call it directly. Route the calls through a proxy on your origin, or through a backend that adds the bearer token. jetty.io rewrites /api/mise/* to /api/v1/* on the API for this purpose.
registerJettyWebMcpTools accepts these options:
signal: anAbortSignal. Abort it to unregister the tools. A signal that is already aborted registers nothing.include: a list of tool names. Only these tools are registered.exclude: a list of tool names. These tools are never registered.readOnly: whentrue, only the tools withreadOnlyHint: trueare registered.namePrefix: a string added to the front of each tool name, for examplejetty_. The default is no prefix.
The function returns the API shape it used (registerTool or provideContext) and the names of the tools it registered. Both shapes of the WebMCP API are supported.
Each WebMCP tool keeps the name, description, and annotations of the MCP tool. Its inputSchema is JSON Schema, derived from the same zod shape. Its execute function validates the input, calls the API, and returns the same { content: [{ type: "text", text }] } result as the MCP server. On failure it returns isError: true instead of throwing. An agent that knows the MCP server can use the page without new instructions.
Transport
The server runs on your machine as a stdio process. Your token goes from the process to the Jetty API and to no other server. There is no endpoint to deploy and no URL to configure. A guide that points an MCP client at an https://…/mcp URL for Jetty is out of date. Use npx -y jetty-mcp-server.
Source: jettyio/jettyio-skills (mcp-server/). To call Jetty from an application, use the Client SDK →