Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
METIS_DOCKERNoSet to 1 when running in the Docker/Glama introspection environment.
METIS_RC_ROOTNoPath to the Research Cortex root inside the container.
ANTHROPIC_API_KEYNoAnthropic API key for unattended automation (morning scan, brief generation). Not required for interactive use with a Claude subscription.
METIS_TOOL_SUBSETSNoSet to 0 to expose all tools (needed for introspection).

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
get_agent_contextA

Load an agent's system prompt and contract from the RC.

Reads system-prompt.md and contract.md from agents/{agent_slug}/.
If the agent is not found, lists all available agents.

Args:
    agent_slug: Folder name of the agent (e.g. "archivist", "librarian").
log_agent_runA

Log a completed agent run to the database for audit and dashboard tracking.

Records that an agent did a piece of work so it appears in the dashboard's
Agents view and in get_agent_runs. Call it after writing an output file, per
the output contract. When a session_id is supplied it also writes a "result"
event to session_events, closing the loop for /metis pipeline calls.

Args:
    agent_slug: Slug of the agent that performed the work (e.g. "librarian").
    task_summary: Brief description of what the agent did.
    input_path: Path to the input file(s), if any (default empty string).
    output_path: Path to the output file(s) produced, if any (default empty).
    complexity: The run status stored in the `status` column — typically
        "completed", "partial", or "failed" (default "standard").
    input_tokens: Input tokens consumed, for cost tracking (default 0).
    output_tokens: Output tokens produced, for cost tracking (default 0).
    model: Model identifier used, e.g. "claude-sonnet-4-6" (default empty).
    session_id: Pipeline session ID from session_bootstrap(); when set, also
        records a result event in session_events (default empty string).

Returns:
    A confirmation message naming the agent and task that were logged.
get_agent_runsA

Retrieve recent agent run history from the database.

Returns the log of past agent work — what ran, when, its status, and token
usage — for the dashboard or for reviewing recent activity. These rows are
written by log_agent_run. Results come back newest first.

Args:
    limit: Maximum number of runs to return, newest first (default 10).
    since: ISO date or datetime string; only runs at or after this time are
        returned. Empty string (default) returns runs from all dates.
    agent_slug: Filter to a single agent by slug, e.g. "librarian" or
        "metis". Empty string (default) returns all agents.

Returns:
    A text block listing the matching runs (run_id, agent, task summary,
    status, timestamp, token counts, model).
search_literatureA

Search the user's literature database.

Searches your curated/seeded literature catalogue by structured facets
(disease, method, geography, keyword). For your Zotero/manual reference
metadata use search_library; for full PDF body text use search_fulltext;
for semantic RAG over indexed PDFs use search_pdf_knowledge.

Searches the library_seeded SQLite table. Use this to find papers
by disease focus, methodology, geography, or any keyword.

Args:
    query: Search term, matched as a case-insensitive substring.
    field: Column to search -- one of "all", "disease", "method",
        "geography", or "article".
    limit: Maximum number of results to return (default 20).

Returns:
    A single TextContent holding a markdown table of matching rows from the
    library_seeded table, or an error/"no results" message if the database,
    table, or column is missing or nothing matches.
search_notesA

Search markdown notes across domains, projects, and library.

Case-insensitive substring search with surrounding context lines.

Args:
    query: Search term.
    scope: Where to search -- "all", "domains", "projects", "library".
    limit: Maximum results (default 15).
    max_chars_per_result: Truncate each result's context to this many characters (default 500).
                          Pass 0 for no truncation.
create_projectA

Register a new project in the Metis platform.

Called when a researcher confirms they want a Claude conversation or project
tracked permanently in Metis. Creates the project record in the DB so it
appears in the Work tab and is available for task linking and memory search.

Args:
    title: Human-readable project name, e.g. "Statistics Course".
    description: What this project is about (one sentence).
    domain: Research domain, e.g. "education", "epidemiology". Optional.
    source: Origin — "claude_project" (default), "claude_cowork", or "manual".
get_project_statusA

Status of your registered projects.

Reads the project REGISTRY (the `projects` table — the source of truth that
the dashboard Work tab shows), not just the folders on disk, and adds task
completion counts. Empty project_id lists ALL active projects; a specific
project_id (exact or partial) shows that one, enriched from its folder card
if a `projects/active/<name>/` folder exists.

Args:
    project_id: Project id (or part of one). Empty string = all active projects.
archive_projectA

Archive a project — marks it inactive but keeps all data.

Sets status='archived' in projects table. Project disappears from
active view but remains available for brainstorm context and search.

Args:
    project_id: The project_id to archive.
unarchive_projectA

Restore an archived project to active status.

Args:
    project_id: The project_id to restore.
remove_projectA

Remove a project from Metis entirely.

Deletes project record and associated tasks from DB.
If delete_files=True, also deletes the external_path folder from disk
(only if path is within RC root — safety check enforced).

Args:
    project_id: The project_id to remove.
    delete_files: If True, delete the project folder from disk. Default False.
load_project_contextA

Load the full context block for a project — ready to paste into Claude.

Returns the project's context_doc, recent session history, and next step
formatted as a structured brief. Use this at the start of any work session
on a specific project so Claude has full background.

Args:
    project_id: The project slug (e.g. "hat-dashboard", "article-1").
update_project_memoryA

Append a session summary to a project's history and refresh its prompt memory.

Call this at the end of any work session on a project. The history feeds
into load_project_context() so future sessions automatically know what
happened before.

Args:
    project_id: The project slug.
    what_was_done: 1-3 sentence summary of what was accomplished this session.
    next_steps: Optional: what needs to happen next. Updates the next_step field.
detect_projectsA

Scan a folder for unregistered git repos and article folders.

Useful for onboarding — finds existing project folders that are not yet
tracked in Metis. Call create_project() for each item you want to register.

