Skip to main content
Glama
maevelynz

zipline-supply-chain

by maevelynz
README.md
# Supply Chain Decision Intelligence MCP

A local, deterministic MCP research project for **high-reliability hardware supply-chain analytics**. It demonstrates how an LLM can ask supply-chain questions in natural language while SQL/Python tools—not the model—own the quantitative answer.

**The problem this demonstrates solving:** supply-chain and manufacturing-ramp decisions (which supplier to qualify, whether a part will stock out before replenishment arrives, whether cheapest-first or dual-sourcing is worth the premium) require joining supplier, inventory, purchase-order, and quality data and running consistent, auditable math — not an LLM's best guess. This project shows that pattern end-to-end on a synthetic dataset: the LLM only chooses which governed calculation to run and narrates the result.

> **Synthetic data only.** This repository does **not** contain real Zipline supplier, production, demand, customer, or operational data. It is a methodology demo inspired by public supply-chain problem patterns: supplier performance, ramp forecasting, MRP shortage risk, source concentration, landed cost, fleet-capacity screening, medical replenishment, and multi-year supplier capacity.


## Live Executive Demo

**[Launch the Ramp Readiness Briefing →](https://claude.ai/code/artifact/97df7f8f-f053-41f8-a6c0-d7cabfaa6698)**

Explore the interactive executive briefing for ramp readiness, supply position, capacity constraints, supplier risk, scenarios, obsolescence exposure, and the path to $1 COGS.

> All supplier, cost, volume, demand, and operational data shown in the demo is synthetic and created solely for methodology demonstration.

## Why this design

```mermaid
flowchart LR
  Q["Natural-language research question"] --> L["LLM chooses a tool"]
  L --> M["MCP typed interface"]
  subgraph D["Deterministic analytics boundary"]
    M --> A["Governed SQL / Python"]
    A --> C["Checked-in synthetic CSVs"]
    A --> R["Structured result + trust block"]
  end
  R --> L2["LLM interprets the result"]
```

The model chooses **which** governed calculation to call and explains the result. The model does not recreate MAPE, OTD, weeks of cover, landed cost, or capacity math from memory.

See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the fully-labeled version of this diagram
(explicitly distinguishing the probabilistic LLM layer from the deterministic governed layer), a
complete MCP tool map (all 13 tools -> the datasets each one reads), and a worked example decision
flow. See [docs/DATA_MODEL.md](docs/DATA_MODEL.md) for the entity-relationship diagram.

## Tool surface

| Tool | Decision question |
|---|---|
| `list_research_questions` | What can this governed dataset answer? |
| `supplier_scorecard` | Which suppliers underperform on OTD + quality? |
| `forecast_accuracy` | Is the ramp forecast inaccurate, biased, or improving? |
| `parts_at_risk` | Which parts can stop the line inside lead time? |
| `dual_source_risk` | Where is single-source exposure concentrated? |
| `compare_landed_costs` | Does sticker-price advantage survive tariff/freight/transit carrying cost? |
| `dock_capacity` | How many aircraft are needed to stay away from the queueing wall? |
| `stockout_reduction` | How does shorter replenishment change synthetic stockout exposure? |
| `capacity_ramp` | What does cheapest-first vs 60/40 resilience cost, and where is the capacity wall? |
| `projected_shortage_risk` | Which parts cross zero inside the next eight weeks after open POs and expected yield? |
| `quality_gate_risk` | Which APQP/PPAP gates threaten the ramp? |
| `quality_rush_signal` | Does late/rushed supply show worse defect PPM? |
| `quality_trend` | Is quality deteriorating over a true trailing seven-day date window? |

There is also a `research://catalog` MCP resource plus `supply_chain_investigation` and `supply_chain_question_generator` prompts.

## Local first: the exact path that avoided earlier MCP setup failures

This project intentionally uses a runtime pattern that has proved robust in earlier local MCP builds:

- **no database file is built during startup**
- **no `.venv` is shipped**
- **no `.mcp.json` is shipped**
- every data path is derived from `server.py` via `__file__`
- DuckDB creates fresh in-memory views over checked-in CSVs
- `uv run --with ...` makes dev/stdio launch independent of editable-install metadata

### 1. Preflight

```bash
cd <where-you-cloned-this-repo>
uv sync --extra dev
uv run python scripts/preflight.py
```

You want `PREFLIGHT PASSED`.

### 2. Launch in MCP Inspector

```bash
./scripts/run_mcp_dev.sh
```

Approve dependency installation if `uv` asks. MCP Inspector should open with **13 tools**.

Recommended first calls:

1. `supplier_scorecard` with `limit=5`
2. `forecast_accuracy`
3. `parts_at_risk` with `limit=10`
4. `dual_source_risk`
5. `compare_landed_costs`
6. `dock_capacity`
7. `stockout_reduction`
8. `capacity_ramp`
9. `projected_shortage_risk` with `horizon_weeks=8`
10. `quality_gate_risk`
11. `quality_rush_signal`
12. `quality_trend`

### 3. Smoke-test the analytics without Claude

```bash
uv run python scripts/smoke_test.py
```

### Executive web app

A local, static "Production Ramp Intelligence" application built on these same governed tools --
ramp readiness, critical-part risk, source concentration, and a capacity/qualification decision
view, each traceable to the MCP tool call behind it:

```bash
uv run python scripts/generate_executive_dataset.py
uv run python scripts/serve_executive_site.py
```

Then open <http://127.0.0.1:8765/>. See [docs/EXECUTIVE_APP.md](docs/EXECUTIVE_APP.md).

### Running the tests

```bash
uv sync --extra dev
uv run pytest -q
```

This runs data-integrity checks, tool-behavior assertions, runtime-contract checks, and the
JSON-safety/packaging/preflight regression suite — see `docs/CODE_WALKTHROUGH.md` ("Tests: what
each file actually proves") for what each test file specifically verifies.

### 4. Register with Claude Code only after Inspector works

```bash
./scripts/register_claude.sh
claude
```

Inside Claude Code run `/mcp`. You should see `zipline-supply-chain` connected with 13 tools.

Then use a prompt such as:

> Act as a supply-chain analyst. Start with `list_research_questions`. Use only the `zipline-supply-chain` MCP tools for quantitative evidence. Tell me which supplier/part risks matter most for the manufacturing ramp, what the evidence says, what is interpretation, and what the synthetic data cannot establish. Do not inspect raw CSVs or recompute the metrics yourself.

## Example research questions

This dataset separates two intertwined supply chains:

**Manufacturing:** supplier performance, forecast bias, MRP shortage, dual-source concentration, landed cost, and multi-year capacity.

**Operational logistics:** peak dock fleet capacity and medical stockout reduction.

That separation is built into the tools and prompt discipline.

See [DEMO_QUESTIONS.md](DEMO_QUESTIONS.md) and [PROMPTS.md](PROMPTS.md).

## Documentation map

Full file tree: [docs/REPOSITORY_GUIDE.md](docs/REPOSITORY_GUIDE.md).

| Doc | What it covers |
|---|---|
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | System/MCP architecture, tool map, entity relationships, and a worked decision-flow — all as GitHub-renderable Mermaid diagrams |
| [docs/CODE_WALKTHROUGH.md](docs/CODE_WALKTHROUGH.md) | Implementation walkthrough: every tool's inputs/logic/outputs, SQL/DuckDB patterns, JSON safety, error handling, and design tradeoffs, cross-referenced to `server.py` |
| [docs/DATA_MODEL.md](docs/DATA_MODEL.md) | What each CSV represents, foreign-key relationships, the entity-relationship diagram, deterministic generation/seeds, and two intentional, documented quirks: (1) `capacity_ramp` distinguishes currently-qualified supplier capacity from a candidate/hypothetical second source, and (2) `inventory.csv`'s current run rate and `capacity_plan.csv`'s forward-looking ramp target are independent planning bases not meant to numerically reconcile |
| [docs/RESEARCH_METHODS.md](docs/RESEARCH_METHODS.md) | The formula/definition behind every analytical tool (scorecard weights, landed-cost formula, MAPE/bias, etc.) |
| [docs/LIMITATIONS.md](docs/LIMITATIONS.md) | What this project deliberately does not claim |
| [docs/LOCAL_RUNBOOK.md](docs/LOCAL_RUNBOOK.md) | Ordered local setup steps and troubleshooting |
| [docs/RUNTIME_DESIGN_LESSONS.md](docs/RUNTIME_DESIGN_LESSONS.md) | Why the runtime is built the way it is (no startup DB build, no persistent connection, etc.) |
| [docs/EXECUTIVE_APP.md](docs/EXECUTIVE_APP.md) | The local executive web app: architecture, how to run it, and exactly which governed tool call backs each chart |

## What this project does not claim

It is not a production ERP/MRP, a route optimizer, an aerospace qualification system, a causal impact study, or real company data. The point is **governed analytical boundaries for LLM-assisted decision support**.


## Integrity / reproducibility checks

The synthetic relational model guarantees: receipt and quality facts carry valid `(part_id, supplier_id)` keys, qualification gates use true supplier-master IDs, every PO uses a valid part-supplier mapping, and inventory has exactly one row per part. See `data/MANIFEST.json`/`DATASET_VERSION` for the current dataset version.

Run before the MCP (also covered by `scripts/preflight.py`):

```bash
uv run python scripts/audit_data_relationships.py
uv run python scripts/generate_synthetic_facts.py --check
```

The first checks foreign keys, composite relationships, uniqueness, and important reference anchors (fixed values this dataset is designed to reproduce). The second regenerates the stochastic/enriched fact tables from fixed seeds and master fixtures and byte-compares them with the checked-in outputs.

The server itself contains **no runtime randomness**. Given the checked-in CSVs, tool outputs are deterministic. This is reproducible synthetic research data, not a claim that the synthetic distributions are statistically representative of Zipline.

## Dataset scale

The 12-week `demand.csv` is the exact governed ramp case behind the reference anchors; `annual_demand.csv` adds 52 deterministic weekly observations for longer rolling-error analysis, exposed via `forecast_accuracy(series="annual_52w")`, so it does not silently change the 12-week worked example.

The synthetic part universe spans 60 parts across 14 commodity families — intentionally demonstration-scale: enough observations for meaningful inventory and sourcing rankings, still small enough to inspect and explain live.

Maintenance

ActivityMaintained
ResponsivenessNo issues