| distillery_storeA | Store a new knowledge entry and return its ID with dedup/conflict information. USE WHEN: capturing a new piece of knowledge (session notes, bookmarks,
meeting minutes, ideas, etc.) into the Distillery store. PARAMS: content (str, required): The knowledge content to store. entry_type (str, required): Entry classification. Valid: [session, bookmark,
minutes, meeting, reference, idea, inbox, github, person, project, digest, feed]. author (str, required): Who authored this entry. project (str, optional): Project scope for the entry. tags (list[str], optional): Tags for categorisation; supports namespaced tags (e.g. "topic/ai"). metadata (dict, optional): Arbitrary key-value metadata. Some entry
types REQUIRE specific metadata keys (TYPE_METADATA_SCHEMAS); omitting
them returns INVALID_PARAMS naming the missing/invalid field: person: expertise (list[str]) project: repo (str) digest: period_start, period_end (str) github: repo, ref_type, ref_number; ref_type in
[issue, pr, discussion, release] feed: source_url, source_type; source_type in [rss, github]
Other types (session, bookmark, minutes, meeting, reference, idea,
inbox) accept arbitrary metadata.
source (str, optional, default="claude-code"): Origin of the entry.
Valid: [claude-code, manual, import, inference, documentation, external]. session_id (str, optional): Opaque session identifier for grouping related entries. dedup_threshold (float, optional, default=config): Cosine similarity threshold (0-1)
for near-duplicate warnings. dedup_limit (int, optional, default=config): Max duplicates to report. verification (str, optional, default="unverified"): Verification status.
Valid: [unverified, testing, verified]. expires_at (str, optional): ISO 8601 datetime; entries past expiry appear in stale results. output_mode (str, optional, default="full"): Response verbosity.
Valid: [full, summary]. Use "summary" for bulk imports to skip dedup/conflict checks. include_conflict_prompt (bool, optional, default=False): When true,
each conflict candidate carries the ~1–2 KB conflict_prompt
LLM template required to round-trip through
distillery_find_similar(conflict_check=true). Defaults to
false to keep store responses small (issue #348).
RETURNS (success): { entry_id: str, persisted: bool, dedup_action: str,
conflicts?: list[{entry_id, content_preview, similarity_score,
conflict_prompt?}], warnings?: list }
RETURNS (error): { error: true, code: "INVALID_PARAMS" | "BUDGET_EXCEEDED" | "INTERNAL", message: "..." } RELATED: distillery_find_similar (for pre-store dedup checks),
distillery_correct (to supersede an existing entry) |
| distillery_store_batchA | Batch-store multiple knowledge entries in one call (no dedup/conflict checks). USE WHEN: bulk-importing entries (e.g. GitHub history sync, migration,
backfill) where per-entry dedup is unnecessary and throughput matters. PARAMS: entries (list[dict], required): List of entry dicts. Each must have: content (str, required): The knowledge content. author (str, required): Who authored this entry. entry_type (str, optional, default="inbox"): Entry classification.
Valid: [session, bookmark, minutes, meeting, reference, idea,
inbox, github, person, project, digest, feed]. tags (list[str], optional): Tags for categorisation. metadata (dict, optional): Arbitrary key-value metadata. source (str, optional, default="claude-code"): Origin of the entry. project (str, optional): Per-entry project override.
project (str, optional): Default project applied to entries lacking one.
RETURNS (success): {
entry_ids: list[str | None], # per-item ids; null for failed items
count: int, # number actually persisted
results: list[dict], # per-item status preserving input order
} Successful items: { entry_id, persisted: true, dedup_action: "stored" } Failed items: { entry_id: null, persisted: false, error: { code, message, details? } }
Validation failures on individual items no longer abort the batch —
valid entries are persisted and failures are reported per item in
results (issue #364). Iterate results to discover failures.
RETURNS (error): { error: true, code: "INVALID_PARAMS" | "BUDGET_EXCEEDED" | "INTERNAL", message: "..." }
Top-level error is returned only for schema-level problems
(entries not a list, budget exhaustion, persistence failure).
RELATED: distillery_store (single entry with dedup/conflict checks),
distillery_watch (add feed sources with optional history sync) |
| distillery_ingest_docA | Ingest an arbitrary document (ADR, spec, decision, customer feedback). USE WHEN: importing a standalone document — a markdown ADR/spec/RFC, a
design decision, or a customer-feedback transcript/doc — so it becomes
queryable knowledge with provenance. Distinct from distillery_store
(single entry, semantic dedup) and from PreCompact transcripts: this
chunks large text into multiple linked entries and deduplicates
idempotently by content hash, so re-ingesting identical content adds
no second entry. PARAMS: text (str, required): The full document text. Large text is split
into multiple linked entries (relation_type="chunk"). author (str, required): Who is ingesting / owns this document. doctype (str, optional, default="doc"): Document kind. Valid:
[adr, spec, decision, feedback, doc]. Applied as both a
"doctype/" tag and metadata.doctype for faceted retrieval. source (str, optional): Provenance label (file path, Drive URL,
etc.). Stored in metadata.source. external_id (str, optional): Explicit dedup key. Defaults to the
SHA-256 hash of text, making re-ingest idempotent. title (str, optional): Human-readable title (stored in metadata.title). project (str, optional): Project scope. tags (list[str], optional): Extra namespaced tags. metadata (dict, optional): Arbitrary extra metadata.
RETURNS (success): { entry_ids: list[str], count: int, doctype: str,
external_id: str, chunked: bool, persisted: bool,
dedup_action: "stored" | "skipped" }
On re-ingest of identical content, persisted=false,
dedup_action="skipped", and entry_ids points at the existing entries.
RETURNS (error): { error: true, code: "INVALID_PARAMS" | "INTERNAL", message: "..." } RELATED: distillery_store (single entry with semantic dedup),
distillery_search (to retrieve ingested documents) |
| distillery_getA | Retrieve a single knowledge entry by its unique ID. USE WHEN: fetching the full content and metadata of a specific entry
(e.g. after finding its ID via search or list). PARAMS: RETURNS (success): { id: str, content: str, entry_type: str, ... }
RETURNS (error): { error: true, code: "NOT_FOUND" | "INTERNAL", message: "..." } RELATED: distillery_search (to find entries by content),
distillery_list (to browse entries by filters) |
| distillery_updateA | Update one or more fields on an existing knowledge entry. USE WHEN: modifying an entry's content, type, tags, status, or other
mutable fields. At least one updatable field must be provided. PARAMS: entry_id (str, required): UUID of the entry to update. content (str, optional): Replacement content. entry_type (str, optional): New type. Valid: [session, bookmark, minutes,
meeting, reference, idea, inbox, github, person, project, digest, feed]. author (str, optional): New author. project (str, optional): New project scope. tags (list[str], optional): Replacement tag list. status (str, optional): New status. Valid: [active, pending_review, archived]. verification (str, optional): New verification. Valid: [unverified, testing, verified]. metadata (dict, optional): Replacement metadata dict. session_id (str, optional): Session identifier for grouping. expires_at (str, optional): ISO 8601 datetime; pass null to clear.
RETURNS (success): { id: str, content: str, entry_type: str, ... } (full updated entry)
RETURNS (error): { error: true, code: "NOT_FOUND" | "INVALID_PARAMS" | "FORBIDDEN" | "INTERNAL", message: "..." } RELATED: distillery_correct (to supersede rather than edit),
distillery_get (to read before updating) |
| distillery_correctA | Store a correction that supersedes an existing entry. USE WHEN: an existing entry contains wrong information and you want to
replace it with corrected content while preserving the audit trail. PARAMS: wrong_entry_id (str, required): UUID of the entry being corrected. content (str, required): The corrected content. entry_type (str, optional): Override type; inherited from original if omitted.
Valid: [session, bookmark, minutes, meeting, reference, idea, inbox,
github, person, project, digest, feed]. author (str, optional): Override author; inherited from original if omitted. project (str, optional): Override project; inherited from original if omitted. tags (list[str], optional): Override tags; inherited from original if omitted. metadata (dict, optional): Additional metadata for the correction entry.
RETURNS (success): { correction_entry_id: str, archived_entry_id: str }
RETURNS (error): { error: true, code: "NOT_FOUND" | "INVALID_PARAMS" | "FORBIDDEN" | "INTERNAL", message: "..." } RELATED: distillery_update (for non-breaking edits),
distillery_relations (to view the 'corrects' relation) |
| distillery_listA | List knowledge entries with optional filters and pagination (newest first). USE WHEN: browsing or filtering entries without a semantic query.
Use distillery_search instead when you have a natural-language question. By default, only entries with status in (active, pending_review) are
returned — archived entries are hidden. Pass status="archived" to
list only archived entries, status="any" to include every status,
or include_archived=true to add archived entries to the default view. PARAMS: entry_type (str | list[str], optional): Filter by type, or a list of types
matched with OR (e.g. ["session", "reference"]) — pair with group_by to
aggregate across several types in one call. Valid: [session, bookmark, minutes,
meeting, reference, idea, inbox, github, person, project, digest, feed]. author (str, optional): Filter by author. project (str, optional): Filter by project scope. tags (list[str], optional): Filter by tags (AND match). status (str, optional): Filter by status. Valid: [active, pending_review,
archived, any]. Default hides archived; use "any" to include all. verification (str, optional): Filter by verification. Valid: [unverified, testing, verified]. source (str, optional): Filter by origin. Valid: [claude-code, manual, import,
inference, documentation, external]. As a convenience, a URL-shaped value
(starting with "http://" or "https://") is aliased to feed_url so
source="https://hnrss.org/frontpage" matches feed items ingested from
that source (same semantics as passing feed_url=...). session_id (str, optional): Filter by session identifier. date_from (str, optional): ISO 8601 lower bound on created_at. date_to (str, optional): ISO 8601 upper bound on created_at. limit (int, optional, default=20): Max entries to return (1-500). offset (int, optional, default=0): Pagination offset. tag_prefix (str, optional): Filter tags by namespace prefix. output_mode (str, optional, default="summary"): Response shape.
Valid: [full, summary, ids, review]. "summary" returns id/title/tags/project/
author/created_at plus a ~200-char content_preview (default — keeps responses
small to conserve context). "full" returns entire content body. "ids" returns
id/entry_type/created_at only. "review" filters to pending_review and enriches
with confidence/classification_reasoning. content_max_length (int, optional): Truncate content to N chars (full mode only). stale_days (int, optional): Restrict to entries not accessed in N days (>= 1). group_by (str, optional): Return grouped counts instead of entries.
Valid: [entry_type, status, author, project, source, tags].
Mutually exclusive with output="stats". output (str, optional): Set to "stats" for aggregate statistics.
Mutually exclusive with group_by. feed_url (str, optional): Filter to entries ingested from a registered feed
source URL (matches metadata.source_url written by the poller). Use this to
retrieve all items polled from e.g. "https://hnrss.org/frontpage". include_archived (bool, optional, default=False): Include archived entries
in the default view (same effect as status="any" when status is unset). published_after (str, optional): ISO 8601 inclusive lower bound on
metadata.published_at (the feed-item publication timestamp written by the
poller). Use this to bound the /radar candidate set by the digest window. published_before (str, optional): ISO 8601 inclusive upper bound on
metadata.published_at. include_evergreen (bool, optional, default=False): When False (default) and
published_after/published_before is set, also drops entries flagged
metadata.backfill=true so first-poll backfill items don't surface as
"new intelligence". Set to True to surface older / evergreen items
explicitly. See issue #444. structural (list[str], optional): Surface entries with specific graph
anomalies relative to entry_relations. Accepted values:
["orphans"] — entries that do not appear as either endpoint of any
relation row. Unknown values yield INVALID_PARAMS. Combines (AND) with
every other filter (project, tags, status, date range, stale_days,
etc.) — orphans are first restricted by those filters, then the
no-relations predicate is applied.
RETURNS (success): { entries: list, count: int, total_count: int, limit: int,
offset: int, output_mode: str } — when structural is set, the payload
additionally includes structural_filter (comma-joined applied filters,
e.g. "orphans"). Existing fields are unchanged.
RETURNS (error): { error: true, code: "INVALID_PARAMS" | "INTERNAL", message: "..." } RELATED: distillery_search (for semantic search),
distillery_status (for lightweight server health/metadata) |
| distillery_searchA | Search knowledge entries using semantic similarity (cosine distance, ranked descending). USE WHEN: finding entries that match a natural-language question or topic.
Each result includes a similarity score (0-1, higher is more relevant). By default, only entries with status in (active, pending_review) are
considered — archived entries are hidden. Pass status="archived"
to search only archived entries, status="any" to include every
status, or include_archived=true to add archived entries to the
default candidate set. When expand_graph=true, after the semantic search returns its
seed result set, the tool BFS-expands 1 or 2 hops via
entry_relations to surface structurally connected entries.
Graph entries are scored at parent_score * 0.5 ** depth, marked
with provenance="graph", and merged into the result list (sorted
by descending score, truncated to limit). Seeds are tagged
provenance="search". The envelope gains a graph_expansion
summary. When expand_graph=false (default), the existing
envelope is unchanged — strictly additive. PARAMS: query (str, required): Natural-language search query. entry_type (str | list[str], optional): Filter by type, or a list of
types matched with OR (e.g. ["session", "reference"]). author (str, optional): Filter by author. project (str, optional): Filter by project scope. tags (list[str], optional): Filter by tags (AND match). status (str, optional): Filter by status. source (str, optional): Filter by origin. session_id (str, optional): Filter by session identifier. date_from (str, optional): ISO 8601 lower bound. date_to (str, optional): ISO 8601 upper bound. limit (int, optional, default=10): Max results (1-200). tag_prefix (str, optional): Filter tags by namespace prefix. include_archived (bool, optional, default=False): Include archived entries
in the candidate set. published_after (str, optional): ISO 8601 inclusive lower bound on
metadata.published_at (poller-recorded publication timestamp). Used by
/radar to bound the candidate set by the configured digest window. published_before (str, optional): ISO 8601 inclusive upper bound on
metadata.published_at. include_evergreen (bool, optional, default=False): When False (default) and
published_after/published_before is set, also drops entries flagged
metadata.backfill=true so first-poll backfill items don't surface as
"new intelligence". Set to True to surface older / evergreen items
explicitly. See issue #444. expand_graph (bool, optional, default=False): When true, expand the seed
result set via entry_relations and merge the neighbours into the
results. expand_hops (int, optional, default=1): Depth of graph expansion when
expand_graph=true. Must be 1 or 2. output_mode (str, optional, default="summary"): Response shape.
Valid: [summary, full, ids]. "summary" returns score plus a compact entry
(id/title/~200-char content_preview, no full body — default, keeps responses
small to conserve context). "full" returns score plus the entire entry
(pre-output_mode behaviour). "ids" returns score + id only.
RETURNS (success): { results: [{ score: float, ... }], count: int }.
Result shape follows output_mode: "summary" (default) nests a compact
entry (no full content); "full" nests the complete entry; "ids"
returns score + id only.
When expand_graph=true each result also has provenance ("search" or
"graph"); graph results additionally carry depth and parent_id, and
the envelope includes graph_expansion: { seed_count, expanded_count }.
RETURNS (error): { error: true, code: "INVALID_PARAMS" | "BUDGET_EXCEEDED" | "INTERNAL", message: "..." } RELATED: distillery_list (for filter-based browsing without semantic ranking),
distillery_find_similar (to compare against arbitrary text) |
| distillery_find_similarA | Find stored entries similar to the given text (cosine similarity). USE WHEN: checking for duplicates or conflicts before storing, finding
entries related to arbitrary text, or surfacing hidden connections to a
known entry (entries that are similar but not yet linked via relations).
Supports progressive disclosure modes. PARAMS: content (str, optional): Text to compare against stored entries.
Required unless source_entry_id is provided. When both are set,
content wins as the similarity probe. threshold (float, optional, default=0.8): Cosine similarity cutoff (0-1). limit (int, optional, default=10): Max results (1-200). dedup_action (bool, optional, default=false): When true, includes dedup
check with recommended action (create/skip/merge/link). conflict_check (bool, optional, default=false): When true, includes
conflict candidates with LLM evaluation prompts. llm_responses (list[dict], optional): With conflict_check=true, evaluates
LLM conflict verdicts. Each item: { entry_id: str, is_conflict: bool, reasoning: str }. source_entry_id (str, optional): Anchor entry whose content is used
as the similarity probe when content is omitted, and whose id is
self-excluded from results. Required when exclude_linked=true. When
set without content/dedup/conflict/accept_action, reuses the entry's
STORED embedding (no re-embed, no embedding-budget spend). source_entry_ids (list[str], optional): BATCH mode. Up to 50 seed
ids. Reuses each seed's STORED embedding (no re-embed, no
embedding-budget spend) and runs all similarity queries in ONE
round-trip. Standalone — cannot be combined with content,
source_entry_id, dedup_action, conflict_check, accept_action, or
llm_responses (INVALID_PARAMS). Honours threshold, limit, and
exclude_linked per seed; each seed always self-excludes. exclude_linked (bool, optional, default=false): When true, filters out
entries already linked to source_entry_id (or, in batch mode, to each
seed) via entry_relations (any direction, any relation_type).
Surfaces hidden connections. accept_action (str, optional): When set, persists an
entry_relations row from source_entry_id to each result above
threshold. Valid: ['link' → related, 'merge' → merge_source,
'duplicate' → duplicate]. Requires source_entry_id. Idempotent via
the unique (from_id, to_id, relation_type) index.
RETURNS (success, single/content): { results: [{ score: float, entry: {...} }], count: int,
threshold: float,
dedup?: { action: str, similar_entries: list },
conflict_candidates?: list, conflict_evaluation?: dict,
excluded_linked_count?: int }
Note: excluded_linked_count is present whenever source_entry_id is
set or exclude_linked=true. It counts both linked-source exclusions
(when exclude_linked=true) and the self-exclusion of source_entry_id
itself (when source_entry_id == candidate); a non-zero value is
therefore possible even with exclude_linked=false.
RETURNS (success, batch / source_entry_ids):
{ results_by_seed: { "": { results: [{ score: float, entry: {...} }],
count: int, excluded_count: int } },
seed_count: int, threshold: float }
A seed with no stored embedding maps to an empty results list (not an
error). excluded_count is best-effort (reported as 0 in batch mode).
RETURNS (error): { error: true, code: "INVALID_PARAMS" | "NOT_FOUND" | "BUDGET_EXCEEDED" | "INTERNAL", message: "..." } RELATED: distillery_store (stores with automatic dedup/conflict checks),
distillery_search (for natural-language queries),
distillery_relations (to inspect existing links between entries) |
| distillery_classifyA | Apply a pre-computed classification to an existing entry. USE WHEN: you have determined an entry's type and confidence via LLM
or heuristic analysis and want to persist the classification result. PARAMS: entry_id (str, required): UUID of the entry to classify. entry_type (str, required): Assigned type. Valid: [session, bookmark, minutes,
meeting, reference, idea, inbox, github, person, project, digest, feed].
Common intuitive aliases like "note" are NOT accepted but the
error response includes a details.suggestion pointing to the
canonical type (e.g. "note" -> "inbox"). confidence (float, required): Classification confidence (0-1). Entries below
the configured threshold (default 0.6) go to pending_review. reasoning (str, optional): Explanation of the classification decision. suggested_tags (list[str], optional): Tags to merge onto the entry. suggested_project (str, optional): Project to assign if entry has none.
RETURNS (success): { id: str, entry_type: str, status: str, ... } (full updated entry)
RETURNS (error): { error: true, code: "NOT_FOUND" | "INVALID_PARAMS" | "INTERNAL",
message: "...", details?: { field, provided, allowed, suggestion? } } RELATED: distillery_resolve_review (to act on pending_review entries),
distillery_list (with output_mode="review" to see the review queue) |
| distillery_resolve_reviewA | Resolve a pending-review entry by approving, reclassifying, or archiving it. USE WHEN: acting on entries in the review queue (entries with
status=pending_review from low-confidence classifications). PARAMS: entry_id (str, required): UUID of the pending-review entry. action (str, required): Resolution action. Valid: [approve, reclassify, archive]. new_entry_type (str, optional): Required when action="reclassify".
Valid: [session, bookmark, minutes, meeting, reference, idea, inbox,
github, person, project, digest, feed]. reviewer (str, optional): Reviewer identity for audit metadata.
RETURNS (success): { id: str, status: str, ... } (full updated entry).
When the requested action is a no-op (e.g. approve on an already-active
entry), the response also includes { already_in_state: true } and the
entry is returned unchanged (version is NOT bumped, reviewed_at /
archived_at are NOT rewritten).
RETURNS (error): { error: true, code: "NOT_FOUND" | "INVALID_PARAMS" | "FORBIDDEN" | "INTERNAL", message: "..." } RELATED: distillery_classify (to classify entries),
distillery_list (with output_mode="review" to see the queue) |
| distillery_watchA | Manage monitored feed sources for ambient intelligence. USE WHEN: listing, adding, or removing RSS/GitHub feed sources
that Distillery polls for new content. PARAMS: action (str, required): Operation to perform. Valid: [list, add, remove]. url (str, required for add/remove): Feed URL or GitHub owner/repo slug. source_type (str, required for add): Feed type. Valid: [rss, github]. label (str, optional): Human-readable label for the source. poll_interval_minutes (int, optional, default=60): Polling frequency in minutes. trust_weight (float, optional, default=1.0): Source trust weight (0-1). thresholds (object, optional): Per-source overrides for the global
feeds.thresholds values. Mapping with optional float keys
alert and/or digest in [0.0, 1.0] (when both set,
digest <= alert). When omitted, the global cutoffs apply
(pre-existing behaviour). Use this to raise the bar for noisy
aggregators (HN/Lobsters/Reddit) since trust_weight only
attenuates downward. sync_history (bool, optional, default=false): When true and source_type is
"github", kicks off an async background import of historical issues/PRs
(returns immediately with job_id; use distillery_sync_status to check progress). purge (bool, optional, default=false): When true and action is "remove",
archives all entries from the removed source (soft-delete). Returns the
count of archived entries in purged_entries. probe (bool, optional, default=true): When adding, lightly probe the URL
for reachability (HEAD with GET fallback, short timeout). Returns an
INVALID_PARAMS error (with details.probe_failed=true) if the probe fails. force (bool, optional, default=false): When adding, persist the source
even if the reachability probe fails (useful for sites that block HEAD
but work via the poller). mode (str, optional, github only): Which content-bearing surface to poll.
Valid: [releases, events]. Defaults to "releases" (one body-bearing
entry per release). "events" is the opt-in contentless firehose.
RETURNS (success): { sources: list, count: int } (list) or
{ added: dict, sources: list, sync_job?: dict } (add) or
{ removed_url: str, removed: bool, sources: list, purged_entries?: int } (remove)
RETURNS (error): { error: true, code: "INVALID_PARAMS" | "CONFLICT"
| "INTERNAL", message: "..." } RELATED: distillery_configure (to adjust feed thresholds),
distillery_store_batch (for bulk entry ingestion) |
| distillery_relationsA | Manage typed relations between knowledge entries. USE WHEN: linking entries together (e.g. marking one as blocking another,
citing a reference, or flagging duplicates), walking the relation
graph from a seed entry to surface multi-hop neighbours, or computing
graph metrics (bridges, communities) on the relations subgraph. PARAMS: action (str, required): Operation. Valid: [add, get, remove, traverse, metrics, promote_entities]. from_id (str, required for add): Source entry UUID. to_id (str, required for add): Target entry UUID. relation_type (str, required for add, optional for get/traverse): Relation type.
Valid: [link, corrects, supersedes, related, blocks, depends_on, citation,
duplicate, merge_source, sync_source, mentions, chunk]. weight (float, optional for add): Edge strength (e.g. interest/engagement
magnitude). On a re-assert of an existing edge, supplied attributes are upserted. valid_at / invalid_at (str ISO 8601, optional for add): Bi-temporal validity
window — when the relationship became / stopped being true (invalid_at null = current). metadata (object, optional for add): Arbitrary per-edge attributes (JSON). entry_id (str, required for get/traverse, required for metrics scope='ego'):
Entry UUID to query relations for (BFS root for traverse / ego-graph). direction (str, optional for get/traverse, default="both"): Filter direction.
Valid: [outgoing, incoming, both]. relation_id (str, required for remove): UUID of the relation to delete. hops (int, optional for traverse, default=2): BFS depth, capped at [1, 3]. metric (str, required for metrics): Graph metric to compute.
Valid: [bridges, communities, constraint, link_prediction, orphans].
Requires the [graph] optional extra. scope (str, optional for metrics, default="global"): Subgraph scope.
Valid: [global, ego]. "ego" requires entry_id. limit (int, optional for metrics, default=10): top-k results.
bridges = entries by betweenness centrality; communities = K
largest communities; constraint = entries by lowest Burt constraint
(strongest structural-hole brokers); link_prediction = top predicted
edges by Adamic-Adar (pass entry_id to score adjacencies for one entry);
orphans = sample (<=50) of entry IDs absent from the relations graph
(unlinked entries — feeds a linking / gap-scan pass). project / tags / date_from / date_to (optional, metrics global scope):
restrict the entries whose relations participate in the graph.
RETURNS (success): { relation_id: str, from_id: str, to_id: str, relation_type: str,
weight: float | null, valid_at: str | null, invalid_at: str | null,
metadata: object | null } (add) or
{ entry_id: str, relations: list, count: int } (get) or
{ relation_id: str, removed: bool } (remove) or
{ action: "traverse", root: str, hops: int, direction: str, relation_type: str | null,
nodes: [{id: str, depth: int}], edges: [{from_id, to_id, relation_type}],
node_count: int, edge_count: int } (traverse) or
{ action: "metrics", metric: str, scope: str, node_count: int, edge_count: int,
total_entries: int, graph_node_count: int, orphan_rate: float,
results: list, count: int, computed_at: str, cache_hit: bool } (metrics).
orphan_rate = 1 - graph_node_count/total_entries (graph-health signal;
0.0 when total_entries is 0). Or
{ action: "promote_entities", entities_created: int, entities_reused: int,
mentions_created: int, threshold: int } (promote_entities).
Scans entity/* and tech/* tags and promotes any canonical tag
meeting the configured tags.entity_promotion_threshold to an ENTITY
entry node, linking each tagged entry with a mentions edge. Idempotent.
RETURNS (error): { error: true, code: "NOT_FOUND" | "INVALID_PARAMS" | "INTERNAL", message: "..." } RELATED: distillery_correct (creates 'corrects' relations automatically),
distillery_find_similar (to discover related entries) |
| distillery_gh_syncA | Sync GitHub issues and PRs into the knowledge base using a batched pipeline. url: repository slug (owner/repo) or full GitHub URL.
author: author field for created entries (default: gh-sync).
project: optional project name to scope entries.
background: when true, runs async and returns a job_id immediately. |
| distillery_sync_statusA | Check the status of background sync jobs. job_id: look up a specific job by ID.
source_url: list jobs for a specific source URL.
If neither is provided, lists all recent jobs. |
| distillery_configureA | Read or update a runtime configuration value. USE WHEN: reading current thresholds/settings, or adjusting them
at runtime without editing the config file directly. PARAMS: section (str, required): Config section path (dotted notation).
Valid: [feeds, feeds.thresholds, defaults, classification]. key (str, required): Config key within the section.
Valid keys by section: feeds: [user_agent];
feeds.thresholds: [alert, digest];
defaults: [dedup_threshold, dedup_limit, stale_days];
classification: [confidence_threshold, mode]. value (str | int | float | None, optional): New value. Omit to read
the current value. When provided, must satisfy type and range
constraints for the given key.
RETURNS (read): { section: str, key: str, value: any, message: str }
RETURNS (write): { changed: bool, section: str, key: str, previous_value: any,
new_value: any, disk_written: bool, message: str }
RETURNS (error): { error: true, code: "INVALID_PARAMS" | "INTERNAL", message: "..." } RELATED: distillery_watch (to manage feed sources),
distillery_status (to review current system state) |
| distillery_statusA | Return a lightweight in-protocol health/metadata probe. USE WHEN: verifying MCP connectivity (e.g. from the /setup wizard)
without relying on the HTTP-only /health endpoint. Works uniformly
on stdio and HTTP transports. PARAMS: (none) RETURNS (success): {
status: "ok",
version: str, # distillery package version
build_sha: str, # git SHA (or "dev")
transport: "stdio" | "http" | "unknown",
tool_count: int, # number of registered MCP tools
store: { entry_count: int | null, db_size_bytes: int | null },
embedding_provider: str, # model name or provider class name
last_feed_poll: { source_count: int, last_poll_at: str | null },
uptime_seconds?: int # seconds since server startup
} RELATED: distillery_list (for entry counts, filtering, and
per-group aggregates),
distillery_configure (to inspect/adjust runtime configuration) |