Skip to main content

Maintain a local, LLM-queryable corpus of an IETF Working Group's public record (drafts, mailing list, GitHub issues, meetings), with an MCP server, semantic search, and NotebookLM export.

Project description

ietf-llm

Maintain a local, queryable corpus of an IETF Working Group's public record — charter, drafts, RFCs, meeting agendas, minutes, slides, transcripts, mailing list archives, and GitHub issues — for use with LLM-based tools.

What it's for

A working group's history is spread across mailing list archives, Datatracker, GitHub, and meeting materials — too much to hold in your head, and too scattered to search well by hand. With the record gathered into one queryable corpus, an LLM can help you:

  • Get up to date with the state of discussions — what's open, what was recently decided, where a debate currently stands.
  • Summarise the arguments already made about an issue — every distinct position on a topic, who holds it, and how the chairs ruled.
  • Formulate a new proposal — surface the objections raised against similar ideas before, so you can anticipate them.
  • Fact-check assertions about what's happened so far — grounded in the actual list traffic and chair statements, not someone's recollection.

Three supported workflows:

  1. Use it as an MCP server — register ietf-llm-mcp with Claude, Codex, Gemini, Cursor, Zed, etc. and ask questions across any WG you've gathered.
  2. Use it with NotebookLM — export the gathered corpus as a directory of clean text files (or push directly to NotebookLM Enterprise) and ingest it as a notebook source set.
  3. Use it from the CLI — run semantic search over the cache directly with ietf-llm-search, no LLM client required.

Also works with IRTF Research Groups. Pass the RG's shortname (e.g. cfrg, hrpc, pearg) anywhere this README says <wg>.

Table of contents

Installation

pipx install ietf-llm

Behind a corporate firewall with TLS interception? Install with the certs extra:

pipx install ietf-llm[certs]

Shell completion

Optional. Add the line for your shell to its rc file to tab-complete commands, flags, and cached WG names:

# bash — in ~/.bashrc
eval "$(ietf-llm --completion bash)"
# zsh — in ~/.zshrc
eval "$(ietf-llm --completion zsh)"
# fish — in ~/.config/fish/config.fish
ietf-llm --completion fish | source

Gather a corpus

Each use mode below reads from a local cache. Gather it once per corpus; the semantic index updates incrementally on re-runs.

ietf-llm httpbis --github httpwg/http-core --github httpwg/http-extensions

Everything lands in ~/.cache/ietf-llm/<name>/ — the single source of truth that the MCP server, NotebookLM exporter, and CLI search all read from.

First run: gathering a corpus also builds a local semantic-search index — this powers both the MCP search_corpus tool and ietf-llm-search. It uses BAAI/bge-small-en-v1.5 by default — ~130 MB, ~33M params, MPS-accelerated, runs entirely on your machine. Downloaded from Hugging Face on first use and cached; subsequent gathers reuse it. Override with --embed-model <id> for any model the llm package recognises. Pass --no-embed to skip the index (and the download) — useful for NotebookLM export or offline gathers.

Subsequent runs: the flags you passed are persisted to ~/.config/ietf-llm/<name>/gather.json, so to refresh just run ietf-llm <name> — no need to repeat --github, --mailing-list, etc. Pass extra flags to add to the set, or --clear-config to start over.

A corpus doesn't have to be a Working Group — the name is classified automatically:

Command Corpus
ietf-llm httpbis a WG / RG / editorial WG / BoF: charter, drafts, meetings, ballots, list
ietf-llm last-call a standalone mailing list (any archived at mailarchive.ietf.org — IETF, IRTF, or RFC-Editor)
ietf-llm rfced --mailing-list rswg@rfc-editor.org a named list corpus (the address domain is optional)
ietf-llm new-ids --new-drafts --months 1 new Internet-Drafts in a rolling window
ietf-llm mnot --author mnot@mnot.net every draft a person has authored

See Gather options for the full flag set.


1. Use as an MCP server

ietf-llm-mcp is a stdio Model Context Protocol server that exposes the local corpus to any MCP-capable agent. Set up once, gather each WG you care about once, then ask questions indefinitely.

Register the server

Pick your client. The snippets below are correct as of writing — if your client has changed since, its own MCP docs are authoritative.

Gotcha (all clients): if ietf-llm-mcp was installed via pipx, the binary is on your shell PATH but may not be on the PATH inherited by a GUI app launched from Finder / Spotlight / Explorer. Use the absolute path (which ietf-llm-mcp) if the client can't find the command.

Claude Code

claude mcp add ietf-llm -- ietf-llm-mcp

