Documentation

Use the app

How it works

Build on it

Get involved

Development

How to work on this repository from source.

Repository layout

Path Contents
client/ The Harness application: packages, skills, launcher
desktop/ Electron app, runtime installer, device and twin management
src/edmore_mcp/ Python MCP server for tool registration and event forwarding
vendor/tem-alignment-twin/ Digital Twin, a submodule
vendor/edmore_windows_node/ Device service and Tango modules, a submodule
deployment/ Native and cloud deployment
docs/ This documentation; docs/diagrams/ holds each image with its editable .excalidraw source

Two related projects live elsewhere: NionSwift's own plugin provides its UI and application-local tools, and ptycho-sem owns SEM hardware control and acquisition. client/runtime/ is an inactive legacy snapshot kept for provenance and rollback; see client/runtime/provenance.json. The former Python edmore_mcp.client has been removed.

git submodule update --init

Run the client from source

Requires Node.js 22.19+ (22.x) or 24+.

cd client
npm ci
npm start

The client listens on http://127.0.0.1:7380 and serves its UI at /edmore/. It discovers the NionSwift MCP server at http://127.0.0.1:7300. NionSwift's start button launches client/start.mjs, and in a different directory layout you set EDMORE_CLIENT_DIR before starting NionSwift.

A source client uses ~/.dsh, unlike the packaged app. Existing data stays in ~/.dsh/edmore, so no migration is needed: sessions, workspace.json, events.jsonl, plan-judge-state.json, provider and role settings, and credentials. Startup creates a separate edmore-client launch profile on those paths. Stop any former backend before using the same data directory. The old EDMORE_HARNESS_URL and event URL variables remain accepted as aliases.

Login and multiple users

EDMORE_AUTH=1 selects the login gateway with isolated user runtimes, and unset or 0 keeps the default user. HU LLM and Bonsai are shared through a protected model proxy, while OpenAI keys and supported plugin preferences belong to each user. Network deployments must set EDMORE_PUBLIC_URL. Validate with npm run test:auth in client/. See EDMORE Auth.

Run the desktop app from source

cd desktop
npm ci
npm start

To exercise the packaged path from source, build the payload and set EDMORE_DESKTOP_PAYLOAD_ROOT to desktop, which holds payload/:

npm run prepare:payload
EDMORE_DESKTOP_PAYLOAD_ROOT="$PWD" npm start

Python MCP server

pip install -e .

edmore-client then launches the same Node client. Python wheels do not bundle it, so set EDMORE_CLIENT_DIR if it is installed elsewhere.

Configuration

Variable Purpose
EDMORE_CLIENT_DIR Client installation location
EDMORE_CLIENT_URL Client address used by NionSwift and event forwarding
EDMORE_CLIENT_HOST, EDMORE_CLIENT_PORT Client bind address; default 127.0.0.1:7380
EDMORE_NIONSWIFT_BASE_URL MCP server address; default http://127.0.0.1:7300
EDMORE_WORKSPACE Initial project directory
DSH_HOME Data and configuration home; default ~/.dsh
EDMORE_CLIENT_EVENT_URL Optional event ingestion URL
EDMORE_AUTH 1 selects the login gateway; see EDMORE Auth
EDMORE_DEFAULT_PROVIDER Fallback model provider; set by the packaged app
EDMORE_HIDDEN_PROVIDERS Comma-separated providers to hide; set by the packaged app
EDMORE_TANGO_MCP_URL, EDMORE_TANGO_MCP_TOKEN, EDMORE_TANGO_SERVER_NAME Instrument gateway; set by the packaged app

HTTP API

GET  /api/edmore/health
GET  /api/edmore/capabilities
GET  /api/edmore/ui/state
GET  /api/edmore/ui/stream
GET  /api/edmore/events
POST /api/edmore/events
POST /api/edmore/actions/trigger
POST /api/edmore/actions/approve
POST /api/edmore/actions/reject
POST /api/edmore/actions/resume
GET  /api/edmore/skills
GET  /api/edmore/harness/tools
GET  /api/edmore/nionswift/tools
GET  /api/edmore-workspace/projects
GET  /api/edmore-workspace/conversations

examples/demo_server.py shows Python MCP tool registration, examples/demo_client.py "your request" submits a request to the running client, and debug_agents.py inspects roles and the tool registry.

Tests

cd desktop && npm test

From client/:

npm test
npm run test:smoke
npm run test:portable

The smoke test uses temporary data and an offline instrument URL, and checks startup, skills, UI, conversation persistence, restart and shutdown. It does not run a model or operate hardware. The portable test copies the client outside the workspace, runs a fresh npm ci, and repeats the smoke test.

Native deployment

To run Tango and the WeKnora Wiki as standalone local services, without the desktop app:

bash deployment/native/deploy.sh up

No Slurm, Apptainer or Docker is needed, and cloud credentials and existing local databases are not copied. See Native Deployment for dependencies, data, ports and lifecycle commands.