Args:
    scan_path: Absolute path to scan. Defaults to the parent of METIS_RC_ROOT.
save_reviewA

Save an agent's output as a review file and record the run.

This is the standard way a Metis agent persists its work: it writes the
markdown to outputs/reviews/{agent_slug}/{date}_{task_slug}.md and, by
default, logs the run so the dashboard's Agents tab tracks it. Use it at the
end of any substantive agent task so the result is filed and discoverable.

Args:
    agent_slug: Slug of the agent that produced the review
        (e.g. "epidemiologist", "writing-partner").
    task_slug: Short kebab-case slug identifying the task; becomes part of
        the filename (e.g. "article1-methodology").
    content: The full review content as markdown.
    log_run: Whether to also record this as an agent run for the dashboard.
        Defaults to True.

Returns:
    A confirmation with the path of the saved review file.
get_tasksA

Query tasks from the SQLite database with optional filters.

Args:
    status: Filter by status -- "open", "done", "blocked", or "" for all.
    project_id: Filter by project. Empty = all projects.
    owner: Filter by owner. Empty = all owners.
    limit: Maximum results (default 25).
create_taskA

Create a new task in the SQLite database.

Args:
    title: Short task description.
    project_id: Which project this task belongs to.
    owner: Who is responsible (default "Metis").
    notes: Additional details or context.
    due_date: Optional due date in YYYY-MM-DD format.
    recurrence: Optional repeat — "daily", "weekly", "monthly", or "yearly".
                When a recurring task is completed, the next occurrence is created automatically.
    parent_task_id: Optional parent task — set this to make this a subtask.
update_taskA

Update an existing task — its status, title, owner, notes, due date, or recurrence.

The companion to create_task and get_tasks: use this to mark a task done or
blocked, reschedule it, reassign it, or edit its details. Only the fields you
pass are changed; empty arguments leave the existing value untouched. Marking
a recurring task "done" automatically creates its next occurrence. Find a
task_id with get_tasks; use delete_task to remove a task entirely.

Args:
    task_id: ID of the task to update (as shown by get_tasks). Required.
    status: New status — "open", "done", or "blocked". Empty = unchanged.
    title: New title. Empty = unchanged.
    owner: New owner. Empty = unchanged.
    notes: New notes/details. Empty = unchanged.
    due_date: New due date in "YYYY-MM-DD" format. Empty = unchanged.
    recurrence: New repeat — "daily", "weekly", "monthly", or "yearly".
        Empty = unchanged; pass "none" to clear an existing recurrence.

Returns:
    A confirmation listing the changed fields (and the next-occurrence id if a
    recurring task was completed), or a note if the task_id was not found.
delete_taskA

Permanently delete a task from the database.

The destructive complement to create_task — removes the task row entirely.
Use this for tasks created in error or no longer relevant; to instead mark
work finished (and continue a recurring series), use update_task with
status="done". Find the task_id with get_tasks. This cannot be undone.

Args:
    task_id: ID of the task to delete (as shown by get_tasks). Required.

Returns:
    A confirmation that the task was deleted, or a note if no task with that
    id exists.
capture_ideaA

Store an idea in the SQLite ideas table.

Auto-extracts tags from content. Links to domains/projects if keywords match.
Unless `auto_cross_pollinate=False`, automatically surfaces up to 5 cross-
pollination matches from library / meetings / news / older ideas in the same
response — so the user sees connections without a second tool call.

Args:
    content: The idea text.
    source: Where the idea came from (default "manual").
    image_path: Optional path to an associated image.
    auto_cross_pollinate: When True (default), include connection matches in the response.
get_ideasA

List captured ideas from your knowledge base, newest first.

Use this to review what you've been thinking about over a chosen time
window — the ideas you logged with capture_idea — so you can revisit,
connect, or act on them. Pairs with capture_idea (to add) and
cross_pollinate (to surface related work).

Args:
    scope: Time window to retrieve. One of "today", "week" (last 7 days),
        "month" (last 30 days), or "all". Defaults to "week".
    limit: Maximum number of ideas to return, newest first. Defaults to 20.

Returns:
    A formatted list of matching ideas with their timestamps and tags, or a
    friendly note if none were found in that window.
add_journal_entryA

Store a journal entry with auto-extracted mood and energy.

Args:
    content: The journal entry text.
    image_path: Optional path to an associated image.
daily_noteA

Append to (or read) today's daily note — one rolling note per day.

Unlike add_journal_entry (which creates a new row each time), daily_note
keeps a single entry per calendar day and appends timestamped lines to it —
the Reflect/Tana "daily note" pattern for fast, low-friction capture.

Args:
    text: Line to append. Leave empty to just read today's note so far.
get_journalA

List journal entries from your knowledge base, newest first.

Use this to look back over your dated journal/log entries — reflections,
progress notes, and session handoffs — optionally from a given start date.
Helpful for "what was I working on lately?" and for rebuilding context at
the start of a session.

Args:
    date_from: Earliest entry date to include, as "YYYY-MM-DD". Empty
        string (the default) applies no date filter and returns the most
        recent entries.
    limit: Maximum number of entries to return, newest first. Defaults to 10.

Returns:
    A formatted list of journal entries with their dates, or a note if none
    match.
get_contactsA

Retrieve all contacts from the contacts table.

update_contactA

Add or update a contact record.

Args:
    name: Contact's full name (used as unique key).
    notes: Notes about this contact.
    role: Contact's role or affiliation.
    birthday: Birthday in YYYY-MM-DD format.
get_glossaryA

Retrieve all glossary terms.

add_glossary_termA

Add a glossary term, or update its definition if it already exists.

Maintains a personal glossary of field-specific terms and acronyms so
Metis can give consistent definitions across sessions. Upserts on the
term (an existing term keeps its created_at but takes the new definition).
Retrieve entries with get_glossary.

