MCP (agents)
PYNE MCP: stdio or HTTP pyne-mcp for LLM hosts, plus in-process pyne mcp call and pyne execute (Runtime.run) with no extra.
This page
Abstract
The PYNE MCP server exposes the Pine toolchain to LLM hosts (Cursor, Claude, Inspector, Grok) over stdio by default, or over HTTP (sse / streamable-http) when PYNE_MCP_TRANSPORT is set. The same tools run from the shell with pyne mcp call and first-class pyne execute (no MCP SDK). Tools call library APIs in-process — they do not shell out. Serving needs hoox-pyne[mcp]; call / execute / config / tools do not. Tool names are prefixed pyne_ so they never collide with AXIS axis_* / app_*. Compose publishes streamable-http on host :5003.
Conceptual model
Rendering…
| Surface | Role |
|---|---|
| PYNE MCP | Language + runtime: parse, lint, convert, compile, execute, builtins |
| AXIS MCP | Chart PWA + Worker APIs (POST /mcp, optional tab bridge) |
pyne-lsp | Editor language server (separate stdio process) |
Clients may enable PYNE MCP and AXIS MCP together.
Interface surface
pip install "hoox-pyne[mcp]"
pyne mcp config # print mcpServers JSON
pyne mcp tools # catalog names
pyne mcp call lint script.pine
pyne mcp call execute script.pine --arg bars=50 --arg mode=interpret
pyne execute script.pine --mode interpret --bars 50
pyne mcp # stdio (blocks)
pyne-mcp # same as pyne mcp
python -m pynescript.mcp
# GHCR streamable-http image (compose also starts this as service mcp)
docker pull ghcr.io/hoox-sh/pyne/mcp:0.6.31
docker run --rm -p 5003:8080 ghcr.io/hoox-sh/pyne/mcp:0.6.31
{
"mcpServers": {
"pyne": {
"command": "pyne-mcp",
"args": []
}
}
}
pyne mcp config --module uses python -m pynescript.mcp instead of the console script.
pyne mcp call and pyne execute / symbols / parity / diagnostics / builtin invoke the same ops in-process and print JSON (no stdio host, no mcp extra). TOOL may be pyne_lint or the short alias lint. Extra arguments: --arg KEY=VALUE (JSON-coerced) or --json '{"bars":50}'.
Every tool returns { "ok": true, ... } or { "ok": false, "error", "kind", "line?", "column?" }. Pine syntax errors are tool results, not protocol failures. Prefer source= (pasted script) over path=. Plot series are truncated (last N samples). Default data provider is mock. Runner tools use PYNE_API_URL / ADMIN_TOKEN and hit the network.
Catalog: MCP tools.
Internals (repo paths)
src/pynescript/mcp/catalog.py— canonical tool / resource / prompt names (docs + tests)src/pynescript/mcp/server.py—MCPServer, tool registrationsrc/pynescript/mcp/dispatch.py— in-processcall_tool(CLIpyne mcp call)src/pynescript/mcp/cli.py— Clickmcpgroup +execute/symbols/parity/diagnostics/builtinsrc/pynescript/mcp/ops/— library-backed operations- Extra:
[mcp]inpyproject.toml(mcp>=2.0,<3,lsprotocol); surfacespyne-mcp/pyne mcp - Entry:
pyne-mcp = pynescript.mcp.__main__:main - Transport:
PYNE_MCP_TRANSPORT(stdiodefault,sse,streamable-http) plusPYNE_MCP_HOST/PYNE_MCP_PORT
Invariants & edge cases
- No disk writes (
format/convertreturn source). pyne_runis the CLI compile + synthetic bars path.pyne_executeisRuntime.run(interpret / compile / auto, caller OHLCV, timeout).pyne_download_builtinslists pine-facade templates; it does not write files.- Hover / complete / signature reuse LSP handlers; they need
lsprotocol(pulled in by[mcp]).
Worked examples
User: lint this script and run 50 bars
Agent: pyne_lint({source}) → pyne_run({source, bars: 50})
User: what does ta.sma take?
Agent: pyne_builtin({name: "ta.sma"})
Failure modes
| Symptom | Cause |
|---|---|
MCP extra missing | pip install "hoox-pyne[mcp]" for stdio. pyne execute / mcp call run without the extra |
ok: false, kind: parse | Syntax error; line / column set when known |
kind: network | Runner / non-mock pyne_data / facade list |
| Large plot dumps | Raise sample only as needed (max 64) |