Skip to content
Agentmart
Submit a tool

Meridian

Persistent memory, task coordination, and HITL queue for AI coding sessions.

Connector by ajc3xc · GitHub account verified by the MCP Registry

IndexedLicense unknownLocal (stdio)Remote (SSE)
Write a review

Install

Works with Claude Code, VS Code, Codex, Cursor, Windsurf, Claude Desktop. Read the repository before you give any tool access to your data.

npx agentmarket install connector/ajc3xc-meridian

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Remote endpoint

  • https://usemeridian.us/mcp/sse Remote (SSE)

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Persistent memory, task coordination, and HITL queue for AI coding sessions.

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this server can do and what it asks for, from its tool list and install config. Checked Oct 25, 2026.

Tools
203 read · 141 write · 19 delete · 70 not yet classified
Secrets
None asked for
Install scripts
Not scanned yet
Runs as
Node.js package

Tools by what they do 433

Read from the source code; the running server may list different tools.

Read 203 · Look things up without changing anything.

  • analyze_model_efficiency
  • analyze_sprint
  • answer_hitl
  • audit_caption_style
  • audit_cross_document_consistency
  • audit_document
  • audit_equation_contract
  • audit_equation_integrity
  • audit_equation_style
  • audit_figure_table_provenance
  • audit_heading_style
  • audit_manuscript_structure
Show 191 more tools
  • audit_reference_consistency
  • audit_table_style
  • batch_read
  • capture_research_finding
  • check_embedded_staleness
  • check_image_rights
  • check_release_render_gate
  • check_render_capability
  • check_section_style
  • check_staleness
  • classify_outputs
  • compare_equation_structures
  • compare_proposal_versions
  • complete_research_run
  • document_outline
  • extract_equations
  • extract_paragraph_images
  • file_fingerprint
  • find_caption_paragraph
  • find_image_paragraph
  • find_orphaned_docx_staged_files
  • find_outputs_by_source
  • find_references_to
  • find_similar_equation
  • find_similar_figure
  • find_similar_table
  • find_stale_by_script
  • find_symbol_usages
  • flag_for_review
  • format_reference
  • get_agent_instructions
  • get_ai_log_export_status
  • get_artifact_sources
  • get_bibliography
  • get_blog_posts
  • get_cached_derived_variant
  • get_capability_manifest
  • get_citation_edges
  • get_commit
  • get_commits
  • get_connection_log
  • get_context_block
  • get_convergence_state
  • get_current_paper_contract_content
  • get_custom_hooks
  • get_deep_research_status
  • get_derived_cache_convergence_state
  • get_derived_cache_stats
  • get_document_review
  • get_document_structure
  • get_docx_document_lease
  • get_docx_region_claims
  • get_effective_capability_profile
  • get_effective_profile
  • get_equations
  • get_evidence_status_and_trusted_pointers
  • get_experiment
  • get_experiment_events
  • get_experiment_run
  • get_external_job
  • get_file_claims
  • get_findings
  • get_flag_drift
  • get_flag_registry
  • get_goal
  • get_graph_diff
  • get_hitl_request
  • get_insights
  • get_issue
  • get_journal_style_preset
  • get_journal_style_preset_provenance
  • get_latex_structure
  • get_live_claims
  • get_notes
  • get_paper_contract
  • get_paragraph
  • get_parallelizable_groups
  • get_pending_zotero_citations
  • get_pinned_decisions
  • get_planning_brief
  • get_plugin_details
  • get_profile_layer
  • get_profile_layer_revisions
  • get_project_by_name
  • get_project_state_milestones
  • get_proposal_gates
  • get_proposal_lineage
  • get_provenance
  • get_provenance_status
  • get_remote_task_status
  • get_research_run
  • get_run_manifest
  • get_section_content
  • get_server_log_checkpoint
  • get_server_logs
  • get_session_activity
  • get_session_brief
  • get_session_log
  • get_session_recovery
  • get_sessions
  • get_source_artifacts
  • get_sprint_item_pointers
  • get_sprint_items
  • get_sprint_notes
  • get_sprint_progress
  • get_structure
  • get_structure_elements
  • get_style_guide
  • get_symbol_claims
  • get_symbol_hotspots
  • get_tasks
  • get_tunnel_diagnostics
  • get_workflow_run_logs
  • get_workflow_runs
  • get_workspace_decisions
  • get_workspace_notes
  • get_workspace_proposals
  • get_workspace_settings
  • get_workspace_sprint_items
  • git_diff
  • github_search
  • idle_until_session_done
  • inspect_file
  • inspect_local_file
  • inspect_tabular_file
  • list_active_worktrees
  • list_branches
  • list_citation_keys
  • list_experiment_runs
  • list_experiments
  • list_external_jobs
  • list_files
  • list_hitl_requests
  • list_internal_notes
  • list_issues
  • list_journal_style_presets
  • list_local_snapshots
  • list_paper_contract_revisions
  • list_plugins
  • list_profile_layers
  • list_project_docs
  • list_projects
  • list_provenance
  • list_registered_artifacts
  • list_remote_tasks
  • list_render_receipts
  • list_research_runs
  • list_resumable_sessions
  • list_run_manifests
  • list_sessions
  • list_watchlist_queries
  • list_worktrees_pending_cleanup
  • load_handoff
  • lookup_citation_key
  • lookup_published_framing
  • npy_metadata
  • outline_tex
  • outline_tex_file
  • paper_search
  • parse_document
  • parse_provenance_envelope
  • plan_batch_transform
  • preview_proposal_promotion
  • promote_research_run
  • pull_doc_expanded
  • read_document_snapshot
  • read_file
  • read_note
  • reconcile_sprint_drift
  • refresh_tool_manifest
  • runpod_check_key
  • runpod_list_pods
  • scan_citation_keys
  • scan_stale_notes
  • search_ai_log
  • search_all
  • search_code
  • search_code_semantic
  • search_commits
  • search_document
  • search_logs
  • search_outputs
  • search_paragraphs
  • search_server_logs
  • search_synthesis
  • search_tasks
  • social_search
  • verify_artifact_hash
  • verify_docx_diff
  • verify_handoff_token
  • zotero_search

Write 141 · Create, change, send or run things.

  • accept_handoff
  • add_custom_hook
  • add_insight
  • add_note
  • add_proposal
  • add_proposal_gate
  • add_sprint_item
  • add_sprint_item_pointer
  • add_sprint_note
  • add_subtask
  • add_workspace_note
  • add_workspace_proposal
Show 129 more tools
  • add_workspace_sprint_item
  • annotate_outputs
  • append_text_run_after_math
  • apply_and_merge_batch_transform
  • apply_batch_transform
  • apply_prose_edit_packets
  • apply_reviewable_edit_transaction
  • apply_zotero_citation_edges
  • approve_paper_contract_revision
  • archive_decision
  • assign_sprint_waves
  • batch_mutate
  • bind_artifact_source_edge
  • build_prose_edit_packet
  • checkpoint
  • clone_profile_layer
  • commit_proposal_promotion
  • complete_experiment_run
  • complete_sprint_item
  • complete_task
  • complete_workspace_sprint_item
  • create_experiment
  • create_issue
  • create_paper_contract
  • create_paper_contract_revision
  • create_project
  • create_proposal_successor
  • edit_caption
  • edit_citation
  • edit_equation
  • execute_batch
  • fail_sprint_item
  • finalize_run_manifest
  • finalize_wave_run
  • highlight_document
  • index_document
  • insert_bibliography_entry
  • insert_caption
  • insert_citation
  • insert_column
  • insert_cross_reference
  • insert_equation
  • insert_figure_block
  • insert_highlighted_note
  • insert_image
  • insert_media_part
  • insert_table
  • link_proposal_lineage
  • mark_provenance_synced
  • merge_docx_draft
  • merge_project
  • merge_sprint_items
  • move_section
  • overleaf_login_status
  • patch_file
  • pin_decision
  • pin_workspace_decision
  • promote_experiment_run
  • push_sprint_item
  • put_cached_derived_variant
  • receive_messages
  • record_experiment_event
  • record_handoff_correction
  • record_provenance
  • register_artifact
  • register_docx_derivative
  • register_external_job
  • register_output_paths
  • register_run_artifact
  • register_session
  • register_session_recovery
  • release_claim
  • release_docx_document_lease
  • release_docx_region_claims
  • release_file
  • release_sprint_item_claim
  • release_task
  • relocate_figure
  • rename_project
  • reopen_proposal_gate
  • request_manual_issue_screening_toggle
  • resolve_artifact
  • resolve_citations
  • resolve_figure_output
  • resolve_proposal_gate
  • resolve_sprint_item_pointers
  • run_verification
  • save_blog_post
  • save_finding
  • save_profile_layer
  • save_user_journal_style_preset
  • save_watchlist_query
  • send_message
  • set_active_repo
  • set_agent_instructions
  • set_ai_log_export_config
  • set_capability_manifest
  • set_capability_profile
  • set_decision
  • set_executor_config
  • set_goal
  • set_north_star
  • set_parent_project
  • set_project_execution_mode
  • set_project_use_mode
  • set_sprint
  • skip_sprint_item
  • start_experiment_run
  • start_remote_task
  • start_research_run
  • start_run_manifest
  • start_session
  • start_wave_run
  • start_worker_session
  • store_finding
  • sync_bibliography
  • tag_output
  • transfer_sprint_item_claim
  • trigger_workflow
  • update_bibliography_entry
  • update_custom_hook
  • update_decision
  • update_external_job
  • update_md_section
  • update_paragraph
  • update_sprint_item
  • update_workspace_settings
  • update_workspace_sprint_item
  • write_section

Delete 19 · Delete, drop, revoke or wipe things.

  • clear_capability_profile
  • delete_custom_hook
  • delete_note
  • delete_sprint_item_pointer
  • delete_user_journal_style_preset
  • delete_watchlist_query
  • evict_derived_cache
  • invalidate_stale_derived_variants
  • move_workspace_note_to_project
  • purge_ai_log
  • remove_bibliography_entry
  • remove_caption
Show 7 more tools
  • remove_citation
  • remove_cross_reference
  • remove_equation
  • remove_package_part
  • remove_table
  • reset_plugin_override
  • reset_profile_layer

Not yet classified 70 · We could not tell from the name and description.

  • acquire_docx_document_lease
  • activate_profile_layer
  • advance_proposal_status
  • bind_artifact_provenance
  • claim_docx_region
  • claim_file
  • claim_node
  • claim_sprint_item
  • claim_task
  • complete_external_job
  • complete_wave_gate
  • configure_wave_gate
Show 58 more tools
  • copy_section
  • deep_research
  • dismiss_hitl
  • enqueue_claude_task
  • expand_section_aliases
  • export_ai_log
  • export_ai_log_artifacts
  • export_ai_log_otel
  • fan_out_sprint_items
  • generate_handoff
  • get_provenance_status_envelope
  • get_run_manifest_envelope
  • heartbeat
  • idle_until_all_done
  • index_document_structure
  • index_equation
  • index_equations
  • index_figure
  • index_project
  • index_table
  • ingest_document
  • ingest_document_structure
  • ingest_local_document
  • ingest_local_document_structure
  • invalidate_derived_variant
  • lease_document
  • link_figure_caption
  • link_flag_to_section
  • link_manual_github_issue
  • link_table_caption
  • lint_tex
  • lint_tex_file
  • locate_anchor
  • locate_anchors
  • log_task
  • promote_docx_candidate
  • promote_proposal
  • prospect_symbol
  • reconcile_legacy_artifact_outputs
  • reconcile_stale_claims
  • refresh_context
  • relocate_sprint_item_pointer
  • relocate_table
  • render_with_receipt
  • renumber_sequences
  • repair_equation_batch
  • request_hitl
  • resume_wave
  • retrofit_plaintext_captions
  • run_watchlist_query
  • script_content_hash
  • serialize_provenance_envelope
  • snapshot_document
  • snapshot_graph_metrics
  • split_cell
  • split_sprint_item
  • transpose_table
  • validate_assumption

Network hosts it talks to 1

  • usemeridian.us · found in remote endpoint, install command

Files it touches

  • Any path the agent passes to its tools

Tools (433)