Args:
    term: The term, acronym, or phrase to define; serves as the unique key,
        so reusing an existing term overwrites its definition.
    definition: The definition text to store for this term.

Returns:
    A confirmation message naming the term that was added or updated.
find_connectionsA

Search library, meetings, and news for items related to given text.

Searches library_seeded, meetings, and news_briefs tables for related
content using keyword matching.

Args:
    content: Text snippet to find connections for.
    limit: Maximum results per source (default 5).
cross_pollinateA

Find cross-domain connections for given text.

Searches library_seeded, meetings, news_briefs, and ideas tables
for related items. Returns top 5 with source type, title, and snippet.

Args:
    content: Text to find cross-domain connections for.
assemble_brainstorm_contextA

Assemble context from multiple sources for brainstorming.

Gathers recent content from selected sources, respecting an 8000 char
limit per source. Returns assembled context string with source labels.

Args:
    sources: List of sources to include: "library", "meetings", "news", "ideas", "journal".
    date_filters: Optional dict with source-specific date filters, e.g. {"ideas": "2026-03-01"}.
check_data_safetyA

Scan content for PII patterns and classify sensitivity level.

Returns safety status, classification, and specific warnings.

Args:
    content: Text content to scan.
    file_path: Optional file path for context-based classification.
scan_tracked_filesA

Scan all tracked files and report which have changed since last scan.

Reads tracked_files table, checks actual file modification times,
and updates last_scanned timestamps.
add_tracked_fileA

Add a single file to the tracked-files list and start watching it.

Registers one file so Metis notices when it changes and can read it later
via read_file; tracked files surface on the dashboard's Planning tab. The
file's current modification time is recorded and watch is set on. Re-adding
an existing path updates it (and keeps the old label unless a new one is
given). To register a whole project at once, use connect_project_folder.

Args:
    path: Absolute path to the file to track; the file must exist or an
        error is returned.
    label: Optional category label for the file (default empty string);
        on re-add, an empty label leaves the existing label unchanged.

Returns:
    A confirmation message naming the tracked file (and its label, if any),
    or a "file not found" / error message.
connect_project_folderA

Register all relevant files in a project folder so Metis can read them.

Walks the folder recursively and adds every file with a recognised extension
(.R, .Rmd, .md, .py, .js, .ts, .sql, .json, .yaml, .qmd, .tex, .csv) to
the tracked_files table. Call this once per project; after that, use
read_file() to read any individual file.

Args:
    folder_path: Absolute path to the project root folder.
    label: Short label for all files from this project (e.g. "MLM Course").
    max_files: Safety limit — stop after registering this many files (default 200).
read_fileA

Read the content of a file and return it as text.

Works for any text file: R scripts, markdown, Python, JSON, CSV, etc.
The file does not need to be pre-registered in tracked_files.

Args:
    path: Absolute path to the file to read.
    max_chars: Maximum characters to return (default 8000). For large files,
               increase this or ask for a specific section.
list_folderA

List files in a folder.

Args:
    folder_path: Absolute path to the folder.
    pattern: Glob pattern to filter files (e.g. "*.R", "*.md"). Default: all files.
list_basketA

List files in the Metis basket (legacy & inspiration documents).

The basket is a flat holding area for any document kept as a reference for future work. The private/ subfolder is NEVER listed — it contains personal or patient data.

promote_basket_itemA

Move a basket item to a stable project folder (promote from basket to active storage).

Refuses to touch basket/private/ items.

Args:
    source_path: Absolute path to the file in basket/ to promote.
    target_path: Absolute destination path (file or folder).
remove_tracked_fileA

Stop tracking a file so Metis no longer watches it for changes.

Removes a single file from the tracked-files list (the files the dashboard
Planning tab scans for activity). Use this when a file is no longer relevant
or was added by mistake. The file on disk is never touched — only its
tracking record is deleted. The inverse of add_tracked_file.

Args:
    path: Absolute path of the file to stop tracking. Must match the path
        exactly as it was registered.

Returns:
    A confirmation that tracking stopped, or a note if the path was not in
    the tracking list.
generate_daily_insightA

Assemble recent activity into context for the daily insight.

Gathers the raw material for a "what's happening across your research"
digest: the last 7 days of agent_runs summaries, last 3 days of high-signal
news_briefs, last 14 days of meeting titles, and last 7 days of new library
additions. It stores a placeholder row in daily_insights; the Metis agent
does the actual synthesis from the returned context. Read the stored result
later with get_daily_insight.

Takes no arguments.

Returns:
    A text block of the assembled recent context (and the sources drawn on)
    for the agent to synthesize into a daily insight.
save_daily_briefA

Save a composed daily brief so the dashboard widget shows it.

This is the write-back half of the daily-brief round-trip. Claude Desktop (or
Claude Code) composes the brief from generate_daily_insight() context, then
calls this to upsert the finished prose into the daily_insights table — the
same table the dashboard's morning-brief widget reads via get_daily_insight().
Desktop and the dashboard share one database, so no files are involved: once
saved, the brief appears in the dashboard on next load.

Args:
    content: The finished daily-brief prose (markdown ok). Required.
    sources: Comma-separated list of what the brief drew on (optional).
    date: YYYY-MM-DD; empty = today.
    model: Model identifier that composed it, for provenance (optional).

Returns:
    Confirmation with the date saved and a pointer to the dashboard widget.
get_daily_insightA

Retrieve a stored daily insight.

Args:
    date: Date in YYYY-MM-DD format. Empty = today.
get_new_publicationsA

Retrieve new publications, optionally filtered by topic.

Args:
    topic: Filter by topic tag. Empty = all topics.
    limit: Maximum results (default 20).
    unread_only: If True, only return unread publications (default True).
mark_publications_readA