Also install the bundled skill so Claude knows how to drive the tools well (digests before raw reads, search before slurping mailing-list files, etc.):

ietf-llm --install-claude-skill

Re-run after upgrading the package to pick up improvements.

Claude Desktop

Edit claude_desktop_config.json (create it if missing):

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "ietf-llm": {
      "command": "ietf-llm-mcp"
    }
  }
}

Quit and relaunch Claude Desktop — the config is only read at startup.

Codex CLI (OpenAI)

~/.codex/config.toml:

[mcp_servers.ietf-llm]
command = "ietf-llm-mcp"

Gemini CLI

~/.gemini/settings.json:

{
  "mcpServers": {
    "ietf-llm": {
      "command": "ietf-llm-mcp"
    }
  }
}

opencode

~/.config/opencode/opencode.json (or opencode.json in your project root):

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "ietf-llm": {
      "type": "local",
      "command": ["ietf-llm-mcp"],
      "enabled": true
    }
  }
}

Cursor

In-app MCP settings panel, or ~/.cursor/mcp.json (global) or .cursor/mcp.json (per-project):

{
  "mcpServers": {
    "ietf-llm": {
      "command": "ietf-llm-mcp"
    }
  }
}

Zed

~/.config/zed/settings.json:

{
  "context_servers": {
    "ietf-llm": {
      "command": {
        "path": "ietf-llm-mcp",
        "args": []
      },
      "settings": {}
    }
  }
}

Tuning. Each tool call has a server-side deadline so a stuck call fails fast with a clear message rather than hanging to the client's timeout. It defaults to 120 seconds; override (or disable, with 0) by setting IETF_LLM_TOOL_TIMEOUT in the server's environment — e.g. add "env": {"IETF_LLM_TOOL_TIMEOUT": "180"} to the JSON config above.


2. Use with NotebookLM

NotebookLM ingests a corpus as a set of source files. ietf-llm-export turns the gathered cache into an upload-ready directory, or pushes straight to a NotebookLM Enterprise notebook.

Workflow note: export always produces a complete fresh dump. Create a new notebook on each refresh rather than trying to merge updates into an existing one.

Pass --no-embed when gathering if you only plan to use NotebookLM — it has its own index, so the local one is wasted work:

ietf-llm httpbis --no-embed \
    --github httpwg/http-core --github httpwg/http-extensions

Export to a local directory

ietf-llm-export httpbis --destination ~/notebooklm/httpbis

Drag the directory's contents into NotebookLM as sources. Per-thread mailing list conversations and per-issue GitHub records are bundled by year / repo to stay under NotebookLM's 50-source free / 300-source Plus limit.

Export to NotebookLM Enterprise

If you have Google Workspace Enterprise with NotebookLM enabled, ietf-llm-export can create the notebook and upload sources directly:

ietf-llm-export httpbis --create my-gcp-project-id

One-time setup:

  1. Google Cloud Project with the Discovery Engine API enabled.
  2. OAuth credentials: create an "OAuth 2.0 Client ID" (Desktop App) in the Cloud Console.
  3. Save the JSON as client_secrets.json in ~/.config/ietf-llm/ (or pass --credentials-file PATH).

First run opens a browser to authorise; the token is cached at ~/.config/ietf-llm/token.json.

Per-WG export settings are persisted at ~/.config/ietf-llm/<wg>/export.json — subsequent runs of the same mode need only ietf-llm-export <wg>.


3. Use from the CLI

ietf-llm-search runs semantic search over a gathered corpus and prints ranked excerpts to stdout — useful on its own, or as input to another tool.

ietf-llm-search httpbis "skepticism about cookie partitioning" -k 8

Chunks are content-aware: one chunk per mailing list message, one per issue comment, and a windowed slice of drafts/RFCs/transcripts. The index lives at ~/.cache/ietf-llm/<wg>/embeddings.db and updates incrementally on each gather — see Gather a corpus for the embedding model.


Reference

Commands

Command Job Reads Writes
ietf-llm Gather / refresh a corpus network cache
ietf-llm-export Mirror cache to dir, or push to NotebookLM Enterprise cache dir / NotebookLM
ietf-llm-search Semantic search over the cache cache stdout
ietf-llm-mcp Expose the cache to MCP clients cache stdio (MCP)

All four are independent. The cache (~/.cache/ietf-llm/<wg>/) is the single source of truth; everything else reads from it.

Gather options

ietf-llm [OPTIONS] <name>

