npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@trent105-unnc/mir_mcp

v0.0.2

Published

MCP server exposing the RAWSim-O warehouse simulation (status / control / task injection / backend switch) to AI agents

Readme

mir_mcp

An MCP (Model Context Protocol) server that exposes the RAWSim-O warehouse simulation to AI agents (Claude Code, Cursor, VS Code Copilot, etc.) — the same control surface the mir_fe dashboard uses. It lets an agent read live system state, launch a suitable scenario, inject tasks, and switch the simulation backend.

Supports both transports:

  • Streamable HTTP (/mcp, protocol 2025-03-26) — Claude Code / Cursor / newer clients.
  • SSE (/sse + /messages, protocol 2024-11-05) — older clients.
  • stdio — local subprocess integration.

What It Does

Provides 13 MCP tools that let an AI assistant observe and drive a RAWSim-O warehouse:

  • Read: live status, rich per-bot metadata, a full positional scene snapshot, the current backend mode.
  • Scenario: pick a named instance from a bundled catalog (12 layouts, from 15-bot pickup-heavy to 300-AGV scale tests), start/stop/pause/resume, set internal-mode speed.
  • Tasks: append orders at runtime (line items, station pinning, scheduling, high-priority dispatch).
  • Backend: switch between RAWSim-O internal kinematics and Isaac Lab external physics.

Configuration

| Env var | Default | Meaning | | ---------- | ---------- | --------- | | RAWSIMO_URL | http://rawsimo:8880 | Base URL of the RAWSim-O web server. | | MCP_TRANSPORT | stdio | stdio · http · all (run both). | | PORT | 3045 | HTTP listen port (http transport). | | MODEL_BASE_URL | — | OpenAI-compatible chat completions base URL (enables /api/chat). | | MODEL_API_KEY | — | Bearer key for the model API. | | MODEL_NAME | — | Model id (e.g. gpt-4o-mini). | | CHAT_CORS_ORIGIN | * | Allowed origin for /api/chat (for browser frontends). |

Chat endpoint (/api/chat)

When MODEL_BASE_URL + MODEL_API_KEY + MODEL_NAME are set, mir_mcp also serves POST /api/chat — a streaming (SSE) LLM agent that drives the warehouse through mir_mcp's own tools (in-process). Each event is a data: {json}\n\n line:

| event type | fields | meaning | | --- | --- | --- | | delta | text | a piece of the assistant's reply (streamed token) | | tool | id, name, args | the agent is calling a mir_mcp tool | | tool_result | id, name, result, isError | the tool's output | | done | — | turn finished | | error | message | failure |

Request body: { "messages": [{ "role": "user"\|"assistant", "content": "..." }] }. Example:

curl -N -X POST http://localhost:3045/api/chat -H 'content-type: application/json' \
  -d '{"messages":[{"role":"user","content":"what is the warehouse status?"}]}'

This is what the mir_fe "AI Assistant" panel (under Scheduling simulator) talks to. When the model env vars are unset, /api/chat returns 503 and mir_mcp behaves as a plain MCP server.

IDE Configuration

Option A: npx (no install)

Once published to npm, anyone can run it with no local checkout. Set RAWSIMO_URL to a reachable RAWSim-O server (it plays the same role as OBS_WEBSOCKET_PASSWORD in other MCP servers).

Claude Code

Project — add to .mcp.json:

{
  "mcpServers": {
    "mir": {
      "command": "npx",
      "args": ["-y", "@trent105-unnc/mir_mcp@latest"],
      "env": { "RAWSIMO_URL": "http://localhost:8880" }
    }
  }
}

Global — run once via CLI:

claude mcp add --scope user mir -- npx -y @trent105-unnc/mir_mcp@latest
# then set the env var via the generated config, or prefix: RAWSIMO_URL=http://localhost:8880

VSCode + GitHub Copilot

Add to .vscode/mcp.json:

{
  "servers": {
    "mir": {
      "type": "local",
      "command": "npx",
      "args": ["-y", "@trent105-unnc/mir_mcp@latest"],
      "env": { "RAWSIMO_URL": "http://localhost:8880" }
    }
  }
}

Cursor

Settings → MCP → Add new MCP server → type stdio, command npx, args -y @trent105-unnc/mir_mcp@latest, env RAWSIMO_URL=http://localhost:8880.

