LineSight
by marcoaguzman
README.md
# LineSight
**An MCP server that turns plant-floor data into continuous-improvement insight.**
LineSight gives an AI assistant the same toolkit a CI engineer carries onto the
shop floor — OEE math, downtime Pareto analysis, SPC control charts, and
yield-loss dollars — exposed through Anthropic's
[Model Context Protocol](https://modelcontextprotocol.io). Ask it *"why is
line-3 slowing down?"* and it doesn't guess: it pulls the control chart, finds
the Western Electric violations, checks the downtime log, and answers with
evidence.
Built by a CI/OE practitioner ([marcoaguzmanjr.com](https://www.marcoaguzmanjr.com))
to bring the DMAIC discipline of the factory floor to AI tooling: every number
the model reports traces back to a formula in
[plant/analytics.py](plant/analytics.py).
---
## What you can ask it
```
> /daily_huddle line-1 # 3-minute tier-1 meeting brief, built from live data
> /dmaic line-2 # full Define-Measure-Analyze-Improve-Control investigation
> /a3_report line-3 # one-page A3 problem-solving report
> why is @line-3 slowing down? # @-mention a line to inject its KPI snapshot
> which shift on line-2 has the quality problem, and what is it costing us per year?
```
The kind of exchange this produces (every number below is what the tools
actually return on the demo dataset):
> **You:** which shift on line-2 has the quality problem?
>
> **Claude:** *(calls `get_oee` with `line_id=line-2, group_by=shift`)*
> Shift C. Its quality rate is 96.8% vs ~98.8% on shifts A and B — roughly
> 3× the scrap. *(calls `get_yield_loss`)* At standard cost that's about
> **$480K annualized** across the line, with shift C driving the majority.
> Worth checking what's different on C: staffing, changeover timing, or
> equipment settings that drift outside day-shift support hours.
## The three MCP primitives, applied
| Primitive | What LineSight exposes |
|---|---|
| **Tools** (model-controlled) | `get_oee` · `pareto_downtime` · `spc_analysis` · `get_yield_loss` · `log_action` · `list_actions` · `close_action` |
| **Resources** (app-controlled) | `plant://overview` · `plant://lines` · `plant://lines/{id}` KPI snapshots · `plant://reason-codes` |
| **Prompts** (user-controlled) | `/daily_huddle` · `/dmaic` · `/a3_report` |
The split matters: analysis lives in **tools** so the model can chain them
freely; context the *user* chooses to bring in (an @-mentioned line) comes from
**resources**; and multi-step CI rituals with a defined shape (a DMAIC, an A3)
ship as **prompts** so they run the same way every time.
```mermaid
flowchart LR
U[You] --> CLI[Chat CLI<br/>prompt-toolkit]
CLI --> C[Claude<br/>Anthropic API]
C <-->|MCP stdio| S[LineSight MCP server<br/>FastMCP]
S --> A[analytics.py<br/>OEE · Pareto · SPC · yield $]
A --> D[(production_log.csv<br/>downtime_log.csv)]
S --> R[(action_register.json)]
```
## The demo dataset tells a story
`data/` holds 90 days of seeded, reproducible shift-level records for a
three-line condiment plant (810 production records, ~2,300 downtime events).
Three problems are hidden in it — the same patterns you'd hunt for in a real
plant:
1. **line-2 bleeds availability to changeovers** — one reason code carries
~52% of all downtime minutes. A Pareto finds it instantly.
2. **line-2, shift C has a quality problem** — scrap runs ~3× the other
shifts (cap-seal torque drift). Invisible in the line-level average;
obvious the moment you group by shift.
3. **line-3 is degrading, not broken** — filler-head bearing wear drags
performance down over the final three weeks. No single bad day; the SPC
chart catches the run below center line and the cascade of below-LCL
points that a "top losses yesterday" report would miss.
Regenerate identical data anytime: `python -m plant.data_gen` (seeded).
## Quick start
Requires Python 3.10+ and an [Anthropic API key](https://console.anthropic.com).
```bash
git clone https://github.com/marcoaguzman/linesight.git && cd linesight
python3 -m venv .venv && source .venv/bin/activate
pip install "anthropic>=0.51.0" "mcp[cli]>=1.8.0" "prompt-toolkit>=3.0.51" "python-dotenv>=1.1.0"
cp .env.example .env # then add your ANTHROPIC_API_KEY
python main.py
```
Or with [uv](https://docs.astral.sh/uv/): `uv sync`, set `USE_UV=1` in `.env`,
then `uv run main.py`.
### Verify without an API key
The smoke test drives every tool, resource, and prompt over a real MCP stdio
connection — no Anthropic key needed:
```bash
python scripts/smoke_test.py # 18 checks, should all PASS
```
### Use it from Claude Desktop instead
LineSight is a standard MCP server, so any MCP client can host it. For Claude
Desktop, add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"linesight": {
"command": "/absolute/path/to/linesight/.venv/bin/python",
"args": ["/absolute/path/to/linesight/mcp_server.py"]
}
}
}
```
## Project structure
```
linesight/
├── mcp_server.py # the MCP server: 7 tools, 4 resources, 3 prompts
├── mcp_client.py # generic MCP stdio client
├── main.py # chat CLI entry point
├── core/ # chat loop, Claude wrapper, tool dispatch, terminal UI
├── plant/
│ ├── analytics.py # OEE, Pareto, XmR control charts, yield-loss math
│ ├── store.py # CSV-backed data layer (swap for a historian/MES)
│ └── data_gen.py # seeded demo-data generator
├── data/ # the demo dataset (committed, reproducible)
└── scripts/smoke_test.py
```
Swapping the demo CSVs for a real historian or MES connection only touches
`plant/store.py` — the MCP surface stays identical.
## Credits
The chat-client scaffolding (`core/`, `mcp_client.py`) is adapted from the
project built in [Anthropic's MCP course](https://anthropic.skilljar.com/introduction-to-model-context-protocol);
the plant domain — server, analytics, dataset — is original work.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues