Skip to main content
Glama
README.md
# Startline AI — MCP server, web app & voice API

The serving layer for [Startline AI](#related-repos): an AI companion for
motorsport event documents. One process gives you an MCP server for AI agents,
a phone-first event-day web app, a voice endpoint for Siri, amendment diffs and
calendar export — all over a local document vault.

Built after marshalling at a Formula 1 event, where the official app delivers
PDFs but can't answer *"what time does sign-on close on Saturday?"* — and where
an amendment is just another PDF that never tells you what changed.

## Two kinds of search

**Index search** — SQLite FTS5 + BM25 over heading-level chunks with
event-jargon synonyms (`sign-on` = `muster`, `MxM` = `minute x minute`).
Instant, deterministic, works with no signal at the track.

**Agent search** — an MCP server exposing nine typed tools, so an AI assistant
can reason across documents and cite pages:

| Tool | Purpose |
|---|---|
| `list_events` / `event_overview` | inventory, categories, amendment count |
| `list_docs` | filter by event and category |
| `search` | full-text with citations |
| `read_doc` | fuzzy name match, `pages="3-5"` slicing |
| `schedule_for` | parsed day timeline, with amendment warnings attached |
| `diff_amendment` | what an amendment actually changed |
| `amendments` / `doc_history` | version chains |

Register it with any MCP client:

```json
{ "mcpServers": { "startline": {
    "command": "uv",
    "args": ["run", "--directory", "/path/to/startline-server", "startline-mcp"]
}}}
```

## Amendment diffs

The feature the official apps don't have. Each amendment is structurally
diffed against the schedule it amends — rows matched by normalised text and
classified moved / added / removed inside the amendment's time window — then
summarised:

> *"The one-minute signal to the marshalling area is delayed from 17:09 to
> 17:24, and the reconnaissance lap release from 17:10 to 17:25. A new
> 20-minute signal checkpoint has been added at 17:15."*

Results are cached by content hash, so each amendment costs one model call ever.

## Running it

```bash
uv sync
uv run startline-mcp        # MCP server (stdio)
uv run startline-serve      # web app + voice API on :8095
uv run startline-caption    # vision-caption maps and diagrams (cached)
uv run startline-faq        # pre-answer common marshal questions (cached)
```

Point it at a vault with `STARTLINE_VAULT=/path/to/vault` (default
`~/startline-vault`). AI features need `ANTHROPIC_API_KEY` in the environment;
without it, index search and the offline answer fallback still work.

### Endpoints

| Route | What |
|---|---|
| `/` | event-day web app — day chips, NOW/NEXT timeline, filter, amendment banner, ask box |
| `/ask?q=` | answer engine (used by the web app, Siri and the iOS app) |
| `/api/events`, `/api/schedule`, `/api/diff` | JSON for clients |
| `/api/docs`, `/api/file?path=` | browse and stream the event's source PDFs/images |
| `/api/faq` | pre-answered common questions, grounded in the event's docs |
| `/calendar.ics?day=&q=` | RFC 5545 export, optionally filtered |

Answers come back in the language the question was asked in — a Vietnamese
question gets a Vietnamese answer, while document titles stay in the original.

### Voice

`SIRI-SETUP.md` has the Apple Shortcut recipe (dictate → HTTP → speak) and a
launchd plist for running the server permanently. The iOS app below does this
natively with an App Intent.

## Vision captions

Maps, gate diagrams and notice photos carry no extractable text, so they are
invisible to search. `startline-caption` sends the rendered pages to a vision
model, asks it to describe the page *and transcribe every label*, and caches the
result by content hash. Ingest bakes captions into the notes, which makes
questions like *"how do I get through the zone fence near post 2.5?"*
answerable from an image.

## Related repos

| Repo | Role |
|---|---|
| **startline-vault** | ingest pipeline + offline index search |
| **startline-ios** | native SwiftUI client |

## License

MIT

TDQS

A3.9/5.0

Scored across 9 tools

Disambiguation5/5

Each tool targets a distinct resource and action: events, documents, search, schedules, amendments, and history. Overlap is minimal and clarified by descriptions (e.g., event_overview vs. list_docs).

Naming Consistency3/5

Names mix conventions: list_events, list_docs, read_doc, diff_amendment follow verb_noun, while event_overview, schedule_for, amendments, and doc_history do not. However, all names are still descriptive and readable, so the inconsistency is moderate rather than chaotic.

Tool Count5/5

Nine tools is well within the ideal 3–15 range. Each tool serves a clear purpose in the event-documentation domain, and none feel redundant or unnecessary.

Completeness5/5

The domain is a read-only knowledge base for motorsport events, and the set covers event listing, document search/read, per-day schedules, amendments, and version history. No obvious workflow dead ends remain; even superseded documents and amendment diffs are handled.

Maintenance

ActivitySlowing
ResponsivenessUnresponsive