Publishing: this option works once @trent105-unnc/mir_mcp is on npm. Tag a release (git tag v0.1.0 && git push --tags) and the Publish to npm workflow publishes it to the @trent105-unnc org (the NPM_TOKEN account must be a member of that npm org with publish rights; scoped public packages need access: public, already set in publishConfig).

Option B: Local Docker (HTTP)

docker compose up -d --build
# MCP endpoint at http://localhost:3045/mcp (and /sse)

Claude Code

Project — add to .mcp.json in the project root:

{
  "mcpServers": {
    "mir": {
      "type": "http",
      "url": "http://localhost:3045/mcp"
    }
  }
}

Global — run once via CLI:

claude mcp add --scope user --transport http mir http://localhost:3045/mcp

VSCode + GitHub Copilot

Add to .vscode/mcp.json:

{
  "servers": {
    "mir": {
      "type": "http",
      "url": "http://localhost:3045/mcp"
    }
  }
}

Cursor

Settings → MCP → Add: http://localhost:3045/mcp.

Option C: Local Node.js

pnpm install
pnpm build

# HTTP + SSE:
MCP_TRANSPORT=http PORT=3045 RAWSIMO_URL=http://rawsimo:8880 pnpm start

# or stdio (Claude Code launches the server as a subprocess):
RAWSIMO_URL=http://rawsimo:8880 node dist/index.js

Claude Code (stdio)

Add to .mcp.json:

{
  "mcpServers": {
    "mir": {
      "command": "node",
      "args": ["/absolute/path/to/mir_mcp/dist/index.js"],
      "env": { "RAWSIMO_URL": "http://rawsimo:8880" }
    }
  }
}

MCP Tools

| Tool | Parameters | Purpose | | ---------- | ---------- | --------- | | get_health | — | RAWSim-O liveness. | | get_simulation_status | — | Running? sim time, error, available item descriptions. | | get_test_metadata | — | Counts (AGV/pod/station/waypoint/orders), idle/busy, per-bot state. | | get_live_snapshot | — | One full-scene frame: every bot/pod/station/waypoint + positions. | | get_sim_backend | — | Current backend mode (internal/external). | | list_instances | — | Named scenario bundles with metadata (AGV/station counts, workload tags). | | start_instance | name, seed?, tag? | Start a sim from a named bundle. | | stop_simulation | — | Stop + finalize + write stats. | | pause_simulation / resume_simulation | — | Pause / resume. | | set_speed | speed_multiplier | Internal-mode speed multiplier (1–400). | | append_tasks | tasks[], high_priority? | Add orders at runtime. | | set_sim_backend | backend | Switch backend; reports the confirmed mode. |

Picking a "suitable instance" from semantics

RAWSim-O has no instance-catalog endpoint, so mir_mcp ships the same 12 named bundles mir_fe ships (under data/). The agent calls list_instances, reads the metadata (e.g. scale-300 → 300 AGV, pickup-5x → pickup-heavy 15-bot), and starts the best match with start_instance.

Development

pnpm install          # install dependencies
pnpm typecheck        # tsc --noEmit
pnpm build            # tsup bundle -> dist/index.js
pnpm test             # vitest (catalog + tool registration smoke test)
pnpm dev              # tsx watch src/index.ts

Architecture

src/
  index.ts              # entry: transport selection (MCP_TRANSPORT=stdio|http|all)
  server.ts             # createServer(client) -> McpServer + registerAllTools
  rawsimo-client.ts     # typed fetch client for the 14 simulation/ endpoints
  config-catalog.ts     # 12 named instance bundles + metadata + XML/zip loader
  types.ts              # RAWSim-O DTO shapes (snake_case wire format)
  transports/
    stdio.ts            # StdioServerTransport
    http.ts             # SSE (/sse) + Streamable HTTP (/mcp) via createMcpExpressApp
  tools/
    _shared.ts          # text/err/run result helpers
    status.ts           # read tools
    scenario.ts         # lifecycle + instance tools
    tasks.ts            # append_tasks
    backend.ts          # set_sim_backend
    index.ts            # registerAllTools
data/                   # bundled sim configs (copied from mir_fe)
  default_sim_config/ 
  test_sim_config/
tests/smoke.ts          # vitest catalog + tool-registration tests

All RAWSim-O endpoints are under /simulation/<Action> and use snake_case JSON. The HTTP transport reads the raw body itself — do not add an express.json() middleware (it starves the transport). See ~/RAWSim-O/RAWSimO.WebServer/SimulationHost/Controllers/SimulationHostController.cs for the authoritative endpoint source.