Skip to main content
Glama
popuripk

ewm-ops-mcp

by popuripk
README.md
# ewm-ops-mcp

A **warehouse operations MCP server** with the control plane production agents actually need: typed tools, shadow mode, human approval, and segregation of duties.

[![CI](https://github.com/popuripk/ewm-ops-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/popuripk/ewm-ops-mcp/actions)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

Not a weather demo. An LLM can list overdue warehouse tasks, inspect a blocked outbound delivery, and *preview* a goods issue — but it cannot post GI, because this operator is not authorized. That denial is **code**, not a prompt.

```
Cursor / Claude / any MCP client
              │ stdio
              ▼
        ewm-ops-mcp
              │
     govern() choke-point
      shadow │ live+approve │ deny
              ▼
        mock EWM store
     (swap for RFC later)
```

Built on the same model as [lattice-mcp](https://github.com/popuripk/lattice-mcp). The mock is the point of the portfolio piece: **the protocol and the policy**, not a live SAP box.

## Tools

| Tool | Kind | Notes |
|---|---|---|
| `list_overdue_tasks` | read | SLA > 40 min |
| `list_at_risk_deliveries` | read | Carrier cut-off |
| `get_delivery_status` | read | Includes block reason |
| `get_stock` | read | Bin + qty |
| `warehouse_overview` | read | KPIs |
| `create_picking_tasks` | write | Fails if delivery blocked |
| `confirm_task` | write | Confirm WT |
| `post_goods_issue` | write | **Always denied** (SoD demo) |

Writes accept `approve: true`. In `EWM_MODE=shadow` (default) they still never execute.

## Run

```bash
npm install
npm test

# MCP stdio (Claude Desktop / Cursor)
npm run mcp

# HTTP for curl
npm start
curl -s localhost:4040/tools
curl -s localhost:4040/invoke -d '{"tool":"warehouse_overview"}' -H 'content-type: application/json'
```

Claude Desktop snippet:

```json
{
  "mcpServers": {
    "ewm-ops": {
      "command": "npx",
      "args": ["tsx", "src/mcp.ts"],
      "cwd": "/path/to/ewm-ops-mcp"
    }
  }
}
```

## Try this conversation

1. “Which deliveries are at risk?”
2. “Why is 80000124 blocked?”
3. “Create picking for 80000124” → error (blocked)
4. “Confirm task 9100004501” → `shadow_blocked` with a planned call
5. “Post goods issue for 80000123” → `denied` (no GI auth)

That sequence is the product.

## License

MIT © Prasanna Kumar Popuri