Knowledge Base MCP - Tools
5 min read
Tools
kb-mcp advertises up to four MCP tools on /mcp. KB_MCP_ENABLED_TOOLS (env) or mcpConfig.enabledTools (Helm) narrows the set; unset means all four. A restart is required.
Each tool also carries an admin configuration, normally set from inside the Unique AI app rather than an environment variable; see Configuration: Admin Configuration for where that setting actually lives. Only the admin metadata_filter and folder allowlist are a floor a caller can't widen, see Permissions. Numeric ones are usually defaults a caller may raise or lower per call (limit, score_threshold, max_tokens_per_call); content_metadata's limit is the exception, clamped to the admin ceiling max_values_per_field.
How the Calling LLM Picks Arguments
Tool descriptions tell the LLM exactly where an argument's value has to come from, as well as its type. search's folder_ids, for example, only accepts a scope_xxx id copied verbatim from a folder_id annotation in a prior content_tree(mode='tree') result, never a folder name, a path, or a scope_xxx lifted from a citation link (that's the file's own folder, not necessarily the one the user meant). metadata_filter's path is one of the fixed fields (mimeType, key, title, validAsOf) or a custom field name, typically one the LLM already saw in a content_metadata call.
That's why a discovery call often precedes the tool that uses its output:
Nothing forces that order. A well-scoped question can call search directly with no folder_ids or metadata_filter at all: an unrestricted search is the default and correct for most requests.
kb-mcp also ships this guidance as an agent skill, unique-kb-mcp, with worked examples. The server serves it as an MCP resource while all four tools are enabled, and it can be read on GitHub.
search
Semantic and internal search over the knowledge base: finds relevant passages by meaning, not just keyword matches, and returns them as citation-ready chunks.
Argument | Purpose |
|---|---|
| The natural-language question or phrase to search for |
| Restrict to folders; subfolders included by default |
| UniqueQL narrowing, AND-ed with the admin filter |
| Override the admin defaults for this call |
KB_MCP_SEARCH_SCOPE_LOOKUP_CONCURRENCY (default 8) bounds the parallel scope lookups used to build citation links.
content_tree
Browses, lists, and fuzzy-searches the folders and files visible to the caller. mode picks the view; only that mode's arguments apply, and passing one that doesn't (e.g. query under mode='tree') is a tool error, not a silent no-op.
Argument | Applies to | Purpose |
|---|---|---|
| all (required) |
|
| all | Scope the walk to this folder and everything under it: a path ( |
|
| Maximum folder depth to render (1 = top-level only) |
|
| Omit files, showing just the folder structure (like |
|
| Fuzzy text to match against file names and/or paths |
|
| Match against the file name ( |
|
| Whether fuzzy matching is case-sensitive |
|
| Minimum fuzzy-match score in |
| all | Maximum files/matches to return; in |
| all | Drop this caller's cached tree and refetch (~20s); use when the user reports added/deleted/changed files |
| all | Seconds to wait before returning a partial tree; the walk continues in the background |
| all | UniqueQL narrowing, AND-ed with the admin filter (see Permissions) |
Admin defaults: limit 50 (1000 for mode='tree'), min_score 0.6, match_on both, and a filter excluding user-memory folders.
Incomplete vs. truncated
Incomplete means the walk is still running; calling again with the same arguments usually
finishes it. Truncated means the walk finished and the result was capped at limit; calling again returns the same thing, raise limit or narrow folder_path instead.
Results are cached briefly (KB_MCP_TREE_CACHE_TTL_SECONDS, default 600) to keep repeat calls fast; a change can take up to that long to show up. If the user reports files just added or changed, call again with refresh=true instead of waiting it out. See Flows for how the cache and the admin filter interact.
content_metadata
Discovers what metadata fields and values exist on the knowledge base's visible content, so a caller can build a metadata_filter for search or content_tree instead of guessing one. Returns complete, an optional notice, and one catalog, metadata for the values themselves, e.g. {"complete": true, "metadata": [{"department": ["Legal", "Finance"]}]}, or metadata_counts with counts_only for just the distinct-value count per field.
Argument | Purpose |
|---|---|
| Restrict the catalog to these folders; a |
| Same, by exact path (e.g. |
| Whether the catalog includes files in subfolders (default |
| Only return these fields, by exact case-sensitive name; omit for every field, |
| Return each field's distinct-value count instead of the values themselves, e.g. |
| Maximum distinct values per field, most common first. Omit for 50, clamped to the admin ceiling |
| Drop this caller's cached snapshot and rescan (~20s) |
| Seconds to wait before returning a partial catalog |
Fields are exhaustive, every known one or every requested one, but each field's own value list is capped: 50 by default, raisable with limit up to the admin ceiling (default 1000). A shortened field is named in the response, e.g. department: showing 50 of 4497 values. On a large knowledge base, call counts_only=true first to see what fields exist and how big each is, then fields to fetch only the ones needed.
Ten platform-stamped fields (key, url, title, folderId, mimeType, companyId, contentId, validAsOf, folderIdPath, externalFileOwner) are excluded from the catalog by default, admin-configurable: identifiers, source links, and owners a caller doesn't typically build a filter around. Excluding a field from the catalog doesn't stop it from being used in a metadata_filter directly, folder and mimetype filtering both work that way already; the catalog just doesn't advertise them as a starting point.
Unlike search and content_tree, it takes no caller metadata_filter: only the admin one applies, since the tool exists to discover what a filter could say, not to apply one.
Shares content_tree's walk and cache entirely, described above: both tools are just different views over the same visible-file snapshot.
read_file
Returns file content by content_id, as surfaced by content_tree or search.
max_tokens_per_call (admin default 8000) bounds one response. Larger files are split into virtual pages of that size, selected with start_page and end_page. A caller may raise or lower it, since it is a default the caller can override; if the file still doesn't fit in one call and no page range was given, the call returns an error instead of silently truncating, naming the file's total token/page count so the caller can pick a range.
Related Documentation
Permissions - how admin and caller filters combine
Flows - what happens during a tool call
Configuration - deployment environment variables