Mark new publications as read by their IDs.

Clears items from the "new publications" queue once the user has seen them,
stamping each with a read time so they stop resurfacing. Use the IDs
returned by get_new_publications.

Args:
    ids: List of new_publications row IDs to mark as read; an empty list is
        a no-op.

Returns:
    A confirmation message with the count of publications marked as read.
get_user_topicsA

Return all active topics from user_topics.

add_user_topicA

Add a topic to track for new publications.

Args:
    topic: Topic name (unique).
    description: Optional description of what to look for.
archive_library_itemA

Archive a library item (mark as no longer active but keep in DB).

Sets status='archived' in library_seeded table. Item stays available
for search and cross-pollination but disappears from default view.

Args:
    relative_path: The relative_path primary key in library_seeded table.
remove_library_itemA

Remove a library item from the Metis index, optionally deleting the file.

De-indexes a paper or document by deleting its row from library_seeded. By
default the file on disk is left untouched (index-only removal); set
delete_file=True to also delete the file, which is guarded so only paths
inside the PKM root can be removed. To hide rather than remove an item, use
archive_library_item instead.

Args:
    relative_path: The relative_path primary key identifying the row in the
        library_seeded table.
    delete_file: If True, also delete the underlying file from disk (subject
        to the within-PKM-root safety check); if False (default), only the
        index row is removed.

Returns:
    A confirmation message of what was removed, or a not-found / error
    message if the item or table is missing.
search_literature_extendedA

Search literature with optional inclusion of archived items.

Searches library_seeded table across basename, relevance_note, disease,
geography, method fields. By default excludes archived items.

Args:
    query: Search term.
    include_archived: Include items with status='archived'. Default False.
    limit: Max results. Default 20.
export_knowledge_markdownA

Export the library as a cross-linked Obsidian-style Markdown vault.

Writes one Markdown note per library item (YAML frontmatter + abstract) plus
an index, with [[wikilinks]] between items that share a tag — the
claude-obsidian / LLM-Wiki pattern. Gives you a portable, human-readable,
git-diffable view of the knowledge graph you can open in Obsidian. Read-only
on the database; writes only Markdown.

Args:
    out_dir: Destination folder. Default: outputs/knowledge-export/ under the RC root.
get_user_configA

Return the full Metis user configuration from user-config.yaml.

Returns the complete YAML content (research interests, data sensitivity,
specialist contexts, etc.). For a lightweight profile summary (name,
interests, news_topics), use get_user_profile() instead.
Creates the config file with defaults if it does not exist yet.
add_specialist_contextA

Add a specialist context to the user profile, or update it if it exists.

Specialist contexts tell Metis which domains the user works in so routing
and search can be tailored. This appends to specialist_contexts in
user-config.yaml (creating the file with defaults if absent); if a context
with the same name already exists, its description is updated instead of
duplicated. Related tools: toggle_context, list_contexts.

Args:
    name: Short label for the context, e.g. "Epidemiological dashboards";
        also the key used to detect and update an existing context.
    description: One or two sentences describing what this context covers.
    active_by_default: If True (default), the context is added to
        active_contexts immediately; if False, it is stored but left
        inactive (and removed from active_contexts if already present).

Returns:
    A confirmation message stating whether the context was added (and
    activated) or an existing one was updated.
toggle_contextA

Activate or deactivate a specialist context.

Args:
    name: Context name to toggle (must exist in specialist_contexts).
    active: True to activate, False to deactivate.
list_contextsA

List all user contexts (general + specialist) with active status.

write_user_configA

Write the full user-config.yaml produced by the first-run config wizard.

Merges the provided YAML into the existing config so that specialist_contexts
and active_contexts set by earlier tools are preserved.

Args:
    yaml_content: Complete YAML string as produced by the wizard (all sections).
write_user_preferencesA

Write user-preferences.json produced by the first-run config wizard.

Merges the provided JSON into any existing preferences so incremental wizard
saves do not overwrite earlier sections.

Args:
    json_content: JSON string with preference keys (news_topics, journals,
                  pubmed_query, openalex_query, theme, density, etc.).
ingest_ideas_documentA

Import an ideas document (Word/text/markdown) and capture each idea.

Reads the file, splits it into discrete items (paragraphs, bullet points,
or numbered items), and calls capture_idea() for each non-empty item.
Supports .txt, .md, and .docx files.

Args:
    file_path: Absolute or METIS_RC_ROOT-relative path to the ideas file.
remove_first_run_markerA

Delete the .first-run marker file to signal that the config wizard is complete.

Called at the end of the first-run wizard after all config files are written. Safe to call even if the marker does not exist.

generate_imageA

Generate an image using AI and save it to the PKM.

Saves to {pkm_root}/outputs/images/YYYY-MM-DD_[slug].png

Args:
    prompt: Description of the image to generate.
    backend: "gemini" (default) or "huggingface"
    model: "flash" (gemini-3.1-flash-preview-image-generation),
           "imagen" (imagen-4.0-generate-001),
           "flux" (FLUX.1-schnell via HuggingFace)
    width: Image width in pixels (default 1024).
    height: Image height in pixels (default 1024).
    output_filename: Optional custom filename (without extension).
list_generated_imagesA

List recently generated images in the PKM.

Reads from {pkm_root}/outputs/images/ directory.
Returns filename, date, and prompt (from JSON sidecar if present).

Args:
    limit: Maximum number of images to return (default 20, newest first).
record_thinking_eventA

Record one signal about how you think and work, to personalise Metis.

Each event is a small piece of evidence — you acted on a brainstorm, rated
an idea highly, flagged an agent's output — that feeds your evolving
"thinking profile". Over time these signals let Metis tailor its routing,
suggestions, and tone to your preferences. Call it whenever a meaningful
preference moment occurs; read the accumulated profile with
get_thinking_profile.

