Edward MCP server
Commit 11. Nov. 2026A local-first research memory and writing workspace that indexes sources, extracts clean text, and provides evidence-backed retrieval for AI agents and humans.
Auch bekannt als nmorton13/edward
- Stars
- 0
- Tools
- —
- Downloads, 30 Tage
- —
- Neueste Version
- —
- Letzter Commit
- 11. Nov. 2026
- Lizenz
- MIT
Was ist Edward MCP?
Edward ist ein MCP server. A local-first research memory and writing workspace that indexes sources, extracts clean text, and provides evidence-backed retrieval for AI agents and humans.
Zusammenfassung generiert aus dem README des Projekts
Über Edward MCP server
Researchers and writers who need to organize external sources can use edward to build a local-first memory workspace. It functions as a repository for articles, PDFs, X threads, and emails, allowing users to capture not just links but the specific context and intent behind every save. By separating captures, resources, and findings, the system ensures that every piece of evidence is traceable to its original source.
Users interact with the system via a command line interface that supports both human and agent workflows. The server uses SQLite FTS5 for exact lexical searches and local FastEmbed for semantic retrieval, meaning conceptual queries can be performed entirely on your own machine. It handles heavy lifting like text extraction and embedding generation through the edward process command, which can be automated with a scheduler.
For those moving from research to drafting, the tool provides dedicated writing project workspaces. These allow you to group resources by their relationship to a topic, such as supporting evidence or counterarguments, and generate cited outlines. The CLI is designed for AI agents to use, providing strict JSON output on stdout to facilitate automated research and drafting tasks.
Was du damit machen kannst
- 1Automated research ingestionAn AI agent can ingest research bundles or web links to build a structured library of evidence.
- 2Verifying claims against sourcesAsk questions about your saved data and receive answers that are checked against the original text to prevent hallucinations.
Geschrieben aus dem README des Projekts. Jeder Use Case wurde gegen ein Zitat daraus geprüft.
Konfiguration
EDWARD_ANSWERER_MODEEDWARD_ANSWER_BASE_URLEDWARD_ANSWER_LOCATIONEDWARD_ANSWER_MODELEDWARD_SUMMARIZER_MODEEDWARD_SUMMARIZER_MODELEDWARD_SUMMARIZER_PROVIDER
| Name | Beschreibung | Typ |
|---|---|---|
| EDWARD_ANSWERER_MODE | — | |
| EDWARD_ANSWER_BASE_URL | — | |
| EDWARD_ANSWER_LOCATION | — | |
| EDWARD_ANSWER_MODEL | — | |
| EDWARD_SUMMARIZER_MODE | — | |
| EDWARD_SUMMARIZER_MODEL | — | |
| EDWARD_SUMMARIZER_PROVIDER | — |
README
Auf GitHub ansehenEdward
A personal research memory and writing workspace.
Edward keeps sources, why you saved them, and useful evidence together. Capture a link, email yourself a note, or add a document; your agent can fetch, extract, and index it for you. Later, search your library or ask a question and get evidence you can trace to its source.
Why Edward?
I built Edward—and Mentat—to fit the way I think about memory. Thoughts I’m working through go in Mentat; sources and evidence I want to use go in Edward. I tried read-it-later tools, wikis, Obsidian, and newer LLM “second brains,” but none fit that mental model. I want to know where I put something and be able to use it later.
The point of saving something is rarely just to own the link. Most of what I save, I want to return to later:
- To seed an essay or commentary piece.
- To study a dense technical topic through a deep dive.
- To hold onto inconvenient counterevidence or dissenting data.
- To check a specific statistic, quote, or claim before citing it.
- To evaluate a cool open-source project, game demo, or new tool.
- Or just to remember a great point for a talk or debate.
Mentat and Edward: Thoughts vs. Research
If you use both, the division of labor is clean:
- Mentat is for your internal thoughts: reflections from a walk, quotes that linger, decisions, voice journals, and evolving perspectives across time.
- Edward is for your external research: articles, X threads, self-sent emails, PDFs, documentation, and data sources. It extracts full clean text, maintains content-addressed snapshots, embeds passages, and assembles verified evidence into structured writing projects.
What Edward Does
- Zero-Friction Ingestion: Bookmark on X (via Birdclaw), forward a link or note to yourself in Gmail (via
gog), paste text or files from your terminal (edward add), or import structured research bundles from AI agents. - Clean Architecture & Tripartite Separation:
Record What it preserves Capture The event and context: why, when, and where a post, email, thought, or report was saved. Resource The reusable source: an article, post, PDF, or repository with its content-addressed snapshot. Multiple captures link to the same resource without duplicate blobs. Finding A specific claim, quotation, question, or conclusion extracted from or verified against the source text. - Queued Processing: Web pages and PDFs can be fetched and extracted into clean readable text by running
edward process. You can automate it with a scheduler; Edward does not run a background daemon by itself. Ifsummarizeis installed, it is used for web extraction. - Dual-Engine Retrieval:
- Exact Lexical Search: Powered by SQLite FTS5 (
unicode61tokenizer) for finding exact phrases, names, and code snippets. - Local Semantic Search: FastEmbed (
BAAI/bge-small-en-v1.5) running entirely in local Python for conceptual and thematic retrieval. - Related Items:
similarfinds saved items close in meaning to any capture, page, or finding.
- Exact Lexical Search: Powered by SQLite FTS5 (
- Themes and Recent Saves: Related captures are grouped into named themes that stay put as you save more, and
recentshows what you saved yesterday or last week, summarised by theme. - Intent Facets: Answers why you kept something (
essay-seed,deep-dive,counterevidence,fact-check,tool-eval,inspiration,reference,try-later). Intents are user-level facets for filtering, never opaque weights that distort search rankings. - Taxonomic Classification: Evaluates topics (
ai/local-models,software/systems,crypto/bitcoin,economics/austrian,infrastructure/energy-grid,creative-tech,gaming,philosophy, etc.) and signals (cool-project,field-report,benchmark,tutorial,warning,data-source). - Writing Projects & Syntheses: Group sources into dedicated writing workspaces, assign explicit roles (
supporting,counterevidence,qualification), track open research gaps and questions, and generate cited outlines.project suggestfinds evidence you already saved by meaning, judged against the project's question, and new saves are checked against every active project as they are processed. - Agent and Human Pair: A rock-solid CLI with
--jsonoutput where machine outputs are strictly JSON onstdoutand logs go tostderr, making it trivial for agents (Codex, Claude, Antigravity) to research and draft with you.
Quick Start
Installation
Requires Python 3.11 or newer and uv.
git clone https://github.com/nmorton13/edward.git
cd edward
uv sync
Save and Retrieve in Seconds
# 1. Save a quick thought with an intent
uv run edward add \
--text "Energy grid constraints will shape data center siting far more than compute efficiency." \
--intent essay-seed \
--json
# 2. Save a URL and why you kept it
uv run edward add \
--url "https://example.com/grid-reliability-study" \
--note "Key transmission capacity data for PJM and ERCOT" \
--intent reference \
--json
# 3. Process pending extraction and local embeddings
uv run edward process --limit 20
# 4. Search exact words via SQLite FTS5
uv run edward search "transmission capacity" --json
# 5. Query evidence without calling an external model
uv run edward ask "What have I saved about grid constraints?" --no-model --json
add records the capture instantly so you can get right back to reading. process runs through pending background jobs—fetching pages, extracting clean text from HTML or PDFs, and generating local embeddings.
Ingesting Content
Edward accepts content from anywhere you encounter it.
| Source | Command | Details |
|---|---|---|
| URL or Local File | edward add --url <URL> / edward add --file <PATH> |
Extracts clean text, stores snapshots in content-addressed storage (blobs/), and queues embeddings. PDFs are parsed locally. |
| Quick Note / Thought | edward add --text "<NOTE>" --intent <INTENT> |
Saves a thought directly with an intent facet. |
| Terminal / Clipboard | pbpaste | edward add --stdin --origin personal |
Ingests piped text from standard input. |
| X Bookmarks | edward sync x --all |
Syncs bookmarks from Birdclaw's local archive. Automatically unrolls author threads into full articles with media and external links when bird is installed. |
| Self-Sent Email | edward sync gmail |
Ingests notes and links you emailed to yourself via gog in read-only mode, verifying headers. |
| Markdown Report | edward import-research report.md |
Ingests structured Markdown synthesis into resources and findings. |
| Agent Research Bundle | edward import-research bundle.json |
Canonical multi-source JSON schema for agent research handoffs. |
Automating Ingestion (Cron / Scripts)
You can set up a simple script or cron job to run sync and processing automatically in the background:
#!/usr/bin/env bash
# ~/.local/bin/edward-sync.sh
cd /path/to/edward || exit 1
# Sync new X bookmarks from Birdclaw
uv run edward sync x --all --quiet
# Sync self-sent emails
uv run edward sync gmail --quiet
# Process up to 50 extraction and embedding jobs in the background
uv run edward process --limit 50 --quiet
Add to crontab (crontab -e) to run every hour:
0 * * * * /path/to/edward/scripts/edward-sync.sh >> ~/.edward/sync.log 2>&1
Search, Discovery & Answering
Exact Lexical Search (search)
# Search for exact phrases or terms across all resources
uv run edward search "proof-of-work"
# Filter by primary form, topic, or signal
uv run edward search "systems" --topic software/systems --form article
uv run edward search "benchmark" --signal benchmark --topic ai/local-models
Lexical search uses SQLite FTS5 with diacritic removal and no destructive stemming, ensuring technical terms, code symbols, and exact quotes match precisely.
Asking Questions & Assembling Evidence (ask)
ask retrieves the best matching passages across your corpus using hybrid search:
# Return a structured Evidence Packet for an agent or personal inspection (no model required)
uv run edward ask "What arguments were made against utility rate decoupling?" --no-model --json
# Answer using an optional configured local model with citation verification
uv run edward ask "Summarize the key findings on transformer latency"
When an answer model is configured and active, ask verifies every citation against the underlying source text. If citations cannot be verified, it cleanly falls back to returning the retrieved evidence packet rather than hallucinating.
Themes and Recent Saves (themes, recent)
Edward groups related captures into themes using their embeddings, with no model needed. Once built, themes stay put: new captures join their nearest theme and nothing else moves. --rebuild regroups everything and keeps the ids and names of themes that survive.
# Build themes the first time; afterwards, place new captures and name any new themes
uv run edward themes refresh
# List themes with example titles, or look inside one
uv run edward themes
uv run edward themes show thm_...
# Your own name wins over automated naming, including after rebuilds
uv run edward themes rename thm_... "Data centers & rates"
# What you saved recently, by day, summarised by theme
uv run edward recent --since yesterday # also: today, week, last-week, 7d, 2026-09-01
Theme names come from the configured summarizer model (EDWARD_SUMMARIZER_*), which reads the titles and summaries of a theme's most central public items only. Gmail, personal notes and local documents are never sent. Without a model, or with --fallback-names, themes are named from their topic labels.
recent dates items by when you saved them. Captures from a bulk backfill (an import run of more than 50 items) are dated by the post's own date instead, since their save date is only the import date; these are marked (posted).
Projects: From Research to Writing
Edward includes dedicated writing project workspaces designed to turn scattered research into coherent essays, articles, or talks.
# 1. Create a writing project
uv run edward project create \
--title "The Real Bottlenecks in Modern Compute" \
--brief "Analyzing electrical grid constraints, cooling limits, and substation lead times." \
--json
# 2. Add saved evidence to the project with explicit relationships
uv run edward project add <PROJECT_ID> <RESOURCE_ID> \
--relationship supporting \
--note "Provides empirical substation transformer lead time data." \
--json
# Mark the counterarguments explicitly
uv run edward project add <PROJECT_ID> <OTHER_RESOURCE_ID> \
--relationship counterargument \
--note "Argues behind-the-meter solar + batteries mitigates grid interconnection queue delays." \
--json
# 3. Record open research gaps and questions
uv run edward project note <PROJECT_ID> --kind gap --text "Need recent 2025/2026 PJM interconnection queue reports."
uv run edward project note <PROJECT_ID> --kind question --text "What percentage of planned capacity drop out before interconnection?"
# 4. View full project context and candidate sources
uv run edward project context <PROJECT_ID> --refresh-candidates --json
# 5. Propose a structured outline
# Option A: Offline deterministic grouping by relationship (no model)
uv run edward project outline <PROJECT_ID> --propose --no-model --json
# Option B: Calling agent supplies full narrative structure with verified citations
uv run edward project outline <PROJECT_ID> --propose --input outline.json --json
# 6. Accept the outline
uv run edward project outline <PROJECT_ID> --accept
Finding Evidence You Already Saved (project suggest)
Edward suggests candidate evidence by meaning, then checks each candidate against the project's actual question:
uv run edward project suggest <PROJECT_ID> # first run checks the whole library
uv run edward project suggest <PROJECT_ID> --full # re-check everything (e.g. after accepting evidence)
- Find: every capture is ranked by embedding similarity to the project brief, blended with the evidence you have already accepted once there are at least three items.
- Judge: the top candidates go to the configured Jev classifier with one question, "is this relevant evidence for your brief?" A page about data-center jobs is near an essay on electricity rates but not relevant to it, and is left out.
Suggestions are added as candidate evidence with a note explaining why. Your accepted and rejected decisions are never changed, and rejected items never come back. Only public content is sent to the judge; private captures are ranked locally and suggested only when they are among the closest matches. Without a configured judge, only the closest matches are suggested.
New saves are checked automatically. After edward process, each newly embedded capture is checked once against every active project, and relevant ones become candidates. edward process lists them, and edward recent marks them with "→ suggested for …". Pass --no-project-match to skip this. Changing a project's brief makes the whole library eligible again.
Outline Invariants & Evidence Mapping
Outlines carry explicit relationships for each cited claim: supporting, counterevidence, or qualification.
- Offline outline (
--no-model): Places memberships into sections based on their assigned relationship. It does not read what the source text says, which is why marking--relationship counterargumentwhen adding evidence is crucial. - Agent outline (
--input outline.json): An agent (or human) crafts the section narrative and thesis; Edward strictly verifies that every cited object ID corresponds to real project evidence.
Local Models, Classification & Privacy
Edward is memory, not a mind. Local capture, indexing, search, and deterministic answers can run without a hosted model. Fetching web sources requires network access, and FastEmbed may download model weights the first time it runs; hosted answer or classification providers are optional.
What Runs Without Any Model
The default posture requires no external APIs or local LLM runtimes:
- Ingestion, URL fetching, PDF parsing, and text extraction.
- Deterministic finding extraction (sentences, quotes, claims).
- FTS5 full-text indexing and querying.
- FastEmbed vector embeddings (
BAAI/bge-small-en-v1.5running locally in Python). similar, theme grouping,recent, and ranking project candidates by meaning (all embedding-based).- Projects, outline proposals (
--no-model), and evidence packet exports (--no-model). - Deterministic question answering for counts, dates, and entity lookups.
Embeddings
Embeddings run locally in Python via FastEmbed. The model weights are automatically cached under <data-dir>/models/. To chunk and embed your entire library in one pass:
uv run edward reindex --embeddings
Opting In to an Answer Model (Off by Default)
Absence is the default. Edward will never contact an LLM unless you explicitly declare an answerer mode:
# In your ~/.edward/.env or shell:
EDWARD_ANSWERER_MODE=local-model # local-model | local | hosted | disabled
EDWARD_ANSWER_BASE_URL=http://localhost:11434/v1
EDWARD_ANSWER_MODEL=llama3.2
EDWARD_ANSWER_LOCATION=local
Setting EDWARD_ANSWER_BASE_URL alone does nothing: model use strictly requires EDWARD_ANSWERER_MODE.
Opting In to Summaries and Theme Names (Off by Default)
A small model can write 2–3 sentence summaries of saved pages and name themes. It is off until you set EDWARD_SUMMARIZER_MODE:
EDWARD_SUMMARIZER_MODE=hosted # hosted | local | enabled | disabled
EDWARD_SUMMARIZER_PROVIDER=openrouter
EDWARD_SUMMARIZER_MODEL=deepseek/deepseek-v4.1-flash
# EDWARD_SUMMARIZER_BASE_URL / _API_KEY / _LOCATION / _TIMEOUT fall back to the EDWARD_ANSWER_* values
uv run edward process --stage summarize --limit 20 # try a small batch first
uv run edward process --stage summarize --limit 1000
- Summaries from imported research bundles and your own summaries are never replaced.
- Texts under 300 characters are skipped (the text already is the summary), as are pages whose words are mostly contained in a longer page of the same capture, such as a link that resolves back to the same post.
- The privacy check runs before anything is sent: Gmail, personal notes, and local documents are refused unless their
EDWARD_HOSTED_*setting allows them. - If the provider rate-limits a request (common with free model tiers),
processstops early and re-queues the job without using one of its retries. Run it again later.
Judging Project Candidates
edward project suggest and the check that runs after edward process rank captures by meaning locally, then ask the configured Jev classifier (EDWARD_CLASSIFIER_PROVIDER) one yes/no question per top candidate: is this relevant evidence for the project's brief? Only public content is sent. Without a classifier, only the closest matches by meaning are suggested. A first pass over a library of about 900 pages judges around 40 candidates per project.
Classification and Privacy Guarantees
Taxonomic classification evaluates topic and signal probabilities. Two distinct rules govern how it interacts with the system:
- Not invoked during retrieval: Queries never trigger a classifier call or wait on an LLM.
- Labels are consumed by the query surface: Stored labels populate
--topic,--signal, and--formfilters, and results return with their assignedlabels[].
Privacy invariant: Local files, personal notes, and self-sent emails are blocked from hosted classifiers (typesafe, openrouter) unless their corresponding EDWARD_HOSTED_* environment setting is explicitly allow. Privacy checks run before serialization or network dispatch. Classification is disabled by default.
Maintaining Your Research Library
Edward provides self-healing tools to ensure database integrity, repair outdated chunks, and clean stale metadata:
# Inspect queue depth, processing stats, and corpus coverage
uv run edward status --json
# Verify SQLite database and blob store integrity
uv run edward doctor
# Retry any failed extraction or embedding jobs
uv run edward retry --failed
# Chunk and embed any live resources missing embeddings
uv run edward reindex --embeddings
# Re-chunk resources if extraction was updated or replaced
uv run edward repair-chunks
# Re-derive titles that fell back to author names or URLs
uv run edward repair-titles
# Unroll X bookmark threads into complete multi-tweet articles with media
uv run edward repair-threads --dry-run
uv run edward repair-threads
# Re-fetch resources that were stored as shortlink interstitials (t.co, bit.ly)
uv run edward backfill-shortlinks --dry-run
uv run edward backfill-shortlinks
# Create a snapshot backup of SQLite and content-addressed blobs
uv run edward backup
# Delete queued jobs for a specific stage (guarded, requires confirmation)
uv run edward purge-jobs --stage finding-extraction --dry-run --json
uv run edward purge-jobs --stage finding-extraction --yes --json
# Permanently purge a specific capture, resource, or project
uv run edward purge <OBJECT_ID> --confirm
uv run edward project delete <PROJECT_ID> --confirm
Configuration Reference (common settings)
Edward reads environment variables and a .env file from the current directory or ~/.edward/.env (environment variables take precedence). The database, blobs, diagnostics, and model cache live under Edward's local data directory—not in this repository by default. This data can contain private research; do not commit it or share backups unintentionally. The data directory is platform-specific unless EDWARD_DATA_DIR is set; set EDWARD_DB_PATH to place the database elsewhere.
| Variable | Description | Default |
|---|---|---|
EDWARD_DATA_DIR |
Storage directory for SQLite, blobs, diagnostics, and models | ~/.edward (or platform standard) |
EDWARD_DB_PATH |
Path to the SQLite database | <data-dir>/edward.sqlite3 |
EDWARD_EMBEDDING_MODEL |
FastEmbed model name | BAAI/bge-small-en-v1.5 |
EDWARD_ANSWERER_MODE |
Opt-in answer model mode (local-model, local, hosted, disabled) |
disabled |
EDWARD_ANSWER_BASE_URL |
OpenAI-compatible API base URL | — |
EDWARD_ANSWER_MODEL |
Chat model name for synthesis | — |
EDWARD_ANSWER_LOCATION |
Declared location (local or hosted) |
— |
EDWARD_ANSWER_API_KEY |
API key for an opted-in answer model | — |
EDWARD_ANSWER_PROVIDER |
Answer provider identifier | llm |
EDWARD_ANSWER_TIMEOUT |
Per-request timeout in seconds | 120 |
EDWARD_SUMMARIZER_MODE |
Opt-in summarizer for resource summaries and theme names (hosted, local, enabled, disabled) |
disabled |
EDWARD_SUMMARIZER_PROVIDER |
Summarizer provider (e.g. openrouter) |
EDWARD_ANSWER_PROVIDER |
EDWARD_SUMMARIZER_MODEL |
Summarizer model name | EDWARD_ANSWER_MODEL |
EDWARD_SUMMARIZER_BASE_URL |
Summarizer API base URL | provider default |
EDWARD_SUMMARIZER_API_KEY |
Summarizer API key | EDWARD_ANSWER_API_KEY / OPENROUTER_API_KEY |
EDWARD_SUMMARIZER_TIMEOUT |
Per-request timeout in seconds | 60 |
EDWARD_CLASSIFIER_PROVIDER |
Taxonomic classifier provider (disabled, typesafe, openrouter, local, dry-run) |
disabled |
EDWARD_CLASSIFIER_MODEL |
Classifier model name | Provider-specific |
EDWARD_CLASSIFIER_BASE_URL |
Classifier API base URL | Provider-specific |
EDWARD_CLASSIFIER_TRANSPORT |
Hosted transport used by the Jev classifier | typesafe |
EDWARD_HOSTED_GMAIL |
Allow private Gmail content to hosted classifiers (allow or deny) |
deny |
EDWARD_HOSTED_PERSONAL_NOTES |
Allow personal notes to hosted classifiers | deny |
EDWARD_HOSTED_DOCUMENTS |
Allow personal documents to hosted classifiers | deny |
EDWARD_HOSTED_PUBLIC_WEB |
Allow public-web content to hosted classifiers | allow |
EDWARD_RECORD_PRIVATE_DIAGNOSTICS |
Opt in to recording private-content diagnostics (1 enables) |
0 |
EDWARD_BIRDCLAW_DB |
Path to Birdclaw's X bookmark archive | ~/.birdclaw/birdclaw.sqlite |
Known hosted classifier providers are always treated as hosted. Private content is blocked before serialization or network dispatch unless its corresponding EDWARD_HOSTED_* setting is allow. Merely configuring credentials or an endpoint does not enable answer-model use; set EDWARD_ANSWERER_MODE to opt in. .env.example is a starter template for common settings; it also shows the privacy defaults.
Agent Protocol & Machine Contracts
Edward is designed from day one to be pair-programmed with AI coding agents:
- Pass
--jsonto any command for valid machine-readable JSON onstdout. - Progress logs, warnings, and diagnostic traces always go to
stderr. - Deterministic exit codes:
0= success,1= domain failure,2= usage error,3= fatal/conflict. - Native MCP Server: Run
edward mcpto connect agents directly via the Model Context Protocol.
See:
Edward MCP Fragen
How does Edward handle web page and PDF extraction?
Web pages and PDFs are fetched and extracted into clean readable text using the edward process command, which can be automated with a scheduler.
Can I use Edward without an external AI model?
Yes, Edward supports exact lexical search via SQLite FTS5 and can answer questions using a --no-model flag to return a structured evidence packet.
What kind of sources can I ingest into Edward?
You can ingest URLs, local files, text notes, X (Twitter) bookmarks, self-sent Gmail messages, and structured Markdown or JSON research bundles.
How does Edward ensure citations are accurate?
When an answer model is active, the system verifies every citation against the underlying source text and falls back to a retrieved evidence packet if they cannot be verified.