Skip to content

Architecture

Process model

Single uvicorn process, single port (8000):

┌──────────────────────────────────────┐
│          uvicorn (port 8000)          │
│  ┌────────────────────────────────┐  │
│  │     Starlette application      │  │
│  │  ┌──────┐ ┌────────────────┐   │  │
│  │  │ /sse │ │  /health       │   │  │
│  │  │ /mcp │ │  (direct)      │   │  │
│  │  │/messages│                │   │  │
│  │  └──────┘ └────────────────┘   │  │
│  │  ┌──────────────────────────┐  │  │
│  │  │  WSGIMiddleware           │  │  │
│  │  │  ┌─────────────────────┐  │  │  │
│  │  │  │  Flask (mount /)    │  │  │  │
│  │  │  │  /api/v1/*          │  │  │  │
│  │  │  └─────────────────────┘  │  │  │
│  │  └──────────────────────────┘  │  │
│  └────────────────────────────────┘  │
└──────────────────────────────────────┘
  • Flask handles all /api/v1/* routes via WSGI.
  • MCP server and /health live directly on Starlette (avoids WSGI threadpool).
  • MCP tools call the same data layer as the Flask API.

Data layer

┌─────────────┐     ┌──────────────┐
│  rfc-editor  │────▶│  data/       │
│  (rsync)     │     │  rfc-json/   │
│              │     │  rfc-text/   │
│              │     │  rfc-html/   │
└─────────────┘     └──────┬───────┘
                    ┌──────────────┐
                    │  ingest.py   │
                    │  (incremental│
                    │   reindex)   │
                    └──────┬───────┘
                    ┌──────────────┐
                    │  db/         │
                    │  rfc_index.db│
                    │  ─────────── │
                    │  rfcs        │
                    │  sections    │
                    │  relations   │
                    │  rfc_fts     │
                    │  section_fts │
                    └──────────────┘

SQLite schema

  • rfcs — metadata: number, title, authors, status, dates, keywords, section counts, sections_tier
  • sections — per-section content: rfc_number, ordinal, section_id, title, level, body
  • relations — link table: source_rfc, target_rfc, relation_type (obsoletes, updates, see_also)
  • rfc_fts — FTS5 virtual table over full RFC text
  • section_fts — FTS5 virtual table over individual sections

Section parsing

Two strategies live in rfc_mcp/sections.py:

  • structured — parses HTML <section id="..."> from xml2rfc output. Preserves nesting, accurate boundaries.
  • heuristic — applies pattern matching on plain text for older RFCs without xml2rfc markup.

Container

  • Base: python:3.12-slim
  • Deps: Flask, uvicorn, starlette, mcp, aiosqlite, rsync
  • No baked data — all data synced and indexed at runtime
  • Entrypoint fires a background sync loop; server starts immediately