# Run Stochastly from an MCP client

Compose a graph, run a real backtest and read the verdict without opening the interface. The gates that apply to you apply to the agent, and a tool that changes something states what it changes.
[Stochastly / stochastly-mcpPublicThe MCP launcher, open source under MIT. It connects Claude, Cursor or VS Code to the engine running in the desktop app; the engine itself stays in the app.PythonMIT licencepip install stochastly-mcpView the source on GitHub ↗](https://github.com/Stochastly/stochastly-mcp)

## Inspect the tools available to your client

A real tools/list response exposes the registered tools and their input contracts. The app editor displays the response recorded from the current local MCP server.

[Screenshot: Actual tool descriptions returned by MCP tools/list, inspected in the current app editor. The client can start a study, poll its result and read research status.](https://stochastly.com/screenshots-current/product-mcp--the-research-tools-exposed-to-a-client.png)

Actual tool descriptions returned by MCP tools/list, inspected in the current app editor. The client can start a study, poll its result and read research status.

## The engine, reachable by an agent

- Compose: build a graph node by node, from the same catalogue the interface uses
- Run: a real backtest on the engine, over the same executor the interface uses
- Read: the runs, the verdicts and the diagnostics already computed

Both classes need an active plan, early access included, and a read tool may refresh its own data cache. Composing a graph and reading a verdict that already exists are reads; running the engine and writing a file to disk are writes, and each write passes a second check. Atelier and Portfolio both include the server.

[Screenshot: A real compose_graph response, opened in the app editor. The isolated development session returns its strategy, configuration count and runnable specification; no backtest is implied.](https://stochastly.com/screenshots-current/product-mcp--mcp-composes-a-runnable-strategy.png)

A real compose_graph response, opened in the app editor. The isolated development session returns its strategy, configuration count and runnable specification; no backtest is implied.

## A tool carries a class, and a self-test walks the source to check it

Each tool is classified as a read or a write. A write tool declares in one line what it changes, and that line is the text the client receives: writes a PDF to disk, runs the engine over N configurations and creates a run, queues a command that drives the app.

An AST self-test over the server source enforces that classification, and the [MCP documentation page](https://stochastly.com/docs/mcp) carries it with the command that runs it. It checks both halves: a tool declared as a write must call the plan gate, and a tool classified as a read must not. Two more conditions are checked, because both have been wrong before — a docstring that points at a tool which does not exist, and a docstring that promises to leave the disk untouched while the tool is gated as a write.

The classification is written by hand, and the self-test is what makes that acceptable. Deriving it from name patterns was tried and failed on a single tool whose name contained a substring of another class (stochastly_mcp.py:586-593), so the list is explicit and its exhaustiveness is checked rather than assumed.

The self-test covers the tools. It does not walk the resources, which return data and are open to reads on all plans. That gap is stated because it is the kind of thing a green line hides.

## Three failures the self-test reproduces on purpose

- the app appears and disappears: the server re-discovers the engine absent, then present, then restarted on another port, without being restarted itself — stochastly_mcp.py:1098
- a call times out: the whole process tree is killed; a grandchild holding the pipe used to block the read indefinitely — stochastly_mcp.py:1175
- a reader holds the state file: the write proceeds without corrupting what the reader sees — stochastly_mcp.py:1315

Each of these is a bug that happened, turned into a case the self-test runs. A reconnection path with 0 exercises behind it holds until the first time it matters.

## A second layer reads files, and writes none

Beyond the engine calls, the server reads what a running app leaves on disk: its state, the tail of its log, and the queued command file, all under the user home (stochastly_mcp.py:157-167). The reader returns an age in seconds with the state, so a caller can tell a live value from a stale one, and degrades to a named absence when the app is closed.

Driving the app is off until a flag file is placed by hand (.mcp_pilot in the app's home directory), and no tool can create it. Secrets are dropped from the state before it leaves the machine, and the self-test checks that removal (stochastly_mcp.py:1363).

Without a readable licence, the write class is refused instead of defaulting open, and the self-test asserts it (stochastly_mcp.py:1297).

## Long sessions, counted draws

A run can be started and left: backtest_graph with background: truehands back a run id, backtest_status reads it until the verdict lands, and the server ships guided prompts for the research loop and the robustness pass. That is enough for an agent to hold a session for hours: compose, run, judge, iterate.

The desk counts finished runs in a session registry (the resource bluxt://session-registry), and each result reports the session totals for runs and configurations. Those counts describe the search history. For an added lever, compare paired results with a placebo and positive control during development. Confirm the finding with one declared reading of sealed data. Session totals remain visible without raising the acceptance threshold by themselves. A session left unattended runs on your machine and spends your CPU for as long as the agent keeps drawing.

[Screenshot: The current app compares in-sample and out-of-sample results from a recorded synthetic parameter search. An agent reviewing repeated searches must retain the trial population and the held-out results.](https://stochastly.com/screenshots-current/product-mcp--is-vs-oos-scatter.png)

The current app compares in-sample and out-of-sample results from a recorded synthetic parameter search. An agent reviewing repeated searches must retain the trial population and the held-out results.

## What the agent is not allowed to do, and how it finds out

MCP is included in both plans, Atelier and Portfolio. An active licence is required. If a request cannot be authorised, the server names the cause: the app cannot be reached, the licence is inactive, or the installed licence does not carry the required rights.

- Caller-supplied Python: off on the MCP channel by default; the restricted builtins do not form a sandbox
- Driving the app: off until a file is placed by hand; no MCP tool can create that file
- Opening a document: a .stly path under a size cap, and the file contents do not travel back to the caller
- Secrets: licence file and API keys stay on the machine; the caller sees a masked status

The lifting of the first two is a human act on the machine, by design. An agent that could grant itself the right to run arbitrary code would make the gate decorative.

## Two commands, and the detail lives in the documentation

The client script ships inside the install. Connecting it and the full list of tools, with the class and effect of each, are on the [MCP documentation page](https://stochastly.com/docs/mcp).

---
Source: https://stochastly.com/product/mcp