Args:
    event_type: The kind of signal. Must be one of: "brainstorm_acted_on",
        "brainstorm_ignored", "idea_rated_high", "idea_linked_project",
        "journal_revisited", "agent_output_accepted", "agent_output_flagged".
    source_type: Domain or category the signal belongs to (e.g. "biology").
        Optional; defaults to empty.
    content_id: ID of the related content record (idea, journal entry, etc.)
        if applicable. Optional; defaults to 0 (none).
    agent_slug: Agent identifier this signal relates to, used for the
        "agent_output_*" event types. Optional.
    context: Free-text note giving context for the event. Optional.

Returns:
    A confirmation that the signal was recorded, or an error listing the
    valid event types if an invalid one was supplied.
get_thinking_profileA

Read and return the current thinking profile from system/thinking-profile.yaml.

Falls back to default structure if the file does not exist.

update_thinking_profileA

Recompute and update the thinking profile from the last 90 days of events.

Computes:
- connection_preferences: acted-on rates per domain_pair (source_type)
- preferred_idea_sources: frequency of source_type in high-rated idea events
- agent_feedback: accepted/flagged rates per agent_slug

Writes updated system/thinking-profile.yaml. Safe to call multiple times.
reset_thinking_profileA

Clear all thinking_profile_events and reset thinking-profile.yaml to defaults.

This erases all recorded preference signals and restores the default profile.
propose_skill_improvementA

An agent proposes a change to its own skill file.

The proposal is queued for human review. The skill file is NOT modified
until the user calls approve_proposal().

Args:
    agent_slug: The agent's slug (e.g. 'librarian', 'writing-partner')
    proposed_content: The full proposed replacement content of the skill file
    rationale: Why this change is being proposed (1–3 sentences)

Returns:
    Confirmation with the proposal ID for the user to review
get_pending_proposalsA

List all skill improvement proposals awaiting review.

Returns proposals sorted by most recent first, with agent slug, rationale, and a diff summary (first 200 chars of proposed content).

approve_proposalA

Approve a pending skill improvement proposal and apply it.

Writes the proposed content to the agent's skill.md file and marks
the proposal as approved. Creates a backup of the current skill file first.

Args:
    proposal_id: The numeric ID from get_pending_proposals()
reject_proposalA

Reject a pending skill improvement proposal without applying it.

The skill file is not changed. The proposal is marked rejected with an
optional reason.

Args:
    proposal_id: The numeric ID from get_pending_proposals()
    reason: Optional note explaining why the proposal was rejected
write_reflexionA

Stage 11: Record an agent self-critique entry to the reflexion_log.

Called at the end of every agent run to capture experience: what worked,
what could be better, what context was missing, what tools were needed.
Entries are reviewed by the weekly Coach loop for self-improvement proposals.

Args:
    session_id: Pipeline session ID from session_bootstrap().
    agent_slug: Which agent is writing the reflexion (e.g. 'librarian').
    went_well: What went well in this run (1–2 sentences).
    could_improve: What could have been done better (1–2 sentences).
    missing_context: What context or data was unavailable but needed.
    tool_wishes: Tools or capabilities that would have helped.
transcribe_recordingA

Transcribe a meeting recording using Whisper.

Optionally applies speaker diarization with pyannote.audio if installed
and HF_TOKEN is set. Saves the transcript alongside the audio file and
updates the meetings table.

Args:
    recording_id: The meeting_id from the meetings table (shown in Meetings tab)

Returns:
    Transcript text (with speaker labels if diarization succeeded) and
    the path where it was saved.
search_memoryA

Search the memory palace by keyword.

Looks across Metis's long-term memory to recall past context — what was
decided, found, or noted before. It searches the memory_entries table
(title, summary, topics) and also greps journal/**/*.md files on disk, so
both structured memory and freeform journal notes are covered.

Args:
    query: Keyword or phrase to match against entry titles, summaries,
        topics, and journal note text.
    entry_type: Optional filter limiting results to one kind of entry —
        "session", "journal", "idea", "decision", or "topic". Empty string
        (default) searches all types.

Returns:
    A text block of matching memory entries and journal hits, or a message
    when nothing matches.
add_memory_entryA

Add a new memory entry to the memory palace.

Use this for a human-curated 'memory palace' note (title + summary + topics,
optionally saved as a markdown file). For machine/agent event logging use
store_episodic_memory; for a distilled concept/definition use
store_semantic_memory.

Inserts into the memory_entries table. If detail is provided, also writes
a markdown file under journal/{entry_type}s/.

Args:
    title: Short title for the entry.
    summary: One-paragraph summary, stored in the DB and shown in search.
    topics: Comma-separated topic tags, e.g. "metis-setup,mcp-server".
    entry_type: One of "session", "journal", "idea", "decision", or "topic".
    detail: Full markdown content for the optional .md file.
    computer: Hostname of the computer this entry is from (optional).

Returns:
    A single TextContent confirming the saved entry (title, generated ID,
    type, topics, and the markdown file path if one was written), or an
    error message if the database is missing or the write fails.
get_topic_memoryA

Return all memory entries tagged with a specific topic, newest first.

Args:
    topic: Topic tag to filter by (e.g. "metis-setup", "phd-research").
list_recent_memoryA

Return the n most recent memory entries (default 10).

Useful at the start of a session to recall what was last worked on.

Args:
    n: Number of entries to return (default 10).
session_bootstrapA

Stage 1: Find or create a session for the current computer.

Checks for an active session (same computer, last active within 2 hours).
If found: resumes it and returns the last 5 events.
If not: creates a new session and seeds context from recent memory.

Args:
    client: Which Claude client is calling ('code'|'chat'|'cowork'|'dashboard').
save_session_eventA

Stage 8: Persist one atomic event to session_events (write-through guarantee).

