knowledge operations
The exact fields each knowledge.* operation takes and returns.
Every op is POST /v1/<op> over HTTP and the MCP tool loom_<op>. The identity fields (org, namespace, agent, user_id, session_id) are filled from the token and the MCP session when a transport can; for an HTTP call with no token on a single-user server, the install's org on every op but code.* and tracker.* (which keep their plane's), and on some ops its namespace and agent; see identities and namespaces. The operations index explains role, kind and the MCP all listing. Unknown input fields are served and named in ignored_args.
knowledge.add
WHAT: Ingest a document into the knowledge base for later retrieval via loom_search.
POST /v1/knowledge.add · MCP loom_knowledge_add · role writer · idempotent
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
source_uri |
str |
required | The document's stable identifier in the namespace; get, upsert and delete name it. |
content |
str |
required | The document's extracted text; it is split into chunks, and each chunk is embedded. |
title |
str |
'' |
Document title, stored on the document and in each chunk's context, which heads the chunk's embedded text and is scored by the lexical leg. |
description |
str |
'' |
Stored (with the title) in each chunk's context, so both search legs carry doc-level context. |
tags |
list[str] |
(computed) | Labels stored on the document and on every chunk; search and list filter on them. |
metadata |
dict[str, Any] |
(computed) | Free-form JSON stored with the document and on every chunk; knowledge.get returns it. |
original_bytes_b64 |
str \| None |
None |
Original file bytes (base64), preserved alongside extracted text so users can download exactly what they uploaded. |
original_filename |
str |
'' |
Name of the uploaded file; empty keeps the prior document's name when its blob carries over. |
blob_content_type |
str |
'' |
Media type of original_bytes_b64; empty keeps the prior blob's type when it carries over. |
agent |
str |
'' |
The agent writing the document, stored on it and on every chunk for provenance; an end-user token's signed agent takes its place. |
session_id |
str |
'' |
The session the document was written in (a chat, an agent run): stored on it and on every chunk, and knowledge.search filters on it. |
source_class |
str \| None |
None |
What the content is, when it is not the writer's own: derived (an agent wrote it from other content), external (fetched: a page, a tool's result) or imported. |
| Output field | Type | Meaning |
|---|---|---|
doc_id |
str |
Id of the document version this call wrote (a fresh UUID per write). |
chunks_created |
int |
How many chunks the content was split into and embedded. |
embedding_model |
str |
Embedding model that produced the chunk vectors. |
embedding_dim |
int |
Dimension of the chunk vectors. |
namespace |
str |
Echo the JWT-bound namespace so agents cite it instead of guessing. |
source_uri |
str |
Echo of the input source_uri. |
knowledge.bulk_add
Batched ingestion: many documents in one CH round-trip.
POST /v1/knowledge.bulk_add · MCP loom_knowledge_bulk_add · role writer · idempotent
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
entries |
list[_KnowledgeBulkEntry] |
required | The documents to add (1-500), each chunked and embedded like a knowledge.add; each source_uri at most once, or the call is refused (422) with nothing written. |
agent |
str |
'' |
The agent writing the documents, stored on each and on every chunk for provenance; an end-user token's signed agent takes its place. |
session_id |
str |
'' |
The session the documents were written in (a chat, an agent run): stored on each and on every chunk, and knowledge.search filters on it. |
source_class |
str \| None |
None |
What the content is, when it is not the writer's own: derived (an agent wrote it from other content), external (fetched: a page, a tool's result) or imported. |
| Output field | Type | Meaning |
|---|---|---|
written |
list[_KnowledgeBulkEntryResult] |
One result per entry, in input order: its source_uri, new doc_id and chunk count. |
embedding_model |
str |
Embedding model that produced the chunk vectors. |
embedding_dim |
int |
Dimension of the chunk vectors. |
knowledge.bulk_delete
Soft-delete multiple documents by source_uri, in one commit.
POST /v1/knowledge.bulk_delete · MCP loom_knowledge_bulk_delete · role writer · idempotent · audited · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
source_uris |
list[str] |
required | The documents to soft-delete (1-500). |
| Output field | Type | Meaning |
|---|---|---|
deleted |
list[_KnowledgeBulkDeleteResult] |
One result per input URI, in input order, with its tombstoned chunk count (0 if none). |
total_chunks_tombstoned |
int |
Sum of each source's count, a source named twice counted once (deleted repeats it). |
knowledge.dataset_approve
Approve a dataset's schema, retyping the columns named: its rows are typed again from the stored extraction under a new snapshot.
POST /v1/knowledge.dataset_approve · MCP loom_knowledge_dataset_approve · role writer · write · audited · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
source_uri |
str |
required | The ingested source whose dataset is approved. |
dataset_id |
str |
required | The dataset to approve, as knowledge.dataset_get names it. |
snapshot_id |
str |
required | The snapshot the caller reviewed (knowledge.dataset_get); refused once another serves. |
columns |
dict[str, Literal['string', 'number', 'bool', 'date', 'datetime', 'time', 'duration']] |
(computed) | Column name to the type it is held as; the columns not named keep theirs. |
| Output field | Type | Meaning |
|---|---|---|
found |
bool |
False when the source or the dataset is not live; a later revision, or another approval that retyped the dataset, since the read is 409 PRECONDITION_FAILED (read it again). |
dataset |
DatasetOut \| None |
The dataset as approved; None when not found. |
retyped |
bool |
True when a retyped column made a new snapshot. |
knowledge.dataset_get
The typed datasets an ingested file's tables became: their schemas, what needs a person's answer, the rows rejected and, on request, the first rows.
POST /v1/knowledge.dataset_get · MCP loom_knowledge_dataset_get · role viewer · read · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
source_uri |
str |
required | The ingested source whose datasets are read. |
dataset_id |
str |
'' |
One dataset of the source; empty for all of them. |
sample_rows |
int |
0 |
Rows to return of each dataset, from its first (of the first 20 datasets). |
| Output field | Type | Meaning |
|---|---|---|
found |
bool |
False when the source has no live document; datasets is then empty. |
revision |
int |
The live document's revision. |
datasets |
list[DatasetOut] |
The live revision's datasets, in the order of the file's tables. |
knowledge.dedup_list
List cross-URI doc duplicates and (optionally) chunk-overlap clusters.
POST /v1/knowledge.dedup_list · MCP loom_knowledge_dedup_list · role admin · idempotent · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
limit |
int |
50 |
At most this many clusters of each kind (1-200). |
include_chunk_clusters |
bool |
False |
Also return chunk-level clusters (identical chunks under different URIs). |
| Output field | Type | Meaning |
|---|---|---|
doc_clusters |
list[_KnowledgeDocCluster] |
Groups of documents under different URIs whose content hash is identical. |
chunk_clusters |
list[_KnowledgeChunkCluster] |
Groups of identical chunks across URIs; empty unless include_chunk_clusters. |
knowledge.dedup_resolve
Resolve one document duplicate pair.
POST /v1/knowledge.dedup_resolve · MCP loom_knowledge_dedup_resolve · role admin · idempotent · audited · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
canonical_uri |
str |
required | The document of the pair that keep_canonical keeps. |
duplicate_uri |
str |
required | The document of the pair that keep_canonical supersedes. |
decision |
Literal['keep_canonical', 'swap'] |
required | keep_canonical supersedes duplicate_uri; swap supersedes canonical_uri. |
confirm_duplicate_uri |
str |
required | Must equal duplicate_uri, or the call fails with 400 and nothing changes. |
| Output field | Type | Meaning |
|---|---|---|
canonical_uri |
str |
Echo of the input canonical_uri. |
duplicate_uri |
str |
Echo of the input duplicate_uri. |
decision |
str |
Echo of the input decision. |
superseded_uri |
str |
The URI that was soft-superseded. |
knowledge.delete
Soft-delete a document by source_uri: writes its tombstone.
POST /v1/knowledge.delete · MCP loom_knowledge_delete · role writer · idempotent · audited · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
source_uri |
str |
required | The document to soft-delete. |
| Output field | Type | Meaning |
|---|---|---|
deleted |
bool |
True when a live document was tombstoned, or leftover chunks of a deleted or never committed source were retired. |
chunks_tombstoned |
int |
The chunks the delete retired; 0 when it had none, or when a deleted source was restored or written again before the delete took its claim. |
knowledge.formats
The document formats this deployment reads, as knowledge.ingest sends them to its extractors, and the upload's limits.
POST /v1/knowledge.formats · MCP loom_knowledge_formats · role viewer · read · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
| Output field | Type | Meaning |
|---|---|---|
formats |
list[KnowledgeFormat] |
Every format the server routes, sorted by name. |
max_upload_bytes |
int |
The largest file POST /v1/knowledge.upload stores, in bytes. |
refused_extensions |
list[str] |
Extensions the upload refuses by name (doc, xls, ppt). |
default_format |
str |
The format of a file whose name and media type name none. |
knowledge.get
Fetch a single document by source_uri.
POST /v1/knowledge.get · MCP loom_knowledge_get · role viewer · read
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
source_uri |
str |
required | The document to fetch. |
include_superseded |
bool |
False |
Also return a soft-deleted or superseded version; False returns only the live one. |
| Output field | Type | Meaning |
|---|---|---|
found |
bool |
False when no document matched; every other field except source_uri is then None. |
source_uri |
str |
The document's identifier (the input source_uri when not found). |
title |
str \| None |
Document title. |
content |
str \| None |
The document's full extracted text. |
tags |
list[str] \| None |
The document's tags. |
metadata |
dict[str, Any] \| None |
The document's metadata JSON; {} when it was empty or unreadable. |
ingested_at |
datetime \| None |
When this version of the document was written. |
superseded |
bool \| None |
True when the returned version is soft-deleted or superseded. |
doc_id |
str \| None |
Id of the returned document version. |
revision |
int \| None |
The source's revision (1, 2, ... per source_uri); 0 for a document no write numbered. |
format |
str \| None |
For a file Loom extracted (knowledge.ingest): the format it was extracted as. |
parser |
str \| None |
For an extracted file: the extractor's parser and version that read it. |
coverage |
dict[str, Any] \| None |
For an extracted file: what was extracted (unit, total, extracted, failed, lost). |
knowledge.ingest
Extract an uploaded file (the extractor service parses it, the server checks what it returns) and publish it as a document revision, asynchronously: the answer names the job, and…
POST /v1/knowledge.ingest · MCP loom_knowledge_ingest · role writer · write · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
upload_id |
str |
required | The upload_id POST /v1/knowledge.upload returned for the file. |
source_uri |
str |
required | The document's stable identifier in the namespace; a later ingest of the same source_uri publishes its next revision. |
title |
str |
'' |
Document title; empty takes the upload's file name. |
description |
str |
'' |
Prepended with the title to each chunk before embedding. |
tags |
list[str] |
(computed) | Labels stored on the document and every chunk. |
metadata |
dict[str, Any] |
(computed) | Free-form JSON stored with the document and every chunk. |
expected_revision |
int \| None |
None |
Publish only if the source's live revision is this one (0: no live document); unset publishes over whatever is live. |
allow_partial |
bool |
False |
Publish an extraction that lost part of the source (coverage incomplete), marked partial; off fails it instead. |
options |
KnowledgeIngestOptions |
(computed) | Overrides for what the file cannot say about itself. |
agent |
str |
'' |
The agent writing the document; an end-user token's signed agent takes its place. |
session_id |
str |
'' |
The session the document was written in. |
source_class |
str \| None |
None |
derived, external or imported when the content is not the writer's own. |
| Output field | Type | Meaning |
|---|---|---|
ingestion_id |
str |
The job's id; knowledge.ingest_status and knowledge.ingest_cancel take it. |
state |
str |
pending until a worker takes it. |
source_uri |
str |
|
namespace |
str |
The namespace the op reads or writes. |
knowledge.ingest_cancel
A pending job is cancelled at once; a running one stops before it publishes; a finished one stays as it ended.
POST /v1/knowledge.ingest_cancel · MCP loom_knowledge_ingest_cancel · role writer · idempotent · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
ingestion_id |
str |
required | The ingestion_id knowledge.ingest returned. |
| Output field | Type | Meaning |
|---|---|---|
found |
bool |
False when no job of this id is in the namespace. |
state |
str |
The job's state after the call: cancelled for a job that had not started, its running state when the worker will stop it before publishing, or where it already ended (a published revision stays published). |
cancelled |
bool |
True when this call stopped the job, or asked the worker to. |
knowledge.ingest_status
A knowledge.ingest job's state, stage, coverage, failure and published revision.
POST /v1/knowledge.ingest_status · MCP loom_knowledge_ingest_status · role viewer · read · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
ingestion_id |
str |
required | The ingestion_id knowledge.ingest returned. |
| Output field | Type | Meaning |
|---|---|---|
found |
bool |
False when no job of this id is in the namespace; every other field is then empty. |
ingestion_id |
str |
The job asked about. |
source_uri |
str |
|
state |
str |
pending, processing, ready, partial, failed or cancelled. |
stage |
str |
Where a processing job is, or where it last ran: parse, embed or publish; empty once it published. |
attempts |
int |
Runs of the job so far, a retry after a transient failure included. |
error_code |
str |
Why it failed (format_unavailable, encoding, incomplete_extraction, revision_conflict, too_large, no_text, retries_exhausted, ...), or retrying while it waits for its next attempt; empty otherwise. |
error_message |
str |
The failure in words, for a person; empty when it did not fail. |
format |
str |
The format the file was extracted as, empty before extraction. |
coverage |
dict[str, Any] \| None |
What the extraction covered (unit, total, extracted, failed, lost). |
warnings |
list[str] |
The extractor's warnings about the file. |
chunks |
int |
Chunks published, 0 until the job publishes. |
revision |
int |
The revision the job published, 0 until it does. |
expected_revision |
int \| None |
The revision the job requires to be live when it publishes; None for any. |
filename |
str |
The uploaded file's name. |
retrieval |
str |
Whether the document is searchable from this job: ready (published), pending (not yet), failed (it will not be) or cancelled. |
cancel_requested |
bool |
Whether knowledge.ingest_cancel was called for the job. |
created_at |
datetime \| None |
|
updated_at |
datetime \| None |
knowledge.inspect
Report a namespace's documents, read-only.
POST /v1/knowledge.inspect · MCP loom_knowledge_inspect · role viewer · read · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
sample_limit |
int |
20 |
Newest live documents listed with their chunks and decisions, and the most sample URIs per finding, 0 to 100 (default 20). |
| Output field | Type | Meaning |
|---|---|---|
org |
str |
The tenant (first element of the identity tuple). |
namespace |
str |
The namespace the op reads or writes. |
computed_at |
datetime |
When the report started (UTC). |
documents |
DocumentTotals |
Live and deleted documents by format and source scheme, and retired versions. |
chunks |
ChunkTotals |
Live chunks by embedding model, and how many knowledge.search reads (under the Postgres authority it serves the current version's alone, a document written before heads excepted). |
decisions |
DecisionTotals |
Decision rows citing a document of the namespace, by stage. |
listed |
list[InspectDocument] |
The newest live documents, at most sample_limit, newest first. |
listed_complete |
bool |
True when listed holds every live document and the count was read, and, under the Postgres authority, every document commit of the namespace was published and the listed rows were checked against it. |
findings |
list[DocumentFinding] |
One per check that ran over the documents and chunks; a clean check is an info finding with count 0. |
coverage |
ReportCoverage |
Which document checks ran and which were skipped. |
ingestions |
IngestionTotals |
knowledge.ingest jobs by state, and the sources with a job and no live document (a first ingest, or one after a delete, queued or failed). |
extraction |
ExtractionTotals |
What the extractor kept of the live ingested documents. |
ingest_findings |
list[IngestFinding] |
One per ingestion and extraction check that ran: a backlog, an extractor unavailable, missing access, content the extractor rejected, jobs that failed on the server's side, extractions that lost structure. |
memory_findings |
list[MemoryFindingRef] |
namespace.audit's oversized_values and episodic_blobs, the memory rows that may belong in documents; mentor.brief reports the same shape per agent as documents_as_memories. |
skipped |
list[str] |
Sections not read or read in part (under the Postgres authority, also what a read section may miss), as "section: reason"; an unread section's fields are null or empty, not zero. |
knowledge.list
Paginated listing of the documents of one namespace or several, for curation tools.
POST /v1/knowledge.list · MCP loom_knowledge_list · role viewer · read
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
namespaces |
list[str] |
(computed) | Also list the documents of these namespaces (or @me), each read-checked (403 for the first refused), with a next_cursor that holds only for the same namespaces; empty = namespace alone. |
tags |
list[str] |
(computed) | Documents carrying any one of these tags, in any case. |
tags_every |
bool |
False |
Require every one of tags instead of any one; default off. |
uri_prefix |
list[str] |
(computed) | Directory scope: documents whose source_uri starts with one of these prefixes; empty = no prefix filter. |
include_superseded |
bool |
False |
Also list soft-deleted and superseded documents (their superseded is True). |
limit |
int |
50 |
At most this many rows per page (1-500); next_cursor fetches the next page. |
cursor |
str \| None |
None |
opaque keyset cursor |
fields |
list[str] \| None |
None |
The output fields the caller reads (a whitelist resolved against the row model, as memory.list's is); unset, every field. |
| Output field | Type | Meaning |
|---|---|---|
rows |
list[_KnowledgeListEntry] |
Documents, newest ingested_at first. |
next_cursor |
str \| None |
Pass as cursor for the next page; None when this is the last page. |
knowledge.outline
A document's table of contents, as recorded on its chunks at ingest, and optionally one section's assembled text.
POST /v1/knowledge.outline · MCP loom_knowledge_outline · role viewer · read · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
source_uri |
str |
required | The document to outline. |
section_path |
list[str] |
(computed) | Heading breadcrumb of the section to return as section_content; empty returns the outline only. |
include_children |
bool |
True |
When True, section_content also includes the section's subsections. |
| Output field | Type | Meaning |
|---|---|---|
found |
bool |
False when no live document has this source_uri; the rest is then empty. |
source_uri |
str |
Echo of the input source_uri. |
title |
str |
Document title. |
structured |
bool |
True when the chunks carry section headings; False means sections is empty. |
chunk_count |
int |
How many chunks the document has for the current embedding model. |
sections |
list[_OutlineEntry] |
The table of contents in document order: each heading's path, depth, chunks and size. |
section_content |
str \| None |
When section_path was given: the section's text (its chunks in order) and the chunk indices it came from. |
section_chunk_idxs |
list[int] |
Chunk indices section_content was assembled from; empty when none matched. |
knowledge.query
Calculate over the live snapshots of ingested datasets with a typed plan: filters, inner joins, groups and aggregates, or the rows themselves.
POST /v1/knowledge.query · MCP loom_knowledge_query · role viewer · read · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
datasets |
list[QueryDataset] |
required | The datasets the plan reads, each under its alias. |
where |
list[QueryFilter] |
(computed) | The conditions every row read must meet, applied in each dataset before any join. |
joins |
list[QueryJoin] |
(computed) | How the datasets past the first join one already in the plan: one join each. |
group_by |
list[QueryGroup] |
(computed) | The columns the aggregates are calculated per; empty for one result row. |
aggregates |
list[QueryAggregate] |
(computed) | The calculations; empty to return the rows themselves (select). |
select |
list[QueryColumn] |
(computed) | The columns of each row returned when the plan has no aggregates; each is named <alias>.<column> in the result when the plan reads several datasets. |
order_by |
list[QueryOrder] |
(computed) | The result's order, by result column names; groups, or rows in source order, by default. |
limit |
int |
100 |
The result rows returned at most; truncated says when more matched. |
| Output field | Type | Meaning |
|---|---|---|
columns |
list[QueryResultColumn] |
The result's columns, in order. |
rows |
list[list[Any]] |
The result's rows; a decimal or an integer JSON cannot hold exactly is its text. |
row_ids |
list[list[int]] |
With no aggregates, each returned row's row id in each dataset, in the plan's dataset order. |
truncated |
bool |
True when more rows matched than limit returned. |
complete |
bool |
False when a dataset read is incomplete or rejected rows: the result may not cover the source. |
incomplete |
list[str] |
Why the result is not complete, one reason per dataset. |
receipt |
QueryReceipt |
What was read and how. |
knowledge.reads
How often agents opened each document over the last days (knowledge.get ledger rows; dashboard, assistant and bench traffic left out).
POST /v1/knowledge.reads · MCP loom_knowledge_reads · role viewer · read · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
days |
int |
7 |
Look-back window in days (1-30). |
source_uris |
list[str] |
(computed) | empty = every document read in the window |
| Output field | Type | Meaning |
|---|---|---|
window_days |
int |
The look-back window the counts cover, in days, after clamping to 1-30. |
reads |
list[dict[str, Any]] |
[{source_uri, reads, agents, last_read_at}], most read first |
knowledge.restore
Undo a knowledge.delete or knowledge.bulk_delete of one document.
POST /v1/knowledge.restore · MCP loom_knowledge_restore · role writer · idempotent · audited · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
source_uri |
str |
required | The deleted document to restore. |
if_revision |
int \| None |
None |
Precondition: restore only when the deleted document is at this revision (from knowledge.get with include_superseded=true); None restores whatever was deleted. |
| Output field | Type | Meaning |
|---|---|---|
restored |
bool |
True when the document and its chunks were made live again. |
reason |
Literal['', 'not_found', 'live', 'revision_mismatch', 'not_restorable', 'expired'] |
Why nothing was restored, "" when it was (the reasons: docs/features/knowledge.md). |
doc_id |
str |
The id of the document the answer is about: the restored one, the live one, or the deleted one left retired. |
revision |
int \| None |
That document's revision; None when no document was found. |
chunks_restored |
int |
Chunks searchable again after the restore. |
original |
Literal['kept', 'gone', 'none'] |
The stored original: kept (downloadable again), gone (the sweep had removed it, so the restored document has none) or none (it never had one). |
knowledge.search
Search the user's uploaded document library — bills, contracts, receipts, resumes, policies, manuals, technical docs.
POST /v1/knowledge.search · MCP loom_knowledge_search · role viewer · read · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
query |
str |
required | Natural-language query; it is embedded for the vector leg and tokenized for BM25. |
tags |
list[str] |
(computed) | Keep only chunks carrying at least one of these tags; empty = no tag filter. |
since_seconds |
int \| None |
None |
optional recency filter |
top_k |
int |
5 |
At most this many hits are returned (1-100). |
namespace_scope |
Literal['this', 'all_mine'] |
'all_mine' |
"this" → input.namespace only; "all_mine" → also the caller's own namespaces, up to knowledge_search_max_namespaces. |
namespaces |
list[str] |
(computed) | Search namespace and exactly these (an agent's collection, @me) instead of a fan-out; each must be one the caller may read, else the call is refused (403). |
search_mode |
Literal['hybrid', 'semantic', 'lexical'] |
'hybrid' |
hybrid: the vector leg, the BM25 lexical leg and the exact-key leg (the query's identifiers looked up in an extracted file's chunk keys) fused by reciprocal rank; semantic: vector only; lexical: BM25 only. |
lexical_weight |
float |
1.0 |
Weight of the lexical leg in reciprocal-rank fusion (hybrid mode). 1.0 = equal weight; lower it for queries whose tokens are ubiquitous in the corpus (paths, boilerplate) where the lexical leg cannot discriminate. |
narrow_spans |
bool |
False |
Needle reads: also return, per hit, the two-sentence window of the chunk nearest the query as span, so a caller after one fact reads a sentence instead of a 1,500-character section. |
collapse_sections |
bool |
True |
Keep one hit per (document, section): the best-ranked chunk represents its section and reports how many siblings it folded. |
uri_prefix |
list[str] |
(computed) | Directory scope: only chunks whose source_uri starts with one of these prefixes. |
session_ids |
list[str] |
(computed) | Only chunks of documents written in one of these sessions (a chat's own attachments, an agent run's output). |
source_classes |
list[str] |
(computed) | Only chunks of these classes, e.g. ["asserted"] for what people and their agents wrote as their own, without what an agent derived or fetched. |
formats |
list[str] |
(computed) | Only chunks of documents in these formats: an ingested file's format (sql, toml, markdown, ...), or '' for every other document, a synced one included whatever knowledge.inspect names it (knowledge.get returns null for those). |
block_types |
list[str] |
(computed) | Only chunks of these block types (sql_statement, toml_table, toml_key, heading, paragraph, code, mixed, ...). |
rerank |
str |
'' |
Reranker for the fused head: "" = the deployment default (LOOM_KNOWLEDGE_SEARCH_RERANK_DEFAULT), "none" = off, "builtin:openai[: |
| Output field | Type | Meaning |
|---|---|---|
results |
list[_SearchHit] |
Hits best first (empty when nothing matched): when reranked_by is set, the reranked head in the reranker's order, then the rest by score; else by score (then similarity). |
reranked_by |
str |
The reranker that ordered results; empty when no reranker ran, it failed, it ran past its time limit, or it kept the fused order. |
embedding_model |
str |
Embedding model the query was embedded with; only chunks of this model are searched. |
namespaces_skipped |
list[str] |
Namespaces of the caller an all_mine search did not read because it stops at memory_search_fanout_max_namespaces; address one by name to search it. |
stale_dropped |
int |
Under the Postgres authority: the candidates left out because their document's current version does not serve them (an older version still being retired, a deleted document, a write not committed); 0 otherwise. |
knowledge.source.add
Register a document source on a namespace: a kind, the ids it reads and a read-only credential.
POST /v1/knowledge.source.add · MCP loom_knowledge_source_add · role admin · write · audited · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The org. |
namespace |
str |
required | The namespace or collection the documents live in; a person's own (personal-…, single sign-on u- |
name |
str |
required | Source name: 2-32 lower-case letters, digits, - or _, starting with a letter; trimmed and lower-cased. |
kind |
str |
required | The source kind: gdrive (a shared folder), linear (a project tracker's project documents), notion (a page store's pages and databases) or recording (a meeting store's transcripts). |
config |
dict[str, Any] |
required | The ids and filters the source reads, per kind; gdrive: {folder_ids: [1-20 folder ids], include: [docs, slides, pdf, pptx, docx] (default all but docx)}; linear: {project_ids: [1-20 project ids, UUIDs]}; notion: {page_ids: [...]… |
credential |
str |
required | The source's read-only credential (gdrive: a service account's JSON key, with the folders shared to the account read-only; linear: a read-only API key of an account that sees the projects; notion: an integration token with read content… |
dry_run |
bool |
False |
Probe and write nothing. |
| Output field | Type | Meaning |
|---|---|---|
name |
str |
The registered source's name, normalised. |
kind |
str |
The source kind, normalised. |
namespace |
str |
The namespace the source was registered on. |
config |
dict[str, Any] |
The config as stored. |
probe |
KnowledgeSourceProbe |
What the probe with the credential found. |
dry_run |
bool |
True when the call only probed. |
knowledge.source.check
Probe a registered document source with its stored credential now (a check and a listing of each folder or project), nothing written.
POST /v1/knowledge.source.check · MCP loom_knowledge_source_check · role admin · idempotent · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The org. |
namespace |
str |
required | The namespace the source's documents live in. |
name |
str |
required | The source name. |
| Output field | Type | Meaning |
|---|---|---|
name |
str |
The source checked. |
reachable |
bool |
False when the probe failed; summary says why. |
documents |
int |
Documents the source lists now: at most 1000 (gdrive, recording), each project's first page (linear), the listed pages and the first 100 pages of each of up to three databases (notion). |
more |
bool |
True when more documents match than were listed, so documents is a lower bound. |
sample |
list[str] |
Up to five document titles, most recently changed first. |
summary |
str |
One line: what was found, or why it failed. |
checked_at |
str |
When the probe ran, ISO UTC. |
knowledge.source.inspect
One registered document source: its config, its sync state and the documents it wrote (the 200 most recently ingested).
POST /v1/knowledge.source.inspect · MCP loom_knowledge_source_inspect · role viewer · read · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The org. |
namespace |
str |
required | The namespace the source's documents live in. |
name |
str |
required | The source name. |
| Output field | Type | Meaning |
|---|---|---|
name |
str |
The source's name. |
kind |
str |
The source's kind. |
config |
dict[str, Any] |
The ids and filters the source reads; never a credential. |
created_by |
str |
Token subject of the admin who added it; '' with auth off. |
created_at |
str |
When it was added, ISO UTC. |
sync |
KnowledgeSourceSync |
The source's sync state: a waiting request and the last pass. |
documents |
list[KnowledgeSourceDocument] |
The source's live documents, most recently ingested first, at most 200. |
knowledge.source.list
The document sources registered on a namespace, with each one's sync state.
POST /v1/knowledge.source.list · MCP loom_knowledge_source_list · role viewer · read · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The org. |
namespace |
str |
required | The namespace the sources live in. |
| Output field | Type | Meaning |
|---|---|---|
sources |
list[KnowledgeSourceEntry] |
The namespace's active sources, by name. |
enabled |
bool |
Whether this deployment runs the sync worker (LOOM_KNOWLEDGE_SOURCE_SYNC_ENABLED); false: sources are stored and probed, but nothing pulls from them. |
accepts_sources |
bool |
False where add would refuse the namespace (PERSONAL_NAMESPACE, NAMESPACE_INACTIVE). |
knowledge.source.remove
Retire a registered document source: its registry row goes inactive and its credential is cleared.
POST /v1/knowledge.source.remove · MCP loom_knowledge_source_remove · role admin · write · audited · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The org. |
namespace |
str |
required | The namespace the source's documents live in. |
name |
str |
required | The source name. |
confirm |
str |
required | Type the source name to confirm. |
delete_documents |
bool |
False |
Record a request to retire the source's documents (default keep them). |
| Output field | Type | Meaning |
|---|---|---|
name |
str |
The source retired. |
documents_pending |
int |
Live documents the recorded delete request covers (none retired yet), 0 without delete_documents. |
knowledge.source.rotate
Replace a registered document source's credential.
POST /v1/knowledge.source.rotate · MCP loom_knowledge_source_rotate · role admin · write · audited · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The org. |
namespace |
str |
required | The namespace the source's documents live in. |
name |
str |
required | The source name. |
credential |
str |
required | The replacement credential, of the same form as add's; stored encrypted, never returned. |
| Output field | Type | Meaning |
|---|---|---|
name |
str |
The source whose credential was replaced. |
probe |
KnowledgeSourceProbe |
What the probe with the new credential found. |
rotated_at |
str |
When the credential was replaced, ISO UTC. |
knowledge.source.sync_now
Record a request to sync one document source in its sync state: the sync worker starts its next pass with it.
POST /v1/knowledge.source.sync_now · MCP loom_knowledge_source_sync_now · role admin · idempotent · audited · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The org. |
namespace |
str |
required | The namespace the source's documents live in. |
name |
str |
required | The source name. |
full |
bool |
False |
Ask for a pass that lists every document, not only those changed since the last pass. |
| Output field | Type | Meaning |
|---|---|---|
name |
str |
The source the request was recorded for. |
enabled |
bool |
Whether this deployment runs the sync worker; false: the request waits until it does. |
knowledge.synthesize
Complete a task over WHOLE documents, not a search slice: every active chunk of the named documents is read in order, in windows that respect section boundaries, each window is noted once, and the…
POST /v1/knowledge.synthesize · MCP loom_knowledge_synthesize · role viewer · idempotent · audited · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
source_uris |
list[str] |
(computed) | The documents to read in full (up to 50; this, datasets or both); unknown URIs contribute nothing. |
datasets |
list[QueryDataset] |
(computed) | Datasets to calculate over (up to 4, as knowledge.query takes them); one plan is proposed for the task, checked against their schemas and run over every row. |
task |
str |
required | What to do with the documents and datasets: a question to answer or a summary to write. |
window_chars |
int |
24000 |
Characters of document text per map call; the reduce folds notes into batches of the same size, and a calculation's note is at most half of it. |
max_answer_chars |
int |
8000 |
Cap on the answer's length in characters; a longer answer is cut and ends with …. |
max_windows |
int |
64 |
Cap on map calls; a corpus needing more is answered from the first max_windows windows and truncated is set. |
| Output field | Type | Meaning |
|---|---|---|
answer |
str |
The task's answer, citing chunks as [source#idx] and the calculation as [knowledge.query#1]; empty when it abstained. |
windows |
int |
How many windows were read (one LLM map call each). |
chunks_read |
int |
How many chunks the read windows covered. |
documents |
int |
How many of the named documents had chunks to read. |
reduce_rounds |
int |
How many fold rounds merged the notes into the answer; 1 when they fit one call. |
citations |
list[str] |
Distinct source#idx (or source#a-b, or a list of them for a window spanning documents) citations in the answer, and knowledge.query#1, in the order found; each names chunks the passes read or the calculation run. |
cited_chunks |
list[_CitedChunk] |
Each chunk the kept citations name, once, in the order first cited: its revision and its locator, so a caller can open the passage the answer came from. |
unsupported_citations |
list[str] |
Citations the model wrote naming a chunk the passes did not read, or a calculation not run; removed from answer. |
truncated |
bool |
True when the documents needed more than max_windows windows and only the first were read. |
abstain |
bool |
True when there is no answer to give; abstain_reason says why. |
abstain_reason |
str |
Why it abstained: budget_capped (over the cost cap), no_chunks (nothing to read), needs_clarification, ambiguous, invalid_plan (see clarification) or empty_answer. |
clarification |
str |
ambiguous: the question to ask; invalid_plan: why no plan held; needs_clarification: the dataset to approve (knowledge.dataset_approve); empty otherwise. |
calculations |
list[SynthesizeCalculation] |
The calculation run over the datasets, cited in answer as [knowledge.query#1]. |
model |
str |
LLM that wrote the notes and the answer; empty when it abstained before any call. |
knowledge.update_metadata
Edit doc-level metadata (title, description, tags).
POST /v1/knowledge.update_metadata · MCP loom_knowledge_update_metadata · role writer · idempotent · audited · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
source_uri |
str |
required | The live document to edit; an unknown or deleted one is a 404. |
title |
str \| None |
None |
None means "leave unchanged" (sparse update); empty string is an explicit clear. |
description |
str \| None |
None |
New description; None leaves it unchanged, empty string clears it. |
tags |
list[str] \| None |
None |
New tag list, replacing the old one; None leaves it unchanged, [] clears it. |
reindex |
bool |
False |
When True, rewrite every chunk with the new title + description in its context (re-embedded, re-scored by the lexical leg), routed through the upsert flow for identical supersession semantics (same content, fresh chunks). |
| Output field | Type | Meaning |
|---|---|---|
updated |
bool |
True when the title, description or tags changed; a reindex's rewrite shows in chunks_reindexed. |
title |
str |
Echo the post-update state so the client doesn't need to refetch. |
description |
str |
The document's description after the call. |
tags |
list[str] |
The document's tags after the call. |
chunks_reindexed |
int |
Count of chunks re-embedded when reindex=True; 0 otherwise. |
knowledge.upsert
Same fields as knowledge.add.
POST /v1/knowledge.upsert · MCP loom_knowledge_upsert · role writer · idempotent · not listed under the MCP all toolset
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
source_uri |
str |
required | The document's stable identifier in the namespace; get, upsert and delete name it. |
content |
str |
required | The document's extracted text; it is split into chunks, and each chunk is embedded. |
title |
str |
'' |
Document title, stored on the document and in each chunk's context, which heads the chunk's embedded text and is scored by the lexical leg. |
description |
str |
'' |
Stored (with the title) in each chunk's context, so both search legs carry doc-level context. |
tags |
list[str] |
(computed) | Labels stored on the document and on every chunk; search and list filter on them. |
metadata |
dict[str, Any] |
(computed) | Free-form JSON stored with the document and on every chunk; knowledge.get returns it. |
original_bytes_b64 |
str \| None |
None |
Original file bytes (base64), preserved alongside extracted text so users can download exactly what they uploaded. |
original_filename |
str |
'' |
Name of the uploaded file; empty keeps the prior document's name when its blob carries over. |
blob_content_type |
str |
'' |
Media type of original_bytes_b64; empty keeps the prior blob's type when it carries over. |
agent |
str |
'' |
The agent writing the document, stored on it and on every chunk for provenance; an end-user token's signed agent takes its place. |
session_id |
str |
'' |
The session the document was written in (a chat, an agent run): stored on it and on every chunk, and knowledge.search filters on it. |
source_class |
str \| None |
None |
What the content is, when it is not the writer's own: derived (an agent wrote it from other content), external (fetched: a page, a tool's result) or imported. |
| Output field | Type | Meaning |
|---|---|---|
doc_id |
str |
Id of the document version this call wrote (a fresh UUID per write). |
chunks_created |
int |
How many chunks the new content was split into and embedded. |
chunks_superseded |
int |
How many live chunks of the prior version were superseded; 0 on a first write. |
embedding_model |
str |
Embedding model that produced the chunk vectors. |
embedding_dim |
int |
Dimension of the chunk vectors. |
duplicate_of_uri |
str |
Content-hash dedup surfacing: warn-not-block — the upsert succeeds either way; the caller decides whether to reuse the existing doc. |
duplicate_chunk_count |
int |
New chunks whose content hash already lives under a different source_uri. |
namespace |
str |
Echo the JWT-bound namespace so agents cite it instead of guessing. |
source_uri |
str |
Echo of the input source_uri. |