margins-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| MARGINS_VAULT | Yes | Absolute path to your Obsidian vault or Markdown folder. | |
| MARGINS_TELEMETRY | No | Override telemetry: 'on' or 'off'. Default uses consent decision. | consent file |
| MARGINS_INDEX_ROOTS | No | Comma-separated subfolders to index. Auto-detected if not set. | auto-detected |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| margins_startA | Conversation-start primer. Always call this once at the start of every vault-relevant conversation. The response includes a 'mode' field — read it and follow the 'guidance' field tailored to that mode: (1) mode='pile' for unstructured many-file vaults — returns a time-stratified sample of vault files, filename patterns, and (importantly) a rawScan with a priorityQueue of raw/ files to compile FIRST via propose_compile_from_raw. If priorityQueue is non-empty, your best opening move is to compile those files in parallel in a single turn (read_page each to get readable text, then propose_compile_from_raw with a structured summary) — the user dropped source documents and wants wiki source pages within ~90 seconds. (2) mode='empty' for near-empty vaults — ask what the user wants and offer to scaffold. (3) mode='synthesis' for organized linked vaults — returns folder stats, pending proposals, uningested files, recent user preferences, and the vault's CLAUDE.md. Ground answers in this structure and cite file paths. All modes also return pendingProposals, uningestedRaw, recentPreferences, and vaultManual. |
| recall_preferencesA | Read the user's vault-scoped preferences file (.margins/preferences.md). Returns durable rules the user has stated or that you've recorded via record_preference. Call this before any propose_* tool so your proposals follow the user's filing conventions, naming patterns, and prior corrections. |
| get_vault_contextA | Read the vault's wikilinking context: entity slugs (people, organizations, places, tools, projects), active project/decision slugs (priority=active or recently updated), and the in-use semantic tag taxonomy. Call this BEFORE propose_compile_from_raw so the page you stage uses real entity slugs in [[wikilinks]] (not invented names) and existing tags (not new variants). Region/X and vibrance/X tags are excluded from the response — those are auto-computed by scripts/wiki_regions.py and must not be model-generated. Cached on a vault-mtime key; safe to call repeatedly. |
| record_telemetry_consentA | Record the user's choice on anonymous telemetry. Call this exactly once, only when the margins_start response had telemetryConsentNeeded=true AND the user has answered the in-chat opt-in question. Pass enabled=true if they said yes, enabled=false if they said no. The choice persists in ~/.margins/consent.json and applies to all future Margins sessions. |
| record_preferenceA | Append a durable user preference, convention, or correction to the vault's preferences file. Call this when the user corrects a proposal in a way that should apply next time (filing path, naming pattern, summary length, link style, etc.). Do NOT record one-off disagreements or transient feedback. Aim for one-line rules. |
| search_vaultA | Full-text + filename search across the Margins vault. Returns top hits with path and snippet. |
| read_pageA | Read a single vault file by relative path (e.g. 'wiki/career/career.md' or 'raw/report.pdf'). Extracts readable text from supported document formats before returning it. |
| list_recentA | List the most recently modified vault files. Use this to answer 'what did I just ingest / update'. |
| get_backlinksA | Find vault pages that link to a target slug or filename. Matches [[wikilinks]] and relative .md links. |
| propose_wikilinksA | Scan vault pages for entity-shaped phrases and propose wikilinks to other vault pages that share the same slug. Two modes:
(1) single-page — pass |
| scan_entity_candidatesA | Find capitalized phrases that recur across vault pages but have no matching slug — i.e. entities the user keeps mentioning without having a page for them. This is the inverse query of propose_wikilinks: instead of 'where should I add a wikilink to an existing page?', it answers 'what page should exist that doesn't yet?'. Returns candidates ranked by file-spread × mention-count, with snippets and the list of files where each appears. Read-only — never stages. The companion tool propose_entity_stubs takes the slugs you choose from this list and stages stub entity pages. Layered filtering: a global English/structural stoplist, an optional domain pack ('med', 'realestate', 'law', 'generic'), and an optional excludeUserRejections list (slugs the user already rejected). Existing slugs are excluded automatically — the shared vault-slug index is the same one propose_wikilinks uses. Best used right after a fresh import or split-mode compile, when the corpus has many entity references but few entity pages. |
| propose_entity_stubsA | Stage stub entity pages for a list of candidate slugs (typically from scan_entity_candidates). Each stub becomes a proposed page at wiki//.md (default bucket 'entities') with frontmatter type:entity + a from_scan marker, an auto-built '## Mentioned in' block linking source files when snippets/files are provided, and a '## Next' checklist. Skips slugs whose destination page already exists in the vault — edit those directly instead of overwriting them. Closes the cold-start loop: scan finds names with no page; this stages the pages; resolve_proposal accepts the ones the user wants. Reject events on a stub (single or bulk) automatically append the slug to .margins/entity-rejections.md so it doesn't re-surface in the next scan. |
| propose_pageA | Propose a new page in the vault. Body is the full markdown (frontmatter optional). The page is staged at proposed/ until the user accepts it via resolve_proposal. Errors if a page already exists at this path in the vault — use propose_edit or append_to in that case. |
| propose_editA | Propose an edit to an existing page via exact string replacement. 'before' must appear exactly once in the current file (or in the pending proposal if one exists); add surrounding context if it doesn't. The edit is staged at proposed/. |
| append_toA | Append content to the end of a page. If the page doesn't exist, it's created. If a pending proposal exists for the path, the append stacks on top of it. Result is staged at proposed/. If the user asks for final proposed content, read proposed/ after appending instead of inferring. |
| propose_compile_from_rawA | Compile a supported source file (.adoc, .asciidoc, .conf, .csv, .docx, .eml, .epub, .htm, .html, .ini, .json, .log, .markdown, .md, .mdx, .odp, .ods, .odt, .org, .ott, .pdf, .pptx, .rst, .rtf, .srt, .tex, .text, .toml, .tsv, .txt, .vtt, .xlsm, .xlsx, .xml, .yaml, .yml) into a wiki source page proposal staged at proposed/. IMPORTANT — produce a knowledge artifact, not a topic recap. The page you stage is the substrate the user (and future Claude sessions) will retrieve from. Thin pages = thin retrieval. Before calling, call get_vault_context to know which entity slugs and active project slugs to wikilink, and which semantic tags are already in use. For a meeting/call/transcript: pick content-specific H2 headings that reflect what was actually discussed (e.g. 'Practice Overview', 'Service Philosophy', 'Succession Status' — NOT 'Summary' / 'Bullets' / 'Takeaways'). Quote verbatim where the exact phrasing matters. Wikilink every entity using slugs from get_vault_context. Include a relevanceCallout naming the active projects/decisions this source bears on. Surface 2-4 concrete applications. For a synthesis page (pageType='synthesis'): pass the source URLs as For a concept page (pageType='concept'): structure as snapshot + context + source log. Legacy callers can still pass |
| margins_doctorA | Diagnose the vault's health. Returns a structured report of issues: orphan source pages (raw_file points to a missing file), tracker drift (source pages without tracker rows, or tracker rows for missing sources), files with malformed frontmatter, and large raw files. Read-only — never modifies the vault. Use when the user asks 'is anything broken?', 'check my vault', or before major operations. |
| list_unprocessedA | List vault files that have not yet been compiled into a wiki source page. Files can live anywhere in the vault (raw/ is conventional but not required) — detection works on raw_file: frontmatter, not folder placement. Use this when the user asks 'what haven't I filed yet?' or before a compile pass. Each item is a vault-relative path you can pass directly to propose_compile_from_raw. |
| list_proposalsA | List pending proposals with optional filtering. Each entry has proposal path, destination path, whether accepting overwrites an existing vault file, size, and (for overwrites under default settings) a small first-diff preview. Use the pattern filter to scope to a folder or file shape when the queue is large. |
| resolve_proposalA | Accept or reject pending proposals. Two modes: (1) single — pass |
| margins_reset_proposalsA | Clear all pending proposals from proposed/. Use when proposals have accumulated from failed Claude sessions, or when the user wants a clean slate. Returns the number of files that would be deleted. Requires confirm=true to actually delete — without confirm, returns a dry-run list. Vault files are never touched; only files under proposed/. |
| searchB | ChatGPT Deep Research search. Returns a list of {id, title, url} where id is the vault path. Pair with fetch. |
| fetchB | ChatGPT Deep Research fetch. Returns {id, title, text, url, metadata} for the given vault path. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/cflorczyk9/Margins'
If you have feedback or need assistance with the MCP directory API, please join our Discord server