<name> is the corpus to gather, classified automatically:

  • a Working Group / Research Group / editorial WG / BoF shortname (httpbis, cfrg, rswg) — gathered in full (charter, drafts, meetings, ballots, mailing list);
  • a mailing list archived at mailarchive.ietf.org — IETF, IRTF, or RFC-Editor (last-call, irtf-discuss, rfc-interest) — that list on its own;
  • any other label given explicit sources (--draft / --mailing-list / --github / --new-drafts / --author);
  • prefix with x- to skip the Datatracker group lookup entirely (a fully manual corpus).

A name that is none of these and has no configured sources is rejected as a likely typo.

Sources (what to gather; all repeatable / persisted):

  • --github OWNER/REPO — a GitHub repo whose issues to include.
  • --draft DRAFT-NAME — an extra Internet-Draft to track, beyond a WG's own documents. Version suffix stripped; every revision gathered.
  • --mailing-list LIST — an extra list to sync (any archived at mailarchive.ietf.org). A bare name or a full address; the domain is optional and ignored (rswg, rswg@rfc-editor.org).
  • --new-drafts — subscribe to new Internet-Drafts: every -00 submitted within --months (rolling window; drafts age out).
  • --author PERSON — every draft PERSON authored. PERSON is an email (mnot@mnot.net, recommended), a Datatracker person id, or an exact full name. Drafts only.
  • --add-mentioned-drafts — also pull drafts the corpus's threads/issues mention but don't already include. Sticky.

Scope & filtering:

  • --months N — months of mailing list / meeting / new-draft history (default 12).
  • --github-label LABEL / --exclude-github-label LABEL — include / exclude issues by label.

Digests & search index:

  • --summarize / --summarize-model MODEL — add LLM-generated one-liners to digests via the llm package.
  • --no-embed — skip the semantic search index (it backs ietf-llm-search and the MCP search_corpus tool). On by default, incremental.
  • --embed-model MODEL — embedding model id (default: a small local model).
  • --rebuild-embeddings — drop and re-embed everything instead of the incremental update.

Cache & config:

  • --list — list cached corpora (name, kind, status, last-gathered, and a one-line subject — the group name, list, or tracked author), then exit.
  • --clear-cache — wipe this corpus's cache and re-download.
  • --clear-config — clear this corpus's persisted config.
  • --quiet / --verbose.

Per-corpus settings are persisted at ~/.config/ietf-llm/<name>/gather.json.

GitHub auth. Set GITHUB_TOKEN on the gather invocation (a fine- scoped read-only token is plenty); without one you'll hit anonymous API rate limits quickly on large WGs. Prefer inline-passing over exporting in your shell rc so the token doesn't leak into every other subprocess:

GITHUB_TOKEN=ghp_... ietf-llm httpbis
# or, from a secret manager:
GITHUB_TOKEN=$(security find-generic-password -s github-readonly -w) \
    ietf-llm httpbis

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ietf_llm-0.7.4.tar.gz (346.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ietf_llm-0.7.4-py3-none-any.whl (273.9 kB view details)

Uploaded Python 3

File details

Details for the file ietf_llm-0.7.4.tar.gz.

File metadata

  • Download URL: ietf_llm-0.7.4.tar.gz
  • Upload date:
  • Size: 346.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ietf_llm-0.7.4.tar.gz
Algorithm Hash digest
SHA256 e613e61c4e5b0a5ec1bb0312ecb8cc8c275efedbdf90b70f998b080bdd4b403d
MD5 1ee6c13b71c875d355d3cb9a95786c92
BLAKE2b-256 a7807e6049cb1035107a9ad575819356a693266f4296069403114902b40397bc

See more details on using hashes here.

Provenance

The following attestation bundles were made for ietf_llm-0.7.4.tar.gz:

Publisher: publish.yml on mnot/ietf-llm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ietf_llm-0.7.4-py3-none-any.whl.

File metadata

  • Download URL: ietf_llm-0.7.4-py3-none-any.whl
  • Upload date:
  • Size: 273.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ietf_llm-0.7.4-py3-none-any.whl
Algorithm Hash digest
SHA256 0d2d53558ce7316e52a65578f0d29953def492c40ac0ebfc089e14efec531768
MD5 0f622e7f25736c25c88dc6daad3f7702
BLAKE2b-256 e97be45dee815568d2a9640b1e3a3f18b1bc56843caedbb76df3b49d274f3298

See more details on using hashes here.

Provenance

The following attestation bundles were made for ietf_llm-0.7.4-py3-none-any.whl:

Publisher: publish.yml on mnot/ietf-llm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page