second-brain-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| EMBED_URL | No | Embedding server endpoint | http://localhost:11435/v1/embeddings |
| EMBED_PORT | No | llama-server port (use 11434 for Ollama) | 11435 |
| EMBED_MODEL | No | Embedding model name | nomic-embed-text |
| ANTHROPIC_API_KEY | No | Optional API key for better compression quality in vault_sleep | |
| SECOND_BRAIN_PATH | No | Path to your vault directory | ~/second-brain |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| auth_contextA | Return the authenticated caller's canonical EP UUID and current role. |
| get_contextA | Load session context: current goals + top-20 most recently active notes. Call this at the start of every session to orient yourself. |
| new_noteA | Create a new note in the vault using the correct folder and template. If the title or tags contain a known project slug (from PROJECT_REGISTRY.md), the note is automatically routed into that project's subfolder: coding → {project}/phases/, research/paper/finding → {project}/research/, resource/reference/tool → {project}/docs/ decision/adr always go to decisions/; project always goes to 10-projects/. A coding-type note whose title slug starts with "fix-" routes to {project}/fixes/ instead of phases/ — a postmortem isn't an in-flight phase plan. Args: note_type: Type of note — decision, project, research, coding, resource, or inbox title: Human-readable title (will be converted to kebab-case filename) content: Optional initial content to append after the template tags: Comma-separated tags, e.g. 'evo-prism,architecture'. Added to frontmatter. |
| search_notesA | Hybrid semantic + full-text search across knowledge notes (excludes daily news archives). Uses BM25 + cosine similarity (bge-m3, 1024d) when embedding server is available, falls back to BM25-only, then file scan. To search news specifically, use search_news_tool. Args: query: Search term — supports natural language and keywords |
| search_articlesA | Search article-only structured bibliography fields. Use this instead of search_notes when asking for papers by an author. Author matching is based only on article frontmatter, never body text or references. Full names, surname-first initials and ORCID are supported. A surname-only result is marked ambiguous and must not be treated as identity resolution. |
| search_snippetsA | Precise localization: return the VERBATIM source sentence from each of the most relevant notes, with its citation. The sentence is quoted exactly from the paper, never rewritten — ideal for 'what does the literature say about X' or 'a factor's role': jumps to the passage. Args: query: keyword or phrase, e.g. 'TGF-beta fibrosis', 'hair follicle stem cell niche'. top_k: how many notes to pull snippets from (default 8). |
| query_graphA | Dual-path knowledge-graph query for an entity (gene / factor / phenotype / …). Path 1 — structured typed edges (ACTIVATES / INHIBITS / PROMOTES / CAUSES / PREVENTS / ASSOCIATED_WITH) mentioning the entity, aggregated ACROSS papers with verbatim evidence + source note. Cross-paper agreement = stronger (shown as ×N). Path 2 — full-text verbatim snippet recall net (same engine as search_snippets), so a relation the edge extractor missed is still surfaced (goal: 無遺漏). Args: entity: e.g. 'TXNDC5', 'TGF-beta', 'pulmonary fibrosis'. mode: 'edges' | 'snippets' | 'both' (default 'both'). top_k: snippet notes to pull for the recall net (default 12). |
| litnet_answerA | Answer a literature question as a fixed-format, CITED synthesis note (retrieve → synthesize). Retrieves grounded material via query_graph (LitNet 正本 edges + full-text net), then Claude writes a cited summary. GENERATED prose (not raw literature): every claim is anchored to a source note in the retrieval; tagged type: synthesis; a synthesis is NEVER re-extracted into the 正本 (saved outside 20-areas/research/). Args: entity: comma-separated entities to look up; if empty, extracted from the question (auto-extraction caps at _LA_MAX_AUTO_ENTITIES=3 entities — pass entity explicitly to query more than that in one call; see AGENTS.md's SOP note on this). fmt: middle-section shape — auto | mechanism | compare | list | methods (auto = model picks). save: if true, write the note into VAULT/20-areas/syntheses/ (else just return it). model: Claude synthesis model. Each entity is queried via query_graph(e, "both") — top_k intentionally omitted so it always tracks query_graph's own default (currently 12) instead of a second hardcoded number that can silently drift from it. |
| search_news_toolA | Search recent cnyes daily news archives. Only searches cnyes_archive notes within the last N days. Use search_notes for knowledge base search. Args: query: Stock ticker, keyword, or company name (e.g. '2317', 'TSMC', 'AI') days: How many days back to search (default 7) |
| get_decisionsB | Get decision records from the vault. Args: project: Filter by project name (optional). If empty, returns all decisions. |
| update_goalsB | Replace the contents of memory/goals.md with new content. Args: new_content: Full new content for goals.md (markdown format) |
| read_noteA | Read a specific note by its relative path within the vault. Args: path: Relative path from vault root, e.g. 'decisions/my-decision.md' |
| update_noteA | Overwrite an existing note with new content. Use when rewriting or restructuring a note. For adding content without losing existing text, use append_to_note instead. Args: path: Relative path from vault root, e.g. 'decisions/my-decision.md' content: Full new content to write (replaces the entire file) |
| append_to_noteA | Append content to the end of an existing note. Safer than update_note — existing text is never lost. Use for adding progress updates, new findings, or extra sections. Args: path: Relative path from vault root, e.g. '10-projects/my-project.md' content: Text to append (added after a blank line at end of file) |
| mark_note_statusA | Update the frontmatter status field of a note and sync to DB. Use this to track note lifecycle without rewriting the whole file — including a decision note's proposed → accepted → superseded progression. Args: path: Relative path from vault root, e.g. '30-resources/my-note.md' status: active | completed | archived (general / project notes), proposed | accepted | superseded (decision / ADR), or consolidated | archive_backup (normally written by consolidate_tool / vault_sleep, accepted here for repairs). |
| audit_article_recordsB | Audit article records and social-source state without changing the vault. Args: scope: Audit article notes, social-source state, or both. limit: Maximum results returned per issue category (1..500). stale_after_days: Age at which source state is considered stale (1..90). |
| sync_notesC | Reindex only the explicitly requested vault notes. |
| sync_indexA | Rebuild the DuckDB index by scanning all vault markdown files. Run this after adding notes manually, or when setting up on a new machine. Also backfills note_chunks for up to _SYNC_INDEX_CHUNK_LIMIT notes that predate chunking or whose chunks failed previously. If more than that are outstanding, run sync_chunks_tool() separately to drain the rest — this tool intentionally does not attempt the whole backlog in one call. |
| sync_chunks_toolA | Backfill note_chunks for notes whose chunks are missing or stale — the dedicated tool for draining a large backlog (sync_index()'s own chunk backfill is capped small so it stays fast; see its docstring). limit: max notes to process this call (default 200). Call repeatedly (the response says how many remain) until "remaining" reaches 0 — each call is its own bounded unit of work rather than one unbounded one, so a big backlog never turns a single call into an hours-long block (see PostgresStore.sync_chunks's docstring for the architecture debt this replaced, fixed 2026-09-04). |
| index_statsA | Show vault index statistics: total notes, breakdown by type, DB location. |
| vault_sleepA | Compress old low-activity notes to slim down the vault. Thresholds are read from vault/.sleep-config.json (per-folder):
Args: dry_run: If True, show candidates without making changes. |
| sleep_statusA | Check current sleep triggers and list candidates without compressing. |
| extract_rules_toolA | Extract L3 declarative rules from high-access notes into memory/rules.md. Rules are auto-injected at the top of every get_context() call so Claude always has the most important project constraints in view. Args: note_path: Specific note to extract from (e.g. 'decisions/my-note.md'). Leave empty to run batch extraction on all eligible notes (access_count >= 5, not extracted in last 90 days). |
| expand_semantic_keywords_toolA | Batch-extract or refresh semantic_keywords for notes via llm_cli (local Gemma4 → Claude CLI → Gemini CLI, in that priority order — see llm_cli.py's module docstring). Writes extracted keywords into each note's frontmatter and rebuilds FTS index. Skips notes that already have semantic_keywords unless force=True. Args: note_path: Specific vault-relative path to process (e.g. 'decisions/my-note.md'). Leave empty to process all indexed notes missing keywords. force: If True, overwrite existing semantic_keywords (default False). Returns: Summary dict: {"processed": N, "skipped": M, "failed": K} |
| enrich_neighbor_keywords_toolA | Enrich notes with neighbor_keywords and cluster_topic derived from embedding similarity. Computes cosine similarity between all notes' embeddings, finds top-5 neighbors per note, and writes high-frequency words from neighbors back into each note's frontmatter. No API or model calls — pure local computation from vault.db embeddings. Args: note_path: Relative path to a single note (e.g. "10-projects/foo.md"). Empty string = process all notes without neighbor_keywords. force: If True, overwrite existing neighbor_keywords. Default: skip existing. Returns: JSON-like string with {"enriched": N, "skipped": M, "no_neighbors": K}. |
| save_articleA | Convert a web article or PDF into a markdown note and save it to the vault. Args: source: URL of a web article, or absolute path to a local PDF/DOCX file. title: Optional title override. If empty, inferred from the source filename or URL. tags: Comma-separated tags to add to frontmatter, e.g. 'bioinformatics,clustering'. dest_folder: Vault-relative folder to save into. Defaults to '30-resources'. Use '20-areas/research' for academic papers with DOI/journal. filename: Filename stem (without .md). If empty, auto-generated from title as kebab-slug. Use 'YYYY_Author_ShortTitle' format for research papers, e.g. '2024_Bakr_ARID1A'. metadata: Optional structured bibliographic fields. Only authors, author_ids, DOI/PMID/PMCID, journal, publication_year and canonical_url are written. |
| update_links_toolA | Refresh auto-generated related wikilinks in one note or all notes. Uses semantic similarity (bge-m3, 1024d) to find related notes and
writes them into the frontmatter Args: note_path: Relative path within vault (e.g. 'decisions/my-note.md'). Leave empty to update ALL notes that have embeddings. |
| extract_figures_forB | Manually trigger figure extraction for a saved article. Args: note_path: Relative path within vault, e.g. '30-resources/my-article.md' |
| reconcile_figuresA | Reconcile figure files and index rows without Vision-model calls. Only deterministic evidence is applied: a unique canonical local file, a unique same-stem replacement for a missing path, or a guarded public image URL with an existing text proxy. Ambiguous cases remain in the manual queue. Research Markdown is never modified. Args: note_paths: Explicit vault-relative Markdown paths; at most 20. dry_run: Report actions without downloading files or updating rows. limit: Maximum notes to inspect from the supplied list; 1 through 20. |
| backfill_figure_textA | Fill empty OCR/description fields using only the configured local VLM. The call is resumable and bounded to at most 20 notes and 20 images. Each
successful image is committed separately; model failures remain queued.
Args: note_paths: Explicit vault-relative article paths; at most 20. dry_run: List the next bounded image batch without model calls or writes. note_limit: Maximum supplied notes to inspect; 1 through 20. image_limit: Maximum images to analyse in this call; 1 through 20. |
| restore_missing_pdf_imagesA | Restore missing legacy embedded-image files from their original PDFs. Restoration is fail-closed: the reconstructed PDF sequence must match every database row and every surviving file byte-for-byte before any file is written. The call never changes research Markdown or figure database rows. Args: note_paths: Explicit vault-relative article paths; at most 20. dry_run: Validate and list the next bounded restore batch without writes. note_limit: Maximum supplied notes to inspect; 1 through 20. image_limit: Maximum missing image files to restore; 1 through 20. source_pdfs: Optional local PDF paths aligned with note_paths, for an explicitly verified copy when the recorded File Provider path is unavailable. |
| search_figuresA | Search figures by OCR text or semantic description across all saved articles. Args: query: Search term, e.g. 'UMAP', 'TYRP1', 'cluster', 'p < 0.001' |
| snapshot_note_toolB | Render a markdown note to PNG snapshot for token-efficient storage. Args: note_path: Relative path within vault, e.g. 'decisions/my-note.md' tier: Resolution tier — 'large' (400 tokens), 'base' (256), 'small' (100) |
| consolidate_toolA | Find and consolidate clusters of semantically similar notes. Groups notes with cosine similarity >= threshold, then uses Gemini CLI to synthesise each cluster into one abstract note in 20-areas/consolidated/. Source notes are marked status='consolidated' and deprioritised in context. Default dry_run=True — inspect clusters before committing. Args: threshold: Cosine similarity threshold for clustering (default 0.85) dry_run: If True, show clusters without consolidating (default True) |
| prune_archive_toolA | Delete archived originals older than min_age_days that have a snapshot. Safe to run: only deletes when a PNG snapshot exists as long-term memory. Default dry_run=True — set to False to actually delete. Args: min_age_days: Minimum age of archived file to consider (default 365) dry_run: If True, only report what would be deleted (default True) |
| read_note_as_imageA | Read a note as a PNG snapshot (direct image for VLM agents) or text fallback. Returns the PNG image directly so the calling agent (Claude, Gemini, etc.) reads it with its own vision model — cheaper and faster than routing through an intermediary. Args: path: Relative path from vault root |
| read_figureA | Load ONE extracted figure as a down-scaled image (the cheap rung of the recall ladder — between text search and rendering a whole page). Use this only when search_figures' text proxy (caption + OCR + description) can't answer the question. Returns a thumbnail (long edge ~768px, ~256-400 tokens) rather than the full-resolution image or the whole page. Args: note_path: Vault-relative path of the source note, e.g. '20-areas/research/paper.md' fig_index: 0-based figure index as shown by search_figures |
| annotate_figureA | Save a read-time insight about a figure as an atomic vault note. Use AFTER you have loaded a figure (read_figure) and reasoned out something worth keeping — e.g. a specific value, trend, or conclusion. The insight is stored as a short standalone note (fully within the search index window) that backlinks the paper, so next time the question can be answered from text alone without re-loading the image. Insights for the same figure are appended. Store STRUCTURED facts ('panel C: IC50 = 2.3 µM') over prose — they cache better. Args: note_path: Vault-relative path of the source paper note fig_index: 0-based figure index (as shown by search_figures / read_figure) insight: The fact/observation to remember about this figure |
| find_related_notesA | Find semantically related notes for a given note (by vault-relative path). Uses cosine similarity on stored embeddings. Useful for:
Args: path: Vault-relative path, e.g. "20-areas/personal/finance/NVDA_analysis_20260601.md" limit: Max results to return (default 5) threshold: Minimum cosine similarity 0–1 (default 0.7) Returns: Markdown list of related note paths and titles, or a message if no embeddings found. |
| search_groupedA | Hybrid search that returns results split into two groups in one call:
Useful for finance research (get stock report + morning brief context together) and general knowledge work (see both deep notes and recent news at once). Args: query: Search terms, e.g. "NVDA" or "transformer architecture" limit: Max results per group (default 10) Returns: Markdown with two sections: Knowledge and News. |
| top_notesA | Return your most important notes ranked by engagement. Two ranking modes:
Use cases:
Args: by: "score" or "recency" (default "score") limit: Number of notes to return (default 20) Returns: Ranked Markdown table of notes. |
| init_vaultA | Initialize or repair vault directory structure and default templates. Safe to re-run: only creates missing items, never overwrites existing files. Call this after cloning the repo or setting up on a new machine. |
| get_agent_instructionsA | Return the full AGENTS.md operating manual for AI agents. Call this at the start of a remote session (when AGENTS.md cannot be read from the filesystem) to learn vault structure, tool SOP, and hard constraints. Returns: str: Full contents of AGENTS.md |
| manage_api_keyA | Manage API keys for multi-user access (admin only). action: "register" | "revoke" | "list" raw_key: the plaintext API key (register/revoke). Never stored; only its SHA-256 hash is persisted. user_id: human-readable owner label (register/list filter). role: "reader" | "member" | "writer" | "admin" (register only, default "reader"). 'member' (lab-open plan) requires user_uuid — it is how the key's private 90-personal// area is derived (see visibility.py). user_uuid: canonical UUID from EP lab-access (register only). Required for role='member'; optional for other roles. expires_days: if > 0, the key expires that many days from now (register only). 0 (default) means no expiry, same as every key before this. Returns a plain-text summary of the operation. |
| query_audit_logA | Query the write-action audit log (admin only). user_id: filter by actor (optional). tool_name: filter by tool (optional). limit: max rows to return (default 50). |
| health_checkA | Diagnose second-brain system health. Checks: DB connectivity, note count vs vault files, WAL file size, duplicate server processes, embedding server, and vault accessibility. Returns a plain-text report with OK / WARN / ERROR per item. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 46 tools
Several search/retrieval tools overlap in purpose (search_notes, search_articles, search_snippets, search_news_tool, search_grouped, query_graph), and sync tools (sync_index, sync_notes, sync_chunks_tool) or write tools (update_note, append_to_note, new_note) can be confused without careful reading. The descriptions do clarify target and method, so boundaries exist but require effort.
Mostly snake_case, but patterns vary: verb_noun (search_notes), noun-first (auth_context, index_stats, vault_sleep, sleep_status, health_check), and an inconsistent _tool suffix on about nine tools. The naming is readable but not uniform.
46 tools is well above the typical 3–15 range and feels heavy even for a broad vault-management domain. Many tools could be consolidated or grouped without losing capability.
The surface covers note CRUD, search, indexing, article ingestion, figure management, graph queries, synthesis, admin, and health checks. Minor gaps exist (e.g., no explicit delete/rename/move note tool), but archival/pruning tools mitigate some of that.