Call this after every tool call, file write, and classification decision.
Event types: 'turn' | 'tool_call' | 'result' | 'file_write' | 'redline' | 'classification'

Args:
    session_id: Session ID from session_bootstrap().
    event_type: Category of event being recorded.
    content: Event content (truncated to 2000 chars).
run_metisA

Master /metis entry point — runs the 11-stage pipeline and returns a routing decision.

Every /metis invocation passes through here. The pipeline:
  1. Bootstraps or resumes the session
  2. Classifies content (PUBLIC/INTERNAL/CONFIDENTIAL/SENSITIVE)
  3. Data Guardian: blocks SENSITIVE requests outright
  4. Cybersecurity: blocks prompt injection and suspicious URLs
  5. Parses intent and selects the appropriate agent(s)
  6. Allocates model and token budget
  7. Assembles minimum surgical context from memory
  8. Persists the turn to session_events
  9. Returns routing decision — agents execute and then call:
       save_session_event(..., 'result', output)
       log_agent_run(..., session_id=session_id)
       write_reflexion(session_id, agent_slug, ...)

Stages 10 (logging) and 11 (reflexion) are called by the executing agent
after completing their work.

Args:
    request: The researcher's request text.
    session_id: Existing session ID if resuming. Leave empty to auto-bootstrap.
    client: Which Claude client is calling ('code'|'chat'|'cowork'|'dashboard').
    max_turns: Maximum pipeline turns before graceful truncation (default 20).
store_episodic_memoryA

Store an event in episodic memory and index it for vector search.

Logs a time-stamped EVENT (something that happened) and indexes it for vector
search. For a distilled, timeless concept/definition use store_semantic_memory;
for a human-curated palace note use add_memory_entry.

Episodic memory is a chronological log of things that happened — ideas,
notes, papers read, tasks completed, agent runs.

Args:
    content: The text content of the event to remember.
    event_type: One of 'idea', 'note', 'task', 'paper', 'meeting', or
        'agent_run'.
    session_id: Current pipeline session ID (optional).
    metadata: JSON string with extra fields such as title, tags, or source.

Returns:
    A single TextContent confirming the stored event (its row id and type),
    or an error message if the database is missing, fastembed is not
    installed, or the write fails.
store_semantic_memoryA

Store a distilled knowledge node in semantic memory.

Stores a distilled CONCEPT/definition (timeless 'what I know'). For a
time-stamped event use store_episodic_memory; for a human-curated palace
note use add_memory_entry.

Semantic memory holds the 'what I know' layer — concepts, definitions,
and their relationships. Used by retrieval to surface relevant knowledge
without relying on raw event history.

Args:
    concept: Short name for the concept, e.g. 'RDT sensitivity' or
        'fAChE inhibition'.
    definition: A one-to-three-sentence definition or explanation.
    related_concepts: Comma-separated names of related concepts.
    source_type: Where this came from: 'paper', 'note', 'idea', or
        'user_defined'.
    source_id: ID of the source record, e.g. a paper DOI or idea_id.

Returns:
    A single TextContent confirming the stored node (its row id and concept
    name), or an error message if the database is missing, fastembed is not
    installed, or the write fails.
store_procedural_memoryA

Store a successful workflow pattern in procedural memory.

Procedural memory captures 'how to do things' — repeatable processes,
workflows that worked well, or step-by-step patterns for recurring tasks.

Args:
    procedure_name: Short name for this procedure (e.g. 'Domain literature search').
    steps: Markdown-formatted steps for the procedure.
    trigger_context: What situation should trigger using this procedure.
set_working_memoryA

Write a key/value pair to the current session's working memory.

Working memory is an ephemeral scratchpad — it persists for the session
but is not indexed for vector search. Use it for state that agents need
mid-pipeline (e.g. intermediate results, decisions made so far).

Args:
    session_id: Pipeline session ID from session_bootstrap().
    key: Variable name (e.g. 'current_article', 'user_intent').
    value: Value to store (any string, JSON, or text).
get_working_memoryA

Retrieve working memory for a session, or the most recent entries if no session given.

Args:
    session_id: Pipeline session ID. Leave empty to get the 20 most recent entries
                across all sessions.
semantic_searchA

Search across memory layers using vector similarity + keyword RRF fusion.

Searches your personal MEMORY layers (episodic/semantic/procedural — things
you or Metis recorded), NOT your document library. For documents/PDFs use
search_pdf_knowledge; for reference metadata use search_library.

Retrieval pipeline (M5.8):
1. Embed the query.
2. Run vector similarity search on each requested layer.
3. Run keyword LIKE search on each layer.
4. Fuse results using Reciprocal Rank Fusion (RRF, k=60).
5. Return top_k deduplicated results ranked by fused score.

Args:
    query: Natural language search query to embed and keyword-match.
    layers: Comma-separated memory layers to search, drawn from 'episodic',
        'semantic', and 'procedural'.
    top_k: Number of fused results to return (default 5).

Returns:
    A single TextContent listing the top fused results (layer, title, score,
    timestamp, and a content preview), or a "no results" / error message.
probe_tool_resultA

M5.7.1 — Probe external tool result for injection patterns.

Call this before inserting any externally-sourced content into agent context:
web scrapes, RSS items, PDF extracts, YouTube transcripts, GitHub readmes.

Args:
    content: The external content to probe.
    source_label: Human-readable label for logging (e.g., "PubMed abstract", "RSS item").

Returns:
    JSON with {probed_content, flagged, patterns_found}.
get_constitutionA

M5.7.3 — Load the Metis constitutional policy for agent context.

Returns a compact summary of behavioral rules appropriate for the
complexity level. Prepend to any agent's system context to enforce
shared policy across all agent types.

Args:
    level: 'quick' | 'standard' | 'deep' | 'chain'
validate_pipeline_stageA

