← All Docs

MCP Tools Reference

The Lore MCP tools with parameters, descriptions, and usage examples.

Lore is the shared substrate for humans and agents on one team. Three memory primitives: sources (eternal evidence), briefs (compounding synthesis), procedures (how-we-do-things). Everything else — logs, open questions, entities, personal vs team scope — composes on top.

Lore exposes its tools via MCP. They fall into three categories: simple query tools (fast, cheap), project briefs (living synthesis), and agentic tools (multi-step, higher cost).

search

Semantic search across the knowledge base. Returns source summaries with relevance scores.

ParameterTypeRequiredDescription
querystringYesSearch query
projectstringNoFilter to specific project
source_typestringNoFilter by source type (e.g. "meeting", "slack")
content_typeenumNoFilter by content type (interview, meeting, conversation, document, note, analysis)
tagsstring[]NoFilter to sources matching ANY listed tag
tags_allstring[]NoFilter to sources matching ALL listed tags
entitiesstring[]NoFilter to sources mentioning ANY of these entities — UUIDs or canonical names
limitnumberNoMax results (default 10)
include_archivedbooleanNoInclude archived projects (default false)
modeenumNoSearch mode: hybrid (default), semantic, keyword, regex
sincestringNoOnly sources after this date. Accepts ISO dates, relative shorthand (7d, 2w, 1m), or natural language ("last week")
beforestringNoOnly sources before this date. Same formats as since
sortenumNoSort order: relevance (default) or recent (newest first). Auto-set to recent for temporal queries
capture_methodstringNoCapture-origin filter: exact match on the producer-stamped capture_method (e.g. voice_note_capture, browser_gmail)
app_bundle_idstringNoCapture-origin filter: exact match on the producer-stamped app_bundle_id (e.g. com.tinyspeck.slackmacgap)
corpus_classenumNoCorpus partition: signal (default), ambient, or any. Defaults to signal — ambient sources (terminal / observed-session scroll) stay out of results unless opted in.

Search modes:

  • hybrid (default) — Combines vector similarity + full-text search via RRF fusion. Best for most queries.
  • semantic — Vector similarity only. Use for conceptual queries where exact terms don't matter.
  • keyword — Full-text search only. Use for exact terms, identifiers, or proper nouns.
  • regex — Pattern matching in local files.

Temporal awareness: Queries with temporal language ("latest", "most recent", "last week") automatically boost recent sources and sort by date. Use since/before for explicit date filtering.

get_source

Retrieve full details of a source document by ID.

ParameterTypeRequiredDescription
source_idstringYesID of the source document
include_contentbooleanNoInclude full original content (default false)

Use after search returns a relevant source_id and you need the full document. The response includes an actor object ({ id, kind, name }) identifying who wrote the source, and an entities array ({ id, type, name }) of the people / companies / products / deals it mentions. When producer-stamped at capture, the response also carries capture_method, app_bundle_id, and app_name — the attribute-plane axes that describe how the source was observed. When the source sits in a workstream, the response carries the resolved workstream slug. When the source was auto-routed at ingest (the caller omitted project), the response carries routing_metadata — the raw JSONB record of the auto-router's decision (proposed project / tags / workstream, confidence, audience verdict, applied state).

list_sources

Browse all sources, optionally filtered by project, type, actor, or entity.

ParameterTypeRequiredDescription
projectstringNoFilter to specific project
source_typestringNoFilter by source type
content_typestringNoFilter by content type (e.g. "interview", "meeting", "document")
tagsstring[]NoFilter to sources matching ANY listed tag
tags_allstring[]NoFilter to sources matching ALL listed tags
entitiesstring[]NoFilter to sources mentioning ANY of these entities — UUIDs or names
actorstringNoFilter to sources written by a specific actor (by name)
kindstringNoFilter to sources written by human or agent actors
capture_methodstringNoCapture-origin filter: exact match on the producer-stamped capture_method
app_bundle_idstringNoCapture-origin filter: exact match on the producer-stamped app_bundle_id
corpus_classenumNoCorpus partition: signal (default), ambient, or any. Defaults to signal — ambient sources stay out of the listing unless opted in.
sincestringNoOnly sources created on or after this date (filters on created_at). Accepts ISO dates (2026-06-01), relative shorthand (7d, 2w, 3m), or natural language ("last week", "today"). When set, results are ordered newest-created-first within the window.
beforestringNoOnly sources created before this date (exclusive — a half-open [since, before) window with since). Same formats as since.
include_logsbooleanNoInclude log entries (default false)
limitnumberNoMax results (default 20)

