Skip to main content
Glama
README.md
# Yard Desk

**Simulated Alexa+ trade desk** for a small CCTV / field business (Sky Guard–style ops).

**Not a shell** — a practice desk with session memory, editable drafts, and an activity audit. An agent lists today’s jobs, triages inbox items, drafts client chases, and proposes invoices — always through **real MCP tools**. A human must **Approve / Leave it / Later**. Yard Desk **never** auto-sends money or legal commitments.

Built for the **Amazon Developer Hackathon** — track: **Alexa+**.

> This is a **new project** created during the submission window (not a pre-existing product wrap).  
> No payment cards. No Nebius.

## Eligibility map

| Requirement | How Yard Desk meets it |
|-------------|------------------------|
| Real MCP server (official Python SDK) | `yard_desk/mcp_server.py` uses `mcp.server.MCPServer` |
| Streamable HTTP | Mounted at **`/mcp`** via `streamable_http_app(...)` |
| Tools actually called in code | Sim agent uses `mcp.Client(mcp)` → `call_tool(...)` |
| Simulated Alexa+ experience | Cream/navy Sky Guard desk phone UI; MCP tool names on chip tooltips |
| Works without paid APIs | Rule-based dry-run agent when no LLM key |
| Human gate | Yes, go ahead / No, leave it / Later → `record_decision` (editable draft audited) |

## Product depth

| Feature | What you get |
|---------|----------------|
| Session memory | Remembers last item/job; “chase them” / “invoice it” work |
| Editable drafts | Full draft in the decision bar — edit before Yes/No/Later |
| Activity audit | Sidebar **Activity** + `GET /api/activity` (process lifetime) |
| Chat yes/no | Typing “yes” / “leave it” / “later” maps to `record_decision` |
| Richer tools | `get_job`, `get_inbox_item`, `list_overdue`, `list_activity` |

## MCP tools

| Tool | Purpose |
|------|---------|
| `list_todays_jobs` | Sample field schedule |
| `get_job` | Single job detail (address, tech, £ totals) |
| `get_inbox_item` | Single inbox item |
| `list_overdue` | Overdue / chase items with amounts |
| `list_activity` | Recent drafts + gate decisions |
| `triage_inbox_item` | Classify a message |
| `draft_client_chase` | Draft chase text for overdue bill |
| `propose_invoice` | Draft invoice send proposal after job complete |
| `record_decision` | `approve` \| `leave` \| `later` with optional note + edited draft |

## How MCP Streamable HTTP is exposed

- **URL path:** `http://127.0.0.1:43150/mcp`
- **Transport:** Streamable HTTP (`json_response=True`, `stateless_http=True`)
- **SDK:** official `mcp` Python package v2 (`MCPServer`)
- FastAPI lifespan enters `mcp.session_manager.run()` so the mounted ASGI app can serve sessions.

### Verify the MCP endpoint

With the server running:

```bash
# Health (REST) confirms tools + path
curl -s http://127.0.0.1:43150/api/health | python3 -m json.tool

# MCP initialize (Streamable HTTP / JSON)
curl -s -X POST http://127.0.0.1:43150/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{
    "jsonrpc":"2.0",
    "id":1,
    "method":"initialize",
    "params":{
      "protocolVersion":"2025-11-25",
      "capabilities":{},
      "clientInfo":{"name":"yard-desk-verify","version":"0.2.0"}
    }
  }'
```

You should get a JSON-RPC result with `serverInfo.name` ≈ `yard-desk` (not HTTP 404/421).

### MCP Inspector

If you have the [MCP Inspector](https://github.com/modelcontextprotocol/inspector):

```bash
npx @modelcontextprotocol/inspector
```

Connect with transport **Streamable HTTP** to:

```text
http://127.0.0.1:43150/mcp
```

List tools — you should see the Yard Desk tools above. Call `list_todays_jobs` from the Inspector to prove the server.

In-process (no HTTP), tests also call tools via `Client(mcp)`.

## Product UI

Cream / navy phone desk for Sky Guard ops — Instrument Sans / DM Sans, expandable job cards (address, tech, £), inbox badges after decisions (chased / left / later), editable draft textarea in the Decision Gate, and an **Activity** feed in the sidebar. Main chrome stays trade-desk language; MCP / Streamable HTTP details sit in a subtle footer and settings chip. Tool chips show human labels with the technical `MCP · tool_name(...)` name in the tooltip for judges.

## Desk walkthrough (demo video)

1. Start the app (`./scripts/start.sh`).
2. Open [http://127.0.0.1:43150/](http://127.0.0.1:43150/).
3. Use chips or type:
   - **What's on today?** → `list_todays_jobs` (at-risk called out + next action)
   - **What's overdue?** → `list_overdue` with £ + offer to chase top one
   - **Chase Ridgeway** → triage + draft + editable pending decision
   - **Invoice Oak Street** → `get_job` totals + invoice draft
   - Follow-ups: **chase them** / **invoice it** / chat **yes**
4. Edit the draft textarea, then **Yes, go ahead / No, leave it / Later** → `record_decision` (edited text on Activity).
5. Watch the Activity panel and inbox badges update.

## Stack

- Python 3 + FastAPI + official **MCP** SDK (`MCPServer`, Streamable HTTP)
- Package `yard_desk/`
- Product cream/navy Sky Guard desk UI (`web/static/`)
- `uvicorn` on port **43150**

## Quick start

```bash
cd yard-desk
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
cp .env.example .env   # optional — leave LLM keys blank for dry-run
.venv/bin/pytest -q
./scripts/start.sh
```

Then open [http://127.0.0.1:43150/](http://127.0.0.1:43150/)

```bash
curl -s http://127.0.0.1:43150/api/health | python3 -m json.tool
curl -s http://127.0.0.1:43150/api/jobs | python3 -m json.tool
curl -s http://127.0.0.1:43150/api/activity | python3 -m json.tool
curl -s -X POST http://127.0.0.1:43150/api/chat \
  -H 'Content-Type: application/json' \
  -d '{"message":"What'\''s on today?"}' | python3 -m json.tool
```

## Optional later — AWS Builder mini

Not required for this MVP. A future iteration can add an AWS Builder ID–oriented mini (e.g. deploy notes / Cognito-less static hosting) without changing the MCP tool contract.

## Seed desk items

1. Overdue invoice chase (Ridgeway / INV-2841)  
2. Quote request (cameras + NVR)  
3. Supplier delay (Ash Grove parts)  
4. Spammy vendor blast  
5. Family / household bill reminder  
6. Job complete — Oak Street ready to invoice  

## License

MIT © MN Labs