M5.7.4 — Validate a sub-agent output before passing to the next pipeline stage.

Treats sub-agent output with the same suspicion as external tool output.
Rejects if any required keys are missing or empty.

Args:
    output_json: JSON string of the sub-agent output dict.
    required_keys: Comma-separated list of required keys (e.g., "title,summary,agent_slug").
_obsidian_vaultA

Resolve the configured Obsidian vault path, if one is set and valid.

Looks up the user's external Obsidian vault so note-indexing tools
(e.g. kg_index_notes) know where to read .md notes from. Checks the
METIS_OBSIDIAN_VAULT environment variable first, then the
integrations.obsidian_vault (or top-level obsidian_vault) key in
user-config.yaml.

Takes no arguments.

Returns:
    A Path to the vault directory if it is configured and exists on disk,
    otherwise None.
kg_pathsA

Find connection paths between two knowledge library notes via BFS.

Args:
    from_path: Relative path from knowledge/library/ (e.g. 'concepts/elimination-framework.md')
    to_path:   Target note path.
    max_hops:  Maximum path length (default 4).

Returns all paths found up to max_hops, ranked by length.
kg_communityA

Return the connected cluster around a given knowledge library note.

Performs BFS flood-fill from the given note up to `depth` hops,
returning all reachable notes grouped by distance. Useful for surfacing
related concepts when working on a specific topic.

Args:
    note_path: Relative path from knowledge/library/ (e.g. 'disease-areas/[condition].md')
    depth:     Maximum hop distance to explore (default 2).
start_spanA

Open a new tracing span. Returns the span_id to pass to end_span().

Args:
    name:       Human-readable span label (e.g. 'stage_1_bootstrap', 'tool:search_library').
    kind:       Span type — 'internal' | 'tool' | 'agent' | 'llm'. Default: 'internal'.
    session_id: Session identifier (from session_bootstrap). Optional.
    run_id:     FK to agent_runs.run_id. Optional.
    parent_id:  Parent span_id for nested spans. Optional.
    tags:       JSON string of extra key/value metadata. Optional.

Returns the span_id string — pass it to end_span() when the work is done.
end_spanA

Close an open span. Computes duration from start_ms to now.

Args:
    span_id: The span_id returned by start_span().
    status:  'ok' | 'error'. Default: 'ok'.
    error:   Error message if status='error'. Optional.

Returns a summary line: '{name} — {duration_ms}ms [{status}]'
log_spanA

Record a completed span in one call (no separate start/end needed).

Useful for logging retrospective timing data (e.g. 'that DB query took 42ms').

Args:
    name:        Span label.
    duration_ms: How long the work took in milliseconds.
    kind:        'internal' | 'tool' | 'agent' | 'llm'. Default: 'internal'.
    session_id:  Session identifier. Optional.
    run_id:      FK to agent_runs. Optional.
    parent_id:   Parent span_id. Optional.
    status:      'ok' | 'error'. Default: 'ok'.
    tags:        JSON string of metadata. Optional.

Returns the new span_id.
get_spansA

Fetch recent agent spans, optionally filtered by session or run.

Args:
    session_id: Filter to this session. Optional.
    run_id:     Filter to this agent_runs.run_id. Optional.
    limit:      Max rows to return. Default: 50.

Returns a JSON array of span objects.
anonymize_textA

Scrub PII from text and return anonymized version + replacement map.

Replaces:
  - Patient/case IDs        → [PARTICIPANT_001]
  - GPS coordinates         → [GPS_001]
  - Belgian national IDs    → [NID_001]
  - Email addresses         → [EMAIL_001]
  - Phone numbers           → [PHONE_001]
  - Name-like tokens (opt.) → [NAME_001]

Args:
    content:        Text to anonymize.
    mode:           'full' — replace; 'preview' — mark without replacing.
    replace_names:  Also replace CAPITALIZED name-like tokens (heuristic).

Returns JSON with keys 'anonymized' (str) and 'replacements' (dict).
scan_outgoingA

Output rail: check a drafted response for leaked PII before it's sent.

The output-side complement to the read-side hook. Agents call this on any
response that might contain individual-level data; it enforces the
constitution's no-pii-output rule. Returns a verdict, what was found, and a
masked version safe to send.

Args:
    text: The drafted response text to check.

Returns JSON: {safe: bool, found: {type: count}, masked: str}.
redact_data_fileA

Read a sensitive data file and return a REDACTED preview (masked values).

The redaction half of /safe-analysis: where check_data_safety only *detects*
sensitive data and the read-hook *asks*, this returns a masked version so an
approved read shares no raw identifiers. Sensitive columns (patient/case IDs,
names, GPS, etc.) are pseudonymised consistently — the same value always maps
to the same placeholder, so record linkage survives while identity does not.
PII patterns (emails, phones, IDs) are scrubbed from all remaining cells.

Local I/O only — nothing leaves the machine except the masked preview you see.

Args:
    path:     Absolute local path to a CSV/TSV/text data file.
    max_rows: Rows to include in the masked preview (default 20).

Returns JSON: redacted preview rows, the columns masked, and a per-type count.
diff_anonymizationA

Return a unified diff comparing original and anonymized text.

Args:
    original:   Original (pre-anonymization) text.
    anonymized: Anonymized text from anonymize_text().

Returns a plain unified-diff string suitable for display.
log_consent_eventA

Append a row to the consent_ledger table.

Call this whenever an agent processes data so there is an audit trail
of what was processed, when, and under what classification.

Args:
    action:              Short description — e.g. 'scan_document', 'anonymize_patient_data'.
    data_classification: 'PUBLIC' | 'INTERNAL' | 'CONFIDENTIAL' | 'SENSITIVE'.
    agent_slug:          Which agent performed the action.
    notes:               Free-text context.
    session_id:          Current session identifier.
get_consent_ledgerA