Each returned source carries an actor object identifying who wrote it and, when present, an entities array of its entity mentions.

Date window: since/before filter on the source's creation date (the same field search filters on), as a half-open interval [since, before)before is exclusive. An unparseable date returns an error rather than silently ignoring the filter. For "what happened across the whole substrate in a window" (sources + logs + ambient + question lifecycle, not just sources), use timeline instead.

list_projects

List all projects with source counts and latest activity dates. Takes no parameters.

list_entities

Browse the entity registry — the thin people / companies / products / deals bridge layer. Entities are resolved automatically as content is ingested; they carry stable IDs, external IDs, and mention counts, but no brief (they are a bridge layer, not a synthesis unit).

ParameterTypeRequiredDescription
entity_typeenumNoFilter to person | company | product | deal
searchstringNoSubstring match against canonical / display name
include_archivedbooleanNoInclude archived (merged-away) entities (default false)
limitnumberNoMax results (default 100)

get_entity

Get one entity plus the sources that mention it — the "everything about X" aggregation.

ParameterTypeRequiredDescription
entity_idstringNoThe entity UUID — pass when you have an id from list_entities or a source's entities[]. Either entity_id or name is required; entity_id wins when both are passed.
namestringNoCanonical name (workspace-scoped, case-insensitive). Resolves against the active workspace's entity registry — useful when you have the display name in hand from a brief or search snippet and would otherwise have to call list_entities first.
include_sourcesbooleanNoInclude the sources that mention this entity (default true)
sources_limitnumberNoMax sources to return (default 50)

For synthesis about an entity, scope search / research by the entities filter rather than reading get_entity — entities deliberately carry no brief.

get_brief

Get the living project brief — a continuously-updated synthesis of all knowledge in a project. Returns the current state, key evidence with citations, open questions, and project trajectory.

ParameterTypeRequiredDescription
projectstringYesProject name
scopestringNoproject (default), workstream, or workspace
workstreamstringNoWorkstream slug — required when scope is workstream
sectionstringNoFetch a single addressable section instead of the whole brief: current_state, open_questions, key_evidence, trajectory, or recent_changes
include_historybooleanNoInclude version history metadata (default false)

Start here when working on a project. The brief gives you immediate context without searching from scratch. Returns staleness info — if new sources have been added since the brief was generated, it tells you how many.

Briefs auto-update when material content is ingested into the project (debounced 60s for projects, 30s for workstreams) so they stay current without manual intervention. You can also manually refresh via lore brief generate <project> in the CLI. If a regen produces content identical to the previous version, the new version is dropped — the history chain stays dense with signal.

Briefs are made of five typed sections. Pass section to fetch just one — the response carries that section's content plus its per-section metadata: a content hash, a section_version that carries forward unchanged across regens that didn't touch the section, a generated_at, and per-section staleness. An agent that only needs "what's open" can fetch open_questions alone instead of parsing the whole brief.

The open_questions section is a rendered view of the scoped open_question objects, not synthesized prose. The brief synthesizer extracts candidate questions and files them (reconciling against questions already filed, so nothing duplicates); the section is then computed at read time from the live open questions for the scope — resolving or dismissing a question drops it from the section on the next read with no brief regen. The get_brief response (and each layer of get_brief_stack) carries open_question_items — the full objects (ids, bodies, citations, lifecycle status) — alongside the rendered title list, so an agent can resolve or dismiss a question without a separate list_open_questions call.

get_brief_stack