Read from the source code; the running server may differ. Descriptions are the server’s own words; hidden characters are shown as [U+…].

  • accept_handoff

    Read-only: (1bd5e810) Canonical receiver-side acceptance check for a handoff envelope — composes token verification, capability/tool availability, tool-manifest drift, and board-revision divergence into ONE structured verdict, so MCP/HTTP/stdio all produce identical results for identical input (same underlying meridian.handoff.accept_handoff_envelope every transport calls). Every input is optional and independently gated — supply whatever you have; an omitted check is skipped, never failed. Returns {accepted: bool, result: 'ok'|'STALE_HANDOFF'|'FOREIGN_PROJECT_CONFIG'|'BOARD_DIVERGENCE'|'TOOL_…

  • acquire_docx_document_lease

    6507e83a — Whole-document cross-process lease for .docx files, the counterpart claim_docx_region never provided (that tool hard-requires a specific element_id). Use this when a session needs to rewrite an ENTIRE document (a bulk restructure, a canonical-merge promotion) and must block out every other writer, not just one element. Blocked by another live session's whole-file lock (claim_file) OR ANY other live session's claim on the file (lease or scoped element) — a whole-document lease requires the document be free of every other session's claims first. Once held, blocks every other session's…

  • activate_profile_layer

    0bec79a7 (PROFILE-5) — Advance a hosted_default layer's lifecycle to 'active' — the single 'publish' operation for the hosted_default floor (fae6e882 pinned decision collapsed 'publish' and 'activate' into this one tool: a hosted_default layer becomes authoritative the moment it reaches 'active', so there is no separate publish step to expose). Only a draft -> active or deprecated -> active transition is valid; any other current state (e.g. retired, which is terminal) rejects with {error}. Idempotent: calling on an already-active scope is a no-op success (same revision, no new audit row). See …

  • add_custom_hook

    273287cb — define a user-creatable Claude Code hook (PreToolUse | PostToolUse | Stop), generalizing past sprint_guard.sh/.ps1 (the only hook Meridian auto-writes today). Written into the repo's .claude/hooks/<slug>.sh / .ps1 on the next generate_handoff — the same auto-inject mechanism sprint_guard already uses. script_sh (POSIX shell body) is required; script_ps1 (PowerShell body) is optional — omit it to only ever write the .sh file. matcher is a Claude Code tool-name regex (e.g. "Edit|Write"), ignored for Stop hooks. blocking (default true) controls determinism vs. suggestion power: true wr…

  • add_insight

    Record a durable STRATEGIC INSIGHT — accumulated understanding that generates future decisions. A first-class knowledge type SEPARATE from decisions (choices with a lifecycle) and notes (reference). horizon sets its shelf-life: 'permanent' insights ALWAYS surface in get_planning_brief; 'year'/'quarter' are time-boxed. Returns the stored insight.

  • add_note

    Add a per-project wiki note (setup, gotcha, howto, env, ...). Free-form title/body; comma-separated tags optional. Optional kind (wiki=gotcha/rule/howto, insight=strategic/product analysis, reference=external/one-off docs, code=warning/context anchored to a file, document=ingested report/spec/thesis) controls how the dashboard renders it. For a code anchor pass kind='code' plus file_path (and optional symbol): the note is then surfaced automatically when a session calls claim_file/get_file_claims for that path, so the executor sees the warning before editing. Pass source (a URL or file path) t…

  • add_proposal

    Capture an idea into a proposal — PROJECT-SCOPED BY DEFAULT (a8afd8f9). This is the preferred entry point going forward; add_workspace_proposal remains available as the explicit workspace-global opt-in for cross-project ideas. Pass project_id (or project_name) to scope the proposal to that project, XOR pass scope='workspace' to explicitly opt into a workspace-global proposal instead — an ambiguous call (neither, or both) is rejected with an error rather than guessed. Like add_workspace_proposal, these are NOT executor-claimable; a human reviews and promotes them via promote_proposal. Proposals…

  • add_proposal_gate

    Raise a typed, lane-blocking HITL gate for a materially ambiguous decision — legal/IP, product scope, destructive operations, production deployment, human acceptance of a contradiction, or other materially ambiguous decisions (category must be one of: legal_ip, product_scope, destructive_ops, production_deploy, contradiction_acceptance, other_ambiguous). Always starts state='blocked' (fail-safe) with no decision yet — routine read-only decomposition and bounded fallback work never needs a gate. affected is a non-empty list of sprint_item_id strings and/or generic pointer objects ({source_type,…

  • add_sprint_item

    ALWAYS call get_sprint_items first to check for existing pending items before adding. Append a todo item to the project's sprint checklist. Use when starting work on a new version so the next session sees what's in flight. Optional: group items under a named objective with 'group'; attribute to a person with 'human_id'. Use 'depends_on' to block until another item finishes. Blocks near-duplicate titles (>=60% word overlap with an open pending/in_progress item) and returns the conflict; also warns (drift_warning) when the title looks already-shipped — 3+ keyword overlap with a migrations.py/_mi…

  • add_sprint_item_pointer

    2976e168 — attach a GENERIC POINTER to a sprint item: a portable, composable reference to a thing-in-a-source, grounded in LSP Location + W3C Web Annotation Selector composition. targets is an ARRAY of {uri, selector, subSelector?} objects (native multi-file, the LSP WorkspaceEdit pattern); the whole composite shape is stored as JSON, not per-domain columns. Every selector is an object with an explicit "type" PLUS that type's own field(s): • range — {"type":"range", "start_line":int, "end_line":int, "start_char"?:int, "end_char"?:int} (an LSP Range); the pointer IS the location. • symbol — {"t…

  • add_sprint_note

    Add an ephemeral note to the current session's scratch pad. Use for constraints, blockers, working assumptions valid only this session. Notes are auto-deleted when the session closes. Pass note_kind='thinking' for a thinking_sync (HOOKS_DEBUG_STATE) note: a structured snapshot of the reasoning state (what was tried, what failed, current confirmed state) that the dashboard renders with a distinct icon. Intended for Claude's client-side thinking_sync post-tool-call hook, which extracts the extended-thinking scratchpad and persists it here so debugging state survives across turns and into the nex…

  • add_subtask

    Add a child sprint item under an existing parent item. Inherits the parent's version. Status starts as pending. Rejects if the parent is already done, failed, or skipped. Pass owner='human' or owner='ai' to build a mixed-ownership task chain: owned subtasks added in sequence become a strict chain (each depends on the previous owned sibling), and completing one auto-advances ownership — an AI→human step files a HITL handoff, a human→AI step un-blocks the next AI subtask. The parent stays in_progress until all subtasks are terminal.

  • add_workspace_note

    Add a workspace-level wiki note that applies across ALL projects in this workspace (onboarding, cross-cutting conventions, shared infra). Unlike add_note, it is not tied to a project. Its body is NOT inlined by default: session start and get_context_block carry only a short index (a note count plus the titles of notes tagged policy or workspace-policy), and a handoff carries notes only when generate_handoff(mode="full") is requested explicitly. Read bodies with get_workspace_notes (tag="policy" for the policy-tagged ones); the operator setting include_workspace_context inlines them into sessio…

  • add_workspace_proposal

    Capture a workspace-level flash of insight into the 'drawer of inspiration' — cross-project ideas that don't belong to any one project yet. Unlike sprint items these are NOT executor-claimable; they require a human to review and promote them. Proposals start at status='raw' and progress through an enforced lifecycle: raw → investigating → promoted|rejected. Use advance_proposal_status to move through the lifecycle; use promote_proposal to convert one into a real sprint item.

  • add_workspace_sprint_item

    Add an item to the workspace-level personal backlog — a cross-project board NOT tied to any single project (track thesis + Meridian + personal goals in one view). Use the per-project add_sprint_item for project work instead. 'group' is the cross-project bucket the item lives under (e.g. 'thesis', 'meridian', 'personal'); 'human_id' assigns it to a person. New items start as 'todo'.

Show 418 more tools
  • advance_proposal_status

    Transition a workspace proposal through its lifecycle. Enforced transitions: raw → investigating|rejected; investigating → promoted|rejected|raw; rejected → raw. 'promoted' is a terminal status reachable only via promote_proposal (which also creates the sprint item). Returns the updated proposal.

  • analyze_model_efficiency

    0fba4cb6 — MECHANICAL (zero-token) model-tier suggestion for a task or sprint item. Deterministic, rule/heuristic classifier: NO model call, NO DB, NO network — it mirrors how the ultracode orchestration script spends zero model tokens on routing. Pass a task descriptor (any of title, description, file_count, files, touches_resources, size) and it returns a suggested tier: {tier: 'haiku'|'sonnet'|'opus', score, signals:[{signal, detail, weight}...], rationale, mode:'mechanical'}. Cheap-leaning signals (title keywords like 'typo'/'docstring'/'lint', 1 file, size 'xs'/'s') pull toward 'haiku'; e…

  • analyze_sprint

    PLANNING: Read-only synthesis of the current sprint into one structured brief — parallelizability (conflict-free groups + max fan-out), dependency chains (depends_on walked to the root), resource/file conflicts (items sharing touches_resources), and stalls (stall_count>0). Returns {summary, recommended_strategy, parallelism, dependency_chains, longest_chain, file_conflicts, stalls, blocked, running}. Call in planning sessions instead of stitching together get_parallelizable_groups + manual dependency/conflict analysis.

  • annotate_outputs

    Add or update a human annotation for a file or directory in the outputs tree. Stores the note in the local outputs index (DuckDB ``annotations`` table). Annotations are automatically surfaced alongside search hits -- no extra tool call needed. ``path`` may be: - The ``outputs_dir`` root (Tier 1 -- "what this entire run tree is for"). - Any sub-path (file or directory) within the tree (Tier 2 -- per-run or per-file context such as "PCA on, BFS off, overwritten 5x"). Args: outputs_dir: Absolute path to the outputs directory. path: File or directory path to annotate (withi…

  • answer_hitl

    Answer a pending HITL request programmatically. Marks it answered so the waiting session can resume. Use list_hitl_requests to find request IDs.

  • append_text_run_after_math

    Append a normal text run after an equation selected by stable paragraph id. When a paragraph contains multiple equations, math_index is required so the operation never guesses which equation should receive the text. session_id: 273df573 — identifies the calling Meridian session to the tunnel-layer DOCX region-claim guard (check_docs_write_conflict in meridian/routes/tunnel.py). Not forwarded to docs_intel; has no effect when this tool is invoked outside Meridian's tunnel (e.g. standalone `uvx meridian-docs`).

  • apply_and_merge_batch_transform

    982f8564 -- end-to-end declarative batch transform: plan -> apply to an isolated draft -> promote via merge_docx_draft's own merge_draft_into_canonical (existing, unmodified -- full structural + render verification, atomic backup and restore-on-failure). On any planning or apply failure, returns apply_batch_transform's own result verbatim -- canonical_path is never even opened for writing in that case. On a successful promotion, returns merge_draft_into_ canonical's own result PLUS a batch_receipt: ``{manifest_hash, source_fingerprint, operations_applied, draft_write_manifest_hash, draft_prom…

  • apply_batch_transform

    982f8564 -- apply a declarative batch of operations to an ISOLATED draft. document_path is opened read-only throughout and is never the write target -- draft_output_path is. ALL-OR-NOTHING: if planning finds even one stale/conflicted/invalid operation, NOTHING is written -- draft_output_path is never created or partially written, so a partial batch failure leaves document_path unchanged by construction. Operations are applied in a fixed, deterministic order (document position, tied-broken by op_id). Args: document_path: The document to transform. Read-only. operations: …

  • apply_prose_edit_packets

    4c992e91 -- re-resolve and apply a batch of build_prose_edit_packet packets to an ISOLATED draft. document_path is opened read-only throughout and is never the write target -- draft_output_path is. ALL-OR-NOTHING: every packet's anchor is re-resolved fresh against document_path's CURRENT content (the packet's own stored anchor/hashes are never trusted blindly); if even one packet fails re-resolution or drift-checking, NOTHING is written -- draft_output_path is never created or partially written. Drift is rejected with one of two distinguishable reasons: "context_hash_mismatch" (this anchor's…

  • apply_reviewable_edit_transaction

    0d62f067 (BE4ED581-W2) -- batch staged prose replacements and/or section/table/figure relocations into ONE all-or-nothing writer transaction, then promote to canonical_path exactly once. canonical_path is opened READ-ONLY for the first step and is NEVER a write target anywhere in this call except inside the final promotion (merge_draft_into_canonical's own atomic stage/verify/backup-restore). Each subsequent step chains onto the PREVIOUS step's own isolated draft inside draft_dir -- docx_path=draft_(n-1) -> draft_output_path=draft_n -- so canonical_path and every earlier draft stay untouched …

  • apply_zotero_citation_edges

    Apply workstation-resolved Zotero items to existing citation markers. The hosted handler revalidates every marker id/ref within project_id before writing through DocStore. This accepts no attachment bytes, local paths, or credentials; attachment provenance stays local.

  • approve_paper_contract_revision

    7c96d41b — the human-approval gate: pin revision_id as its contract's binding current_revision_id, the one snapshot an editorial session should treat as authoritative from now on. Requires a non-empty approved_by_human_id — an unattributed approval would defeat the point of the gate, so only call this with a real human identity/name that actually signed off (e.g. in chat), never a placeholder. Supersedes the contract's previously-approved revision, if any, and flips the contract's status to 'active'. Idempotent when the revision is already approved (no-op success); rejects {error} when the rev…

  • archive_decision

    Archive a pinned decision by id. Soft-deletes to preserve the audit trail. Use when something was filed by mistake or is a duplicate. For retiring a valid but superseded decision, prefer update_decision(status=superseded).

  • assign_sprint_waves

    58a45b92 — PERSIST the parallel grouping: writes the conflict-free batches get_parallelizable_groups computes onto each eligible item's stored `wave` field (group i -> 'wave-{i+1}'), so parallelism becomes deterministic and inspectable (get_sprint_items surfaces `wave`) instead of recomputed every call. Only currently-eligible items (pending/todo, dependency-satisfied, unclaimed, non-manual-blocker) are labelled; blocked/in-flight/done items are left untouched (re-run once they clear). Idempotent — recomputes from the live board each call. Hand-override any item afterwards with update_sprint_i…

  • audit_caption_style

    8e2f4a17 — Audit every figure/table caption's LABEL formatting (boldness, punctuation immediately after the number) against a style_policy/journal preset; returns structured findings, not free text. Closes a real gap: figure_caption_bold / table_caption_bold / figure_caption_label_punctuation / table_caption_label_punctuation have existed on resolve_style_policy() and every JOURNAL_STYLE_PRESETS entry since 4d0ca929, but nothing ever read them back against a document — this is that missing consumer. Caption detection is text-and-style based (paragraph style name contains "caption" AND the tex…

  • audit_cross_document_consistency

    df716454 — Diff specific style-DEFINITION values (word/styles.xml, not paragraph instances) between a manuscript and its Supplementary Information companion, and separately check the body-text style's font against a style_policy/journal preset in each document. Genuinely new shape versus every other audit_* tool: takes TWO docx paths instead of one. Findings carry a "document" tag ("manuscript"/ "si") or both "manuscript_style_id"/"si_style_id" instead of a para_id/locator — a style definition isn't anchored to one paragraph. Two finding families, each skipped when the relevant style can't b…

  • audit_document

    d092d2a4 -- read-only, authoritative figure/table/caption OWNERSHIP audit: reconciles headings, paragraphs, captions, embedded media, relationships, and tables into ONE structural-ownership graph (nodes + edges, each id from the SAME stable id scheme locate_anchor / get_paragraph / insert_caption already resolve), plus a findings list covering orphan_image, repeated_embed, caption_only_figure, non_adjacent_caption_attachment, table_cell_image_ambiguity, duplicate_para_id, and (when index_db_path is given) stale_or_empty_sidecar. This is the read-only detector build_document_review's "structur…

  • audit_equation_contract

    6bbce476 (W1-L, Phase 1 of proposal cfe4c6df) -- read-only, deterministic equation-contract audit: consolidates this module's three previously-scattered equation-audit utilities (extract_equations / parse_docx_equations_local, the raw-OOXML equation INTEGRITY auditor behind audit_document's equation category, and audit_equation_style) into ONE structured manifest instead of three differently-shaped results a caller would have to reconcile by hand. For every native OMML equation in the document, classifies inline vs. display (vs. table-numbered) layout, and reports BOTH a stable audit_serial (…

  • audit_equation_integrity

    3d0769ab (MDE-B1) -- read-only raw-OOXML equation INTEGRITY audit. Distinct from audit_equation_style (alignment/punctuation/explicit- number-gap STYLE): this never treats "an <m:oMath> element exists" as proof an equation is healthy. Detects plaintext duplicated alongside real OMML, equation-like plaintext with NO OMML at all, two equations spliced into one <m:oMath>, ambiguous/mixed equation-numbering conventions, and duplicate equation numbers whose underlying structure actually differs. Args: document_path: Absolute path to the .docx to audit. Read-only. Returns ``{document_path, sour…

  • audit_equation_style

    4efc63fd — Audit every equation in a .docx for alignment, trailing punctuation, and numbering consistency; returns structured findings, not free text. Three finding types: misaligned_equation — a display equation's paragraph alignment doesn't match style_policy["equation_alignment"] (default "center"). Inline and table-numbered equations are excluded. missing_trailing_punctuation / incorrect_trailing_punctuation — a display equation has no (or the wrong) trailing punctuation immediately after the <m:oMath> — the same spot append_text_run_after_math wri…

  • audit_figure_table_provenance

    6b657a8b — batch analogue of check_embedded_staleness: walks EVERY figure and table stored for a document and links each caption to its embedded asset, its exact/fallback output match, SHA-256, and generating script, in one whole-document integrity report. Figures resolve via file_path + outputs_dir (exact match, then a relocation-tolerant basename fallback); a basename match with 2+ same-name candidates is reported as ambiguous (non-authoritative), never silently picked. Tables carry no file_path, so their generating script is inferred from the caption text itself and traced forward via find_…

  • audit_heading_style

    df716454 — Audit every H1/H2/H3 heading for per-level spacing (before/after, in twips) against a style_policy/journal preset, AND flag existing headings that already violate style_policy["heading_terminal_punctuation"] — the read-only counterpart to _apply_heading_terminal_punctuation, which only fires when NEW heading content is authored via write_section. Three finding types, each skipped entirely when the corresponding policy key is unset (None — no verified rule, don't guess): heading_spacing_before_mismatch / heading_spacing_after_mismatch — a heading paragraph's own <w:spacing…

  • audit_manuscript_structure

    docs-intel-jcshm-linter-gap-cleanup-20260918 — Audit the manuscript's Abstract word count and Keywords count against style_policy["abstract_word_count_min"/"_max"] / ["keyword_count_min"/"_max"]. Neither fact was checked by any tooling before this; JCSHM's own live submission guidelines state both as explicit numeric rules (Abstract 150-250 words, 4-6 Keywords). Section location is TEXT-pattern based (the Abstract heading is any heading paragraph whose text matches the same _ABSTRACT_RE document_outline already uses; the Keywords line is any paragraph matching a "Keywords:"/"Key words:" label…

  • audit_reference_consistency

    docs-intel-jcshm-linter-gap-cleanup-20260918 — Audit reference-list <-> in-text-citation consistency for JCSHM's numbered_bracket citation style: every in-text numbered citation ("[7]", "[3, 5]", "[3-7]") has a matching reference-list entry, every reference-list entry is cited somewhere, and the reference list's own printed numbering is sequential 1..N with no gaps or duplicates. Does NOT check citation first-appearance order (real published JCSHM articles are genuinely mixed on that convention) — that stays an editorial judgment call. Four finding types, all UNCONDITIONAL (not style-policy-g…

  • audit_table_style

    9c1a3fd2 — Audit every real, CAPTIONED content table (a Caption- styled "Table N"/"Table SN" paragraph immediately followed, possibly after blank spacer paragraphs, by a table) for three structural/style defects: misalignment, a missing page-break header-row-repeat, and a redundant blank paragraph between the caption and its table. Deliberately scoped to CAPTIONED tables only (same text-and-style detection audit_caption_style uses), not every table in the document — a real document's table count is usually dominated by un-captioned equation-numbering layout tables, which have different format…

  • batch_mutate

    133bfff6 — run a batch of TRANSACTIONAL mutation entries in ONE call, mixing entry kinds selected per-entry via 'kind': 'sprint_item_pointer' (attach a pointer — same shape as add_sprint_item_pointer: sprint_item_id, source_type, targets, optional label), 'sprint_item_update' (patch an EXISTING sprint item — same shape as update_sprint_item: item_id + at least one patchable field; sprint-item CREATION is not supported here, use execute_batch(operation='sprint_items', ...) or add_sprint_item for that), and (PROFILE-7) 'profile_layer' (upsert one scope_type+scope_id profile layer — same shape as…

  • batch_read

    133bfff6 — run a batch of DOMAIN-AWARE, CONCURRENT read requests in ONE call. Each request names an 'adapter' + 'operation' + 'args'; independent requests (no depends_on) execute concurrently via asyncio.gather — this is pure in-process dispatch, no subagents/worktrees involved. A request with 'depends_on' (a list of other requests' 'request_id's in this SAME batch) waits only for its own declared prerequisites, not the whole batch; if a prerequisite fails, the dependent resolves immediately with error_code='DEPENDENCY_FAILED' and is never executed. Two requests with the identical adapter+oper…

  • bind_artifact_provenance

    Join structural document artifacts (figures/tables/equations) to authoritative per-file provenance, fail-closed (item 6d02f343). Given a document's own list of structural artifacts -- one entry per figure/table/equation it currently embeds, each carrying whatever ``canonical_path``/``expected_sha256`` the document-writing tool already knows -- resolves each against meridian-outputs' per-file provenance (:func:`resolve_figure_output`'s exact + basename tiers, authoritative; :func:`get_provenance_status`'s directory-level note, fallback evidence only) and classifies it so a caller can reject or…

  • bind_artifact_source_edge

    Record a typed source<->artifact edge for a registered artifact (item e1c979e3). Idempotent for the same (artifact_id, source_locator, relation) triple. Args: outputs_dir: Absolute path to the outputs directory. artifact_id: Must already be registered (``register_artifact``). source_locator: Portable locator for the source side of the edge. relation: Free-text edge verb (default "produced_by"). metadata: Opaque extra fields, shallow-merged on update. Returns: The stored edge dict {edge_id, artifact_id, source_locator, relation, created_at, metadat…

  • build_prose_edit_packet

    4c992e91 -- build ONE reviewable, typed prose-edit packet for a single anchor. READ-ONLY: resolves anchor_query the same way locate_anchor does, against a fresh parse of document_path; never mutates it. Refuses (status="refused", no packet built) when replacement_text/ anchor_query are malformed, the anchor does not resolve cleanly, or the resolved element is not prose (paragraph/heading only -- an equation, caption, or table is refused so it can never be routed through the plain-text prose writer). Args: document_path: Document to build the packet against. …

  • capture_research_finding

    Inline capture for web/paper research during planning: save a finding from a URL as an addressable note with the source link, optionally linked to a decision. A research-shaped wrapper over save_finding — arXiv URLs and arXiv-issued DOIs are tagged source_type=arxiv automatically; everything else as web. Turns web-search results into durable Meridian artifacts instead of evaporating. In-project dedupe: if this project already has a finding for the same paper/page (case-folded DOI, arXiv id without version, PMID, or normalised URL) nothing is created and the result carries existing_note_id (a s…

  • check_embedded_staleness

    432fcfcb — detect whether a figure or table EMBEDDED into a .docx has since drifted from its generating source (a plot script output, CSV, etc.). Distinct from the .docx mtime staleness check: this checks whether the SOURCE FILE that fed the embedded copy changed AFTER the copy was made. Covers figures (resolved via file_path + outputs_dir) and tables (explicit source_path) via one shared mechanism. Uses SHA-256 fingerprint + mtime from the outputs_index (same outputs_dir resolve-through as find_similar_figure). Returns {stale, reason, source_path, embed_sha256, current_sha256, embed_mtime, cu…

  • check_image_rights

    Read-only preview of the image-storage rights policy for ONE source image in a project. Pass the source's license (a canonical id such as 'cc-by-nc', a license string, or a creativecommons.org URL), and whether the stored figure is a derivative of the source (derived) or a redrawn or cropped copy (redrawn). Returns the tier (STORE_IMAGE, STORE_UNMODIFIED or LINK_ONLY), the flags (for example requires_credit and needs_review), the project's use mode, and override_required: true when image bytes would be refused without a human-approved override. A missing or unknown license is LINK_ONLY. This t…

  • check_release_render_gate

    1e6150ef -- fail-closed release gate: refuses release unless a FRESH, content-matched, real ``"rendered"`` receipt is on file for ``docx_path``. "Fresh" requires the newest matching receipt in ``receipts_path`` to have ``status="rendered"`` AND a ``source_docx_sha256`` matching the document's CURRENT on-disk content AND an age no greater than ``max_age_seconds``. With no such receipt, release is refused unless a human explicitly passes ``allow_degraded_override=True`` WITH a non-empty ``override_reason`` -- which durably records a second, audited ``degraded_override`` receipt in the SAME ledg…

  • check_render_capability

    93cd9798 -- lightweight render-capability detection for visual QA. This is capability DETECTION, not a rendering engine (mirrors the .pdf boundary in ``ingest_local_document``, which also declines to embed a rendering pipeline). Returns a dict with a ``status`` key that is exactly one of three states: - "rendered" -- a real render backend (LibreOffice headless, or Word COM on Windows) was available and actually produced visual output for this document. This is the …

  • check_section_style

    Heuristically compare a section's text against get_style_guide's expected move sequence for a declared section_type, reporting moves present/missing/out-of-order. THIS IS A STRUCTURAL HEURISTIC BASED ON KEYWORD/CUE MATCHING, NOT A GROUND-TRUTH OR COMPILER-VERIFIED CHECK -- the result's own `disclaimer` field repeats this. Provide either 'text' (already-resolved raw section text) or 'source_text' plus 'heading_id'/'heading_title' to resolve the section's range from a heading node in a fresh outline of source_text (see style-guide.js's resolveSectionText for the exact range rule and its document…

  • check_staleness

    Re-hash every generating script referenced in the ``tag_output`` ledger and report which previously-tagged outputs are now stale (item 7518bfcd). An output is flagged stale when its generating script's CURRENT content hash differs from the hash recorded at tag time -- the script has been edited (bug fix or otherwise) since that output was produced, so the output may still reflect the OLD script behaviour even though the output file itself never changed and looks perfectly valid/cached. Also flagged stale if the generating script can no longer be read at all (deleted/moved). Args: outputs_d…

  • checkpoint

    Save progress mid-session. Runs auto_capture (buckets done tasks into a note), generates a delta handoff, and returns a compact summary with what was done, what's pending, and the suggested next /goal string (now the same canonical, token-embedded continuation block generate_handoff renders — verify it with verify_handoff_token exactly like any other /goal block). Call before context fills up or before ending a session.

  • claim_docx_region

    f7ee1ba7 — Model B scoped-region claiming for .docx files. Claim a specific paragraph/element by its durable `element_id` (the w14:paraId surfaced by get_document_structure / update_paragraph) so another session cannot overwrite it concurrently. Two sessions can hold NON-OVERLAPPING element claims on the SAME file — the real precision benefit vs. a whole-file lock. An edit to a claimed element_id by another session is REJECTED structurally (not just advisory) at the update_paragraph level. A whole-file lock by another session blocks this claim. Returns {claimed: true, file_path, session_id, el…

  • claim_file

    Claim edit rights on a file for this session. Whole-file by default (auto-expires after 2 hours). For symbol-level claims — so two sessions can edit the same file if they own different classes/functions — also pass `symbol` (e.g. 'AuthRouter' or 'AuthRouter.login') AND `content` (the file's full source). Meridian parses the source (stdlib ast for Python, tree-sitter for JS/TS/C/C++/Go/Rust/Java/C#), and hard-blocks if another live session already owns an overlapping line range — the block lists which symbols are still safe to claim. Unparseable content falls back to a whole-file lock. The resp…

  • claim_node

    Claim a single addressable node (section, table, figure, equation, citation, ...) for exclusive editing. Mirrors POST /claim exactly, including routing a claim aimed at the reserved whole-document sentinel to lease semantics. Read-only against Overleaf itself -- this only writes to the local claims table.

  • claim_sprint_item

    Claim a pending sprint item: sets status to in_progress and records claimed_at + actor. Read-only: false. Rejects if the item is already in_progress, done, failed, skipped, its touches_files overlap active file claims from another live session, or (18c488b6) a touches_resources file:/symbol: entry is locked by another live session — this last check ACQUIRES the resource lock (via claim_file/claim_symbol) as part of claiming, is a hard block regardless of worktree isolation, and rolls back cleanly if the claim itself doesn't land. 54c488b6/54d2c2af: every symbol:/file: resource this acquires al…

  • claim_task

    Atomically claim a pending task so no other worker picks it up. Returns claimed=True on success or claimed=False (with the current holder) when another session already holds the lock. Call this before doing the work; pair with release_task on completion or failure.

  • classify_outputs

    Classify a list of output file paths as canonical or archival (item 2820ab1f's broader superset). Delegates to outputs_local's two-stage classification for everything it already resolves: Stage 1 (cheap): filename heuristic (``*_old.csv``, ``_results.csv`` etc.) Stage 2 (SHA-256): byte-identity check against the canonical twin. ...then adds a broader stage-1b naming heuristic (``_backup``/``_bak``/ ``_deprecated``/``_mislabeled``/``_wip``/``_copy``/``_stale``/``_archived`` suffixes, plus a whole extra suffix appended after the real extension like ``.bak_41img_mislabeled`` or a trailing `…

  • clear_capability_profile

    02038afe — Delete a scope's ENTIRE capability profile row (both its capabilities and its disabled_capability_ids) so it reverts to purely inheriting from less specific layers. Distinct from disabling individual capability ids via set_capability_profile's disabled_capability_ids — this clears the whole layer. Idempotent: clearing an already-empty or never-set scope is a no-op, not an error.

  • clone_profile_layer

    0bec79a7 (PROFILE-5) — Copy one layer's fields/reset_fields/provenance onto another scope, going through the exact same validation/hashing path as save_profile_layer (not a raw copy) — the target scope's allowed_layers may differ from the source's, so a field the source layer legally carries can still be rejected at the target. Rejects with {error} when the source layer does not exist (revision=0 — cloning nothing is a caller error, not a silent no-op). Cloning INTO a hosted_default target never carries over the source's lifecycle_state — a fresh clone always lands in 'draft', exactly like any…

  • commit_proposal_promotion

    Commit a proposal's promotion through 'depth' (ce4883f3), cumulative over every shallower depth. Requires 'preview_hash' from a just-called preview_proposal_promotion with the SAME arguments — a mismatch (proposal or target project's board changed since) is rejected rather than silently committed against stale information, and nothing is written. Committing an already-satisfied depth is an idempotent no-op success (matches the preview's already_satisfied=true case). A genuine lost race against a concurrent caller (caught by the underlying race-safe functions) is reported honestly as a failure …

  • compare_equation_structures

    e4265dd1 (MDE-B2) -- reference-aware structural comparison between two documents' equations (e.g. a prior-accepted revision vs a new candidate, or a canonical source vs an isolated draft). Composes directly on docs_intel.audit_equation_integrity for both sides -- identity and structure come from the exact same records that audit already produces. Equations are matched by explicit number (strongest signal), then by stable w14:paraId anchor, then by document position as an explicitly-labeled degraded fallback. Args: reference_path: Absolute path to the reference/baseline .docx. candidate_p…

  • compare_proposal_versions

    Read-only: structural diff between two proposals — most commonly two adjacent versions in a lineage chain, but works for any two existing proposal ids. Reports per-field before/after/changed for title/body/tags/status/scope_type/project_id/family_id, plus a difflib similarity ratio and a unified diff for body specifically, plus whether the two are directly linked in the lineage graph ('adjacent') and the connecting edge(s) if so. Returns {from, to, direct_relations, adjacent, diff}.

  • complete_experiment_run

    3f6b8715 — finalize a run as status='completed' (default) or status='abandoned'. outcome_summary and disposition (keep|discard|promote) are explicit and REQUIRED — rejected with {error} when missing/empty, even on a retry against an already-terminal run. result_receipt is bounded to 32KB; past that cap it is spilled to durable object storage (local content-addressed storage today, transparently upgrading to Tigris when configured) and replaced with a small pointer — never truncated, and rejected outright only if the spill itself fails. HARD INVARIANT: this call always writes an experiment_even…

  • complete_external_job

    Finalize an external job with an explicit terminal outcome. This never infers success from output files and never reopens a terminal record. It appends a final task-log event and refreshes the local snapshot.

  • complete_research_run

    a5343387 — finalize a research run with a compact, byte-bounded receipt (16KB cap; exceeding it is REJECTED, never silently truncated). disposition is explicit and REQUIRED (keep|discard|promote) — never inferred from the run's outcome. Idempotent on an already-terminal run (completed/failed/abandoned/expired): a duplicate call returns the existing terminal state unchanged, never an error. Only disposition='promote' runs are eligible for promote_research_run, and only disposition in (keep, promote) runs are ever embedded into a handoff's research_run_receipts (see generate_handoff/build_contin…

  • complete_sprint_item

    Mark a sprint item done. Pass task_id to link the task that shipped it. Pass session_id to get a board_change field (items injected mid-run) and an active-worktree merge reminder in the response. If the item is flagged required_notes, you MUST pass notes= (evidence: what shipped / how verified) or a task_id, or completion is refused (EVIDENCE_REQUIRED). If the item is flagged require_verification (e2e1b682), completion is refused (VERIFICATION_REQUIRED) unless an independent PASS is on file: pass verifier_session_id (a DIFFERENT, REAL session of this project — the fresh, no-memory subsession's…

  • complete_task

    Mark a claimed task as done and log an optional completion note. Call this after finishing the work described in the task. Pair with claim_task at the start of work. If the task was already marked done or failed by another process, the call is safe and returns the current task state.

  • complete_wave_gate

    d2430713 — EXECUTOR GATE: call this AFTER you have actually run a wave's gate action list (push, deploy, wait, run_verification) to unblock the next wave's sprint items. 0ff5e59f — pass verification_run_id: the id that run_verification returns for the real, server-recorded test run. The RECORDED run's own status/exit_code decide the unlock (status=='ok', exit_code==0, same project, completed, and not already spent on another gate) — nothing you type is consulted. A hand-typed verification_payload is a self-report and is REFUSED (WaveGateUnboundPayload); the only escape hatch is a HUMAN's decis…

  • complete_workspace_sprint_item

    Mark a workspace personal-backlog item done (stamps completed_at). Returns the updated item.

  • configure_wave_gate

    74a8f420 — PLANNING: configure (or on-the-fly reconfigure) a deterministic action pipeline attached to a wave or wave-range, ENFORCED STRUCTURALLY — not just advisory /goal prose. Once set, claim_sprint_item refuses (WAVE_GATE_PENDING) to claim any item whose wave sorts beyond wave_end until complete_wave_gate records real run_verification evidence for that boundary. actions is an ordered, non-empty list of {"type": ...} dicts — type must be one of push_dev | push_main | deploy | wait | run_verification (push_dev/push_main/deploy are run by the executor via trigger_workflow; run_verification m…

  • copy_section

    8213050a — Duplicate an existing section (heading + its content) to a new location, leaving the original untouched (unless trim_original_to is given). Same section-boundary rule as move_section, but deep-COPIES the range: every copied paragraph gets a FRESH w14:paraId, and every bookmark name inside the copied range is renamed to a fresh unique name (duplicate paraIds/bookmark names would silently break paraId-addressed tools and cross-reference resolution). A REF/PAGEREF/NOTEREF field inside the copied range that targets a bookmark ALSO inside the copy is repointed at the copy's own renamed …

  • create_experiment

    3f6b8715 — W1-M Experiment Registry: create a named experiment (a research question; many runs belong to one). Reuses the pre-existing experiments table (4376e655) additively — config_template/created_by (an unrelated ML-style tracking interface's own columns) are left untouched.

  • create_issue

    Open a new issue in the project's connected GitHub repository. Returns the created issue number and url.

  • create_paper_contract

    7c96d41b — create the stable (project_id, paper_key) identity a paper_contract's editorial-intent revision ledger hangs off of. Contains no editorial content itself — propose that separately with create_paper_contract_revision. Not idempotent on paper_key: a repeat call with the same key in the same project returns {error} naming the existing contract's id; call get_paper_contract first if you want get-or-create semantics. Returns {contract: {...}} including the new contract_id, status='draft' (no revision approved yet).

  • create_paper_contract_revision

    7c96d41b — propose a new PENDING revision of a paper_contract's editorial-intent content: working_title, target_venue, audience, thesis, scope_in/scope_out, required_sections, style_guide (free-text — figure/prose conventions, tone, whatever this manuscript needs), citation_style, word_limit, constraints. This is the proposal step only — a freshly created revision is NEVER binding (an editorial session must not assume it) until a human explicitly calls approve_paper_contract_revision, even when this tool itself is called from an AI drafting session. Returns {revision: {...}} including the new …

  • create_project

    Create a new Meridian project.

  • create_proposal_successor

    Create a NEW, distinct proposal that is a version/successor of an existing one, linked to it by an explicit typed relation (supersedes/refines/forks/continues/duplicates/responds_to) — never by mutating the predecessor or overloading family_id/proposal_events (pinned decision 6aef812e). Inherits the predecessor's project scope (project-scoped stays project-scoped, workspace-global stays workspace-global) and family_id automatically. Idempotent: pass the same idempotency_key on a retry to get back the SAME successor rather than a second one — the underlying proposal creation AND the lineage edg…

  • deep_research

    Run a real, multi-step deep-research agent over ``query`` and return its final report. THIS TOOL MAKES A REAL HOSTED CALL -- see the module docstring. Every successful invocation drives open_deep_research's compiled LangGraph agent end to end (clarify -> research brief -> supervised, concurrent sub-agent research -> compression -> final report), spending real Anthropic API tokens and making real Anthropic-native ``web_search`` calls against the live internet. This is not a local simulation and has no cached/offline mode. Configured Anthropic-only on every call -- see :func:`_build_configurat…

  • delete_custom_hook

    273287cb — delete a user-defined hook by id (the id returned by add_custom_hook / get_custom_hooks). Idempotent: deleting an already-gone hook returns {deleted:false} rather than erroring, matching delete_sprint_item_pointer's convention. Does NOT remove any already-written .claude/hooks/<slug>.* files — those are simply no longer refreshed on the next generate_handoff.

  • delete_note

    Hard-delete a project note by id.

  • delete_sprint_item_pointer

    2976e168 — delete ONE generic pointer from a sprint item by its pointer id (the id returned by add_sprint_item_pointer / get_sprint_item_pointers). Idempotent: returns {pointer_id, deleted:false} when no pointer had that id, rather than erroring. To CHANGE a pointer's targets/source_type/label in place instead — preserving its id/created_at, and without the data-loss/visibility window a delete-then-re-add pair has — use relocate_sprint_item_pointer (W1-J); reserve this tool for when you actually want the pointer gone. project_id (or project_name) is required (6f7ce9d6) and is enforced in the d…

  • delete_user_journal_style_preset

    8e2f4a17 — Remove one named preset from a user presets JSON file (every other entry preserved). A no-op, not an error, if the file doesn't exist or doesn't contain name. Args: name: The preset name, matched EXACTLY (case-sensitive) against the file's own keys. path: Path to the user presets JSON file. Returns: {status: "ok", name, path, deleted: bool, preset_count} or {error: <message>} if the file exists but isn't valid JSON.

  • delete_watchlist_query

    Delete a saved research watchlist query. Scoped to project_id + the watchlist tag, so it never deletes an unrelated note.

  • dismiss_hitl

    Dismiss a HITL request (won't-answer / no longer relevant). Stays in audit trail. Use list_hitl_requests to find request IDs.

  • document_outline

    Heading outline of a .docx: paragraph_count, heading_count, and an ordered list of headings (level, text, para_id, index, section_type). Stateless — builds no index. Every response includes document_fingerprint. 1dff1300 — cursor-based pagination + section scoping, so a large document's outline can never silently truncate or exceed a token budget. Omitting page_size and cursor (the default) returns the full outline, unchanged from before. Pass page_size (no cursor) for the first page: at most page_size headings, plus cursor (opaque token for the next page, or None when this is the last page)…

  • edit_caption

    9d749639 — Edit the label text of an existing Word Caption paragraph. Locates the paragraph by caption_para_id, verifies it is a Caption paragraph (Caption style or SEQ field present), replaces the label text run while preserving the SEQ field and style. The SEQ number is NOT changed so Word's field-refresh cycle continues to work correctly. Args: docx_path: Absolute path to the .docx file (mutated in place). caption_para_id: w14:paraId or p{N} of the Caption paragraph. new_label_text: Replacement label text. index_db_path: If supplied, sidecar is invalidated after write. …

  • edit_citation

    9d749639 — Replace an existing CSL_CITATION field with updated keys/text. Locates the complex field in the paragraph whose instrText contains CSL_CITATION, removes the old field runs (begin through end), and inserts a new complex field with the updated keys / formatted text in their place. At least one of new_citation_keys or new_formatted_text must be supplied. When only one is given the other is inferred from the existing field. Args: docx_path: Absolute path to the .docx file (mutated in place). anchor_para_id: w14:paraId or p{N} of the paragraph to edit. new_citation_…

  • edit_equation

    a80af3a0 — Replace the <m:oMath> in an existing equation paragraph. Locates the paragraph by equation_para_id, verifies it contains at least one <m:oMath>, and replaces exactly ONE targeted equation with a precise single-element swap, preserving every other child of the paragraph (other equations, text runs, fields, bookmarks, drawings) in its exact original order. b6a9ec99 — when a paragraph contains multiple equations, equation_index is required so the operation never guesses (and never silently drops the equations it doesn't touch). Args: docx_path: Absolute path to the .docx f…

  • enqueue_claude_task

    PAID-TIER. Queue a long-running Claude Code subprocess without blocking this session. Returns immediately with a pending task row; the worker writes its result back into the same row when it finishes. Poll get_tasks to see the result. Use this when an MCP tool call would otherwise time out waiting for a Claude subprocess to complete.

  • evict_derived_cache

    Real LRU eviction over the derived-artifact cache (item 19917525): removes the oldest-accessed entries (and their on-disk artifact files) until both an optional byte budget and an optional file-count budget are satisfied. Args: outputs_dir: Absolute path to the outputs directory. max_bytes: Optional byte budget (None = unbounded). max_files: Optional file-count budget (None = unbounded). Returns: ``{"evicted_count", "evicted_keys", "freed_bytes", "remaining_count", "remaining_bytes"}``. A no-op (both budgets None, or nothing over budget) returns zero counts, never an error…

  • execute_batch

    627187b8 — run a HOMOGENEOUS batch of management writes (all entries the SAME operation) with real atomic-or-independent semantics. Every entry in ``entries`` is validated and reported individually — no guessing whether a partial write happened. operation selects the entry shape: • sprint_items — create new sprint items. Each entry needs a non-empty 'title' plus any add_sprint_item kwarg (version, group, human_id, depends_on, priority, touches_resources, ...). Every entry's own 'action' (if present) must be 'create'. • item_updates — patch existing sprint items. Each entry needs a non-empty 'i…

  • expand_section_aliases

    Rewrite \newcommand-defined section-aliasing macros (e.g. \newcommand{\mysection}[1]{\section{#1}}) to their underlying sectioning macro, so a paper's own aliased headings become visible to outline_tex. Pure text in, text out -- no file or network access.

  • export_ai_log

    c0168425 — Read-only: project-scoped, receipted export of ai_log_events (meridian.db.ai_log — the append-only ExecutionEvent log). Nothing captures events into this table automatically yet (see meridian.ai_log's module docstring); this exports whatever has been recorded via append_event so far. Filter with session_id/event_type/correlation_id/parent_event_id exactly like list_events. limit defaults to 5000 and is capped at 5000 — the response's truncated field is true when more matching rows exist than were returned. Returns {project_id, exported_at, filters, event_count, truncated, events, ex…

  • export_ai_log_artifacts

    c0168425 — Read-only: project-scoped, receipted export of stored ai_log artifacts (meridian.artifact_store — the local-first, content-addressed blob store an ExecutionEvent payload can point to via artifact_ref instead of inlining large content). Pass content_hashes to export an explicit subset (sha256:... values) — every requested hash must exist for this project, or the call errors rather than silently returning a shorter list; omit it to export every artifact currently stored for the project. Returns {project_id, exported_at, artifact_count, total_size, artifacts, export_hash} — each artifa…

  • export_ai_log_otel

    R2-G — Run ONE bounded export pass of new ai_log_events to the configured OTel/Langfuse-compatible OTLP endpoint for a project, resuming from the durable watermark left by the previous pass. Always safe to call: returns {"status": "disabled"} immediately if MERIDIAN_AI_LOG_OTEL_ENABLED (or this project's own override) is off, {"status": "unavailable"} if the optional opentelemetry client library isn't installed or no endpoint is configured, {"status": "idle"} if there is nothing new to export, {"status": "sent"} on full success, {"status": "degraded"} if part of the batch sent before a chunk e…

  • extract_equations

    a80af3a0 — Parse all OMML equations out of a local .docx (stdlib only, no lxml). Detects two patterns: 1. Standalone: an <m:oMath> inside a regular <w:p> body paragraph. 2. Table-numbered: a 2-column <w:tbl> row where the first cell contains an <m:oMath> and the second cell holds a parenthesised equation number like "(1)" or "(2a)". The number is attached as the "number" field. Each record: {ordinal, para_id, omml_raw, pattern, number, flat_text}.

  • extract_paragraph_images

    b2e6a7d0 — Extract EVERY image embedded in one paragraph to real files on disk, with basic metadata, so the resulting paths can be handed straight to an image-capable Read instead of hand-rolling a disposable zip/blip/rId-resolution script every time a figure needs to actually be looked at. Blip-complete by construction: walks every <w:drawing> in the anchored paragraph and every <a:blip> within each — never just the first blip in the paragraph. (A prior hand-rolled audit script in this project had exactly that "first blip only" bug and produced 18 false-positive findings before a cross-check…

  • fail_sprint_item

    Mark a sprint item failed — attempted but could not be shipped. Provide a one-line ``reason`` so the next session knows what went wrong. The item stays on the board in 'failed' state so it isn't silently lost.

  • fan_out_sprint_items

    Bulk-insert sprint items from a single orchestrator call — decompose a goal into parallel work items without N sequential add_sprint_item calls. Pass a list of {title, description?, group?, version?} dicts; returns the list of new item_ids in insertion order. By DEFAULT (strict omitted/false) no duplicate guard is applied (the caller is assumed to have deduped) and titles that resolve to an empty string are silently skipped — unchanged, original behavior, kept for compatibility. 468ab67d — pass strict=true to opt into the SAME shared engine execute_batch uses (meridian.db.batch_management, add…

  • file_fingerprint

    Compute a cheap content-derived fingerprint for one output file. For CSV: returns column names (header row) + generating_script hint. For JSON: returns top-level keys + generating_script hint. For NPY and other binaries: metadata-only (no content read). Useful for "does this output already exist / has it changed?" checks without re-running the full search index rebuild. Args: path: Absolute path to the file. Returns: {path, kind, csv_columns, json_keys, generating_script}.

  • finalize_run_manifest

    Bind exact output hashes and artifact-id references to an already-started run manifest, and mark its final phase (item 37ce5537). Fail-closed exact output binding: every path in ``output_paths`` is RE-HASHED right now -- never trusts a caller-declared hash. A missing/ unreadable output, or an ``artifact_id`` that doesn't resolve via ``resolve_artifact``'s own registry, automatically downgrades an attempted ``status="complete"`` to ``"partial"`` -- a finalize call is never silently reported as a clean, fully-verified run when something it claimed doesn't actually check out. Args: outputs_di…

  • finalize_wave_run

    2a654cb0 — IDEMPOTENT FINALIZATION: close a wave run opened by start_wave_run. Safe to retry: if the run is already merged this returns the ORIGINAL result with already_finalized=true, writes no row and appends no event (event_count is identical across the retry — that is the observable proof). Fails CLOSED in three cases: (1) a failure_mode='stop' child has failed — returns {finalized: false, blocked_by: [...]} naming the items; (2) expected_revision_hash does not match the board the run was planned against — you are holding a stale manifest, re-read the board first; (3) evidence is not a gen…

  • find_caption_paragraph

    3f9a1c72 — Find the paragraph whose caption label says exactly `label` (e.g. "Figure 3", "Table 2", "Fig. S47", "Table S3"). A pure, read-only delegation to locate_anchor(document_path, {"caption_label": label}) under a discoverable name, so a caller reaches for a real function instead of re-deriving caption lookup with a hand-rolled document.xml string search. Resolves BOTH real Word-numbered captions (tracked by an actual "SEQ Figure"/"SEQ Table" field) AND manually-typed labels that never got a real SEQ field at all — e.g. Supplementary Information captions like "Fig. S47" — via a loose, p…

  • find_image_paragraph

    Scan a .docx for paragraphs that contain an embedded image. Detects both DrawingML (<w:drawing>) and legacy VML (<w:pict>) image paragraphs. Use this to find the correct anchor_para_id before calling insert_caption with kind="Figure" — passing the image paragraph's own para_id (not the preceding paragraph) ensures the caption lands BELOW the image, not above it. Args: docx_path: Absolute path to the .docx file. figure_index: 1-based index selecting which image to return when the document has multiple images. None (default) returns ALL image paragraphs…

  • find_orphaned_docx_staged_files

    6507e83a (C84-W3, category 8 follow-up) — Detect staged-DOCX temp files left behind by a process that crashed between STAGE and PROMOTE inside a write transaction (see docs_intel._atomic_write_docx_bytes). A crash mid-write leaves an orphaned ``.meridian-docx-stage-*.tmp`` file in the destination document's own directory forever — nothing scanned for or cleaned these up before this tool existed (the detection function itself, ``docs_intel.find_orphaned_docx_staged_files``, predates this wiring but had zero real callers — this is the first one). Run this against a document's directory after a …

  • find_outputs_by_source

    Reverse resolution: a script/data ``source_path`` -> the outputs it produced (item e422de44's new direction -- did not exist before this). Given the generating script or data file, scans the outputs index for rows whose recorded ``generating_script`` traces back to it (exact-string or basename match) -- i.e. "what did this thing produce?". This is the direction needed to catch a docx figure quietly citing STALE data: walk the source's outputs forward, newest first, and compare against what the docx actually shows. Args: outputs_dir: Absolute path to the outputs directory. source_path: …

  • find_references_to

    fea654f9 — Find everything that points AT a figure/table/heading id. The missing inverse of insert_cross_reference: given a target (a Figure/Table caption's para_id, a heading's para_id, or an existing bookmark name directly), scans the whole document for REF / PAGEREF / NOTEREF fields whose instruction targets that same bookmark. Needed for safe renumbering/moving without breaking references elsewhere. b2035fb4 — when the target resolves to a Figure/Table caption and include_literal is True (default), also scans plain-text paragraphs (never fielded ones) for literal mentions such as "Figure…

  • find_similar_equation

    06df6ab3 — fuzzy-match a LaTeX string against every equation already indexed (via index_equation) for one stored document, best match first. Each result carries the stored equation row PLUS a difflib similarity score (0..1) against its latex_normalized. Useful before index_equation to check whether an equation is already present under a slightly different LaTeX spelling. Returns {document_id, matches:[...]} — an empty list (never an error) when the document has no stored equations, or doc doesn't resolve to a stored document.

  • find_similar_figure

    c623e648 — fuzzy-match a free-text description OR a file path against every figure already indexed (index_figure) for one stored document, best match first. Each result carries the stored figure row PLUS a difflib similarity score (0..1) — the better of the match against its normalized_caption and against its file_path. Useful before index_figure to check whether a figure is already present under a slightly different caption or path. Returns {document_id, matches:[...]} — an empty list (never an error) when the document has no indexed figures, or doc doesn't resolve to a stored document. d2a35…

  • find_similar_table

    2622182d — fuzzy-match a free-text description against every table already indexed (index_table) for one stored document, best match first. Each result carries the stored table row PLUS a difflib similarity score (0..1) against its normalized_caption. Useful before index_table to check whether a table is already present under a slightly different caption. Returns {document_id, matches:[...]} — an empty list (never an error) when the document has no indexed tables, or doc doesn't resolve to a stored document.

  • find_stale_by_script

    All ledger-tagged output paths produced by ``script_path`` in a content state OTHER than its current on-disk content (item 7518bfcd). The direct tool for the motivating scenario: "``script_path`` was just found buggy and fixed -- which previously-tagged outputs did the buggy (pre-fix) version produce?" Every ledger entry tagged against this script whose recorded hash doesn't match the script's CURRENT hash was generated by a script content-state that no longer exists on disk -- i.e. potentially the just-fixed bug. Args: outputs_dir: Absolute path to the outputs directory. script_path: …

  • find_symbol_usages

    9605edb0 — READ-ONLY cross-reference tracking: given a document and EITHER a doc_equations row id OR a symbol / normalized-LaTeX string, resolve it to ONE target normalized-LaTeX (an equation id uses that row's stored latex_normalized as-is; a raw string is normalized with the SAME normalize_latex that produced every stored latex_normalized) and return every place that target reappears in the document — matching equations (exact normalized-latex equality) AND paragraphs whose text textually contains the symbol. Each hit carries element_id, document_id, ordinal, matched_text, context (equation|…

  • flag_for_review

    7c3e4b9a — Flag a location in a .docx for human review: a native highlight on every run of the anchored paragraph PLUS a real Word comment explaining what needs attention, anchored to that same paragraph, written in ONE atomic operation. Replaces the ad-hoc pattern of hand-rolling a raw-zip script every time a document needed a flagged spot for a reviewer: this handles comment- infrastructure creation (word/comments.xml, the [Content_Types].xml override, the document.xml.rels relationship) whether the document has zero pre-existing comments or already has some, safe comment-id allocation eith…

  • format_reference

    1258794a — Format a CSL-JSON item as an APA 7th-edition reference string. Formats journal articles, books, book chapters, and conference papers per APA 7th edition. Other item types produce a minimal fallback: Author (Year). Title. This is a pure formatting utility — it does not read or write any file. Use it to preview or verify a reference before writing it to a document. Args: csl_item: A CSL-JSON-shaped dict with at minimum ``author``, ``title``, ``type`` (or ``itemType``), and ``issued`` (or ``year``) fields. As returned by Zotero's local API or zotero_client…

  • generate_handoff

    EXECUTOR SESSIONS: MANDATORY - call at end of every session before disconnect. Never write markdown manually. Read-only: Generate a context handoff. mode='full' writes the complete L0/L1/L2 handoff; mode='delta' returns a compact session update (completed + pending + /goal); mode='starter' returns a <=20-line block for paste-after-/compact or cold start - project_id, start_session command, last 5 completed titles, top 3 pending IDs, /goal; mode='planner' returns strategic context for a claude.ai planning chat; mode='goal' (682005f4) returns ONLY the bare /goal block itself - no readiness heade…

  • get_agent_instructions

    Read-only: Return the custom agent_instructions for a project. These are injected automatically by start_session so every session picks them up. Use this when you need to read or display the current instructions.

  • get_ai_log_export_status

    R2-G — Read-only: status/diagnostics for the OPTIONAL AI-log -> OTel/self-hosted-Langfuse export adapter (meridian.ai_log_otel_export). Attempts NO network call — only reports whether the feature is globally enabled (MERIDIAN_AI_LOG_OTEL_ENABLED), the effective per-project enabled state, whether the optional opentelemetry client library is installed, the resolved endpoint/protocol/service_name, and the stored config/watermark row (last export status, last error, retry_count) if one exists. Meridian's own ai_log_events table stays authoritative regardless of this feature's state — see meridian.…

  • get_artifact_sources

    Artifact -> its bound sources (item e1c979e3). Sorted, deterministic.

  • get_bibliography

    Parse bibliography entries out of .tex source text: inline \bibitem entries, plus -- if bib_text is supplied -- bibtex/biblatex @-entries from an already-fetched .bib file's text. Pure and local: takes plain source text as input and performs no file or network access of its own.

  • get_blog_posts

    Read-only: List workspace-scoped blog posts, newest first. Optional 'status' filter (draft|published|archived). Each post includes a 'url' (/blog/<slug>).

  • get_cached_derived_variant

    Look up one cached derived variant of ``source_path`` (item 19917525), verified fresh against the source's CURRENT on-disk state before ever being returned as a hit. See :func:`meridian_outputs.derived_cache.get_cached_variant` for the full verification contract (fast stat-only path, content-hash fallback, and the exact ``reason`` values). Cached bytes cross this MCP boundary base64-encoded (``data_base64``) -- JSON has no native binary type. Args: outputs_dir: Absolute path to the outputs directory. source_path: The file this derived artifact was rendered from. variant: Vari…

  • get_capability_manifest

    649e095f — Read-only: return a project's structured capability manifest (id/purpose/required_tools/fallback_chain/provenance/availability_policy/verification_command per capability), plus its schema version and a stable content hash for change detection. A project that has never set one gets an empty manifest back, never an error — old projects continue unaffected. Foundation-only: this is the raw declared manifest, not yet resolved against live tool/tunnel availability or profile inheritance.

  • get_citation_edges

    fefb596a — read the CITATION GRAPH of a project's ingested documents. Returns every in-text citation marker (a kind='citation' element parsed from an ingested .tex/.docx) together with its resolved edges: • bibentry edges — the intra-document link from a \cite{key} marker to a matching \bibitem/bibliography entry in the SAME document (materialised automatically on ingest). • zotero_item edges — the cross-document link from a marker to a canonical Zotero library item, keyed on DOI (materialised by the opt-in resolve_citations pass); target_document_id is set when the cited paper is itself inges…

  • get_commit

    Return details for a specific commit from the project's connected GitHub repository.

  • get_commits

    Return recent commits from the project's connected GitHub repository. Returns helpful error if no GitHub repo is connected.

  • get_connection_log

    Read-only: Return the recent /mcp connection-event log for this tenant (newest first, up to 200 entries). Every HTTP /mcp request Meridian receives is recorded: timestamp, MCP method (initialize/tools/list/tools/call/...), auth_result (success/oauth/no_token/invalid_token/expired), tools_returned (tool count for tools/list responses), client_user_agent, and HTTP response_status. Use this to diagnose client-side outages (zero tools returned, auth failures, unexpected User-Agents) in real time or after the fact without needing raw Fly.io log access.

  • get_context_block

    Read-only: Return a compact project context block (north star, sprint, pending sprint items, recent tasks, recent decisions, active sessions) wrapped in a <meridian_context project_id="..." mode="..."> XML envelope for structured parsing by AI clients (v2.5+). The 'text' field in the response contains the XML-wrapped content. mode='full' (default) for Code Handoff into a fresh Claude Code session; mode='chat' for a shorter paste into a new claude.ai conversation. The HTTP route /projects/{id}/context-block returns the same content as unwrapped plain text.

  • get_convergence_state

    Explicit convergence-state snapshot for a local outputs index (item 6af1518d requirement 1) -- read-only, does NOT trigger any indexing. Answers, without guessing from a search result's shape: how far has the index walk gotten (``scan_boundary``), how much work is still queued (``pending_count``), did the walk hit anything it couldn't read (``last_error``), and how does the indexed count compare to the best- known expected total (``indexed_count``/``expected_count``)? Call this BEFORE trusting a zero-hit ``search_outputs`` result as a genuine miss, or poll it while a large tree is still conve…

  • get_current_paper_contract_content

    7c96d41b — read-only convenience: resolve straight to the content of a paper_contract's CURRENTLY APPROVED revision in one call, by contract_id or paper_key, instead of chaining get_paper_contract -> read current_revision_id -> fetch that revision by hand. Returns {contract, revision, content}, where content is the plain editorial-intent object (working_title, style_guide, scope_in/out, etc.) — or content: null (never an error) when the contract doesn't exist yet, or exists but has never had a revision approved (status still 'draft'). This is the one call an editorial session most wants: 'what…

  • get_custom_hooks

    273287cb — list a project's user-defined hooks (newest first). Optional event filter and enabled_only flag. Each entry includes the derived slug (the filename stem used when written to .claude/hooks/) alongside the stored fields.

  • get_deep_research_status

    Cheap, no-network diagnostic: is this tool actually usable right now? Never makes a network call and never requires an API key -- safe to call unconditionally (e.g. from a capability-manifest ``verification_command``, or before a UI enables the "deep research" action) to distinguish "package not installed" from "package installed but no API key yet" from "ready". Returns: {available, api_key_configured, ready, defaults} where: - ``available``: whether ``open_deep_research`` imported successfully. - ``api_key_configured``: whether ``ANTHROPIC_API_KEY`` is currently set (non-em…

  • get_derived_cache_convergence_state

    Real, checkable convergence state for the derived-artifact cache (item 19917525) -- NOT the same question ``get_convergence_state`` answers for the (walk-based) search index. This cache has no background walk; "converged" here means the on-disk manifest is genuinely readable AND every artifact file it references actually exists on disk -- i.e. the persisted cache is self-consistent, not merely present. Intended for a benchmark/qualification harness (see item 28448a5c) to confirm a freshly-written cache is real and valid before trusting any timing/throughput figure measured against it. Args: …

  • get_derived_cache_stats

    Aggregate, read-only summary of the derived-artifact cache (item 19917525): entry/byte counts, total hits, distinct variants, and the age range of what is currently persisted. Args: outputs_dir: Absolute path to the outputs directory. Returns: ``{"outputs_dir", "entry_count", "total_bytes", "total_hits", "distinct_variants", "oldest_created_at", "newest_created_at"}``.

  • get_document_review

    b67ec6b5 -- non-mutating DOCX review: findings grouped by category (structure/equation/caption/section_page/ownership/provenance/ render_integrity) and severity, each carrying a locate_anchor-style locator (section_path, target_para_id, document_order, quoted_text, word_search_locator, bookmark/REF status) instead of a raw paragraph id alone. Composes existing read-only primitives (audit_equation_style, audit_caption_style, audit_table_style, audit_heading_style (df716454), scan_stale_notes, a read-only legacy-plaintext-caption detector, and optionally check_render_capability) rather than re-…

  • get_document_structure

    13462df2 — return the heading outline of a Word .docx WITHOUT ingesting it as a note. Meridian parses the .docx server-side (stdlib only, no python-docx, no persistent index) and returns paragraph_count, heading_count, and an ordered list of headings (level, text, para_id) — a fast structural map of a thesis chapter / spec before deciding what to read or ingest. Pass file_path to a server-accessible .docx.

  • get_docx_document_lease

    6507e83a — Read-only: the live whole-document lease on a .docx file, if any (who holds it). Use before acquire_docx_document_lease or a bulk rewrite to see whether the document is already leased by someone else.

  • get_docx_region_claims

    f7ee1ba7 — Read-only: list active scoped docx-region claims on a file (who owns which element_ids). Use before update_paragraph to see whether the target element is claimed.

  • get_effective_capability_profile

    02038afe — Read-only: resolve and return the MERGED capability profile for a project (optionally narrowed to one sprint item) across every applicable layer — workspace -> user -> project -> sprint_version -> item, least to most specific. A capability id declared at more than one layer resolves to the most specific layer's declaration; the response's capability_sources maps each effective capability id to the layer that won. overrides lists every capability id declared by more than one layer (each entry flagged conflict=true when the two declarations disagree on required_tools or availability_p…

  • get_effective_profile

    0bec79a7 (PROFILE-5) — Read-only: resolve and return the MERGED profile for a project across every applicable layer — hosted_default -> workspace -> user -> project -> session, least to most specific (see meridian.db.profile_layers.get_effective_profile). The 'project' layer is synthetic: its 7 legacy ProjectSettings/executor_config fields come from the existing get_project_settings authority (zero duplication), and its 3 new fields (tool_priority_map, capability_manifest_ref, claim_verification_mode) come from the real profile_layers row. A hosted_default layer only applies when its lifecycle…

  • get_equations

    a80af3a0 — Retrieve all locally-stored equations from the sidecar SQLite. Returns a list of equation records in ordinal order from the docx_equations table populated by index_equations. Returns an empty list when no equations have been indexed yet.

  • get_evidence_status_and_trusted_pointers

    MDE-5 -- the small, BOUNDED projection a handoff embeds instead of the full envelope: a machine-readable evidence status summary plus the subset of records safe to treat as already-verified ("trusted pointers") without re-resolving anything. ``envelope`` is the canonical dict shape (same as every other tool on this surface -- ``get_provenance_status_envelope``'s return value, or ``research_evidence.envelope_to_dict``'s). This is the SAME data ``meridian.handoff.generate_handoff(research_evidence_envelope=..., emit_manifest=True)`` embeds into a goal-mode ``<handoff_manifest>``'s ``<evidence_s…

  • get_experiment

    3f6b8715 — read one project-scoped experiment by id.

  • get_experiment_events

    3f6b8715 — list an experiment's events, oldest first. Optionally scoped to one run_id. Includes BOTH auto-skeleton writes (dead_end/pivot/breakthrough) and manually recorded ones.

  • get_experiment_run

    3f6b8715 — read one project-scoped experiment run by id.

  • get_external_job

    Read one project-scoped external job and its durable observation history. Use this from a fresh session before taking any action on a live job.

  • get_file_claims

    Read-only: show active claims on a file — the whole-file lock (with the holder's session name, if any) plus any symbol-level claims. Use to check who owns a file before editing it. Pass project_id (and optional symbol) to also get a `code_notes` list of code-anchored notes (kind='code') for that path.

  • get_findings

    Read-only (c35370cc): read stored session_findings for a project (newest first), optionally scoped by key and/or session_id. The read side of store_finding.

  • get_flag_drift

    8ca89e8f — read side of link_flag_to_section: for every recorded flag link (optionally scoped to one doc / element_id / flag_name — pass flag_name alone with no doc for the REVERSE query 'flag X changed, which sections does it touch'), re-scan the CURRENT codebase (same AST scan as get_flag_registry) and diff each link's recorded default against what the flag defaults to NOW. Only the most recently recorded link per (element, flag) pair is diffed — a re-verified section's older links are history, not live claims. Each result carries status: 'removed' (the flag, or this exact call site, no long…

  • get_flag_registry

    45802b67 — scan a source tree for `os.environ.get(...)` / `os.getenv(...)` call sites (AST-based, not regex) and return a flat inventory of every config flag the codebase reads: {flag_name, file, line, default}. Only call sites where the flag name is a STRING LITERAL first argument are included — dynamic names (a variable, f-string, etc.) are skipped gracefully rather than erroring. The default is best-effort literal-eval'd from the second positional arg (or a `default=` keyword); a non-literal default evaluates to null. Useful for auditing config drift — 'what env flags exist, where are they …

  • get_goal

    Read-only: Fine-grained — return just the goal fields (north_star, sprint, version_goal) in isolation. Use start_session or get_session_brief for full context including tasks and decisions. Use get_goal when you only need the raw goal fields.

  • get_graph_diff

    Read-only: compare the latest code-graph snapshots of two sessions — returns delta in node_count, hotspot_count, and file_churn. Use snapshot_graph_metrics first to record each session's current state.

  • get_hitl_request

    Read-only: Poll a HITL request for the human's answer. Returns the row including status ('pending'|'answered'|'dismissed') and answer text.

  • get_insights

    Read-only: List a project's strategic insights (newest first), optionally filtered by horizon (permanent|year|quarter). Review accumulated understanding before planning. permanent insights also appear automatically in get_planning_brief.

  • get_issue

    Read a single issue plus its comments from the project's connected GitHub repository.

  • get_journal_style_preset

    4544bbe5 — Look up a named publishing-convention style-policy preset (a "document profile" shorthand) instead of hand-writing a full style_policy override dict. The returned dict is the FULLY RESOLVED policy (every resolve_style_policy key populated), ready to pass straight through as style_policy= to insert_figure_block, insert_caption, audit_equation_style, audit_caption_style, audit_table_style, audit_heading_style, audit_cross_document_consistency, insert_equation, insert_highlighted_note, write_section, or insert_table. 8e2f4a17 — journal is no longer limited to the ~29 built-in presets…

  • get_journal_style_preset_provenance

    docs-intel-journal-preset-externalization-20260918 — Return the full EVIDENCE record backing one built-in journal-style preset: value, tier (1=real official template/stylesheet source; 2=the journal's own live guidelines page; 3=corroboration from real sampled articles; 4=generic/unsourced, explicitly needs verification), source citation, and verified_date for every field that preset actually sets — not just the resolved policy VALUES get_journal_style_preset returns. Use this to audit how well-sourced a preset is before trusting it for a real submission — e.g. to find every field still at ti…

  • get_latex_structure

    106118cd — parse a LaTeX (.tex) source's structure WITHOUT a PDF intermediary. Meridian parses the .tex server-side with pylatexenc (pure-Python, no LaTeX install) and returns heading_count, an ordered headings outline and a nested tree of \part/\chapter/\section/\subsection/\subsubsection/\paragraph (level, kind, text, children), plus unexpanded_inputs (\input/\include filenames, not expanded) and a bibliography list (thebibliography \bibitem entries, and \bibliography{...} + a sibling .bib when a path is given). Pass file_path to a server-accessible .tex, OR pass source with the raw LaTeX in…

  • get_live_claims

    List every currently-live claim (scoped or whole-document) on a project. Mirrors GET /claims exactly.

  • get_notes

    Read-only: List project notes (newest first), LIGHTWEIGHT by default — each item is id/slug/title/tags/kind/priority/timestamps with NO body, so the list never overflows context. This is the pull model: scan the list, then call read_note(project_id, slug) to fetch one note's full body on demand. Optional ?tag substring filter and ?query full-text search (matches title+body even though bodies aren't returned). Pass bodies=true only when you truly need every body inline. Pagination: pass limit (default 100, max 500) and/or cursor to get a {notes, has_more, next_cursor} envelope, then re-call wit…

  • get_paper_contract

    7c96d41b — read-only lookup of one paper_contract by contract_id or by its natural key paper_key (pass exactly one, alongside project_id). Returns {contract: {...}} including status ('draft'|'active'|'archived') and current_revision_id (null until a revision has been approved) — or {contract: null} for a nonexistent contract, never an error. To read the actual editorial content of the currently-approved revision in one call, use get_current_paper_contract_content instead.

  • get_paragraph

    Fetch one paragraph by its para_id from a previously-built index.

  • get_parallelizable_groups

    Read-only: Return clusters of pending sprint items that are safe to run simultaneously. Filters pending/todo items (optionally by version) whose depends_on is satisfied, then greedily partitions them into groups where no two items in a group share a touches_resources identifier. The orchestrator fans out each group as a parallel subagent batch and runs the groups in sequence. Returns {version, groups: [[item,...],...], group_count, eligible_count, undeclared_count, blocked: [...]}. Items still waiting on an unfinished dependency are listed under 'blocked', not in any group. Makes parallel spri…

  • get_pending_zotero_citations

    Read a bounded, deterministic page of this project's citation markers that do not yet have a Zotero edge. Intended for a workstation with Zotero Desktop running locally; hosted Meridian does not contact the workstation's Zotero API.

  • get_pinned_decisions

    Read-only: List pinned decisions, highest priority first (urgent → normal → low, then newest-first). Active only by default. Each row includes its priority and a parsed edit_log array of prior bodies ({body, ts}) recorded on every in-place body edit. Pass query to filter to decisions whose title or body matches (every whitespace-separated term must appear in the title or the body, same multiword-AND convention as search_tasks/search_all) — omit or pass a blank string for no filter (W1-A).

  • get_planning_brief

    PLANNING SESSIONS: CALL THIS FIRST before anything else. Read-only: Return a compact planning context — sprint, north star, pending items, in-progress items, recent tasks, active sessions, recent decisions, unvalidated assumptions, the last session's output (last_session), and a new-handoff signal. No session registration needed. Designed for planning chat sessions that need to see project state without side effects. Pass `since` (a prior call's generated_at) to flag only handoffs filed since you last checked. pending_items/in_progress default-collapse any parent_id/item_group cluster (2+ item…

  • get_plugin_details

    Read-only: Full schema for one named plugin (all tool definitions, description overrides, and stored skill guide if available). Use list_plugins first to see which plugins are active, then call get_plugin_details(name) to load the schema for a specific plugin on demand.

  • get_profile_layer

    0bec79a7 (PROFILE-5) — Read-only: return the raw, single-layer profile for one (scope_type, scope_id) — one row of the hosted_default -> workspace -> user -> project -> session contract, with no merging against any other layer. A scope with no persisted row gets an empty profile back (revision=0, fields={}), never an error — mirrors get_capability_manifest's 'never a read error' contract. Use get_effective_profile instead when you want the MERGED, multi-layer view for a project.

  • get_profile_layer_revisions

    0bec79a7 (PROFILE-5) — Read-only: the hosted_default revision/audit history for one scope_id, newest first — the rollback/audit trail the profile contract requires for the one layer that is 'immutable once published'. Only hosted_default writes are ledgered; a non-hosted_default scope_id always returns []. Each entry carries revision, content_hash, lifecycle_state, fields, reset_fields, actor, and created_at.

  • get_project_by_name

    Read-only: Find a project by name — look up, search, or resolve a project's project_id from its name (exact match, then case-insensitive exact match; not a substring search). Use when the user names a project but you need its id. Returns the match with id, name, and sprint.

  • get_project_state_milestones

    Read project-scoped, append-only recovery milestones and their content-hash status. Milestones contain compact state and pointers only; provider transcripts and artifact bytes stay in their local stores. Pass before_sequence for older records. A pointer is resolved only in the owning project and only when its stored hash verifies.

  • get_proposal_gates

    Read-only: list proposal HITL gates for a project, optionally filtered by category and/or (raw, stored) state. Pass sprint_item_id to instead list only the gates currently blocking/quarantining that one item (an effective-state-aware view — an expired auto_on_expiry gate is included even if its stored state says 'allowed').

  • get_proposal_lineage

    Read-only: everything known about one proposal's place in its lineage graph in one call — raw relation edges touching it (either direction), its ancestor chain (walking predecessor-ward, nearest first), its direct successors (proposals that relate TO it, sequence-ordered), and its full descendant set (every proposal that transitively relates to it, breadth-first, nearest first). Descendants are capped at max_items edges with a non-silent 'descendants_truncated' marker reporting the true total when exceeded — ancestors/successors/links are not capped (a lineage chain/fan-out this large would it…

  • get_provenance

    Exact-match lookup for one output file's reproducibility record. Queryable WITHOUT opening/parsing the output file itself -- reads only the lightweight JSON ledger written by ``record_provenance`` (corrected bd5b8d79 -- this was never a JSONL sidecar log; see ``record_provenance`` for the storage-shape correction). A bare ``None`` here is AMBIGUOUS -- it does not distinguish "this path is completely unknown to the outputs tree" from "this path is a real, indexed output that just never had ``record_provenance`` called on it" from "no exact record, but a directory-level MERIDIAN_NOTES.md note …

  • get_provenance_status

    Richer, authoritative per-file provenance answer (item bd5b8d79). Composes ``get_provenance`` (exact machine-recorded provenance) with ``outputs_local``'s index-membership and directory-level ``MERIDIAN_NOTES.md`` annotation systems into ONE ranked answer, so a bare ``None`` from ``get_provenance`` never has to be treated as "this file is unknown" when it might just mean "known, but unregistered" or "covered only by a directory-level note". Args: outputs_dir: Absolute path to the outputs directory. path: The output file to look up. Returns: {error: ...} if outputs_dir/path ar…

  • get_provenance_status_envelope

    Typed, lossless research-evidence provenance envelope for a batch of output paths (item 0ea8fd3c bridge over ``get_provenance_status``). One :class:`research_evidence.EvidenceRecord` (kind ``output``) per path, built via :func:`provenance_status.build_provenance_envelope` from that SAME path's :func:`get_provenance_status` answer -- never a second, independent provenance lookup. See that module's own docstring ("Typed research-evidence bridge") for the exact ``provenance_type`` -> resolver-status mapping (verified/stale/held/ ambiguous/unavailable/degraded) and the partial-record rule. Args:…

  • get_remote_task_status

    32d3d5de — Open a FRESH SSH connection (never the launching one) and determine a remote task's real status: completed (with the real exit code), still running (PID alive), terminated-unexpectedly (PID gone, no exit code — often OOM-kill or a host reset), connection-lost-but-possibly-still-running (the SSH connection itself could not be established, explicitly distinct from a failure), or unknown. A successful status check (one that connects to the host) re-checks the row, including a launch_unconfirmed one, and replaces its status with the one observed there, except that an observed unknown ne…

  • get_research_run

    a5343387 — read one project-scoped research run by id.

  • get_run_manifest

    Look up the current run-manifest record for ``run_id`` (item 37ce5537), whatever phase it's currently in. Args: outputs_dir: Absolute path to the outputs directory. run_id: The run to look up. Returns: The manifest record dict, or ``None`` if nothing was ever started for this ``run_id``.

  • get_run_manifest_envelope

    Typed, lossless research-evidence envelope for one run manifest (item 37ce5537) -- a single ``RUN``-kind ``EvidenceRecord`` (the previously-unused ``EvidenceKind.RUN`` slot ``research_evidence.py`` already reserved) wrapping the manifest's full structured fields under ``attributes``. Args: outputs_dir: Absolute path to the outputs directory. run_id: The run to build an envelope for. Returns: The canonical envelope dict (same shape ``get_provenance_status_envelope`` returns) -- pass to ``serialize_provenance_envelope``/``parse_provenance_envelope`` for a round-trippable JS…

  • get_section_content

    178a82dd — Targeted read of ONE section's content (no full parse_document dump). A "section" is the heading paragraph at heading_id plus every block that follows it up to (not including) the next heading at the same or a shallower level, or the end of the document. Read-only; builds no index. Building block for move_section / copy_section below. Args: docx_path: Absolute path to the .docx file. heading_id: w14:paraId (or synthesised p{N}) of the section's OWN heading paragraph. Returns: {heading_id, heading_text, level, start_index, end_index, blocks, paragraph_count,…

  • get_server_log_checkpoint

    b241a437 -- Read-only: Return the positional/checkpoint index for the server_logs ring-buffer. The checkpoint is a lightweight 'table of contents' mapping minute-level timestamp buckets to the first/last row id and row count in that bucket. Use this for fast navigation through large log windows: find the bucket just before your target timestamp, then use its min_recorded_at as the since= argument to get_server_logs to skip all older rows without scanning. Complementary to search_server_logs (BM25 text search): this is positional navigation (WHERE in the log?) not semantic ranking (WHAT text?).…

  • get_server_logs

    Read-only: Return recent application-level WARNING/ERROR/EXCEPTION log records (newest first, up to 500 entries). Captures any logging.warning() / logging.error() / unhandled-exception records emitted anywhere in the Meridian process — not just /mcp request metadata. Use this to diagnose server-side errors (OAuth flow failures, tools/list timeouts, deploy health issues, DB connection errors) without needing raw Fly.io log access. Complements get_connection_log (which covers per-request /mcp metadata only). Returns {count, since, level_filter, module_filter, entries}.

  • get_session_activity

    Read-only: Return the raw MCP-tool-call heartbeat feed for the given executor session — a ring-buffer of the last tool calls (newest first, up to 50 entries). Populated automatically by the MCP dispatcher on every executor tool call, no log_task() needed. Use this to check whether an executor is still running when task_count is 0.

  • get_session_brief

    Read-only: Call this FIRST for project summaries or to see what a session did — returns session, tasks, decisions, and recent commits in one call. Replaces the start_session + get_context_block two-call pattern for worker/automation sessions. Returns sprint focus, pending sprint items, recent tasks, any blocking failures, and pending HITL requests in a compact XML envelope (<500 tokens).

  • get_session_log

    Read-only: Return the full task log for the given session. Returns every log_task description logged during the session (transcript/task_count) PLUS a recent_activity ring-buffer of the last tool calls the executor made — even before log_task() was called. Use recent_activity to check signs of life in a running executor. Useful for post-session review, handoff, or remote planner polling.

  • get_session_recovery

    cdd0ef6c — Read-only: fetch one session's recovery record (by session_id or recovery_id) plus, by default, a continuation payload that RE-DERIVES the live sprint board and this session's own still-active file claims — never a stored /goal body. resume_recipe is resolved from THIS machine's own host-local snapshot only and is null when this machine never registered that session's local identity.

  • get_sessions

    List all active sessions connected to this project.

  • get_source_artifacts

    Source -> the artifacts it produced (item e1c979e3). Sorted, deterministic.

  • get_sprint_item_pointers

    2976e168 — list the GENERIC POINTERS attached to a sprint item (oldest first). Each pointer is {id, source_type, targets:[{uri, selector, subSelector?}], label, created_at} — the stored shape with its JSON targets deserialized. Read-only; does NOT resolve the targets (use resolve_sprint_item_pointers for that).

  • get_sprint_items

    Read-only: List sprint items for a project. Optional status filter (todo|pending|in_progress|provisional_complete|done|failed|skipped|pushed|indeterminate). Cold sessions read this to know what's still owed. By default, items sharing a ``parent_id`` (subtasks) or ``item_group`` collapse into one summary row per cluster ({collapsed, cluster_kind, item_group_or_parent, count, done, description, ids}) instead of listing every item — pass expand=true for the full ungrouped list. Pagination (W1-A): pass limit and/or cursor to get a {items, has_more, next_cursor, total_count} envelope instead of the…

  • get_sprint_notes

    Read-only: Get all ephemeral scratch-pad notes for the current session. Shown at the top of session briefs so every cold start sees active constraints. Pass note_kind='thinking' to fetch only thinking_sync scratchpad notes, or 'note' for only normal notes; omit for all.

  • get_sprint_progress

    Read-only: Return a SUMMARY of sprint items by status (pending/in_progress/done/failed) optionally filtered by version or item_group. Returns total, done, in_progress, pending, failed, percent_complete, and by_status (counts only — no per-item list; call get_sprint_items(status="pending") for the live item list). Useful to see how far through the sprint we are without listing all items. Pass session_id to also get a board_change field reporting items added since that session started (live-queue signal — call this between sprint items to pick up mid-run injections).

  • get_structure

    Return the heading outline from a previously-built index.

  • get_structure_elements

    c39ae092 — retrieve all locally-stored structural elements from the sidecar. Returns {headings, figures, tables} lists from the docx_headings, docx_figures, docx_tables tables populated by index_document_structure. Returns empty lists for any table not yet populated. e9b2cd2b — FAILS CLOSED by default: raises if the structural index is stale (source .docx content changed since the last successful index_document_structure run) or incomplete (that run never finished), instead of returning partial/outdated counts as if they were authoritative. Pass allow_stale=True to read the best-effort data …

  • get_style_guide

    Pure data lookup (no network) of the 8-category, originally-written reference of rhetorical move sequences per section-type (Abstract, Introduction, Related Work, Methods, Results, Limitations, Discussion/Conclusion, Ethics/Broader Impact) -- see style-guide.js's own header for the tier-1, npm-publishable content note. Omit section_type for the full structure, or pass one to filter to a single section-type's guide (accepts common aliases, e.g. "related work", "prior work", "intro").

  • get_symbol_claims

    Read-only: list symbol-level claims on a file (who owns which class/function/method line ranges).

  • get_symbol_hotspots

    Read-only: symbols claimed by 3+ distinct sessions within 14 days — a refactor/ownership smell. Optionally scope to one file.

  • get_tasks

    Read-only: Get recent tasks across all sessions.

  • get_tunnel_diagnostics

    f1e0df55 — Read-only: ONE layered diagnostic snapshot of your tunnel/connectors, separating what's SAVED in the dashboard from what's ACTUALLY running so a saved-but-not-yet-applied setting is never reported as active. Per slot (fs/code/extract/ppt/word/dc/docs/zotero/outputs/debug): dashboard_configured (persisted), process_active (live server-side socket), external_child_state (last client-reported lifecycle state), last_error, and exact remediation text — plus one of five distinct states: healthy, stale, degraded, quarantined, or restart_required (persisted config and observed runtime disag…

  • get_workflow_run_logs

    Return the failed job steps for a GitHub Actions run belonging to the project's connected GitHub repository, with the last 50 log lines per failed job. Use to see why CI is red.

  • get_workflow_runs

    List recent GitHub Actions workflow runs for the project's connected GitHub repository, with status/conclusion/url. Optionally filter by workflow file name (e.g. deploy.yml).

  • get_workspace_decisions

    Read-only: List workspace-level pinned decisions (active only by default, newest first).

  • get_workspace_notes

    Read-only: List workspace-level notes (newest first). Optional ?tag substring filter.

  • get_workspace_proposals

    Read-only: List a bounded page of workspace proposals (human-authored flashes of insight), newest first. When status is omitted, defaults to 'live' proposals only (raw + investigating) — terminal proposals (promoted/rejected) are excluded so the default view reflects what's actually still open. Pass status='all' to fetch every status, or an explicit status (including promoted/rejected) to filter to just that one. Optional tag substring filter. Pass project_id (or project_name) to restrict the listing to that project's proposals only (a8afd8f9) — omitted, every proposal matching the other filte…

  • get_workspace_settings

    Read-only: Read workspace-global default settings (applies across ALL projects in this workspace): hitl_auto_answer_default and sprint_name_default. Returns the singleton settings row.

  • get_workspace_sprint_items

    Read-only: List workspace personal-backlog items (grouped by 'group', then position). Optional 'status' (todo/pending/in_progress/done/skipped/failed) and 'group' filters.

  • git_diff

    Compare two refs (base...head) in the project's connected GitHub repository. Returns changed files with additions/deletions/patch and the total commit count.

  • github_search

    Search GitHub — a REAL external lookup (keyless), sibling to paper_search/social_search for external prior-art / competitive-repo research. Distinct from search_code, which only searches the CALLING project's own connected repo. Two keyless endpoints via the 'type' param: 'code' (default; GitHub Code Search — actual usage of a symbol/pattern/API across public repos) and 'repo' (GitHub Repository Search — competitor/prior-art repositories by topic/description/stars). Returns {query, count, results:[{title, authors, summary, published, url, ...}]} — code rows carry path/repo/sha/score, repo rows…

  • heartbeat

    Touch this session's last_seen so the idle sweep doesn't expire it. Long-running workers should call this every ~5 minutes between log_task calls. Returns ok=True when the session exists and is still open.

  • highlight_document

    Apply native Word highlighting to structural XML search matches. ddd79188 follow-up -- once the highlighted parts are staged, verified (ZIP/XML/relationship/media integrity), and promoted, a real Word/COM (or LibreOffice) render-capability check also runs against the just-written file, mirroring insert_figure_block / merge_docx_draft. "rendered" continues normally with render evidence attached to the result. "failed" (a render backend was available but errored on this document) restores the pre-write backup and returns an error, same as a structural verification failure. "unavailable-with-rea…

  • idle_until_all_done

    PARALLEL COORDINATION (d3a3a01d): non-blocking barrier check across sibling sessions. Returns {all_done, pending, statuses}; a session is done when closed/archived/missing. The server can't block, so poll until all_done is true — the A2A 'wait for X, Y, Z to finish' primitive.

  • idle_until_session_done

    Read-only: Poll every 30 seconds until another session is closed or archived. Use this when you need to wait before editing a locked file. 6f9503a9 — BOUNDED: the wait times out after timeout_seconds (default 1800s / 30 min) and returns {done:false, timed_out:true, status} so a stuck subagent in a parallel fan-out fails that one item fast instead of hanging the whole batch. Pass timeout_seconds=0 or a large value to tune; there is no unbounded wait.

  • index_document

    Build a sidecar SQLite index for a .docx so paragraphs are navigable by id.

  • index_document_structure

    c39ae092 — parse a .docx and store structural elements (headings/figures/tables) into the sidecar SQLite index at index_db_path (local, no network call). Extends the same sidecar DB used by index_document / search_paragraphs with three new tables: docx_headings, docx_figures, docx_tables. Figures are detected by SEQ Figure field codes; tables by raw <w:tbl> blocks plus optional SEQ Table captions. Returns {index_db, heading_count, figure_count, table_count, complete, source_sha256}. e9b2cd2b — complete is always True on a successful return (a failed/ interrupted run raises instead); source…

  • index_equation

    06df6ab3 — index ONE Word equation (OMML) against a document already stored in the doc-structure store — populated by ingest_document (which registers a docx/latex document's structure here in addition to storing the flat note text). Pass the SAME source/path you ingested under as `doc`. omml_or_latex is auto-detected: a string starting with '<' is treated as raw OMML XML (stored as-is); anything else is treated as LaTeX source (real OMML is generated best-effort — pure-Python latex2mathml piped through a hand-written MathML->OOXML mapper; returns null omml on an unsupported construct, never a…

  • index_equations

    a80af3a0 — Parse equations from a .docx and store them in the sidecar SQLite. Extends the sidecar DB at index_db_path with a docx_equations table. Idempotent — fully replaces the table on each run. Call after index_document / index_document_structure on the same file. Returns {index_db, equation_count}.

  • index_figure

    c623e648 — index ONE figure into the SEMANTIC figure index against a document already stored in the doc-structure store — populated by ingest_document (which registers a docx/latex document's structure here in addition to storing the flat note text). Pass the SAME source/path you ingested under as `doc`. This is the figure parallel of index_equation and is COMPLEMENTARY to the structural kind='figure' section-tree placement (it adds caption dedup + similarity, it does not replace placement). Provide file_path and/or caption. Before inserting, the normalized caption is fuzzy-matched against eve…

  • index_project

    Refresh the search index for a project directory and report what changed.

  • index_table

    2622182d — index ONE table into the SEMANTIC table index against a document already stored in the doc-structure store — populated by ingest_document (which registers a docx/latex document's structure here in addition to storing the flat note text). Pass the SAME source/path you ingested under as `doc`. This is the table parallel of index_figure and is COMPLEMENTARY to the structural kind='table' section-tree placement (it adds caption dedup + similarity, it does not replace placement). Provide caption and/or table_index. Before inserting, the normalized caption is fuzzy-matched against every t…

  • ingest_document

    Turn a Word/PDF/text document into a queryable kind='document' note with a source link — a report, thesis chapter, or spec doc becomes searchable project memory. Pass file_path OR content (one is required): • file_path → Meridian extracts the text SERVER-SIDE, STDLIB ONLY: .txt/.md/.markdown and source files are read directly; .docx is unzipped and its paragraphs extracted (no python-docx). No new dependencies. • content → use this for .pdf and anything Meridian can't parse server-side: extract the text with YOUR OWN tools first, then pass it here. (Passing file_path for a .pdf returns an erro…

  • ingest_document_structure

    db42acce — persist pre-parsed structural data (headings/figures/tables) into the doc-structure store, keyed on the SAME source as ingest_document(content=...) so find_similar_figure / index_figure / index_table / index_equation see the correct document_id. Use this when the .docx lives on the caller's local machine (not on the Meridian server): call the tunnel-side ingest_local_document_structure tool (from the meridian-docs extension) which parses the file locally and forwards the blocks JSON here. The source must exactly match the source that ingest_document stored the flat note under (defa…

  • ingest_local_document

    fdbd4296 — read a local file, extract its full text, and ingest it into Meridian. This is the single-call replacement for the two-step manual workaround required when the hosted ``ingest_document`` tool is called with a local file path (it runs on Fly.io and has no access to the caller's machine). Supported file types (stdlib only, no third-party deps): - .docx -- OOXML paragraph text extracted via zipfile + ElementTree. - .txt / .md / .markdown / common source extensions -- read as UTF-8. The extracted text is forwarded to the hosted Meridian ``ingest_document`` tool via an authentica…

  • ingest_local_document_structure

    db42acce/c39ae092/f8c7ffdc — parse a local .docx's structural content and persist it. TWO PATHS — hosted routing is OPT-IN (f8c7ffdc): 1. LOCAL SIDECAR (DEFAULT, no network) — supply ``index_db_path`` to store headings/figures/tables into a local SQLite sidecar (same DB used by ``index_document`` / ``search_paragraphs``). NO network call — immune to Cloudflare 403 blocks and the 100 KB hosted body cap. 2. HOSTED POST (explicit opt-in only) — when ``index_db_path`` is omitted AND ``force_hosted=True`` is set, blocks are forwarded to the hosted ``ingest_document_structure`` MC…

  • insert_bibliography_entry

    1258794a — Write a formatted APA bibliography entry into a .docx. Locates (or creates) a References heading at the end of the document, then appends a new entry paragraph at the end of the references block. The entry is formatted from the supplied CSL-JSON item (journal article, book, book chapter, or conference paper; other types use a minimal fallback). A bookmark (bibkey_<key>) is embedded in the paragraph so that update_bibliography_entry and remove_bibliography_entry can locate it. If an entry for citation_key already exists, returns an error — use update_bibliography_entry to refresh …

  • insert_caption

    9d749639 — Insert a real Word Caption paragraph into a .docx file. Writes a new paragraph with style Caption and a SEQ Figure / SEQ Table field directly into word/document.xml, then re-packs the ZIP preserving all other members. The SEQ number is auto-incremented (count of existing same-kind captions + 1). Both Figure and Table captions use the same Word Caption-style + SEQ mechanism — the ``kind`` parameter selects which counter to use. 4efc63fd — style_policy["caption_centered"] (default False) controls whether the new caption gets w:jc w:val="center". ddd79188 — AFTER the write is stag…

  • insert_citation

    9d749639 — Insert a real CSL_CITATION complex field into a .docx paragraph. Appends the citation complex field (begin / instrText / separate / cached / end) to the end of the target paragraph. The field instruction is "ADDIN ZOTERO_ITEM CSL_CITATION {...}" (Zotero) or "ADDIN CSL_CITATION {...}" (generic CSL), making it recognisable by Zotero/Mendeley on document open and by the extraction side (CSL_CITATION token in docparse.docs_intel). This is the write counterpart of the read-side citation extraction already present in packages/docparse. The bibliography write path (1258794a) depends on…

  • insert_column

    a2cd9f54 — Insert a new, empty grid column into an existing table. col_index addresses an existing GRID column (0-based); position ("before", default, or "after") says which side of it the new column lands on. For each row: if the insertion point falls strictly inside an existing horizontally-merged cell's span, that cell's w:gridSpan is incremented (the new column joins the merge) — otherwise a brand-new, empty cell is spliced in. w:tblGrid always gets exactly one new w:gridCol. Refuses (file untouched) with reason="ambiguous_grid" when the table's rows do not consistently account for its d…

  • insert_cross_reference

    1c59cb90 — Insert a live Word REF-field cross-reference into a .docx file. REFILED (original 7b5bfb00) — insert_caption above only gives captions Word's SEQ-field auto-numbering. This adds the other half: a REF field in prose ELSEWHERE that quotes a caption's number (e.g. "as shown in Figure 3"). A hand-typed "Figure 3" string goes stale the instant captions are reordered; this REF field tracks the SAME field-refresh cycle (F9) that keeps the caption's own SEQ number correct, because it targets the caption's own cross-reference bookmark rather than a fixed string. Appends a REF complex field…

  • insert_equation

    a80af3a0 — Insert an equation into a .docx file. Accepts a raw OMML XML string (starting with "<") or a LaTeX expression (e.g. r"\frac{a}{b}" or "E=mc^2") which is converted to OMML locally using latex2mathml (pure Python, no lxml). Three positions: "before" — new display-mode paragraph immediately before the anchor. "after" — new display-mode paragraph immediately after the anchor. "append" — append the <m:oMath> inline to the anchor paragraph itself. 4efc63fd — style_policy (see resolve_style_policy) controls the new display paragraph's alignment (equation_alignment, default "cente…

  • insert_figure_block

    19be1551 — atomically insert a centered image paragraph AND its adjacent real SEQ Figure caption in ONE document-load-mutate-save transaction. Unlike calling insert_image then insert_caption as two separate write transactions, both paragraphs are built against a single in-memory document tree and reach disk via exactly one zip rewrite — there is no window in which a failure leaves an orphan image with no caption, or an inconsistent caption index. The image paragraph is always centered (w:jc val="center", equivalent to Ctrl+E), regardless of any alignment the anchor paragraph carries. The cap…

  • insert_highlighted_note

    Insert an internal note inline or as a native Word comment. mode="inline" preserves the highlighted Meridian note paragraph. mode="comment" creates a real Word comment visible in Word's review pane. 4efc63fd — for mode="inline", style_policy["note_style"] (default "MeridianInternalNote") and style_policy["note_highlight_color"] (default "yellow") control the OOXML paragraph style / highlight color. Not consulted for mode="comment". Distinct from the `style` parameter above, which selects the note's category (only "internal_note" is supported), not its rendering. ddd79188 — for mode="inline"…

  • insert_image

    Insert a local image as a centered inline OOXML figure. The generated image paragraph is always centered with w:jc val="center", equivalent to pressing Ctrl+E in Word. session_id: 273df573 — identifies the calling Meridian session to the tunnel-layer DOCX region-claim guard (check_docs_write_conflict in meridian/routes/tunnel.py). Not forwarded to docs_intel; has no effect when this tool is invoked outside Meridian's tunnel (e.g. standalone `uvx meridian-docs`).

  • insert_media_part

    d371b00b -- safe insertion of a brand-new image/media package member. Lower-level, caption-less sibling of insert_figure_block (pair with insert_caption / insert_figure_block for a captioned figure, same two-step composition insert_image already documents). Adds beyond insert_image: collision-free relationship id + media part name generation that is explicitly RE-VERIFIED (not just trusted) before use; matching [Content_Types].xml Default/Override entries (a Default is reused when it already declares the right content type, added when the extension is new to the package, or a part-specific Ov…

  • insert_table

    0a1e9c22 — Insert a brand-new bare <w:tbl> at a position relative to an anchor paragraph, atomically. rows/cols are always caller-specified — there is no implicit default shape, the same discipline split_cell already applies to its own cols/rows. Table STYLE, though, is not a real design question: every new table uses Word's own built-in "TableGrid" style, the same style Word itself applies via the ribbon's default table insert. Column widths split the page's standard 9000-twip (6.25in) content width evenly across cols. position="before"/"after" (default) mirrors relocate_table's destination…

  • inspect_file

    Inspect exactly ONE local XML or JSON file and return a bounded, deterministic structural summary -- never the full file content. Fully local and read-only: no directory walk, no shell, no network access, no writes, no database/cache persistence. XML is parsed under hardened settings that reject DTDs, entities, and external resolution outright (see ``meridian_file_inspection.xml_safe`` for the full threat model) -- this is the ONLY supported way to inspect untrusted XML through this tool. Secret-named files (``.env*``, ``*.key``, ``*secret*``, ``*credential*``, ``config.*``, etc.) are refused…

  • inspect_local_file

    One bounded local inspect/read workflow for a single file -- XML, JSON, CSV, XLSX, or DOCX -- without a tunnel and without a duplicate parser (item a4cb12bf). Routes ``path`` to whichever existing capability already understands its format -- ``extensions/meridian-file-inspection``'s ``inspect_file`` (raw XML, generic JSON) or ``inspect_tabular_file`` (CSV, XLSX, row-shaped JSON), or ``extensions/meridian-docs``'s ``document_outline``/ ``read_document_snapshot`` (DOCX/DOTX/DOCM/DOTM) -- each spawned as its own short-lived local MCP stdio server (never a direct cross-package import; see ``file_…

  • inspect_tabular_file

    Inspect exactly ONE local CSV, JSON, or XLSX file's TABULAR shape (schema, a bounded row sample, and a row count) through DuckDB -- never the full file content, never a second index/database. This is the Wave 1 companion to ``inspect_file`` (which covers raw XML and generic JSON structure): a bare JSON array-of-objects or JSON-Lines file is treated here as ROWS with COLUMNS (via DuckDB's ``read_json``), a genuinely different and complementary view from ``inspect_file``'s generic key/structure summary of the same bytes. Fully local and read-only: no directory walk, no shell, no writes, no dat…

  • invalidate_derived_variant

    Explicitly purge cached derived variant(s) of ``source_path`` (item 19917525). ``variant=None`` purges EVERY cached variant for this source path; a specific ``variant`` (with optional ``params``) purges only that exact entry. Args: outputs_dir: Absolute path to the outputs directory. source_path: The source file whose cached variant(s) to purge. variant: Specific variant to purge, or None for all variants of this source. params: Params identifying the specific entry (only used with an explicit ``variant``). Returns: ``{"removed_keys"…

  • invalidate_stale_derived_variants

    Purge every cached derived variant whose SOURCE is currently flagged stale by the existing ``fingerprint`` staleness ledger (item 19917525). Composes with :func:`check_staleness` rather than duplicating it: an unchanged output file's own bytes can never reveal that the SCRIPT which produced it has since changed, but a derived variant rendered from that output (e.g. a thumbnail) would otherwise keep being served from cache forever. Call this after fixing a generating script (the same trigger ``find_stale_by_script`` targets) to force every downstream derived variant to be re-rendered on next r…

  • lease_document

    Take a whole-document lease (mutually exclusive with any other holder's live claim on the same project). Mirrors POST /lease exactly.

  • link_figure_caption

    0ff8b982 — DURABLY link an already-indexed figure (doc_figures row) to its caption paragraph (a doc_elements id), by stable structural id rather than paragraph proximity. Use this to confirm an advisory suggested_caption_element_id returned by index_figure, or to backfill a durable link on a figure that was indexed before caption linkage was supported. Provide figure_id (the doc_figures.id of the figure to link) and caption_element_id (the doc_elements.id of the caption paragraph — a kind='figure' SEQ-field element from the section-tree store). This is the confirmation primitive for the 'Figur…

  • link_flag_to_section

    8ca89e8f — DURABLY link a docx section/paragraph/figure/table (any doc_elements id — the same id space index_figure/index_table/link_figure_caption already anchor to) to the config-flag state that produced its underlying numbers. This is the check that catches 'results computed with the wrong flag state, then cited as current' — e.g. a flag that silently skipped a whole code path regardless of another flag, or a stale count cited after a fix superseded it. Typical flow: call get_flag_registry to find the flag's current file/line/default, compute the section, then call this tool with value=the …

  • link_manual_github_issue

    5dfe34b2 — attempt to link a manually-filed GitHub issue (one Meridian did NOT create) to a sprint item, extending fdaa5b55's automated comment/propose flow to it. No-ops safely (action='skipped') unless manual_issue_screening_enabled is on. When enabled: reads the issue's raw content, logs it (hashed, append-only) before any processing, runs a wave-relative velocity/anomaly check (non-blocking escalation only), then screens title/body/comments for hardcoded injection shapes — flagged content is never auto-linked (a human-review HITL is filed instead); only screening-clean content gets linked …

  • link_proposal_lineage

    Record a typed lineage relation between two EXISTING proposals: from_proposal_id --relation_type--> to_proposal_id (to_proposal_id is the older/predecessor side). Idempotent — linking the same (from, to, relation_type) tuple again returns the same row rather than duplicating it. Rejected (ValueError -> {"error": ...}) if either proposal doesn't exist, if the two belong to different tenants/workspaces, or if the new edge would create a cycle in the lineage graph. Prefer create_proposal_successor when the successor doesn't exist yet — this tool is for linking two proposals that both already exis…

  • link_table_caption

    42d398a5 — DURABLY link an already-indexed table (doc_tables row) to its caption paragraph (a doc_elements id), by stable structural id rather than paragraph proximity. The table analogue of link_figure_caption. Use this to confirm an advisory suggested_caption_element_id returned by index_table, or to backfill a durable link on a table that was indexed before caption linkage was supported. Provide table_id (the doc_tables.id of the table to link) and caption_element_id (the doc_elements.id of the caption paragraph — a kind='table' SEQ-field element from the section-tree store). This is the co…

  • lint_tex

    Run the static-AST lint suite (see lint.js's own header for the full list of 11 checks: missing/duplicate citations and labels, unresolved \ref targets, section-hierarchy skips, unclosed-environment/parse-failure recovery, duplicate/unused bibliography entries, empty captions/labels, empty citation keys, stray TODO/FIXME/XXX markers, and unresolved nested sub-labels) against raw .tex source text. Never throws -- a parse failure itself becomes a single finding rather than a tool error. Mirrors outline_tex's text-in split.

  • lint_tex_file

    Run the same static-AST lint suite as lint_tex, but reading a LOCAL .tex file on disk via lintFile() -- no server or browser tab involved, same relationship to lint_tex that outline_tex_file has to outline_tex.

  • list_active_worktrees

    dffcde86 — Read-only: list active (not-removed) git worktrees registered for a project, newest first, each row including the owning session's name. Reads the same active_worktrees registry the merge guard (validate_worktree_merge) and the REST worktree endpoints (GET /projects/{id}/worktrees) use — this is the MCP-side view of it, for a session that wants to check what's checked out before creating a new worktree or investigating a stale one, without going through the REST API. Works identically on hosted and self-hosted Meridian: it only reads DB rows, never the filesystem.

  • list_branches

    List branches in the project's connected GitHub repository. Returns name, head sha, and protected flag.

  • list_citation_keys

    List every tag string in the local Zotero library (127.0.0.1:23119, Zotero desktop's own local API), including the ':key:<citekey>' tags lookup_citation_key resolves against. Wraps zotero.js's fetchAllTags() directly -- the same paginated, read-only GET already used internally by lookup_citation_key, just returned as a flat list instead of tested against one key. No side effects. Returns a tool-level error (never a raw throw) if the local Zotero API is unreachable.

  • list_experiment_runs

    3f6b8715 — list a project's experiment runs, newest-started first. Optionally scoped to one experiment_id and/or status.

  • list_experiments

    3f6b8715 — list a project's experiments, newest first.

  • list_external_jobs

    Read the project's live external-job register. By default terminal jobs are omitted so a new session sees only work that may require observation or resumption. The response also reports the host-local snapshot state.

  • list_files

    List all files in the project's connected GitHub repository (recursive tree).

  • list_hitl_requests

    Read-only: List HITL requests without needing UUIDs. OMIT project_id to list pending HITLs across ALL your projects (matches the dashboard) — planning sessions should call it this way so HITLs filed under another project aren't missed (a common cause of false 'no pending HITLs' confidence). Pass project_id to scope to one project. Returns pending queue plus answered/dismissed from the last 24 h by default so planning sessions can see what was recently decided without a separate call. Pass status='pending' for only the active queue, or status='answered'/'dismissed'/'all' for specific history.

  • list_internal_notes

    65c8eb31 — List internal-author-note paragraphs recorded in the sidecar. Reads the docx_internal_notes table populated by insert_highlighted_note. Sidecar QUERY (matching the convention of get_equations / get_local_structure_elements) — reports notes recorded at insertion time, not a live re-scan of the .docx. A note inserted without index_db_path set will NOT appear here even though it exists in the document. Args: index_db_path: Path to the sidecar SQLite index. Returns: A list of {note_id, anchor_para_id, text} dicts. [] when the sidecar doesn't exist yet or has no recorded notes.

  • list_issues

    List issues in the project's connected GitHub repository. Returns number, title, state, labels, created_at, url, and a body preview. Pull requests are excluded.

  • list_journal_style_presets

    8e2f4a17 — Enumerate every journal-style preset get_journal_style_preset can currently resolve: the ~29 built-ins, plus (when user_presets_path is given) every preset defined in that user's JSON file, each tagged with its source and whether it shadows a built-in of the same name. Args: user_presets_path: Optional path to a user presets JSON file. Omit to list only the built-in catalog. Returns: {presets: [{name, source, shadows_builtin}, ...], builtin_count, user_count} or {error: <message>} if the user presets file exists but is malformed.

  • list_local_snapshots

    List the local, on-disk pre-write snapshot files already saved for one project/doc (under ~/.meridian-latex/snapshots), newest first. Read-only -- lists what already exists on disk; never creates a new snapshot itself.

  • list_paper_contract_revisions

    7c96d41b — read-only: every revision in one contract's ledger, oldest first, including pending/approved/rejected alike — the full editorial history. Each entry's approval_status and (for approved ones) approved_by_human_id/approved_at show who made what binding and when. Returns {revisions: [...]}.

  • list_plugins

    Read-only: Lightweight index of active tunnel plugins — name, description, enabled state, and tool_count. Does NOT return full tool schemas (use get_plugin_details for that). Dramatically reduces context bloat vs. dumping all plugin schemas at startup (~500 tokens vs 50k+). Returns an 'active_plugins' list plus any stored skill notes.

  • list_profile_layers

    0bec79a7 (PROFILE-5) — Read-only: enumerate every persisted profile_layers row across the 5-layer hosted_default -> workspace -> user -> project -> session contract (see meridian.profile_contract / meridian.db.profile_layers for the full design), optionally narrowed to one scope_type. Each entry is shaped exactly like get_profile_layer's return value: scope_type, scope_id, schema_version, revision, fields, reset_fields, lifecycle_state (hosted_default only), content_hash, provenance, updated_at. Ordered by (scope_type, scope_id) for deterministic output — this is a raw listing, not a resolved/…

  • list_project_docs

    List every document's project-relative path and doc id in a live Overleaf project's file tree. Read-only: connects using the locally saved Overleaf session (the same one `meridian-latex login` creates) to fetch the current file tree, exactly like the CLI's own `ls` command, and never modifies anything in the project. Returns a clear tool-level error, never a raw throw, if no saved session exists.

  • list_projects

    Every project that has a search index, with file counts and refresh times.

  • list_provenance

    List provenance rows for a project, newest first. Set unsynced_only to restrict to rows a meridian-outputs sync hasn't consumed yet. Mirrors GET /provenance exactly.

  • list_registered_artifacts

    All registered artifacts, optionally filtered by kind/lifecycle_state (item e1c979e3). Sorted by artifact_id.

  • list_remote_tasks

    32d3d5de — Read the project's persisted remote-task register (last-known status only — no live SSH check is made; call get_remote_task_status for that). By default terminal jobs are omitted so a new/resumed session sees only work that may still need checking on.

  • list_render_receipts

    1e6150ef -- list durable render receipts (and audited degraded overrides) from a receipts ledger, newest first. Args: receipts_path: Path to the JSON ledger written by ``render_with_ receipt``/``check_release_render_gate``. docx_path: Optional filter to one document's receipts. Returns: ``[]`` if the ledger doesn't exist yet or is empty; otherwise every receipt dict, newest ``created_at_epoch`` first.

  • list_research_runs

    a5343387 — list a project's research runs, newest-started first. By default terminal runs (completed/failed/abandoned/expired) are omitted so a fresh session sees only runs that may still be live.

  • list_resumable_sessions

    cdd0ef6c — Read-only: list this project's session recovery registry, newest heartbeat first, each with a freshly computed liveness classification (resumable/stale/dead/unknown). Dead rows are omitted by default.

  • list_run_manifests

    List every run-manifest record ever started under ``outputs_dir`` (item 37ce5537), sorted by ``run_id``. Args: outputs_dir: Absolute path to the outputs directory. Returns: A list of manifest record dicts; ``[]`` if none have been started yet.

  • list_sessions

    Read-only: List active sessions for a project. Useful for planning chat to see what's currently running before filing new sprint items.

  • list_watchlist_queries

    Read-only: list saved research watchlist queries for a project (optionally filtered by source_type), each with its watchlist_id, query, source_type, limit, and sort_by.

  • list_worktrees_pending_cleanup

    dffcde86 (a03c0eeb) — Read-only: list active_worktrees rows still marked active in the DB (removed_at IS NULL) whose owning sprint item has reached a terminal status (done/skipped/failed/pushed) or whose owning session is closed/archived — the real disk-cleanup candidates the periodic sweep (worktree_cleanup.sweep_stale_worktrees) reclaims. On hosted Meridian the POST /worktrees/sweep endpoint is an explicit filesystem no-op (hosted has no access to the caller's disk, so there is nothing there to remove from disk) — this tool is the DB-only, hosted-safe way to see which registry rows are stale…

  • load_handoff

    Read-only: Return the latest stored handoff for a project as an MCP tool result — a trusted-channel alternative to a copy-pasted /goal. Returns {pending_goal, pending_goal_receiver, handoff:{content, mode, session_id, created_at}, has_handoff}. Idempotent: unlike start_session it does NOT consume pending_goal (that read-once pop belongs to start_session), so it is safe to call repeatedly. (0527f636) pending_goal_receiver is the {session_name, role, worktree} address the handoff was generated FOR (generate_handoff's receiver argument), or null for an unaddressed handoff: a start_session that do…

  • locate_anchor

    2271789f -- read-only, fresh-snapshot deterministic anchor locator. Resolves ``query`` against sections, paragraphs, captions, tables (including cell text), and equations, re-parsing ``document_path`` from disk on every call (never a stale sidecar index). Query keys (all optional; at least one required): ``para_id``, ``section_path`` (e.g. "3.2.4"), ``section_text``, ``caption_label`` (e.g. "Table 3"), ``text`` (Ctrl+F-style literal substring), ``element_types``, ``case_sensitive``, and ``expected_source_fingerprint`` (detects the document having changed since a previously-returned ``source_f…

  • locate_anchors

    2271789f -- resolve multiple independent locate_anchor queries against ONE fresh parse of document_path (one source_fingerprint, one index pass), preserving query order in the returned ``results`` list. See :func:`locate_anchor` for the per-query contract and :func:`meridian_docs.docs_intel.locate_anchors` for full details.

  • log_task

    Log a task this session completed or is working on. Valid statuses: pending, in_progress, done, failed, backlog, future, backburner.

  • lookup_citation_key

    Validate a citation key against the local Zotero library's ':key:' tag convention. Mirrors GET /zotero-lookup exactly: resolved:true/false/null (null means Zotero's local API was unreachable, not 'no match').

  • lookup_published_framing

    STRETCH, OFF BY DEFAULT -- clearly separated from get_style_guide/check_section_style's safe, static, no-network default tier. Given a section_type + topic, fetches a short, properly attributed excerpt from a REAL published paper LIVE at call time, via a research/paper-search capability the calling session must wire in -- this package never hardcodes a specific provider. The excerpt is NEVER cached or bundled into this npm package: it is an ephemeral tool response only (see the result's own stored:false field). Gated off by default behind the MERIDIAN_LATEX_ENABLE_PUBLISHED_FRAMING environment…

  • mark_provenance_synced

    Mark a set of provenance rows as synced, after actually pushing them into meridian-outputs yourself in this same agent session. Mirrors POST /provenance/mark-synced exactly. Idempotent.

  • merge_docx_draft

    fe989980 — promote an isolated wave-scoped draft into canonical_path. The file-level counterpart to the Meridian core package's meridian.db.docx_merge coordination layer (open_merge_manifest / declare_merge_anchors / claim_merge_owner / check_merge_stale_or_overlap / record_merge_result / finalize_merge_manifest — a SEPARATE MCP connection, since this stdlib-only extension has no database access of its own). Call this ONLY after that DB-side gate has cleared for the caller — this tool performs no ownership/overlap/staleness checks itself; it only performs the physical promotion, verification,…

  • merge_project

    d6bd60e0 — merge a phantom-duplicate project INTO another. Re-parents EVERY child row of the source project (sprint items, tasks, decisions, insights, notes, HITL requests, sessions, handoffs, pointers, …) to the target project via pure UPDATEs — NO row is ever deleted. By default the now-empty source project is soft-archived (status='archived', name prefixed with '[merged] '), never hard-deleted; pass archive_source=false to leave it untouched. Returns {source_project_id, target_project_id, moved: {table: count}, source_archived}. Returns {error} if source==target or either project does not e…

  • merge_sprint_items

    Merge multiple sprint items into one. Source items are closed (skipped, merged_into=survivor). Returns the new survivor item.

  • move_section

    6ff24136 — Move an existing section (heading + its content) to a new location in the document. Cuts the heading at section_id and every block up to (not including) the next same-or-shallower heading, then re-inserts that exact range relative to destination_anchor_para_id. Existing paraIds/bookmarks are preserved (not regenerated), so cross-references INTO the moved section stay valid. Before anything is cut/spliced/saved, this runs two safety checks and ABORTS cleanly (file untouched) if either fails: 1. find_references_to for section_id itself, against the still-intact file. 2. A ch…

  • move_workspace_note_to_project

    Reclassify a workspace-level note (visible across ALL projects) into a single project's notes: copies title/body/tags to a new project note then removes the workspace note. Tenant-safe on the source note (scoped like every other workspace-note tool) and atomic-in-effect on the write (a concurrent move/delete of the same note is detected and compensated rather than silently duplicated). Returns the new project note, or {error} if note_id is unknown/not yours, the destination project doesn't exist, or a race already claimed the note.

  • npy_metadata

    Read metadata from a .npy file WITHOUT loading the full array. Uses numpy.load(mmap_mode='r') to read only the header, never pulling the full array into memory. Safe on large arrays. Args: path: Absolute path to the .npy file. Returns: {path, shape, dtype, size_bytes, modified_at} plus optional {error}.

  • outline_tex

    Parse raw .tex source text into its structural outline (headings, citations, tables, figures, equations). Mirrors POST /outline exactly, including its auto-register-project behavior: when project_id is given, the project's previous outline (if any) is diffed against the new one and this project_id is (re-)registered in the local store, same as a real popup /outline call would do.

  • outline_tex_file

    Parse a LOCAL .tex file on disk into its structural outline, via outlineFile(). No server or browser tab is involved at all -- this is the one thing this MCP surface can do that the Chrome-extension-only path never could: parse a paper's .tex source directly from a checked-out repo.

  • overleaf_login_status

    Check whether a saved Overleaf session exists, without ever touching or returning the session cookie itself. Wraps overleaf-login.js's status(): a pure local file read + JSON parse of the cookie file under ~/.meridian-latex (or a saved-session-free {loggedIn:false} if none exists or it can't be parsed). Mirrors the CLI's own `status` command. Read-only, no network access -- does NOT connect to Overleaf, and never returns the cookie value.

  • paper_search

    Search academic papers — a REAL external lookup. Per the research-routing protocol, use this FIRST for academic/paper questions (cite the paper itself, not a secondary write-up), then capture_research_finding to save what you cite. Sources via the 'source' param: 'arxiv' (default; preprints, physics/CS/math), 'openalex' (broadest journal/conference coverage across every discipline), 'semantic_scholar' (citation counts + TL;DRs), 'pubmed' (biomedical/agricultural), 'crossref' (the DOI registry: best for DOI resolution and venue metadata — journal name, ISSN, publisher — weaker for topical disco…

  • parse_document

    Parse a .docx into ordered paragraph records ({index, para_id, style, text}).

  • parse_provenance_envelope

    Inverse of ``serialize_provenance_envelope`` (item 0ea8fd3c): parse a JSON or XML provenance envelope payload back into its canonical dict shape. Args: payload: The serialized envelope string (as produced by ``serialize_provenance_envelope``, or hand-built by another system to the same schema). format: ``"json"`` (default) or ``"xml"`` -- must match the format ``payload`` was serialized in. Returns: The canonical envelope dict (``envelope_id``, ``generated_at``, ``records``, ``links``, ``version``, ``partial``, ``partial_reason``) -- the exact…

  • patch_file

    Make a targeted edit to a file in the project's connected GitHub repository: replace an exact substring (old_str) with new_str and commit it. old_str must match the current file contents exactly (including whitespace) and appear exactly once. Sends only the changed snippet, so it edits very large files trivially — the targeted-write counterpart to read_file.

  • pin_decision

    Create a pinned decision (editable constitution row). Use for the current authoritative truth that supersedes earlier statements. category is free-text; suggested values: STRATEGIC, COMPETITIVE, TECHNICAL, TACTICAL, BUSINESS, PRODUCT, ARCHITECTURAL.

  • pin_workspace_decision

    Pin a workspace-level decision that applies across ALL projects (shared architecture, org-wide standards). Session start and get_context_block show only a short index of the newest few decisions (one clipped line each, plus a count of the rest); a handoff carries none unless generate_handoff(mode="full") is requested explicitly. Read the full text with get_workspace_decisions; the operator setting include_workspace_context inlines it into session start and get_context_block. category is free-text (STRATEGIC, TECHNICAL, ARCHITECTURAL, PRODUCT, ...).

  • plan_batch_transform

    982f8564 -- PURE, READ-ONLY, REPRODUCIBLE dry-run for a declarative batch of operations against document_path's CURRENT on-disk content. Each operation is anchored to a stable semantic anchor (a locate_anchor-style query) with an explicit content precondition (expected_quoted_text) -- a stale anchor (the document, or just that one anchor's content, changed since the operation was authored) is rejected explicitly, never silently applied. Tables and figures are treated as OWNED COMPOUND OBJECTS with their captions: deleting one auto-includes its linked caption in the plan unless keep_caption=Tr…

  • preview_proposal_promotion

    Read-only (ce4883f3): preview what commit_proposal_promotion would do for a proposal at a given depth, WITHOUT writing anything. Depths are cumulative, shallow to deep: 'proposal' (intake/scope only) -> 'investigation' (+ raw->investigating transition) -> 'pointers' (+ pointer recording) -> 'sprint_items' (+ promote_workspace_proposal) -> 'executable_handoff' (+ a handoff scoped to the new sprint item). Returns {proposal_id, project_id, depth, already_satisfied, contract_status, would_create, wave_preview, preview_hash, computed_at}. 'already_satisfied'=true when the proposal's current status …

  • promote_docx_candidate

    W1-K — explicitly promote a status='candidate' docx derivative to be THE accepted derivative for its source_path, demoting whatever derivative previously held that role (if any) to status='superseded' in the same call — a real state transition with an audit trail (promoted_at/promoted_by_session_id on the newly-accepted row; superseded_at/superseded_by_derivative_id on the demoted one), mirroring promote_experiment_run's promotion-pattern precedent. Idempotent on an already-accepted derivative (mirrors promote_research_run's idempotency guard): a repeat call on the same derivative_id returns t…

  • promote_experiment_run

    3f6b8715 — explicitly promote a run whose stored disposition is already 'promote' (set at completion time via complete_experiment_run) — rejects with {error} otherwise. Never triggered automatically by completion. Always auto-writes a 'breakthrough' experiment_events row.

  • promote_proposal

    Promote a workspace proposal into a real sprint item, creating the link between them. The proposal must be in 'raw' or 'investigating' state. Creates a sprint item under the given project and sets the proposal's status to 'promoted' with promoted_to_sprint_item_id pointing to the new item. a8afd8f9 — when the proposal is project-scoped (created via add_proposal with a project_id) and this project_id differs from that, the promotion is rejected UNLESS allow_project_transfer=True is passed together with a non-empty transfer_reason (recorded on the resulting 'promoted' proposal_events row). A pro…

  • promote_research_run

    a5343387 — explicitly promote a completed, disposition='promote' research run into a durable, addressable project finding (kind='finding' note, discoverable via get_findings/get_notes) summarizing its receipt. Never triggered automatically by completion — promotion is always a separate, explicit call. Rejects with {error} when the run's stored disposition is not 'promote'.

  • prospect_symbol

    2ce5bc76 — ROBUST symbol prospecting with a three-rung fallback chain: tries codebase__search_graph FIRST (fast, graph-indexed); when it returns zero results OR the caller flags a mismatch (stale_graph=true), automatically retries via Serena extractor__find_symbol / extractor__find_declaration (AST-accurate, never stale); falls back to a BM25 keyword grep over search_code_semantic as a last resort so the caller NEVER has to notice a miss and switch tools by hand. Each rung is labelled in the result ({rung: 'graph'|'serena'|'semantic', hits:[...], fallback_reason: str?}) so the caller knows whi…

  • pull_doc_expanded

    Fetch one document's current, fully-expanded text from a live Overleaf project (every \input/\include reference spliced in) and return it directly, without writing a local file. Read-only, matching the CLI's own `pull` command's fetch step exactly, minus its local-file-write side effect -- an MCP tool's job is to return data to the calling agent, not manage files on disk. Connects using the locally saved Overleaf session. doc_id_or_path may be a raw doc id or a project-relative path like "chapters/intro.tex".

  • purge_ai_log

    c0168425 — Project-scoped, cutoff-based retention sweep spanning BOTH ai_log_events (meridian.db.ai_log.purge_events_before) and their stored artifacts (meridian.artifact_store.purge_artifacts_before) in one call, with a single receipt. Deletes every event/artifact strictly older than cutoff (an ISO-8601 UTC datetime, e.g. '2025-01-01T00:00:00Z') for the given project. Irreversible — this is a hard bulk delete, not a soft archive (call export_ai_log / export_ai_log_artifacts first if the data needs to survive the sweep). Returns {project_id, cutoff, events_deleted, artifacts_deleted, purged_at…

  • push_sprint_item

    Push a sprint item to a future version. Use this when scope creep means the item won't fit this sprint. ``to_version`` records where it was moved (e.g. 'v2.0'). The item status becomes 'pushed'; the next sprint can add it fresh with add_sprint_item. This DEFERS the item to the backburner and leaves its own version unchanged. To keep an item pending and only put it in another version, update_sprint_item(version=...) re-versions that one item and nothing else: unlike the dashboard's 'Move to next version' it does not work out the next number for you, does not carry the item's subtasks along (the…

  • put_cached_derived_variant

    Persist a rendered derived variant of ``source_path`` to the cache (item 19917525), recording the source's signature and content hash AT THIS MOMENT. See :func:`meridian_outputs.derived_cache.put_cached_variant` for the full contract. Written under ``<outputs_dir>/.meridian-outputs-cache/derived/`` -- the same ``.meridian-outputs-cache/`` convention every other ledger in this package already uses, so ``get_cache_quota_status`` sees this cache's disk usage for free. Args: outputs_dir: Absolute path to the outputs directory. source_path: The file this derived artifact was rendere…

  • read_document_snapshot

    Read the last saved DOCX snapshot without writing or requiring a close. c7cc9da4 -- the entry point for a Meridian-docs review session: never treats a Word ~$ lock file as a blocker, and always reads the last SAVED on-disk bytes (unsaved Word edits are invisible until saved). Returns a ``source_sha256`` fingerprint of those exact bytes -- record it and re-check it (e.g. via ``render_gate.verify_promotion_readiness``) before promoting any later draft/overlay, so a promotion never lands against content the review never actually saw -- plus an explicit ``limitations`` list spelling out both cave…

  • read_file

    Read a file from the project's connected GitHub repository. Returns decoded UTF-8 content.

  • read_note

    Read-only: Fetch one project note's full body by its per-project slug (the ``slug`` field from get_notes). The pull half of the list→read model — get_notes returns slugs without bodies, read_note pulls a single body when you need it.

  • receive_messages

    PARALLEL COORDINATION (d3a3a01d): fetch unread messages addressed to a session (oldest first) and mark them read by default. The receive side of send_message.

  • reconcile_legacy_artifact_outputs

    Migration/reconciliation report for legacy outputs against the artifact registry (item e1c979e3). Defaults to reconciling everything already known to ``annotate.list_provenance`` (the common "predates the registry" case) when ``legacy_entries`` is omitted. Args: outputs_dir: Absolute path to the outputs directory. legacy_entries: Explicit ``{kind, canonical_path, expected_sha256, generator, source_locator, role}`` dicts to reconcile, or omit to use the provenance ledger. dry_run: Preview only (default True) -- nothing is written; …

  • reconcile_sprint_drift

    Read-only: Cross-reference pending sprint items against recent git commits and return items that may already be done. Uses keyword matching — confidence 'high' means 3+ keywords overlap (safe to mark done), 'medium' means 1-2 (verify first). Also surfaces 'notes_blocker_drift': pending items whose notes describe a deferral or blocker (keywords: FLAGGED, DEFERRED, BLOCKED, 'not implementable', etc.) but whose structured fields (blocker_kind, deferred_until) are both unset — these items will keep surfacing as ordinary claimable work until you call update_sprint_item with blocker_kind='manual' or…

  • reconcile_stale_claims

    56e9b3c7 — project/version-scoped, auditable stale-claim reconciliation sweep. The bulk counterpart to claim_sprint_item's own inline autonomous reconciliation (which only ever fires reactively, on a claim attempt against one already-claimed item) — use this for a scheduler path, or an explicit human/planner/executor-triggered audit across a whole board. Scans in_progress items in project_id (optionally narrowed to one version and/or an explicit item_ids allow-list — never cross-project), classifies each claim as active/stale/ambiguous via the same multi-signal check claim_sprint_item uses (se…

  • record_experiment_event

    3f6b8715 — manually record an experiment_events row (dead_end|pivot|breakthrough|note|milestone). Separate from, and coexists freely alongside, the auto-skeleton events start_experiment_run/complete_experiment_run/promote_experiment_run/expire_stale_runs write unconditionally — this is the enrichment path for everything else worth recording.

  • record_handoff_correction

    3af86d28 — record a corrective handoff when a blocked executor session reaches a wall after receiving a handoff (its evidence/scope no longer holds, a pointer stopped resolving, a required capability went away, etc.). Links to the immutable source_handoff_id (never mutated), classifies the blocker, and carries structured investigation evidence, added/removed/superseded pointers, and changed resources. Records status='draft' by default (or pass status explicitly). Pass idempotency_key to make retries safe — a repeat call with the same key returns the existing correction unchanged rather than du…

  • record_provenance

    Record one applied edit in the local, durable provenance ledger (NOT a live meridian-outputs call -- see provenance.js's header comment for why this is a local buffer a later agent session syncs from). Mirrors POST /provenance exactly.

  • refresh_context

    Single-call post-compaction recovery for planning chats. Returns a COMPACT snapshot — current sprint + progress, next pending items, the active session id, recent handoffs, high-priority (urgent) decisions, unvalidated assumptions, and key note slugs — small enough not to overflow context. Call this the moment a chat feels disoriented (e.g. right after a /compact) to re-orient in one round-trip.

  • refresh_tool_manifest

    Read-only: return the authoritative, compact manifest of ALL built-in Meridian MCP tools (name + one-line summary). Call this when you suspect your client's tool schema went stale ('I nuked the schema', a tool you expected is suddenly 'not found', or right after a /compact) — it is a plain tool CALL, so it works even on clients that ignore the notifications/tools/list_changed signal (e.g. Claude Desktop). Names returned here are canonical: a name present here but absent from your tool list is a stale-schema artifact, not a removed tool. If you're tunnel-connected, this also forces a synchronou…

  • register_artifact

    Bind (create or update) a stable, relocation-safe public artifact identity (item e1c979e3). The public ``artifact_id`` is minted deterministically from PORTABLE signals only (``kind`` + content hash + ``generator`` + ``source_locator``) -- never from ``canonical_path`` -- so re-registering the same logical artifact after it has been moved/copied/renamed yields the identical id. ``canonical_path`` is stored only as redacted, local metadata (see ``strip_local_metadata`` for a shareable projection). Args: outputs_dir: Absolute path to the outputs directory. kind: Artifact …

  • register_docx_derivative

    W1-K — record that derivative_path (e.g. a rendered PDF/DOCX export) was generated FROM source_path at a known content state. source_content_hash is the CALLER-computed content hash of the source document at generation time (the server never reads either file itself — hash it locally, e.g. sha256, before calling this). Always creates a NEW row with status='candidate' — re-rendering the same source/derivative pair over time is expected and never overwrites a prior registration; use promote_docx_candidate to make one candidate the accepted derivative for its source. generating_tool names the too…

  • register_external_job

    Create or reaffirm a project-scoped record for long-running external work such as RunPod, SSH, Slurm, or CI. Meridian records the opaque external identity and resumable state, appends a task-log event, and writes an atomic host-local JSON snapshot. Do not include credentials or machine-local absolute paths in shared hints or metadata.

  • register_output_paths

    Directly register a small, EXPLICIT list of exactly-known output file paths so they're searchable right away (item b85394bd), instead of waiting for the ambient full-root walk to discover them on its own schedule -- the direct MCP-level counterpart to ``outputs_local.index_paths``/``register_priority_path``. The natural caller: a build/pipeline step (or an agent) that just produced or otherwise already knows a specific set of output files and wants them indexed NOW, without triggering (or waiting on) a full ``search_outputs`` rebuild pass over ``outputs_dir``. Cost is bounded by ``len(paths)`…

  • register_run_artifact

    3f6b8715 — register a project-RELATIVE artifact against a run. Rejects an absolute path (any shape capability_manifest recognizes, a bare leading '/', a drive letter, a UNC path, or a '..' traversal segment) or a secret-shaped value with {error}.

  • register_session

    Low-level: register this session without loading goal context. Use start_session instead for executor/human sessions — it registers AND returns goal + tasks in one call. Use register_session when you only need a session ID and will fetch context separately.

  • register_session_recovery

    cdd0ef6c — Create or reaffirm (upsert + heartbeat) this session's entry in the cross-client session recovery registry, so another client/session can tell whether it is resumable instead of guessing from a bare RC bridge id or transcript id. transport + optional local_identity (local_session_id, bridge_id, environment_id, argv — HOST-LOCAL ONLY) are used to compute a resume recipe and verified_resumable flag; local_identity itself is never written to the hosted registry, only to a host-local snapshot file. IMPORTANT: a remote_control transport with a bridge id but no environment_id is NOT assum…

  • release_claim

    Release this holder's claim(s). Omitting node_id releases every live claim this holder_token holds on the project (including a whole-document lease). Mirrors POST /release exactly.

  • release_docx_document_lease

    6507e83a — Release a session's whole-document lease on a .docx file, if held. Returns {released: <0 or 1>, session_id, file_path}.

  • release_docx_region_claims

    f7ee1ba7 — Release scoped docx-region claims held by a session. Without element_id releases all claims on the file; with element_id releases only that one element. Without file_path releases ALL region claims held by the session across all files.

  • release_file

    Release a file lock (and any symbol claims this session holds on it).

  • release_sprint_item_claim

    W1-I — voluntarily release a LIVE in_progress claim on a sprint item back to pending. Distinct from reconcile_stale_claims: that tool is for a claim whose owning session is dead/abandoned (multi-signal liveness classification); this is for a session that is still alive and has simply decided not to work the item after all (wrong scope, superseded, claimed by mistake) and wants to hand it back to the board cleanly instead of going silent and letting it eventually get swept as stale. Only the session recorded as the item's current actor may release its own claim — a mismatch is refused (NOT_CLAI…

  • release_task

    Release a task previously claimed by this session. Returns success=True when the claim was held by the calling session, False otherwise (someone else's lock is left untouched).

  • relocate_figure

    Move an image paragraph together with its immediately following Figure caption. figure_index is the 1-based order among direct-body image paragraphs. The operation requires the next body child to be a SEQ Figure caption and preserves the original OOXML elements and relationship IDs. It rejects bookmark-splitting moves before writing, verifies the saved document, invalidates the local structure sidecar, and renumbers Figure SEQ/REF caches after a successful reorder. fe989980 — draft_output_path + wave_run_id (both or neither): when given, writes to the ISOLATED draft_output_path instead of do…

  • relocate_sprint_item_pointer

    W1-J — atomically UPDATE an existing generic pointer's targets/source_type/label IN PLACE (a single UPDATE statement), replacing the delete_sprint_item_pointer + add_sprint_item_pointer workaround the pointer CRUD previously required to 'move' or correct a stored pointer. That two-call workaround is non-atomic: an exception between the delete and the re-add permanently loses the pointer, a concurrent get_sprint_item_pointers call in that window sees ZERO pointers for the item, and the pointer's id/created_at change — breaking anything that referenced it by its stable id (a decision's evidence,…

  • relocate_table

    c031622b — Move an existing bare <w:tbl> (no owning heading) to a new location in the document, atomically. Unlike move_section (which locates its source via a heading's para_id), a bare table has no heading to anchor on: table_index identifies it by its own 0-based body-child position — the same "index" value index_document_structure stores in the docx_tables sidecar table and get_structure_elements returns for each entry in its "tables" list. Cuts the table from its current position and re-inserts it, as ONE atomic operation, relative to destination_anchor_para_id (same anchor/position con…

  • remove_bibliography_entry

    1258794a — Remove a bibliography entry paragraph from a .docx. Locates the entry by the bibkey_<key> bookmark and removes the entire paragraph. Use this when a citation is deleted from the document body and the corresponding reference list entry should be removed. Args: docx_path: Absolute path to the .docx file (mutated in place). citation_key: The citation key of the entry to remove. index_db_path: If supplied, sidecar is invalidated after write. remove_heading_if_empty: d4a1c3e9 — if true, and this was the LAST entry under the References/Bibliography heading…

  • remove_caption

    9d749639 — Remove a Caption paragraph from a .docx file. Locates the paragraph by caption_para_id, verifies it is a Caption paragraph (Caption style or SEQ field present), removes it from the body, and re-packs the ZIP. Args: docx_path: Absolute path to the .docx file (mutated in place). caption_para_id: w14:paraId or p{N} of the Caption paragraph. index_db_path: If supplied, sidecar is invalidated after write. session_id: 273df573 — identifies the calling Meridian session to the tunnel-layer DOCX region-claim guard (check_docs_write…

  • remove_citation

    9d749639 — Remove a CSL_CITATION complex field from a paragraph. Locates the field by scanning for a complex field (fldChar begin...end) whose instrText contains CSL_CITATION, removes all its constituent runs, and re-packs the ZIP. Args: docx_path: Absolute path to the .docx file (mutated in place). anchor_para_id: w14:paraId or p{N} of the paragraph to edit. index_db_path: If supplied, sidecar is invalidated after write. match_display_text: Required when the paragraph holds more than one CSL_CITATION field -- a substring of the target f…

  • remove_cross_reference

    Remove the first REF-field cross-reference from a paragraph. The missing removal counterpart to insert_cross_reference above (which had no way to undo its own insert). Locates the first REF complex field (fldChar begin...end, excluding PAGEREF/NOTEREF) in the paragraph at anchor_para_id, removes all of that field's constituent runs, and re-packs the ZIP. Every other run in the paragraph -- other text, other fields -- is left untouched. Mirrors remove_citation exactly, one field family over. Pass the SAME anchor_para_id the matching insert_cross_reference call used; this re-locates that parag…

  • remove_equation

    a80af3a0 — Remove an equation from a .docx file. If the paragraph contains ONLY an <m:oMath> (a display-mode equation paragraph), the entire paragraph is removed. If the paragraph also contains non-equation text runs (an inline equation in a text paragraph), only the <m:oMath> elements are removed, leaving the paragraph's text intact. Args: docx_path: Absolute path to the .docx file (mutated in place). equation_para_id: w14:paraId or p{N} of the equation paragraph. index_db_path: If supplied, sidecar is invalidated after write. session_id: 273df573 — identifies t…

  • remove_package_part

    d371b00b -- reference-counted, dry-run-capable removal of an unreferenced word/media/* package part and its relationship(s). part_name (e.g. "word/media/image3.png") must name a word/media/* ZIP member — removal of any other package part is refused outright; this tool's scope is deliberately narrow, not arbitrary-part removal. Every relationship in word/_rels/document.xml.rels that targets part_name is found, then word/document.xml is scanned for any attribute referencing one of those relationship ids — a real reference count, not a heuristic restricted to just inline images. A part with a N…

  • remove_table

    0a1e9c22 — Remove an existing bare <w:tbl> from the document body, atomically. Mirrors relocate_table's addressing (0-based body-child table_index) and safety discipline (bookmark-split guard, mandatory post-write structural-count verification, promotion lock) but for deletion rather than relocation. Verification checks structural counts only (table_count and paragraph_count reduced by exactly the removed table's own content, computed from the table BEFORE it is cut) — there is no destination content to hash-verify the way a move has. Does not invoke the Word-COM render-verification gate: del…

  • rename_project

    7acb8563 — rename a project. Returns the updated project, or {error} if it does not exist.

  • render_with_receipt

    1e6150ef -- run a render attempt and build a DURABLE receipt that survives the render backend's own temp directory being cleaned up. Records source DOCX hash, produced-PDF hash/size/page count, backend name + best-effort version, process identity (word-com only), duration, attempts, timeout state, the configured backend priority order, ``field_refresh_status`` (whether this DOCX's fields will auto-update on open -- a document that won't can render "successfully" while showing stale TOC/page-number/cross-reference text), and an explicit ``visual_qa`` verdict. A successful backend CONVERSION is…

  • renumber_sequences

    595ccea1 — Re-scan SEQ Figure / SEQ Table fields and confirm/fix sequential numbering. Motivated directly by a real Figure 41/42 numbering collision found by hand after a structural move. Walks the document once in true body order, computes the correct 1-based number for each kind, and rewrites any cached SEQ number that doesn't match. Any REF field elsewhere caching the OLD "<Kind> <N>" display text for a corrected caption is also updated. A first-class primitive so move_section / copy_section can call into it rather than duplicate renumbering logic. Args: docx_path: Absolute path to…

  • reopen_proposal_gate

    Invalidate a still-standing proposal gate decision (e.g. new evidence surfaced) so resolve_proposal_gate can be called again. Resets the lane to 'blocked' (fail-safe), snapshots the prior decision into previous_decision / previous_actor / previous_decided_at, and increments reopen_count. Refuses with {error} if the gate was never decided.

  • repair_equation_batch

    e4265dd1 (MDE-B2) -- draft-only staged repair for equation-integrity defects audit_equation_integrity already found. document_path is opened READ-ONLY throughout and is NEVER the write target -- draft_output_path is, mirroring apply_batch_transform (MDE-8)'s own contract exactly. A patch manifest (reusing tools.meridian_fallbacks.patch_manifest.PatchManifest) is built and returned BEFORE any write is attempted, for every outcome including a rejected batch. ALL-OR-NOTHING: if even one operation fails validation, NOTHING is written -- draft_output_path is never created. Args: document_path: …

  • request_hitl

    Surface a question to the human-in-the-loop queue. ALWAYS use this to ask the human a question — never just ask in chat, which is invisible to the dashboard and to an unattended/autonomous run. IMPORTANT: when the project's HITL auto-answer mode is on (1=safe, 2=aggressive) and the question is not destructive / not require_human, this tool RESOLVES IMMEDIATELY and returns the chosen answer inline in the response (it does NOT block) — so calling it is cheap and is the right move even when you expect a quick yes/no. The active mode is reported in the start_session orientation as hitl_auto_answer…

  • request_manual_issue_screening_toggle

    5dfe34b2 — request enabling/disabling the OFF-by-default opt-in extension that lets the automated GitHub-issue comment/propose flow (never auto-close) also act on issues Meridian did not itself create, gated behind hardcoded content screening. enable=true ALWAYS files a require_human=true HITL (kind/require_human are hardcoded — this tool cannot be used to self-escalate; only a genuine human answering in the dashboard/API can enable it). enable=false disables immediately with no HITL (fail-safe direction) and is audit-logged either way.

  • reset_plugin_override

    Clear a tenant's stored command/config override for one plugin slot, resetting it back to the built-in default. Fixes the gap where stale_override detection (surfaced by list_plugins/get_plugin_details) could flag a stale per-tenant override but nothing could programmatically clear it — only dashboard editing worked. Self-hosted only for now: in hosted mode, returns an explicit error rather than risk writing to the wrong database (tunnel_plugins lives on the control-plane tenants table, which this tool call's db handle cannot reach there) — use the dashboard's Tunnel Plugins settings page for …

  • reset_profile_layer

    0bec79a7 (PROFILE-5) — Delete a scope's ENTIRE profile-layer row so it reverts to purely inheriting from less-specific layers — mirrors clear_capability_profile's semantics for the profile-layers contract. Idempotent: resetting an already-empty or never-set scope is a no-op, not an error. For hosted_default this clears the row (back to no-row / implicit draft) but is NOT an audited lifecycle transition — prefer activate_profile_layer's lifecycle machinery when you need an audited retire/reactivate path instead of an unaudited wipe.

  • resolve_artifact

    Resolve an artifact by public id or by local path, with an explicit resolved/ambiguous/unresolved/orphaned/hash_mismatch outcome -- never a silent basename/fuzzy guess (item e1c979e3). Args: outputs_dir: Absolute path to the outputs directory. artifact_id: Direct lookup by public id, when known. canonical_path: Resolve by content hash (strongest) or exact prior local-path sighting (weaker) when ``artifact_id`` isn't known. expected_sha256: Optional hash to verify the resolved record against. Returns: ``{status, artifact_id, reco…

  • resolve_citations

    fefb596a — resolve this project's in-text citation markers to canonical Zotero items via Zotero's LOCAL API and materialise the cross-document 'cites' -> zotero_item edges (keyed on DOI). An OPT-IN, network-making pass — deliberately separate from ingest, which stays offline. For each kind='citation' marker without a zotero_item edge, the marker's ref is resolved: a DOI (doi:.. / a bare 10.x/y / a doi.org URL) matches the library item with that DOI; a zotero:<key> ref is a direct item lookup; a bare BibTeX citekey is a best-effort text search (fuzzy without Better BibTeX). When the resolved DO…

  • resolve_figure_output

    Forward resolution: a document figure's ``file_path`` -> its generating source (item e422de44's relocation-tolerant superset). Two tiers, tried in order: 1. Exact-path (legacy contract, unchanged): the figure file IS itself an indexed output at that same path. Matching is path-normalised (handles back-slashes/forward-slashes, case differences on Windows, relative vs absolute). 2. Basename fallback: when the exact path misses -- the figure was relocated/copied/renamed relative to when it was indexed -- searches the outputs index for files sharing the same basename …

  • resolve_proposal_gate

    Record a human decision on a proposal gate: the lane's new state (blocked | quarantined | allowed), the free-text decision, and the actor who decided (decided_at is auto-stamped). Refuses with {error} if the gate was already decided and has not yet expired — call reopen_proposal_gate first. An expired prior decision is treated as lapsed and a fresh decision is accepted directly.

  • resolve_sprint_item_pointers

    2976e168 — resolve EVERY generic pointer on a sprint item to its concrete location, dispatching by selector.type. A range target returns its location as-is; symbol resolves the qualified_name against the SAME live three-rung chain prospect_symbol uses (graph → Serena → semantic, 653579c5) when this session has an active code tunnel, falling back to the cached code-graph snapshot when it doesn't; node_id looks the element up in the doc-structure store; zotero_key resolves via Zotero's local API; text_quote re-fetches the URL (or docx paragraph text) and flags content drift; finding_id looks up …

  • resume_wave

    efaa918a — STALE-MANIFEST GATING: check whether a wave run opened by start_wave_run is still safe to resume against the LIVE board before you act on its pinned manifest. Re-queries the board across ALL non-done statuses (pending, todo, in_progress, provisional_complete, indeterminate, failed, skipped, pushed) via build_board_snapshot — NEVER status='pending' alone, which is the exact b763d2ba bug class (a sibling-claimed in_progress item looks like it vanished). Fails CLOSED with SPECIFIC, actionable reasons the moment the live board differs from the pinned manifest in ANY of: revision_hash mi…

  • retrofit_plaintext_captions

    82b0b1a6 — Bulk-convert existing plain-text Figure/Table captions (hardcoded numbers, no SEQ field) into real Word SEQ fields. insert_caption above only ever creates NEW captions with real SEQ fields — nothing converted EXISTING plain-text captions (a paragraph whose visible text literally reads "Figure 41" with no SEQ field behind it at all). renumber_sequences only walks SEQ fields, so a plain-text caption is invisible to it and silently survives a renumbering pass — duplicate numbers and all. Scans every paragraph (including inside table cells) for one with no SEQ field already, whose tex…

  • run_verification

    0e973e52 — run the project's stored test_cmd on YOUR local machine via the tunnel and return a REAL, structured result — not self-reported. Fields: {exit_code, passed, failed, stdout_tail, stderr_tail, status, timed_out, verification_run_id}. Pass verification_run_id to complete_wave_gate — the server-recorded run, not a hand-typed result, is what unlocks a wave gate (0ff5e59f). Returns {status: 'not_configured'} (never an error) when no test_cmd is set; call set_executor_config(test_cmd='pixi run test') first. Requires an active `meridian --tunnel`; the hosted server has no access to your mac…

  • run_watchlist_query

    b924fd7c — re-run a saved watchlist query and diff its results against everything already captured for it. Every newly-seen result (matched by a per-source stable id — arxiv_id/openalex_id/s2_id/pmid/doi/core_id/sha/repo/hn_id, falling back to url) is auto-captured via the same durable path as capture_research_finding/save_finding, tagged so the NEXT run recognizes it as already-seen. Returns {new_count, already_seen_count, new_results, captured, total_results}. Never raises — an unresolvable watchlist_id or a network/parse failure from the underlying search both degrade to {error}.

  • runpod_check_key

    RunPod key check. Resolves a RunPod API key on this machine and confirms it works with two read-only calls to the RunPod API: one billing call and one pod listing. Returns ok, credential_source (the source kind only: env, keyring or runpodctl), pod_count (pods on the first page, up to 1000), billing_available and error. The key itself is never returned, logged or echoed. Omit credential_ref to try env:RUNPOD_API_KEY, then keyring:meridian-desktop/runpod-api-key, then runpodctl:default. Pass credential_ref to use one reference only; store a reference, never the key. Local only: refused on hoste…

  • runpod_list_pods

    RunPod pod list. Resolves a RunPod API key on this machine (the same sources as runpod_check_key) and lists one page (up to 1000) of the account's pods as summaries. Each summary has these keys, all always present, with null for a value RunPod does not supply: id (Pod.id); name (Pod.name); status (Pod.status: PROVISIONING, STARTING, RUNNING, EXITED, ERROR or TERMINATED); gpu (Pod.gpu as {id, count}, or null for a CPU pod); costPerHour (Pod.cost, the current cost in USD per hour, 0 when EXITED or TERMINATED); uptimeSeconds (Pod.runtime.uptime, seconds since the container started, null unless th…

  • save_blog_post

    Create or update a workspace-scoped blog post (draft|published|archived lifecycle). Posts belong to the whole workspace, not a single project, and are served publicly at /blog/<slug> once status='published'. Pass 'id' to update an existing post; omit it to create a new draft. 'slug' is optional (auto-derived from the title, de-duplicated). Returns the saved post with a computed 'url'.

  • save_finding

    Phase-agnostic capture primitive: turn a finding into a durable, addressable note with provenance — works with ANY source (Claude's built-in web search, the arXiv MCP, Serena, a teammate). Decoupled from search so capture survives regardless of how you found it. The summary's first line becomes the note title; the note is tagged 'finding' + the source_type. Optionally links to a pinned decision. Returns the note. In-project dedupe: if this project already has a finding for the same source (case-folded DOI, arXiv id without version, PMID, or normalised URL) nothing is created and the result car…

  • save_profile_layer

    0bec79a7 (PROFILE-5) — Validate and persist ONE layer of the hosted_default -> workspace -> user -> project -> session profile contract (see meridian.profile_contract.FIELD_REGISTRY for the full field list and per-field allowed_layers/merge_strategy/narrow_only rules). REPLACES this scope's stored fields/reset_fields wholesale (not a merge) — to add one field to an existing layer, pass the full desired field set, not a delta. Rejects deterministically with {error} on an unknown field, a field not allowed at this scope_type, a secret-shaped value, a machine-local absolute path (outside the fiel…

  • save_user_journal_style_preset

    8e2f4a17 — Validate and persist one user-defined journal-style preset into a JSON file, so it becomes resolvable by name via get_journal_style_preset(name, user_presets_path=path) from then on. Creates the file (and any missing parent directory) if needed; updates just this one entry if the file already exists, preserving every other preset already in it. overrides is validated through the same resolve_style_policy path every built-in preset goes through — a malformed override is rejected before anything is written, never silently saved as a broken preset. name may match a built-in preset's …

  • save_watchlist_query

    b924fd7c — save a recurring research query so it can be re-run and diffed over time via run_watchlist_query. Persisted as a project note (no separate table); the returned watchlist_id addresses it. Every paper_search source ('arxiv', 'openalex', 'semantic_scholar', 'pubmed', 'crossref', 'core' — core needs CORE_API_KEY) is available, plus 'github_code'/'github_repo' (meridian.github_search) and 'hn' (meridian.social_search).

  • scan_citation_keys

    1258794a — Return all citation keys present in a .docx (in appearance order). Walks every paragraph looking for CSL_CITATION complex fields (the same fields written by insert_citation) and extracts the citation key from each. Keys are deduplicated; first-appearance order is preserved. Returns [] when the document has no in-text citations or cannot be read. Args: docx_path: Absolute path to the .docx file. Returns: A list of citation key strings, e.g. ["smith2023", "doi:10.1/x"].

  • scan_stale_notes

    563118d4 — Scan a .docx for placeholder/TODO-shaped text that may now be outdated. Recurring pattern this catches: an ad-hoc bracket-header or inline note (e.g. "[NOTE: currently pending relocation]") that never got updated after the thing it describes actually happened. Paragraphs already using the structured internal-note style (insert_highlighted_note) are excluded — those are already tracked via list_internal_notes. Args: docx_path: Absolute path to the .docx file. Returns: {docx_path, findings, finding_count} where each finding is {para_id, index, text, matched_terms, bracket_hea…

  • script_content_hash

    SHA-256 of a generating script's current on-disk content (item 7518bfcd). The same primitive ``tag_output``/``check_staleness``/ ``find_stale_by_script`` use internally, exposed directly for a quick "what would tagging this script right now record?" check without needing an outputs_dir or an actual output file at hand. Args: script_path: Absolute (or resolvable) path to the script file. Returns: The hex SHA-256 digest, or None if the file can't be read (missing, moved, permissions) -- never raises.

  • search_ai_log

    d26b9943 (R2-B) — Read-only: EXACT-MATCH scoped search over ai_log_events, bounded and cursor-paginated. Every filter is a plain SQL equality (session_id/tenant_id/correlation_id/parent_event_id/actor_kind/actor_id/event_type) or an inclusive occurred_at range (since_occurred_at/until_occurred_at) — there is no lexical (FTS) or semantic index anywhere in this codebase yet, so the response's index_status field always honestly reports 'exact_only', never a fabricated 'complete'/'resolving' state. Filters are AND-ed together (more filters only ever narrow the result). Ordered newest-recorded-firs…

  • search_all

    Read-only: Universal search across all project content: tasks, notes, pinned decisions, and sprint items. Uses LIKE matching (SQLite) or ILIKE (Postgres). Returns grouped results: {tasks, notes, decisions, sprint_items, total, cursor, limit, has_more, next_cursor}. limit (default 10, clamped 1..100) and cursor (default 0) bound and page each of the four lists with one shared offset (W1-A) — pass a prior response's next_cursor back in as cursor to fetch the next page; has_more is a per-list bool so you can tell exactly which list(s) still have more. sprint_items default-collapse any parent_id/i…

  • search_code

    BM25-ranked search over one project directory. Refreshes the index first. ``project`` is an absolute directory path. Returns path, score (higher is better) and a snippet per hit.

  • search_code_semantic

    93fce816 — Cursor-style LOCAL semantic code search over a source tree, entirely in a DuckDB sidecar (no cloud round-trip). Parses Python (stdlib ast) and TypeScript/JavaScript (tree-sitter) into SEMANTIC CHUNKS at function/class/method boundaries PLUS the un-named logical blocks that a named-symbols-only graph search can't reach (module-level dict/list literals, bare calls, __main__ guards, imports) — so a term that only appears in a bare top-level call is still findable. Incremental by a content MERKLE TREE: the root hash is compared first and only divergent subtrees are walked, so only the f…

  • search_commits

    Search recent commits in the project's connected GitHub repository by message substring. Fetches up to 100 recent commits and filters by case-insensitive match. Returns helpful error if no GitHub repo is connected.

  • search_document

    BM25-search all searchable DOCX XML parts with structural filters. c7cc9da4 -- the anchor-resolution surface for review-session recommendations: every result carries a stable ``element_id`` (paragraph/heading/section/table/caption), an exact literal ``quoted_text`` (safe to quote verbatim, unlike ``snippet`` which may be "…"-truncated), and a ``word_search_locator`` -- ``{find_text, part, element_id, unique_in_part, occurrence_count_in_part}`` -- telling a reviewer whether pasting ``find_text`` into Word's own Ctrl+F box lands unambiguously on this occurrence. Image anchors resolve via a ``fi…

  • search_logs

    Lightweight, disposable regex search over a local log directory tree. Unlike ``search_outputs``, this builds NO persistent index -- logs have no guaranteed structure (rotated files, plain text, JSON-lines, syslog, mixed formats), so every call re-scans the tree fresh instead of maintaining a cache that would drift stale on the next rotation. Tier 0 (always on): a sub-second ``rg`` (ripgrep) subprocess scan; transparently falls back to an equivalent pure-Python regex scan when ``rg`` isn't on PATH. Secret-named files (.env*, *.key, *secret*, *credential*, etc.) are excluded, same as outputs i…

  • search_outputs

    BM25 full-text search over a local outputs directory tree, with a literal-filename-match boost (item c6236ef4). IMPORTANT -- a 0-hit result does NOT mean the file/term doesn't exist. On a cold or large ``outputs_dir``, indexing this tool depends on can take longer than one call's budget: check ``partial``, ``fts_pending``, ``pending_stale_count``, and ``db_write_error`` on the response before concluding "not found" -- any of them present means the index is still catching up (or a write failed and will retry), and you should re-invoke this same tool with the same ``outputs_dir``/``query`` to g…

  • search_paragraphs

    Substring-search paragraphs in a previously-built index.

  • search_server_logs

    222d54f8 — BM25 full-text search over the server_logs ring-buffer. Complements get_server_logs (which filters by level/module/since) with keyword-ranked retrieval — useful when you know WHAT went wrong but not exactly WHEN (e.g. search 'OAuth token refresh' or 'psycopg connection pool' across the last 2000 log records). Uses DuckDB native FTS (Okapi BM25) with Porter stemming over a concatenated body of level + logger + message + exc_text. Incremental: re-syncs only new/evicted rows on each call; repeat queries over an unchanged log window are near-free. Ring-buffer eviction is handled consist…

  • search_synthesis

    Read-only: Natural-language search that returns a short, CITED answer (which notes/items it drew from) synthesized over the same retrieval as search_all — not just a list of matches. Uses a cheap Haiku call when ANTHROPIC_API_KEY is set, with a deterministic fallback to the raw results (synthesized=false) otherwise. Returns {query, answer, cited, synthesized, results}.

  • search_tasks

    Read-only: Search tasks by keyword or natural-language query. Uses trigram similarity on Postgres, LIKE on SQLite. Returns top matches with similarity score.

  • send_message

    PARALLEL COORDINATION (d3a3a01d): enqueue an actor-model message to another session (session_messages table). 'Done with X, you do Y' between parallel agents. The recipient reads with receive_messages. A2A-compatible.

  • serialize_provenance_envelope

    Serialize a canonical research-evidence provenance envelope dict (item 0ea8fd3c) to a JSON or XML string. ``envelope`` is the canonical dict shape produced by this server's own ``get_provenance_status_envelope`` (or ``research_evidence.envelope_to_dict``) -- ``envelope_id``, ``generated_at``, ``records``, ``links``, ``version``, ``partial``, ``partial_reason``. Both formats are two projections of the exact same data (see ``research_evidence.envelope_to_dict``'s own docstring) -- they can never drift apart in what they're able to express, and either round-trips losslessly back through ``parse_…

  • set_active_repo

    Update the tunnel's active Serena repo at runtime. When a planning session switches to a different codebase, call this so subsequent Serena requests (find_symbol, find_referencing_symbols, etc.) route to the new repo without restarting the tunnel. Has no effect when no tunnel is connected. 32ba4125 — pass worktree_id instead of repo_path to activate a REGISTERED git worktree (one created via create_worktree / POST /projects/{id}/worktrees) as a validated code-intel context: the repo_path is resolved server-side from that worktree's own record, so an unregistered/arbitrary path can never be act…

  • set_agent_instructions

    Set or update the custom agent_instructions for a project. Instructions are injected into every start_session response so AI sessions see them automatically — no need to repeat in every session. Pass null or empty string to clear. Use for persistent rules like coding conventions, deploy steps, or codebase notes.

  • set_ai_log_export_config

    R2-G — Set per-project override config for the OPTIONAL AI-log -> OTel/self-hosted-Langfuse export adapter. Every field is optional and left-as-is when omitted (partial upsert). 'enabled=false' force-disables export for THIS project even when the global MERIDIAN_AI_LOG_OTEL_ENABLED flag is on; 'enabled=true' or omitted defers to the global flag — a project can never turn export on when the operator has globally disabled it. 'otlp_endpoint' must be an http:// or https:// URL and is validated against this codebase's shared secret/path checks (meridian.secret_redaction.check_for_secrets + meridia…

  • set_capability_manifest

    649e095f — Persist a project's structured capability manifest: a list of capability declarations, each with id, purpose, required_tools (non-empty list of tool/server names), optional fallback_chain, optional provenance (string or object), availability_policy ('required'|'optional'|'degraded_ok', default 'required'), and an optional verification_command. REPLACES the existing manifest wholesale (not a merge). Rejects deterministically with {error} on any unknown/missing field, duplicate capability id, secret-shaped value, or machine-local absolute path — manifests are shared, multi-machine pro…

  • set_capability_profile

    02038afe — Persist ONE layer of the capability-inheritance chain: workspace -> user -> project -> sprint_version -> item (least to most specific). scope_type selects the layer; scope_id is that layer's key (a tenant/workspace id for 'workspace', a user/human id for 'user', the project_id for 'project', the sprint item's id for 'item', or the project_id for 'sprint_version' — the sprint version itself is resolved from whichever sprint item you query via get_effective_capability_profile). capabilities uses the exact same schema as set_capability_manifest and REPLACES this scope's capabilities wh…

  • set_decision

    Append a decision entry to the project's append-only decisions log (v1.1.4). Each entry is prepended with a UTC date stamp so newest decisions appear first. Use this to record architectural calls, scope reductions, key trade-offs — anything a future session must know before doing the work.

  • set_executor_config

    Store per-project executor defaults (repo_path, env_file, test_cmd, test_min, deploy_cmd, shell_type, branch). Merges onto the existing config — other keys (hostnames, filesystem_roots, …) are preserved. Pass repo_paths as an array of {cwd, hostname} known locations; they are merged into the existing repo_paths (deduped) rather than overwriting, so manual + hook-registered entries coexist. Executor sessions auto-load these when start_session(role='executor') is used. Credentials rule is always injected separately: read secrets from env_file only, never remote shell.

  • set_goal

    Set or update the goal state.

  • set_north_star

    Update only the north star — the long-lived product vision that rarely changes. Distinct from the version goal (set_goal). Any team member can call this.

  • set_parent_project

    7acb8563 — set, change, or clear a project's parent AFTER creation (create_project only accepted parent_project_id at creation time). Use this to retroactively nest a project under another, or to detach it. Enforces the one-level-deep invariant (3b6ff466): the parent must exist and be top-level, a project can't be its own parent, and a project that already has subprojects can't become one. Omit parent (or pass empty) to DETACH — make it top-level. Returns the updated project; {error} on an invariant violation.

  • set_project_execution_mode

    c39a1bd3 — set, change, or repair the executor posture on an EXISTING project (create_project only accepts execution_mode at creation time, and the workspace's execution_mode_default only cascades onto NEW projects — neither path can repair an already-created project's persisted mode). Confirmed live 2026-08-26: a child project can end up interactive/relaxed despite explicit autonomous instructions in its own project prose, with no prior MCP path to correct it (only the dashboard's PATCH /projects/{id}/settings route could). 'autonomous' (default) claims and runs sprint items immediately witho…

  • set_project_use_mode

    Set a project's rights-gate use mode on an EXISTING project. 'standard_publication' (default) stores link-only images with credit and a review flag. 'commercialized' refuses their image bytes unless a human approves an override. Strict: any other value returns {error} and changes nothing. Every change writes an audit row. Returns the updated project, or {error} if it does not exist.

  • set_sprint

    Update only the sprint — the short-term focus that changes each session or week. Any team member can call this; no ownership check. If pending items from the current sprint were never started, returns a WARNING block listing them. Pass force=true to override and overwrite anyway.

  • skip_sprint_item

    Mark a sprint item skipped (intentionally not shipped). Provide a one-line ``reason`` so a future session can understand the call.

  • snapshot_document

    Save a full-text local snapshot of a document under ~/.meridian-latex/snapshots -- never touches Overleaf itself, purely a local, one-directional, timestamped copy on disk (see local-snapshot.js's own header for the pre-write-safety-net rationale). Wraps snapshotDoc(): accepts plain 'text' and splits it into lines internally before calling through, the same shape pull_doc_expanded's own 'source' field already produces and an agent could pass straight through. Returns the written file's absolute path.

  • snapshot_graph_metrics

    Record a code-graph snapshot for a session (node count, edge count, hotspot count, file churn). Call at session start and end to enable get_graph_diff comparisons.

  • social_search

    Search public social-media / discussion content — a REAL external lookup (keyless), sibling to paper_search but for social discussion rather than academic papers. Currently one keyless source via the 'source' param: 'hn' (default; Hacker News via the Algolia HN Search API, story submissions only, not raw comments). Returns {query, count, results:[{title, authors, summary, published, url, discussion_url, points, num_comments, hn_id, ...}]}.

  • split_cell

    a2cd9f54 — Split one table cell into `cols` columns and/or `rows` rows. row_index is a 0-based <w:tr> index; col_index is the target cell's STARTING grid column. Refuses (file untouched) with reason="unsupported_merge" when the target cell already has w:gridSpan > 1 or any w:vMerge — splitting an already-merged cell is not attempted. Also refuses with reason="ambiguous_grid" (cols > 1 only) under the same inconsistent-table condition insert_column checks. Column split (cols > 1): the target cell is replaced by `cols` brand-new, independent cells; every OTHER row is widened by cols - 1 grid c…

  • split_sprint_item

    Split a sprint item into multiple smaller items. The original is closed (skipped) and N new items are created with split_from referencing the original. Returns list of new items.

  • start_experiment_run

    3f6b8715 — start a new active run (trial) under an experiment. Passing pivot_parent_run_id (which must belong to the SAME experiment) auto-writes a 'pivot' experiment_events row on the new run — unconditional, not a separate step. ttl_seconds is optional and unlike start_research_run has no forced default: omitting it means the run never auto-expires via expire_stale_runs.

  • start_remote_task

    32d3d5de — Launch a long-running job on a remote host (e.g. a rented GPU pod) over a short-lived SSH connection used ONLY to start it, never held open: the command runs fully detached (nohup+setsid), so it survives the launching connection dropping for any reason. A launch that starts returns within seconds with a job_id, regardless of how long the underlying job takes — poll get_remote_task_status separately to check on it. A launch that cannot confirm within about 15 seconds is recorded as status launch_unconfirmed and may still be running on the host: confirm it with get_remote_task_status …

  • start_research_run

    a5343387 — start a bounded, ephemeral research/scratch run: an ADJACENT primitive for disposable subagent probes that should not need a formal sprint item, a formal claim_file, or a durable handoff entry unless explicitly promoted (see promote_research_run). mode='read_only' needs no claim_file at all. mode='isolated_write' requires is_isolated_worktree=true (never inferred — confirm the session is actually in an isolated git worktree, not the shared working tree) plus a non-empty allowed_paths list of project-RELATIVE paths bounding what may be written; any write outside that list is out of s…

  • start_run_manifest

    Persist an in-progress canonical run manifest for ``run_id`` (item 37ce5537) -- one durable receipt binding project/repo identity, tool/package version, command identity, input hashes, the indexing bounds actually in effect, every sibling ledger's on-disk location, and a convergence-state snapshot, all in ONE place. Composes this package's existing modules rather than duplicating them: hashes via ``fingerprint.script_content_hash``, git state via a local best-effort ``run_manifest.capture_git_state`` (this package cannot import ``meridian.executor_contract`` across the package boundary -- see…

  • start_session

    Register a session and return orientation. Compact by default (session_id, sprint focus + status counts, 3 recent tasks, board_change count) to keep an executor's context small. Pass compact=false for the full block (goal XML, decisions, MERIDIAN.md instructions, workspace context, sprint items) — or fetch it later with get_session_brief. Pass version to scope the session to one sprint-version bucket (e.g. 'v0.1.x'): the orientation's sprint counts/items filter to it and the scope is remembered for the /goal template. Omit version to auto-scope to the bucket with the most pending items (empty …

  • start_wave_run

    2a654cb0 — DURABLE WAVE STATE: open a wave run before dispatching a parallel wave. Returns an immutable wave_run_id pinned to the canonical expanded board snapshot (revision_hash + monotonic revision_counter) the wave was planned against, so a session that dies mid-wave can be resumed against a manifest whose staleness is DETECTABLE instead of assumed. The snapshot is built server-side — you cannot supply one, because the point is to pin what the server saw. Pass item_ids (the sprint items in this wave) and optionally failure_modes ({item_id: 'stop'|'continue'}) to register them as children up…

  • start_worker_session

    v1.2.0 — register a worker session and claim its task in one call. Returns a slim worker_context XML block (version_goal + claimed task + repo + test_cmd + commit_pattern + done_when) under ~500 tokens. Use this for Claude Code subprocess workers that should NOT see north_star, decisions, sprint history, or ambient task log. If task_id is omitted, the oldest unclaimed pending task is picked automatically.

  • store_finding

    PARALLEL COORDINATION (c35370cc): persist a per-task intermediate result to the session_findings table so it survives session boundaries. Parallel reader agents write findings; an orchestrator or writer agent reads them via get_findings. Unlike save_finding (which creates a research note), this is a lightweight key→content store for agent-to-agent handoff of intermediate work.

  • sync_bibliography

    1258794a — Reconcile bibliography entries against in-document citations. Scans the document for all in-text citation keys (inserted via insert_citation) and reconciles the bibliography section: - Keys with csl_items entries but no bibliography paragraph are inserted. - Keys with both in-text citations and bibliography entries are updated (in case Zotero data changed since the entry was first written). - Keys cited in-text but absent from csl_items are reported as missing_data (caller must fetch from Zotero and re-call). - Keys with bibliography entries but no longer cited in-…

  • tag_output

    Fingerprint one output file and record it in a persistent ledger, stamped with its generating script's content hash AT THIS MOMENT (item 7518bfcd). Reuses ``file_fingerprint``'s cheap per-file signature (csv_columns / json_keys / generating_script) and adds one more dimension on top: the SHA-256 of the generating script's own on-disk content, so two runs of the same script (one buggy, one fixed) that happen to produce byte-identical-looking outputs can still be told apart later via ``check_staleness``/``find_stale_by_script``. Stored in ``<outputs_dir>/.meridian-outputs-cache/fingerprint_led…

  • transfer_sprint_item_claim

    W1-I — hand a LIVE in_progress claim on a sprint item off to a different actor/session directly, without a reset-to-pending-then-reclaim cycle. The item's status never leaves in_progress, so there is no window where a third session could see it as pending and race to claim it out from under the intended recipient — only actor/claimed_at (and, best-effort, the underlying file/symbol resource locks) move to the new owner. Only the session recorded as the item's current actor may transfer its own claim away — a mismatch is refused (NOT_CLAIM_OWNER) unless force=true is explicitly passed. When to_…

  • transpose_table

    a2cd9f54 — Transpose a table's rows and columns in place. Supported ONLY for a fully rectangular table with NO w:gridSpan > 1 and NO w:vMerge anywhere — refuses with reason="unsupported_merge" otherwise (a horizontally-merged cell has no single canonical vertically-merged equivalent). Also refuses with reason="ambiguous_grid" if the table's rows do not all have the same cell count. Reuses the SAME <w:tc> element objects (never deep-copied), only repositioning them — every relationship id, bookmark, numbering reference, and run of formatted text inside a cell survives verbatim. Row heights a…

  • trigger_workflow

    Fire a GitHub Actions workflow_dispatch event in the project's connected GitHub repository. ref defaults to the project's configured branch (or main). inputs is an optional object of workflow inputs.

  • update_bibliography_entry

    1258794a — Refresh the formatted text of an existing bibliography entry. Locates the entry paragraph for citation_key by its embedded bookmark (bibkey_<key>), re-formats the reference from the updated csl_item, and replaces the text run in-place. Use this after fetching fresh Zotero data for an already-inserted entry (e.g. if the journal or author list changed). Args: docx_path: Absolute path to the .docx file (mutated in place). citation_key: The same key used when the entry was inserted. csl_item: Updated CSL-JSON item dict. index_db_path: If supplied, sidecar is invalid…

  • update_custom_hook

    b4f4627f — the previously-missing generic enable/disable/edit path for a user-defined hook (id returned by add_custom_hook / get_custom_hooks): patches name, event, matcher, script_sh, script_ps1, blocking, and/or enabled without the delete+recreate round-trip add_custom_hook/delete_custom_hook would otherwise require. At least one editable field is required. Renaming re-derives the slug (same reserved-name / uniqueness checks as add_custom_hook); the db layer raises ValueError for a bad event, the reserved 'sprint_guard' name, or a slug collision — surfaced as {error}. Returns {error} (never …

  • update_decision

    Patch a pinned decision. Pass new_title + new_body to atomically supersede (creates a new active row, marks old as superseded with back-link). Otherwise patches body/title/category/status/priority in place. Editing the body appends the previous body to the append-only edit_log (read it back via get_pinned_decisions).

  • update_external_job

    Record a new observation for an existing external job. Use job_id or job_key, and pass only fields that changed; every write appends durable history and refreshes the local crash-surviving snapshot. Terminal jobs cannot be reopened or silently replaced.

  • update_md_section

    Propose a replacement for an anchored section of an agent template doc (CLAUDE.md or AGENTS.md). Does NOT write the file directly — it creates a human-in-the-loop request carrying a diff preview. A human approves it in the dashboard, then Meridian replaces that section and stages the file for the next checkpoint commit. 'anchor' is the section name between the MERIDIAN:ANCHOR:START/END comments. (ROADMAP/DECISIONS/DEVLOG are append-only and not replaceable.) Pass force=true from a human planning session (claude.ai) to skip the HITL and apply the replacement directly; autonomous executor sessio…

  • update_paragraph

    f978e588 — ID-addressable docx WRITE (the write counterpart of the get_element_by_id / paraId read primitive). Targets ONE paragraph in a stored .docx by its w14:paraId (the 'p{index}' fallback Word writes for an unlabelled paragraph) — NEVER by text match — rewrites its runs, saves the .docx in place, and re-syncs the doc_elements index row so it matches the new text. The document must already be stored in the doc-structure store via ingest_document (which registers a docx/latex document's structure here). Pass the SAME source/path you ingested under as `doc`. Provide EXACTLY ONE of: `new_tex…

  • update_sprint_item

    Edit fields on an existing sprint item: title, version, notes, human_id (assignee), group, deferred_until (enforced deferral), track, or depends_on (dependency ordering). Only the fields you pass are changed; omitted fields are left untouched. Pass an empty string for human_id, group, deferred_until, track, or depends_on to clear it. Returns the updated item, or an error if the id is unknown. Setting prospect_bypass=true is an override of the prospecting safety gate: it needs a non-empty override_reason and a human-approved require_human HITL. The first call returns HUMAN_APPROVAL_REQUIRED; af…

  • update_workspace_settings

    Update workspace-global default settings. Pass only the fields you want to change. hitl_auto_answer_default (bool) seeds new projects' HITL auto-answer behaviour; sprint_name_default (string) is the default sprint name; handoff_template (string) overrides the default full-mode handoff with a custom template — supports {{sprint}}, {{recent_tasks}}, {{decisions}}, {{north_star}}, {{version_goal}}, {{pending_items}}, {{notes}} placeholders. execution_mode_default ('autonomous'|'interactive', '' to clear) and code_intel_enabled_default (bool) are cascade defaults seeded onto NEW projects in this w…

  • update_workspace_sprint_item

    Edit a workspace personal-backlog item: title, status, group, or human_id (assignee). Only the fields you pass are changed. Pass an empty string for group/human_id to clear it. Setting status to done/skipped/failed stamps completed_at. Returns the updated item.

  • validate_assumption

    Confirm or invalidate the assumption a pinned decision rests on, in one call — no phase switching. Stamps the decision's assumption_status (confirmed|invalidated), saves a code-anchored note with your finding, and when confirmed=false fires a BLOCKING HITL so work depending on the decision pauses for human judgment. Use the moment you discover whether an assumption holds (a planning-session prospect moment).

  • verify_artifact_hash

    Recompute a registered artifact's content hash from disk and compare it to what is on file (item e1c979e3). Args: outputs_dir: Absolute path to the outputs directory. artifact_id: The registered artifact to verify. path: Explicit path to hash; defaults to the artifact's most recently seen local path sighting. Returns: ``{artifact_id, verified, current_hash, registered_hash, path, reason}``. ``verified`` is True only when both hashes are present and equal -- a missing registered hash or unreadable path is never reported as verified.

  • verify_docx_diff

    W1-K — compare a registered docx derivative's recorded source hash against the CALLER-supplied CURRENT hash of the source document's on-disk bytes (compute it locally, e.g. sha256, immediately before calling this) and report whether the derivative is stale — i.e. whether the source has changed since this derivative was generated. Optionally also pass current_derivative_content_hash to detect the derivative itself having drifted out of band. Never errors on a 'stale' verdict — that is a normal, expected result, not a failure. Persists the verdict onto the derivative row (last_verified_at / last…

  • verify_handoff_token

    Read-only: Verify a handoff provenance token (dd07ece0). When a /goal block is copy-pasted into chat rather than delivered via the trusted MCP channel (start_session pending_goal / load_handoff), a receiving session can call this tool to independently confirm the <goal_token> line was produced by a real generate_handoff call on this server — not injected or spoofed text. The token is single-use and short-lived (a few minutes); verify immediately on receipt. Returns {valid: bool, reason: str}. reason is 'ok' on success; on failure: 'not_found', 'expired', 'already_consumed', 'wrong_project', or…

  • write_section

    82d22824 — Create a whole new section (heading + body + figure/table references) as ONE atomic operation from a structured spec. Replaces the failure-prone pattern of separate insert_caption / insert_cross_reference / raw-paragraph calls that can each independently fail or land at the wrong position: every block is validated before any XML is touched, then spliced into the document in a single write. content_spec is an ordered list of block dicts, each with a "type": {"type": "paragraph", "text": str, "references": [ref_spec, ...]} ref_spec is {"target_caption_para_id": ...} or {"b…

  • zotero_search

    Search a Zotero library — sibling to paper_search/social_search/github_search, but over YOUR OWN saved references rather than a public corpus. A public GROUP library needs no credential; a private USER library must be searched through the locally configured Zotero MCP connection so its API key stays on the workstation. Returns {query, count, results:[{title, authors, summary, published, url, zotero_key, item_type, tags, ...}]}.

Signals

Stars
0
Forks
0
Open issues
2
Weekly downloads
54
Last commit
Oct 24, 2026 (5 days ago)
Last release
Oct 1, 2026 (27 days ago)
Last package publish
Jul 6, 2026 (3 months ago)

From GitHub (fetched Oct 24, 2026) and the package registry.

Details

Registry name
io.github.ajc3xc/meridian
Version
1.0.2
Auth
Auth not stated
Packages
npm @meridianmcp/mcp
License
License unknown
First seen
Oct 24, 2026
Last checked
Oct 25, 2026
Cite this page

Meridian MCP server. Agent Mart. https://agentmart.dev/connectors/ajc3xc-meridian (last updated 2026-10-25)