Retrieve recent consent events from the audit ledger.

Returns the data-handling consent trail — what data was approved or
classified, by which agent, and when — so you can review or report on how
sensitive data has been treated. Reads the consent_ledger that
log_consent_event writes to.

Args:
    limit: Number of most recent ledger rows to return, newest first
        (default 30).

Returns:
    A JSON text block listing the consent events (id, timestamp, action,
    data_classification, agent_slug, notes).
set_network_policyA

Set the current network access policy for all agents.

'strict'  — No internet access. Only local DB, files, and MCP tools.
'normal'  — Default. Librarian and News Radar may access allowed domains.
'offline' — Airplane mode. All external requests blocked.

Args:
    policy: One of 'strict' | 'normal' | 'offline'.

Prompts

Interactive templates invoked by user choice

NameDescription
metisDefault entry point. Routes your request to the right specialist agent(s), announces the routing, does the work, and logs it.
background-makerbackground, knowledge layer, RAG, index domain, build corpus, download papers, scrub, specialist context, topic layer, knowledge base, background-maker
biostatisticianR package development, simulation studies, sample size calculation, power analysis, statistical computing, Monte Carlo, parametric bootstrap, clinical trial design, dose-response, tolerance intervals, mixed models implementation, custom est…
builderbuild new app, MCP server, multi-agent workflow, orchestrate components, new project architecture, span datasets UI automation, multi-component creator, greenfield system
career-coachUse for career strategy, CV, applications, and professional positioning
content-harvesterInvoke the content-harvester agent.
course-builderbuild a course, create course, learning course, course end-to-end, course from scratch, course builder, course design, learning content, module design, build curriculum, e-learning, knowledge course, statistics course, methodology course, e…
criticVerify, challenge, check
cybersecurityURL validation, domain check, prompt injection, malicious content, security audit, internet threat, agent behavior audit, file integrity, threat intelligence, allowlist, blocklist, suspicious feed
dashboard-engineerdashboard tab, HTMX partial, FastAPI route, epidemiological indicator, surveillance dashboard, KPI panel, health indicator design, coverage gap, screening completeness, positivity rate, burden visualization, dashboard bug, blank panel, spin…
data-analystCSV, Excel, Stata, SPSS, tabular data, data profiling, missing values, outliers, duplicates, data cleaning, before-after comparison, local-only, no data leaves machine
data-guardianpatient data, PII, sensitive data, data classification, Excel file, medical data, data protection, GDPR, personal information, data transmission, prompt with data, data privacy, confidential
design-auditorInvoke the design-auditor agent.
dhis2-expertDHIS2 server administration, metadata configuration, tracker programs, analytics dashboards, app development, Web API, Android SDK, implementation strategy, disease surveillance systems, HMIS, OpenHIE, HL7 FHIR integration, DHIS2 Academy, c…
epidemiologistUse to challenge, audit, or design epi methods
frontend-designer-builderInvoke the frontend-designer-builder agent.
hr-talentcapability gap, agent quality flagged, task unmatched, propose new agent, team assessment, no agent matches, poor agent output, missing specialist, new domain, new tool type
learning-architectInvoke the learning-architect agent.
learning-coachUse for day-to-day learning guidance, spaced repetition, and skill practice
librarianUse to find, retrieve, or annotate research sources
meeting-memorymeeting notes, action items, meeting summary, transcription, decisions captured, follow-up tracking, meeting recap, briefing note, post-meeting, meeting extraction
memory-curatorUse to consolidate session history into permanent memory, retrieve past context before starting a task, or audit memory health
methods-coachstatistical method, regression, multilevel analysis, spatial statistics, Poisson, Bayesian, logistic regression, survival analysis, model selection, R code, sampling design, analytical approach, HPC, overdispersion, propensity score
news-aggregatorRSS feed, feed ingestion, news pipeline, aggregate news, feed parsing, news digest, automated news collection, feed monitoring, news deduplication, signal tagging
news-radarnews alert, global health signal, outbreak news, WHO announcement, surveillance update, policy shift, AI development, geopolitics, emerging signal, news briefing, health intelligence, current events relevant to work
phd-architectUse for PhD planning, thesis structure, and multi-article alignment
presentation-makerslide deck, presentation, PowerPoint, conference talk, briefing deck, one-pager, slide outline, speaker notes, visual summary, stakeholder presentation, narrative structure for slides
rc-builderUse when modifying Metis itself — the dashboard, MCP server, agents, or config
research-architectresearch structure, thesis structure, dissertation plan, article outline, research program, paper coherence, research narrative, PhD structure, conceptual gap, paper-to-thesis alignment, research trajectory, long-form research roadmap
software-engineerUse when writing, fixing, reviewing, or refactoring code
ux-engineerUI design, UX review, accessibility, design system, WCAG, layout, information architecture, color palette, typography, responsive design, dashboard design, component pattern, visual consistency, CSS
visualization-makerInvoke the visualization-maker agent.
writing-partnerUse to improve, edit, or check academic or professional writing
metis-onboardingSet up Metis for your field — background questionnaire, then build your knowledge layer
metis-morningMorning briefing — tasks, inbox, news, new papers, today's focus
safe-analysisAnalyse sensitive data without sending it — send code, not data
basketProcess the basket — classify dropped documents and file them into the right folders
research-modeLibrary-first answer, complemented from the web (with your OK), linked to your work
metis-researchStart/continue a research session on an article
metis-captureQuick-capture an idea, task, or note into Metis
metis-handoffGenerate a portable context handoff brief
metis-weeklyWeekly digest — ideas, papers, meetings, projects
metis-doctorHealth check — is Metis working on this computer?
metis-customizeMake Metis yours — change projects, look, tone, or anything

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

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/SVerITG/Metis'

If you have feedback or need assistance with the MCP directory API, please join our Discord server