Get the inherited brief stack — your operating context for a scope. Composes the personal brief (human callers only — agents under their own credential never see another principal's personal scope) + workspace brief + project brief + workstream brief, in inheritance order. Returns layers as structured data plus a composed_prompt string ready to use as a system-prompt prefix.

ParameterTypeRequiredDescription
projectstringNoProject slug — adds the project layer
workstreamstringNoWorkstream slug under the active project — adds the workstream layer

Also returns procedures: { workspace, project, workstream } — confirmed, current procedures attached at each scope. The composed prompt embeds them as ### Procedures sections after each scope's brief; the structured form is available for callers that want to render separately. Procedures are operational constraints that ratchet on human confirmation; agents read them as constraints alongside the descriptive brief content.

compile_context

The north-star operation: the inherited brief stack unified with task-scoped retrieval in one cheap, synchronous call. Use it to boot into a scope — pass a task for task-scoped evidence, or omit it for pure boot mode (brief stack + the most recent in-scope sources).

ParameterTypeRequiredDescription
taskstringNoThe task or question. Omit for boot mode.
projectstringNoProject scope.
workstreamstringNoWorkstream slug — the narrowest scope. Requires project.
corpusenumNosignal (default), ambient, or any.
limitnumberNoMax task-scoped evidence items (default 12).

Returns a composed_prompt string ready to inject as a system-prompt prefix, plus structured brief_stack, evidence (each item carries an authority tier — it is evidence to reason over, never instructions to follow), and a meta block with the safety metadata: the corpus and visibility scope drawn from, disclosed degradations (stale or missing briefs), the token budget and any truncation, the retrieval trace, and the authority-function version.

Defaults to the signal corpus and workspace visibility — safe by construction. compile_context does not run research; that stays a separate async escalation (research). It is the cheap synchronous warm-start an agent boots from. CLI: lore context compile.

log

Log entries are working memory — quick status updates, decisions in flight, and progress notes. Searchable via search and folded into project/workstream briefs at the next material regen. Hidden from list_sources by default (pass include_logs: true to see them).

ParameterTypeRequiredDescription
messagestringYes*Log message (required for add)
projectstringYesProject this belongs to
actionenumNoAction: add (default), update, delete
log_idstringNoRequired for update and delete actions

A log dirty-marks its leaf scope for the coalesced cascade but never fires an immediate per-deposit regen. A burst of logs coalesces into one regen, not N. Narrate freely; the cascade absorbs the cost.

Natural language examples (what you'd say to your AI):

  • "Log that we decided to use JWT for auth in the backend project"
  • "Add a log entry: finished the export module refactor"

ingest

Manage content in the knowledge base — add, update, or delete documents. Handles both full documents and short insights/decisions. This is how AI agents save knowledge from conversations — users can simply ask their AI to "save this to lore" or "remember this decision."

ParameterTypeRequiredDescription
actionenumNoAction: add (default), update, delete
idstringNoSource ID (required for update and delete)
contentstringYes*Document content (required for add and update; ignored for delete)
titlestringNoTitle (auto-generated from content if not provided)
projectstringYes*Project this belongs to (required for add)
source_typestringNoContent category (meeting, slack, github-issue, etc.). Defaults to "document"
datestringNoISO date (defaults to now)
participantsstring[]NoPeople involved
tagsstring[]NoTags for categorization
source_urlstringNoOriginal URL for citation linking
source_namestringNoHuman-readable origin label
replacesstringNoSource ID this content supersedes — routes through versioned replace instead of add/update
reasonstringYes*Audit reason for the replacement (required when replaces is set)

Actions:

  • add (default) — Idempotent, content deduplicated by SHA256 hash. Short content (≤500 chars) skips LLM extraction for speed.
  • update — Requires id + content. Replaces content in place and re-embeds for search. Optionally updates title.
  • replace (versioned) — Pass replaces: <id> + reason instead of action. Creates a v2 in the source's version chain while v1 stays immutable, so the correction is auditable and citations resolve through the chain root. Tags and project/workstream routing inherit from the parent; title / source_type / source_url / source_name are optional overrides. Identical content returns a no-op; a stale parent (already superseded) returns a structured conflict with the current chain head. Prefer this over in-place update when correcting a settled fact a future agent should trust. The CLI mirror is lore ingest --replaces <id> --reason "…" — the fallback when MCP is unavailable.
  • delete — Requires id. Soft-deletes the source (recoverable via lore docs restore in the CLI). Blocklists the content hash to prevent re-sync.

Ingesting material content into a project with an existing brief automatically triggers a brief refresh (debounced 60s for projects, 30s for workstreams), keeping briefs up to date. log entries are excluded — they're working memory, folded in at the next material regen.

Response shape (cut 2.1): the success response always includes top-level visibility (workspace | personal) — agents auditing whether a write went team-public no longer have to scrape routing_decision. When a workstream resolved (via explicit workstream arg or a high-confidence auto-route), the response also includes the resolved workstream slug at top level.

Entity resolution: on add, Lore resolves the people / companies / products / deals named in the content against the workspace entity registry and returns the result as entity_mentions. High-confidence matches attach an existing entity; unmatched names create a new one; ambiguous names are surfaced (not attached) for you to confirm via lore entities merge. The bias is deliberately toward under-merging — a stray new entity is cheap, a wrong merge is corrosive.

Natural language examples (what you'd say to your AI):

  • "Save this architecture decision to lore under the backend project"
  • "Ingest these meeting notes — project is product, participants are Sarah and Mike"
  • "Remember that we chose JWT over sessions for mobile compatibility"
  • "Update that document with Chris's response"ingest(action: "update", id: "...", content: "...")
  • "That buyer-count figure was wrong — fix it on the source"ingest(replaces: "...", reason: "...", content: "...")
  • "Delete that old draft from lore"ingest(action: "delete", id: "...")

list_procedures

Browse procedural-memory rows — scope-attached "how this team acts" records (release cadences, onboarding playbooks, review checklists). Distinct from briefs (which describe what's true); procedures prescribe action.

ParameterTypeRequiredDescription
scope_kindenumNoworkspace | project | workstream
scope_idstringNoProject / workstream row id (omit for workspace scope)
statusenumNoproposed | confirmed | superseded | archived
include_non_currentbooleanNoWhen true, returns full version history; default returns only current heads of supersede chains

Use this to discover ids, then get_procedure for the full body + version chain.

get_procedure

Return one procedure plus its supersede-chain summary: the full row (title, body, status, version, attribution, source_ids) and a chain array walking the version history root → head. MCP takes the row id only; use list_procedures to discover ids.

propose_procedure

Propose a procedure (status='proposed'). Any actor (human or agent) can propose; a human ratchets it to confirmed via confirm_procedure. This is the "I noticed something repeatable about how we work" deposit path — the third deposit kind alongside log (narration) and ingest (artifact).

ParameterTypeRequiredDescription
workspace_idstringYesWorkspace row id
scope_kindenumYesworkspace | project | workstream
scope_idstringNoProject / workstream row id (omit for workspace scope)
titlestringYesShort label
bodystringYesMarkdown body, intended to read as an agent constraint
source_idsstring[]NoSupporting source row ids

Returns the inserted row. Proposed rows stay out of the inherited brief stack until a human confirms — propose freely without binding the team.

confirm_procedure

Ratchet a proposed procedure to confirmed.

This tool rejects agent callers by design. Confirmation is the substrate's ratchet — only humans bind operational constraints; agents propose. Agents running under their own credential receive a clear refusal; agents running under a human's credential inherit that human's confirm power. Idempotent on already-confirmed rows; errors on superseded / archived rows.

supersede_procedure

Write a new version of a confirmed procedure. The prior version flips to is_current=false, status='superseded'; the new version becomes the head with version+1. Optional new_title and new_source_ids — omit to inherit prior values.

This tool rejects agent callers by design — superseding a confirmed procedure is a ratchet-equivalent act.

dismiss_procedure

Dismiss a proposed procedure (terminal status='archived'). Humans may dismiss any proposed row in their workspace; agents may dismiss only proposals they themselves authored — they clean up their own residue but cannot discard another principal's contribution. Errors on confirmed / superseded / archived rows (use lore procedures archive for confirmed rows); idempotent on already-archived rows.

list_open_questions

Browse open questions — the open_question epistemic-item primitive: scoped, cited, lifecycle-bearing units of unresolved knowledge-state. Distinct from procedures (which prescribe action) and briefs (which describe what's true) — an open question tracks what is not yet known.

ParameterTypeRequiredDescription
scope_kindenumNoworkspace | project | workstream
scope_idstringNoProject / workstream row id (omit for workspace scope)
statusenumNoopen | answered | dismissed
visibilityenumNoworkspace | personal
limitnumberNoMax results

Use this to discover ids, then get_open_question for the full body + lifecycle log.

get_open_question

Return one open question — the full row (title, body, citations, status, scope, visibility, attribution) plus its append-only lifecycle_events log (each entry { at, actor_id, from, to }). MCP takes the row id only.

file_open_question

File a new open question (status='open'). Any actor — human or agent — files and resolves open questions; there is no ratification gate (unlike confirm_procedure), because an open question is epistemic state, not normative state. This is the fourth deposit kind alongside log (narration), ingest (artifact), and propose_procedure (how-to).

ParameterTypeRequiredDescription
scope_kindenumYesworkspace | project | workstream
scope_idstringNoProject / workstream row id (omit for workspace scope)
titlestringYesThe question — atomic, not decomposed into sub-claims
bodystringNoOptional elaboration
citationsstring[]NoSupporting source row ids — the only outbound link type on an open question
visibilityenumNoworkspace | personal (scope-derived when omitted)
review_afterstringNoISO timestamp — a review deadline; a passed review_after makes the question stale on the attention surface

Returns the inserted row with its filing lifecycle event.

resolve_open_question

Resolve an open question (status → answered); appends a lifecycle event. Pass note to record the answer on that event. Any actor. Idempotent when already answered; errors when the question is dismissed (both are terminal — there is no reopen). A resolved question leaves the brief's open_questions rendered view on the next read.

dismiss_open_question

Dismiss an open question (status → dismissed) — no longer worth tracking; appends a lifecycle event. Pass note to record the dismissal reason on that event. Any actor. Idempotent when already dismissed; errors when the question is answered.

observe_principal

Deposit a behavioral observation about how the principal — the operator — works: a confirmed preference, a recurring pattern, a working-style trait. The observation lands as a private visibility='personal' source and folds into the operator's personal brief, so working style is learned once and inherited by every future agent instead of re-discovered per session. This is the fifth deposit kind alongside log (narration), ingest (artifact), propose_procedure (how-to), and file_open_question (open question).

Personal agents only. This writes into the operator's private personal scope — a session running under a workforce-agent credential is refused. Only a session under the operator's own credential may deposit. Near-identical re-deposits are deduplicated. No ratification gate (private, epistemic, about the person).

ParameterTypeRequiredDescription
observationstringYesA behavioral observation about how the principal works — one atomic claim
contextstringNoOptional — what work or moment in the session prompted the observation

research

Start a comprehensive research job. An internal agent iteratively searches, reads sources, cross-references findings, and synthesizes a research package with citations.

ParameterTypeRequiredDescription
taskstringYesResearch task description
projectstringNoFocus research on specific project
include_sourcesbooleanNoInclude source references (default true)
depthenumNoResearch depth: quick (~30-60s), standard (~1-2 min, default), deep (~4-8 min)

Async: Returns immediately with a job_id. Poll research_status to get results.

Depth control:

  • quick — 3-5 sources, ~30-60 seconds. Good for focused, specific questions.
  • standard (default) — 5-10 sources, ~1-2 minutes. Balanced thoroughness.
  • deep — Exhaustive search, ~4-8 minutes. Use for comprehensive audits or broad questions.

Cost: Makes multiple LLM calls internally. Use search for simple lookups.

research_status

Poll for research job results. Long-polls for up to 20 seconds before returning.

ParameterTypeRequiredDescription
job_idstringYesThe job_id returned by research

Returns an activity array showing what the agent is doing (searches, sources read, reasoning). When status is "complete", the full research package is in result.

attention

The attention surface — what needs action now. A union of cheap deterministic predicate-queries over tracked substrate state, never an LLM-ranked feed: every item is a predicate that fires every time its condition holds.

ParameterTypeRequiredDescription
limitnumberNoCap the number of items returned, applied after urgency ordering. Omit for all.

The predicates:

  • stale_open_question — an open question past its review_after date.
  • approaching_review — an open question due for review inside a near-future window.
  • failed_ingest — a file the sync quarantine is skipping (a poison-pill: malformed input, unparseable JSON, oversized content). Silent data loss until acted on.
  • expiring_ambient — an ambient observation inside its pre-expiry TTL window (the same rows lore ambient expiring lists).
  • stale_brief — a leaf brief that has drifted past the staleness threshold behind its scope (the same signal lore lint flags). Surfaced as an actionable prompt to trigger a regen.

The surface is visibility-filtered to the calling actor — a personal open question never surfaces to a team agent. Items are ordered into deterministic urgency tiers (overdue > due_soon > info); within a tier, soonest/most-overdue first, with ambient salience as the tiebreak.

Returns { generated_at, counts, items[] }. Each item carries { kind, id, title, detail, urgency, due_at, scope_label, salience } — use id + kind to route to the follow-up tool (resolve_open_question, get_source, …). An operator-run "chief of staff" agent polls this surface to know what to act on. Distinct from doctor (plumbing health) and lore lint (epistemic hygiene). CLI mirror: lore attention.

timeline

A deterministic, non-LLM substrate diff for a time window — every source, log, ambient observation, and open-question lifecycle event (filed / resolved / dismissed) that touched the substrate in the window, ordered by time and visibility-scoped to the caller. The one path that answers "what happened in window W" without unioning search, list_sources, ambient, and logs by hand.

Headline use: an agent persists its last-run timestamp and calls timeline(since: that_ts) at SessionStart to boot on the substrate diff since it last ran.

ParameterTypeRequiredDescription
sincestringNoLower bound. Window grammar (24h, 7d, 4w, 3mo) or an ISO-8601 timestamp (for an agent's exact last-run time).
beforestringNoUpper bound. Same grammar as since. Half-open window [since, before).
sortenumNoAxis: created | edited | indexed | touched. Default touched = max(indexed_at, edited_at).
corpusenumNosignal (default) | ambient | any.
visibilityenumNoworkspace (default) | personal | any. personal / any refuse agent callers (visibility ceiling — an agent never sees the operator's personal layer).
project / projects / workstreamstring / string[] / stringNoScope filters.
kindsstring[]NoRestrict to event kinds: source, log, ambient, question_filed, question_resolved, question_dismissed.
include_logsbooleanNoInclude log entries (default true).
limitnumberNoMax events (default 100, max 500).

Returns { generated_at, window, counts (per kind), events[], meta }. Each event carries { id, kind, at, title, scope_label, ... }. meta is the §9-invariant block: { truncated, total_in_window, visibility_scope, retrieval_path, degraded[] } — so a capped or stale read never silently reads as "nothing happened".

Use timeline before search when the question is "what happened recently" rather than "find content about X". For a single corpus's rows with a date filter (just sources), list_sources with since/before is the narrower tool. CLI mirror: lore timeline (which defaults corpus and visibility to any, since it runs as the human owner).

whoami

Identify the actor — human or agent — this MCP session is acting as. Takes no parameters.

Returns { id, kind, name, workspace, owner, home_workstream, resolved_via, last_seen_at, last_deposit_at }. kind is "human" or "agent". A human session resolves to that person's actor in the active workspace; an agent running under LORE_AGENT_TOKEN resolves to its own named identity.

last_deposit_at is the timestamp of this actor's most recent deposit across all three kinds — narration via log, artifact via ingest, or how-to-proposal via propose_procedure. It is null when the actor has never deposited. Use it as a "have I deposited yet this session?" check.

Rarely needed — every write is attributed automatically — but useful for an agent to announce itself or decide whether to reload its operating context. See the agent guide for the actor model.