Skip to main content

MCP Tools Reference

All 20 tools registered in backend/internal/api/handler/mcp.go. Every tool takes a repository argument (UUID or slug) unless noted.


Discovery

getRepositories

List the repositories the authenticated user can access. No input.

Returns: array of {id, name, slug, description, tier, roles}.


listSearchProviders

List the search providers available in this deployment and enabled for the given repository.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug

Returns: array of {id, name, enabled, is_default}. Provider ids: serper (Google web search), openalex (academic works). Repos can disable individual providers.


searchSources

Search for candidate source URLs via a registered search provider.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
querystringyesSearch query
providerstringnoserper or openalex (default: configured default, typically serper)
per_pagenumbernoPage size (0 = provider default)
cursorstringnoPagination cursor from next_cursor

Returns: array of {title, url, snippet, doi?, openalex_id?, published_at?, already_exists, existing_status}. Feed url or doi into fetchAndProcessSource; skip hits where already_exists is true.


searchFacts

Full-text search over a repository's facts.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
querystringnoPostgres websearch_to_tsquery syntax (space-separated words, quoted phrases, OR/AND, negation with -). Empty returns newest.
conceptstringnoConcept UUID or canonical name filter
contextstringnoContext filter (only with canonical-name concept)
limitnumbernoMax facts (1-200, default 10)
offsetnumbernoPagination offset (default 0)

Returns: array of {id, text, status, fact_kind, source_count, created_at}. Use getFact with an id to see source URLs.


searchConcepts

List concept groups in a repository, optionally filtered by canonical-name substring.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
querystringnoCanonical-name substring (case-insensitive)
limitnumbernoMax groups (1-200, default 50)
offsetnumbernoPagination offset (default 0)

Returns: array of {canonical_name, fact_count, contexts: [{concept_id, context, fact_count, aliases}]}.


Fact Detail

getFact

Get a single fact's metadata, source URLs, and linked concepts.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
factIdstringyesFact UUID (from searchFacts)

Returns: {id, text, status, fact_kind, embedded_model, created_at, image_url, sources: [{url, parsed_title, first_seen_at}], source_count, concepts: [{id, canonical_name, context, description}], concept_count}.


Concept Detail

getConcept

Get a concept's full group (all contexts sharing the canonical name) plus the authoritative synthesis.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
conceptstringyesConcept UUID or canonical name

Returns: the concept group (contexts, aliases, fact counts) + synthesis (the concept_syntheses content) when one exists.


getConceptSources

List the unique sources backing a concept's facts, with a fact_count per source — the provenance signal for a concept.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
conceptstringyesConcept UUID or canonical name
contextstringnoNarrows to a single context's concept_id when concept is a canonical name (default: aggregate all contexts sharing the name)
limitnumbernoMax sources (1-200, default 50)
offsetnumbernoPagination offset (default 0)

Returns: {sources: [{id, url, doi, parsed_title, parsed_author, fact_count}], total, limit, offset}.


getConceptSummaries

Get the per-context summary slices for a concept group.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
conceptstringyesConcept UUID or canonical name

Returns: array of {context, sequence_num, content, model, is_complete, covered_fact_count}. See Summaries.


getRelatedConcepts

List concepts related to a concept group, ranked by shared fact count.

Relations are classified into three bands by shared_fact_count, based on the OKT research team's graph-analysis experiments:

bandshared_fact_countdefaultshow_insignificant=true
insignificant< 3 (configured min_shared_fact_count)hiddenshown
weak3..5 (between floor and stable_shared_fact_count)shownshown
stable>= 6 (configured stable_shared_fact_count)shownshown

Below the floor (shared_fact_count < 3) a relation has low statistical significance; relations become statistically significant above 5 shared facts. By default only relations at or above the floor are returned, each labeled weak or stable. Pass show_insignificant=true to lower the floor to 1 and surface the insignificant band; it does not change labels and does not hide the weak band.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
conceptstringyesConcept UUID or canonical name
limitnumbernoMax entries (1-200, default 50)
offsetnumbernoPagination offset (default 0)
show_insignificantbooleannoWhen true, also return relations below the floor (labeled insignificant). Default false.

Returns: array of {canonical_name, concept_id, shared_fact_count, relation_kind}.


Ingestion

fetchAndProcessSource

