@process-forge/mcp-server
v0.26.0
Published
Model Context Protocol server for ProcessForge: lets any MCP client (Claude Desktop, Cursor, and others) design, validate and simulate process unit operations.
Readme
@process-forge/mcp-server
A Model Context Protocol (MCP) server for ProcessForge.
It gives an MCP client (Claude, Antigravity, OpenAI Codex, Cursor, VS Code, Gemini CLI and others) tools to design and validate unit-op contracts, run simulations, and, when the ProcessForge desktop app is open, add unit ops to the open flowsheet. The server does no model inference itself: your MCP client is the model.
Tools
| Tool | What it does |
| :--- | :--- |
| design_unit_op | Returns what a model needs to write a unit-op contract: the format, the expression rules, the drawing rules, worked examples, and a phase plan for the kind of equipment (which ports carry liquid, gas, solid or items, the flow units of each, the phase changes and the governing relations). The client writes the contract. |
| calculate_stream | Converts a liquid, gas or solid stream between flow units (kg/s, kg/h, lb/h, ACFM, SCFM, Nm³/h, m³/h, gal/min, L/min) with the ideal gas law, humidity and bulk density, and returns a designInlet to paste. |
| lookup_component | The engine's component database (35 chemicals plus air, sugars and salt; Poling, PSRK and CRC data): a component's molar mass, boiling and critical points, vapour pressure, latent heat, densities and specific heats at a temperature, or a liquid mixture's density, specific heat, bubble point and first vapour (NRTL where ChemSep has the pair, ideal otherwise, and it says which). Unknown names are refused with the names they probably meant. Contracts call the same data as psat('ethanol', T), hvap, cp_gas, rho_liquid, and bubble_point(inlet.x, P) for a mixture. |
| validate_unit_op | Checks a contract through the engine's gates: schema, every expression resolves and the units agree, phases balance (nothing leaves in a phase it never had, and heat-taking changes have a heat source), every ERROR constraint holds, and the drawing gives every port a nozzle. Returns the failures to fix. Accepts parameter overrides to test another operating point. |
| draw_unit_op | Draws a unit you are designing from its contract at the standard of the Standard palette: body, internals and guarding in the theme's tones, the items it carries, parts that move while it runs, a live liquid level, and every port's nozzle where that stream connects. The contract's numbers shape it (valves, lanes, rows and columns, layers, elements) and each unit gets a variant of its own. Kits: rotary machine, labeler, conveyor, case packer, palletizer, tank, carbonator, pump, inline mixer, heat exchanger, machine. |
| preview_unit_drawing | Renders a unit's drawing to an image the model can look at (made by ProcessForge Desktop), with a report: shapes, moving parts, nozzles, a quality score against the palette's drawings, and problems such as a near copy of a drawing that ships with ProcessForge. |
| fork_unit_op | Starts a design from equipment that is already modelled (a Standard unit, a Library listing, or a unit on the flowsheet): its whole contract and a drawing to reshape, under a new id. |
| explore_unit_op | Sweeps a contract's parameters, one at a time, through their ranges and reports where each check passes, warns and fails; solves for the value that brings a result to a target. Draws the unit panel in the chat in MCP Apps clients. |
| get_open_flowsheet | Reads the flowsheet open in ProcessForge Desktop on this computer. |
| add_unit_op_to_flowsheet | Validates a contract and adds it to the flowsheet open in ProcessForge Desktop, drawn from its contract with pipes attaching at its nozzles. |
| plan_changes | Plan, then act: applies a set of changes (add units, pipe them, change settings, hold results, remove) to a copy of the flowsheet, all or nothing, and reports each step, the diff, new static-check errors and a run before and after on the same seed. Changes nothing. Returns a planId bound to the flowsheet and the changes. |
| apply_changes | Applies a planned set of changes in one step (one undo on the canvas), only if the flowsheet and the changes still match the planId, then reads the flowsheet back and reports whether every change landed. Needs ProcessForge Desktop 0.1.87 or later. |
| add_stream | Pipes one unit into another on the open flowsheet (by unit id, name or tag), choosing ports that fit: liquid to liquid, items to items. |
| update_unit | Changes a unit's settings (dotted names for nested ones) or its name on the open flowsheet, and returns old and new values. A setting the unit does not have is refused with the names it probably meant, and so is a result the engine works out (hold those with hold_unit_result). Needs ProcessForge Desktop 0.1.33 or later. |
| hold_unit_result | Holds a unit's result at a target by varying one of its settings (a design spec), re-solved after every later change; or releases it. Needs ProcessForge Desktop 0.1.87 or later (older desktops refused it at the bridge). |
| arrange_unit | Moves, sizes, turns or mirrors a unit on the open flowsheet; its nozzles turn with it. Drawing only: the simulation is unchanged. |
| route_stream | Sets the bends a pipe is drawn through, or hands it back to the router that keeps it clear of the equipment. Drawing only. |
| remove_unit | Removes a unit and its streams from the open flowsheet (undoable in the app). Marked destructive, so clients ask first. Needs 0.1.33 or later. |
| remove_stream | Removes one stream, by id or by the units at its ends. Needs 0.1.33 or later. |
| list_standard_unit_ops | Lists the equipment that ships with ProcessForge (the app's Standard palette) in six categories (feeds and outlets, transfer and storage, heat transfer, reaction, separation, packaging), with ports, default settings and how each is simulated; filter with category or query. Some are designed units (contracts) you can tune or redesign. |
| add_standard_unit_op | Places a standard unit or a feed/outlet arrow on the open flowsheet, with any settings changed, and optionally pipes it in (connectFrom, connectTo). Only Product outlets count as the line's output. Needs ProcessForge Desktop 0.1.30 or later. |
| publish_unit_op | Asks the engineer to publish a unit from the open flowsheet to the ProcessForge Library: opens the publish dialog in ProcessForge Desktop, filled in with the details you suggest. Nothing is published unless the engineer clicks Publish there. Needs 0.1.39 or later. |
| list_flowsheets | Lists the flowsheets saved in ProcessForge on this computer (name, description, units, streams, last change), which one is open, and the templates a new one can start from. Needs 0.1.47 or later. |
| new_flowsheet | Starts a new flowsheet with the name you give, blank or from a template, and opens it on the canvas. The one that was open stays saved. Needs 0.1.47 or later. |
| open_flowsheet | Opens a saved flowsheet by name or id. Needs 0.1.47 or later. |
| save_flowsheet | Saves the open flowsheet, renaming or describing it if you say; cloud: true also uploads it to the engineer's account (they sign in with Google in the app). Needs 0.1.47 or later. |
| search_community_unit_ops | Searches the ProcessForge Library of unit ops people have published from the app. Public and read-only; listings are not reviewed by ProcessForge. |
| add_community_unit_op | Places a community listing on the open flowsheet as its author published it, and optionally pipes it in. Needs ProcessForge Desktop 0.1.30 or later. |
| simulate_process_line | Runs the discrete-event simulation. Returns its status (ok, warnings or failed) and coded issues first, then throughput, scrap, per-unit states, liquid levels, temperatures and heat duty, the bottleneck (or, for a liquid line, what sets its rate), and the run's heat and mass balance: mass across the line, and each heating, cooling or phase-changing unit's duty against what its streams carried. |
| compare_scenarios | What-if runs: the line as it is, then with unit settings changed, on the same seed, with the change in output (by mass for a line that makes no items), where the bottleneck moves, and each run's status; a scenario that changes nothing is marked noEffect. Changes nothing on the flowsheet. |
| solve_steady_state | The line's heat and mass balance at steady state in milliseconds: every stream, each unit's flows, temperature, duty and share of its rating, mass in and out, and each thermal unit's duty against its streams, with status and issues. Steps the same engine as a run, so it agrees with a long run; recycles converged by Wegstein. Reports a tank that fills or a recycle that cannot close; not for lines with batch or cycle units. |
| sweep_line | A sensitivity study of the whole line: one unit's setting across a range, the line simulated at each value on one seed, the results you name in a table (line output, a unit's outlet temperature, duty, flow, OEE, a component's fraction), with each run's status. |
| solve_line_target | A design spec for the line ("vary X so that Y = target"): bracketed regula falsi over full runs, within the setting's range narrowed to where the unit's design holds; returns the value, what it achieved, its status and every try, or the nearest value when the target is out of reach. Changes nothing. |
| diagnose_bottlenecks | Instant static check: port and flow-dimension errors, the capacity bottleneck, and fixed recommendations (for example, add an accumulation conveyor). |
| list_digital_twin_templates | Lists the built-in example lines (paint canning, beverage bottling, spray drying, juice concentration). |
| query_unit_subagent | Returns preset configuration values and inspector controls for a standard machine type. Rotary fillers and labelers have presets; other types get a generic response. No model is called. |
| package_unit_op | Wraps a node in a JSON bundle with author, category, tags and metadata, for sharing. |
| forge_equipment_drawing | Picks one of the template drawings (column, reactor, exchanger, pump, cyclone, spray, sphere, drum or a generic vessel) by keyword-matching the description, and fills in a few parameters such as tray count and agitator type. Returns SVG geometry and nozzle positions. When the match is a tie it says so, and a second call can name the family. |
simulate_process_line, diagnose_bottlenecks and compare_scenarios work on
the flowsheet open in ProcessForge Desktop when you pass no graph or
templateName. Without the app they use a demo line and say so in source.
Every tool has a title and read-only/write annotations, so clients can ask before a tool changes the flowsheet. Results come back as JSON text and as structured content.
In clients that support MCP Apps,
explore_unit_op and validate_unit_op also show the unit's panel at a glance
in the chat: a gauge for how close each check runs to its limit, its headline
figures and notes (ui://process-forge/unit-panel.html). Its operating
conditions (temperatures, pressures, flows, speeds) are input fields: change one
and the engine re-checks the design at your values, and the model is told which
values you set. Other clients get the same JSON answer as before.
Prompts and resources
The server also sends clients a short workflow guide (MCP instructions), and
offers:
- Prompts (slash commands in most clients):
debottleneck-line,design-unit-opandbuild-line. - Resources: the workflow guide, the standard equipment catalog, the unit-op contract guide, the open flowsheet and each built-in template.
Designing a unit op from your MCP client
- Open ProcessForge Desktop (0.1.18 or later) and the flowsheet you are working on.
- In your MCP client, describe the equipment, e.g. "a rotary drum dryer for wet road salt, counter-current hot air".
- The client calls
design_unit_op, writes the contract's physics, draws it withdraw_unit_op(or starts fromfork_unit_opwhen the equipment is already modelled), looks at the drawing withpreview_unit_drawing, and callsvalidate_unit_opuntil the engine accepts it. - It calls
add_unit_op_to_flowsheet. The unit appears on your canvas, drawn as designed, with a nozzle for each stream. It then callsadd_streamto pipe it to the units it connects to, or you pipe it up yourself.
Without the desktop app running, step 4 tells the client so, and it can give you the contract JSON to paste into Design a unit op instead.
The desktop app accepts these requests only from this computer: it listens on 127.0.0.1 with a random token it writes to its data folder, readable only by your user account, and it validates every contract again before adding it.
Configuration
Any MCP client that can start a local (stdio) server works. The server runs
on your machine with Node.js 20 or later; npx fetches it on first use.
Claude Desktop (one click)
Download process-forge.mcpb and open it. Claude Desktop shows ProcessForge and its tools; click Install. It needs no Node.js install: Claude Desktop runs the bundled server itself.
The extension is built by pnpm --filter @process-forge/mcp-server run pack:mcpb
(one bundled file, manifest generated from the server's own tool list, checked
with @anthropic-ai/mcpb) and attached to every GitHub release.
Claude Desktop (manual)
Add this to claude_desktop_config.json (Settings, Developer, Edit Config), then restart Claude Desktop:
{
"mcpServers": {
"process-forge": {
"command": "npx",
"args": ["-y", "@process-forge/mcp-server"]
}
}
}Claude Code
claude mcp add process-forge -- npx -y @process-forge/mcp-serverAntigravity
Agent panel, ⋯, MCP Servers, Manage MCP Servers, View raw
config. Add the same mcpServers entry as for Claude Desktop, save, then
Refresh.
OpenAI Codex (CLI and IDE extension)
codex mcp add process-forge -- npx -y @process-forge/mcp-serverOr in ~/.codex/config.toml:
[mcp_servers.process-forge]
command = "npx"
args = ["-y", "@process-forge/mcp-server"]ChatGPT connectors need a remote (HTTPS) server, which this is not; use Codex for OpenAI models.
Cursor and Windsurf
The same mcpServers entry as Claude Desktop, in ~/.cursor/mcp.json
(Settings, MCP) or ~/.codeium/windsurf/mcp_config.json.
VS Code (GitHub Copilot agent mode)
code --add-mcp "{\"name\":\"process-forge\",\"command\":\"npx\",\"args\":[\"-y\",\"@process-forge/mcp-server\"]}"Gemini CLI
gemini mcp add process-forge npx -y @process-forge/mcp-serverWindows
If a client cannot start npx, use "command": "cmd" with
"args": ["/c", "npx", "-y", "@process-forge/mcp-server"].
The app shows all of these, with copy buttons, under AI model → MCP client.
From a checkout
pnpm install && pnpm run build
pnpm --filter @process-forge/mcp-server run bundle
node packages/mcp-server/bundle/cli.jsPrivacy
The server runs locally as a subprocess of your MCP client. It needs no API key and sends nothing to ProcessForge. What your MCP client sends to its own model provider is up to that client.
Publishing
The published package is a single file, bundle/cli.js, with the engine
packages inlined (they are not on npm); only @modelcontextprotocol/sdk and
zod are dependencies. prepublishOnly builds, bundles, and runs
scripts/smoke.mjs, which starts the bundle as an MCP client would and
checks that it lists its tools. CI runs the same smoke test.
cd packages/mcp-server
npm publishYou must be signed in to npm (npm login) with publish rights to the
@process-forge scope.
