Evaluating an expression is the obvious use and the shallow one. What makes this useful on a real Smalltalk codebase is that classes, selectors and method source come out of the live image — which in Pharo is the actual system, not a serialised copy of it — so an assistant answering a question about existing code is reading what is loaded rather than guessing from a repository checkout. The flip side is the setup: the image and NeoConsole have to be there first, and the server assumes it can find them.
A local MCP server that talks to a running Pharo Smalltalk image through NeoConsole. Two things follow from that: expressions are evaluated in the real image rather than a parser, and the image's own reflection — classes, selectors, method source, live metrics — is readable the same way.
- Expression evaluation through NeoConsole, taking the expression and the command to run it under — `evaluate_smalltalk_with_neo_console`
- A lighter evaluation path that goes through Pharo's own simple option, for when the console round trip is more than the question needs — `evaluate_simple_smalltalk`
- Live system metrics from the image by name, such as `system.status` for overall state or `memory.free` — `get_pharo_metric`
- Class-level reflection: the class comment and the class definition, read from the image rather than from a file on disk — `get_class_comment`, `get_class_definition`
- Method-level reflection: every selector on a class, and the source of one method by class and selector — `get_method_list`, `get_method_source`
A Pharo installation with NeoConsole installed, and `NeoConsole.image` present in the Pharo directory. `PHARO_DIR` points at that directory and defaults to `~/pharo`. Python 3.10 or later and the uv package manager. The project is `pharo-nc-mcp-server` (0.1.0 in pyproject): clone, `uv sync --dev`, then launch with `uv run pharo-nc-mcp-server` — the client config uses uv with `--directory` set to your checkout.