Fetch a URL or DOI into a repository. Enqueues the full 7-stage pipeline.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
urlstringno*The URL to fetch. Required unless doi is given.
doistringno*Bare DOI (e.g. 10.1234/example). Used instead of url.
investigationIdstringnoInvestigation UUID. When set, the worker links the source into this investigation.

Returns: {job_id, source_id, resource_type}. Use getSourceTasks with the source_id to track progress.


getSourceTasks

Track ingestion progress for a repository, a single source, or an investigation's sources.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
sourceIdstringnoSource UUID filter (mutually exclusive with investigationId)
investigationIdstringnoInvestigation UUID filter (mutually exclusive with sourceId)
verbosebooleannotrue = per-job row list; false (default) = global summary
statestringnoRiver job state filter (inspection only)
kindstringnoJob kind filter (inspection only)
limitnumbernoMax jobs per page (verbose only, default 50)
cursorstringnoPagination cursor (verbose only)

Returns (summary mode): {counts_by_state, counts_by_kind, counts_by_kind_and_state, pending_count, running_count, total, complete}. complete=true means the pipeline has drained (pending_count==0 globally). Wait proportionally: 1 source takes minutes, 10 sources take 10-20 min, 100 sources take an hour. Sleep 15-30s between polls. Never synthesize while pending_count > 0.


Investigations

getInvestigation

Get an investigation's metadata and the sources it collects.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
investigationIdstringyesInvestigation UUID

Returns: {id, title, topic, created_at, updated_at, sources: [{url, parsed_title, doi, created_at, added_at}]}.


createInvestigation

Create a new investigation in a repository.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
titlestringyesInvestigation title
topicstringnoFree-text description

Returns: {id, title, topic, created_at}.


addInvestigationSource

Link an already-fetched source to an investigation. Idempotent.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
investigationIdstringyesInvestigation UUID
sourceIdstringyesSource UUID (same repository)

Returns: success/no-op confirmation. The preferred flow is fetchAndProcessSource with investigationId; use this only to reorganize already-fetched sources.


Reports

createReport

Create a report from raw markdown and enqueue autofact annotation.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
titlestringyesReport title
textstringyesReport body as raw markdown
topicstringnoFree-text description

Returns: {report_id, status}. The annotation job chunks the report into sentences, embeds each, and searches the repository's facts for similar ones above the similarity threshold. Use getReport to read the annotated body.


getReport

Get a report's metadata and per-sentence annotations.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
reportIdstringyesReport UUID (from createReport)

Returns: {id, title, topic, status, body_md, sentence_count, similarity_threshold, embedded_model, created_at, annotations: [{sentence_index, sentence_text, fact: {id, text, status, fact_kind, source_count, created_at}, score}]}. Score is cosine similarity 0..1 (higher = stronger match).


updateReport

Update a report's title/topic/body and/or reparent it. Mirrors the REST PUT /reports/{reportID}.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
reportIdstringyesReport UUID to update
titlestringyesNew title
textstringyesNew report body as raw markdown
topicstringnoNew topic / free-text description
parentIdstringnoUUID of a report to set as parent; an explicit empty string clears the parent (top-level). Omit to leave parentage unchanged
childrenIdsstring[]noExisting report UUIDs to reparent under this report

Cycle prevention: parentId must not be this report or any of its descendants. When text differs from the stored body, an auto-annotation job is enqueued and status resets to pending; reparenting alone does not re-annotate. All ids must belong to the same repository.

Returns: the updated report.


listReports

List reports in a repository with optional filtering.

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
searchstringnoMatches title or topic via ILIKE
statusstringnopending, processing, annotated, or failed
limitnumbernoMax reports (1-200, default 50)
offsetnumbernoPagination offset (default 0)

Returns: array of {id, title, topic, status, sentence_count, created_at, updated_at}. Use getReport for the full body.


getReportTasks

Track annotation job progress. Mirrors getSourceTasks (same summary/verbose modes and drain protocol).

ParamTypeRequiredDescription
repositorystringyesRepository UUID or slug
reportIdstringnoReport UUID filter
verbosebooleannotrue = per-job rows; false (default) = global summary
statestringnoRiver job state filter (inspection only)
kindstringnoJob kind filter (inspection only)
limitnumbernoMax jobs per page (verbose only, default 50)
cursorstringnoPagination cursor (verbose only)

Returns (summary mode): same shape as getSourceTasks. complete=true means the annotation has drained and getReport can be called.