Driving it from MCP
From an MCP client like Claude Code or Claude Desktop, you can operate the oniyanma instance open in your browser.
How it works — the server doesn't execute anything
oniyanma's commands drive a live Viewer in the browser. The server can't execute a command, so it acts purely as a relay.
Claude Desktop ──stdio──> mcp.ts (agent) ──WS──> coordinator ──WS──> browser (viewer)
▲ │
└──────────────────────── result ───────────────────────────────────┘Tool definitions are received from the viewer (the browser) at startup. The server doesn't import the app's code. So adding a command on the app side requires no change on the server at all.
There's no authentication
Peers are matched only by a pairing code (room). Identity and permissions are planned to be layered on once the requirements are settled.
Setup
1. Start the coordinator
pnpm --filter @oniyanma/server coordinator # ws://localhost:8787 (change with PORT)2. Connect the browser as a viewer
Open the app and either add a URL parameter or connect from the console.
http://localhost:5173/?relay=ws://localhost:8787&room=bridge1oniyanma.connectRelay('ws://localhost:8787', 'bridge1')room is the pairing code. It has to match the agent side below.
3. Register with your MCP client
Claude Desktop's claude_desktop_config.json:
{
"mcpServers": {
"oniyanma": {
"command": "pnpm",
"args": ["--filter", "@oniyanma/server", "mcp"],
"cwd": "/absolute/path/to/oniyanma",
"env": {
"ONIYANMA_RELAY_URL": "ws://localhost:8787",
"ONIYANMA_ROOM": "bridge1"
}
}
}
}For Claude Code:
claude mcp add oniyanma \
--env ONIYANMA_RELAY_URL=ws://localhost:8787 \
--env ONIYANMA_ROOM=bridge1 \
-- pnpm --filter @oniyanma/server mcpAfter restarting, oniyanma's tools (setColorMode / selectBox / measureDistance …) become available, and the point cloud in the browser actually moves.
| Environment variable | Default | What it is |
|---|---|---|
ONIYANMA_RELAY_URL | ws://localhost:8787 | The coordinator's URL |
ONIYANMA_ROOM | oniyanma | The pairing code. Must match the viewer side |
Things to watch for
Tools come back empty if no viewer is connected. Open the browser first and connect with ?relay=, or call oniyanma.connectRelay(). Either can start first — even if the agent starts first, it connects via a peer notification the moment the viewer shows up.
Edits are recorded as api. Edits made via MCP land in the Command log with actor api, and are subject to the confirmation gate. A destructive command returns a count once — call it again with confirm: true.
Logs go to stderr. stdout is the MCP transport, so it's left clean.
Verifying it works
You can test the relay's round trip without Claude Desktop.
pnpm --filter @oniyanma/server relay-test # round trip, room isolation, startup order, no-viewer caseExposing it as read-only
If you're handing an MCP entry point to a client or a consultant, the intended setup is a read-only surface (only the 18 readonly commands). Since it's blocked at execution time as well as trimmed from the tool list, a write command won't go through even if its name is known.