Search

Search the documentation

Protobox

Knowledge Base

Upload docs, FAQs, and policies. Your AI clients search them instead of guessing

Knowledge Base

Your assistant gets asked about your refund policy. Without a knowledge base, it guesses and guesses wrong. With one, it pulls the exact paragraph from your actual policy and quotes it.

Protobox's knowledge base is a fully managed RAG pipeline. You upload documents; Protobox chunks them, generates embeddings, and stores them for semantic search. Connected MCP clients search your knowledge and get relevant passages in milliseconds.

Uploaded sources are read-only reference. For the documents your agents write and keep current — versioned pages with citations and a trust workflow — see Brain.

Building a RAG pipeline from scratch (chunking, embedding, vector storage, retrieval, reranking) is typically a multi-week project. Protobox does it in minutes.

How It Works

You Upload Protobox Processes Clients Search PDFs / Files Web Pages Text / FAQ Chunking Embeddings Vector Index Search query Relevant Passages

Quick Start

Go to Build → Knowledge in the dashboard, or use the CLI / API. Choose a source:

  • Text: paste FAQ answers, policy snippets, product descriptions (indexed immediately)
  • URL: point to a help article or web page (Protobox crawls and indexes it)
  • File: upload a PDF, TXT, HTML, or Markdown file
protobox kb add "Refunds within 30 days of purchase." --title "Refund Policy"
protobox kb add https://docs.example.com --title "Docs"
protobox kb add ./guide.pdf --title "User Guide"

kb add takes one argument: a file path, a URL, or quoted text. It infers the source type.

curl -X POST "https://platform.protobox.ai/api/v1/knowledge" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "text",
    "title": "Refund Policy",
    "content": "Refunds are available within 30 days of purchase."
  }'

Text entries index immediately. URLs and files process asynchronously. protobox kb add polls the ingestion task to completion by default, and the REST response includes a taskId you can poll:

# skip the polling and return immediately
protobox kb add ./guide.pdf --title "User Guide" --no-wait

# inspect an entry later
protobox kb get <id>

Processing runs content extraction → chunking → embedding → vector indexing. Most documents finish in under a minute.

Once indexed, search from the CLI, the REST API, or any connected MCP client:

protobox kb --search "what is the refund policy?"

Source Types

SourceInputProcessingBest For
textcontent fieldSync (immediate)FAQ entries, policies, short content
urlurl fieldAsync (returns taskId)Web pages, help articles
fileFile uploadAsync (returns taskId)PDFs, manuals, docs

Search Modes

ModeWhat it doesBest for
hybrid (default)Combines vector + text searchMost queries: balances meaning and exact matches
vectorPure semantic searchConceptual questions where exact words differ
textFull-text keyword searchSpecific terms, product names, codes
protobox kb --search "money back guarantee"

The CLI's --search runs the default hybrid retrieval. To pick a mode explicitly or set minScore and limit, use the search API or the SDK.

Which engine answers your searches

When you search, the response includes metadata.mode (the mode that actually ran) and metadata.engine (why it ran that way):

  • free-lexical: free tier with no key of your own. Searches run as full-text only, no embeddings are generated at ingest, and Protobox spends nothing on your behalf.
  • managed: paid tiers. Hybrid search runs on Protobox's embedding key.
  • byo: any tier with an OpenAI key added under Integrations. Embeddings use your key.

Free workspaces requesting mode: "hybrid" or mode: "vector" are answered as text. The default mode depends on your tier and whether you've added an embedding key.

protobox kb --search "what is the refund policy?"
# ...results...
# ℹ Answered with hybrid search (managed).
# on the free tier: ℹ Answered lexically (free tier). Add an OpenAI key or upgrade for semantic search.

SDK: KnowledgeSearchResponse.metadata.mode and .metadata.engine from @protoboxai/sdk.

Bring your own key

Add an OpenAI key under Integrations and every AI call the knowledge base makes runs on your key instead of Protobox's — on any tier, including free. That unlocks:

  • Semantic search — embeddings at ingest, hybrid/vector search modes instead of text-only.
  • OCR — text extraction from uploaded images and scanned PDFs.
  • Extraction — the faq and entity chunking strategies, and synthesized (LLM-written) search answers.

Without a key, all of the above are available on paid tiers using Protobox's managed key. On the free tier without a key, semantic search falls back to full-text lexical search (never fails, just less precise), while OCR, extraction, and synthesis are refused outright with a message pointing at Integrations or an upgrade — they're actions you explicitly asked for, so nothing runs silently on Protobox's account on your behalf.

Removing the key reverses this: knowledge base calls fall back to your tier's default (managed on paid, free-lexical/refused on free) within a minute — credentials aren't watched for changes, so the resolver simply re-checks on its next cache expiry rather than picking up removal instantly.

Answers with receipts

Every search result includes a citation, built once at ingest from markdown headings (the heading path of the section holding most of the chunk) and page numbers. Nothing is generated at search time, so it works in text mode with zero LLM calls.

{
  "content": "Refunds are available within 30 days of purchase.",
  "citation": {
    "documentId": "kb_abc123",
    "title": "Refund Policy",
    "heading": "Billing › Refunds",
    "page": 3,
    "url": "https://example.com/refunds",
    "chunkIndex": 0,
    "freshness": {
      "status": "stale",
      "checkedAt": "2026-08-16T00:00:00.000Z",
      "reason": "last updated 120d ago, cited 14×"
    }
  }
}

The CLI prints it as the "Where" column:

0.91  Refund Policy › Billing › Refunds (p.3) · verified by Ada Lovelace, 3d ago · possibly stale (last updated 120d ago, cited 14×)  Refunds are available within 30 days...

Unlike the rest of the citation, owner/verified/freshness are resolved live from the source document rather than stamped at ingest — set owner/verified with protobox kb owner <id> --me and protobox kb verify <id> (parent documents only, not chunks); freshness you don't set directly, see Keeping Content Fresh below.

SDK types: KnowledgeCitation, Freshness, and KnowledgeSearchResponse.metadata from @protoboxai/sdk.

Organizing with Folders

Group related entries into folders and filter searches and listings by folder. Pass a folderId when creating an entry via the API, and scope listings by folder in the dashboard.

Share a knowledge pack publicly

Turn a folder into a public page anyone can read, install, and search — no Protobox account needed. Useful for a support handbook, a product FAQ, or docs you want prospects to try before they sign up.

protobox kb publish <folderId> --slug acme-support-handbook \
  --title "Acme support handbook" \
  --description "Everything the Acme support team knows."

--slug is required the first time (URL-safe, unique per workspace) and becomes permanent — omit it on a later kb publish call to update the title/description while keeping the same link. Take it back down any time:

protobox kb unpublish <folderId>

Unpublishing keeps the slug on the folder, so re-publishing (with no --slug) restores the exact same URL.

What a reader sees

The link opens https://app.protobox.ai/p/<workspaceId>/<slug> — a standalone page with no dashboard chrome and no login wall:

  • the pack's title, description, and a meta line (source count, last updated, owner/verified when set)
  • a read-only MCP URL, with an Add to your assistant button that opens the same client setup dialog used everywhere else in Protobox
  • the titles of the folder's sources (first 8)
  • a Make your own link into signup
  • a link to the pack's llms.txt

A slug that's unpublished, disabled, or was never public 404s — there's no way to guess your way into a private folder.

What the MCP URL can do

The public MCP URL exposes exactly one tool, kb_search (plus kb_answer when the workspace can run synthesis), scoped to that folder only — never the rest of the workspace's knowledge base, and never any other tool (no execute_action, no memory). It's unauthenticated and rate-limited per IP, so a client can add it with nothing but the URL:

protobox kb publish <folderId> --slug my-pack
# mcpUrl -> https://<workspace>.protobox.app/mcp/kb/my-pack

llms.txt

Every public pack also serves a plain-text llms.txt alongside the page — title, description, the MCP URL, and every source title — for crawlers and LLM clients that read llms.txt instead of rendering HTML.

Save pages from your browser

Save the page you're reading straight to a workspace's knowledge, without leaving the browser. Build → Knowledge shows a "Save pages from your browser" row with a Generate bookmarklet button; clicking it mints a capture key scoped to exactly this feature and shows a Save to Protobox link to drag onto your bookmarks bar.

Clicking the bookmarklet on any page opens a small Protobox window with the page's title and URL filled in, a folder picker, and a Save button. Saving:

  • fetches the page from Protobox's servers first (the same crawl source: "url" entries use), so most saves index the real page content, not just what your browser happened to render;
  • falls back to the text your browser captured (selection, or the whole page) when the server can't fetch it — an intranet page behind your company's login, for example.

Either way the entry lands in Sources with its title and origin URL.

The bookmarklet's link carries a capture token good for exactly one thing: creating knowledge entries. It can't read, list, or delete anything else in your workspace, even if the link leaks. Revoke it from the Knowledge page at any time — the bookmarklet stops working immediately, and generating a new one requires revoking the old one first (a workspace holds one live capture key at a time).

MCP Integration

Once you've uploaded content, it's searchable from any client connected to your workspace's MCP endpoint. No extra configuration is needed. The client receives relevant passages and uses them to ground its answers.

You don't configure anything extra for MCP. Upload documents and they're immediately available to connected clients.

Keeping Content Fresh

Staleness flags: every citation carries a freshness object (see Answers with receipts) computed at read time — stale when a source hasn't been updated, verified, or synced in freshnessDays (default 90, configurable via the KB config API) AND it's actually being cited (at least 5 times in that window — an unread stale doc isn't worth flagging). Nothing is edited automatically; the flag clears itself the next time the source changes at its origin:

  • Editing content (kb sync, kb sync-repo, kb sync-drive, re-running kb add for the same synced file) replaces the entry, which resets its dates.
  • Re-crawling a URL sync (scheduled or kb sync <url> --now via the sync API) stamps a fresh sync time even when the content didn't change — a checked source is a source someone is keeping current.
  • protobox kb verify <id> stamps a fresh verification, the fastest way to clear a flag on content that's still accurate as-is.

List everything currently flagged:

protobox kb stale
Title              Updated    Cited
Refund Policy      120d ago   14
Onboarding Guide   95d ago    8

Or filter the list API directly: GET /api/v1/knowledge?freshness=stale (also current / unknown). SDK: sdk.knowledge.listStale().

URL sync: re-crawl and re-index a URL-sourced entry on a schedule or on demand (configure in the dashboard or via the sync API).

Manual update: the CLI has no in-place edit. Replace the entry (remove it, then add the new content), or update it through the SDK:

protobox kb remove <id>
protobox kb add "Updated refund policy: 60-day window." --title "Refund Policy"

Let your assistant fix a note

An assistant using your MCP server can spot an error in your knowledge base and propose a fix — but nothing changes until you approve it. kb_propose_update and kb_propose_append create a pending change instead of writing directly; kb_proposal_status lets the assistant check what happened to it.

You: "The refund policy doc says 30 days, but we changed it to 60. Can you fix that?"
Assistant: kb_propose_update(documentId: "...", content: "The refund window is 60 days.", reason: "Policy changed from 30 to 60 days")
→ {status: "pending", approvalId: "..."}
Assistant: "I've proposed the fix — it's waiting on your approval."

The proposal shows up in the dashboard's Approvals inbox with a before/after preview. Approving applies the change immediately (re-chunking the document if it's long enough to be split, and clearing its verification — an edited document is unverified again until someone re-checks it). Denying leaves the document untouched; the assistant sees rejected (with your reason, if you gave one) the next time it checks kb_proposal_status.

kb_propose_append works the same way but only carries the ADDITION — the assistant should never repeat the existing content, since the addition is joined onto whatever the document says at the moment of approval, not at the moment of the proposal.

From the CLI or SDK — useful for scripting a review queue, or for a human proposing a change through the same approval gate an assistant would:

protobox kb propose <id> --append "Exceptions apply for defective items." --reason "Missing exception case"
protobox kb proposal-status <approvalId>
const { approvalId } = await sdk.knowledge.proposeUpdate(id, 'The refund window is 60 days.', {
  reason: 'Policy changed from 30 to 60 days',
});
const { status, reason } = await sdk.knowledge.proposalStatus(approvalId);

A member with the viewer (reader) workspace role can't propose changes — same rule as kb_add/kb_remove_source. Proposing and approving both require write access; a reader can still search and ask.

Sync a folder from the CLI: mirror a local folder as knowledge without uploading files by hand. Each file maps to one entry, keyed by its path relative to the folder; re-running only touches what changed.

protobox kb sync ./docs --watch

kb sync walks the folder (markdown, text, JSON/YAML, and common code files by default — override with --include <glob>), skips anything over --max-size (2 MB by default), and diffs by content hash: unchanged files are skipped, edited files replace their entry, and files you deleted locally are removed from the knowledge base. --watch keeps running in the foreground and re-syncs a few seconds after a file settles.

Sync a GitHub repo: connect a repo's docs and code so your assistant cites internal knowledge public assistants can't see. Each matched file maps to one entry, keyed by its path within the repo; re-syncing only touches what changed.

protobox kb sync-repo owner/repo --path docs --path README.md --every 24h

kb sync-repo fetches the branch's file tree (main by default — override with --branch), scopes it to --path (repeatable; omit to sync the whole repo — keep this scoped, every matched file is fetched), and filters with the same default extension list as kb sync (override with --include <glob>). Sync identity is <owner>/<repo>@<branch>:<path>, so an edited file replaces its entry and a deleted file is removed, same diff as folder sync. --every enables scheduled re-sync (hours, or <n>d for days); the platform's sync scheduler runs it and short-circuits when the branch hasn't moved.

Private repos need a connected GitHub App installation (Build → Integrations) or a stored secret referenced via the API's auth.secretRef — the CLI syncs public repos unauthenticated. Citations from a synced repo file read owner/repo:path › heading and link back to the file on GitHub.

Sync a Google Drive folder: connect a team folder so its Docs, Sheets, PDFs, and markdown/text files become cited knowledge that stays current. The folder is walked recursively; each matched file maps to one entry.

protobox kb sync-drive <folderId> --every 24h

Connect Google Drive first (Build → Integrations) — kb sync-drive uses that connection's OAuth token; there's no unauthenticated fallback the way a public GitHub repo has. <folderId> is the id from the folder's Drive URL. Google Docs export to markdown, Sheets export to CSV and render as a markdown table (first sheet/tab only — Drive's export endpoint has no per-tab selector), and PDFs run through the same parser file uploads use. Plain files default to markdown/text extensions — override with --include <glob>; Docs and Sheets always sync regardless of --include, since they carry no filename extension for a glob to match. Sync identity is gdrive:<folderId>:<fileId>, so an edited file replaces its entry and a file removed from the folder is removed from the knowledge base. --every enables scheduled re-sync (hours, or <n>d for days); the platform's sync scheduler runs it and skips the (expensive) re-export/re-download for any file whose Drive modifiedTime/checksum hasn't moved since the last sync.

Citations from a synced Drive file read the file's name and link back to it on Google Drive.

Import from Notion or Confluence: move an existing team wiki over in one command. Every page in the zip becomes a chunked, cited knowledge entry with its folder structure preserved.

protobox kb import ./export.zip
protobox kb import ./space.zip --from confluence --folder "Engineering Wiki"

To export the zip in the first place:

  • Notion: workspace or page ··· menu → Export → Markdown & CSV.
  • Confluence: space settings → Content Tools → Export Space → HTML.

kb import auto-detects the format from the zip's contents (an index.html means Confluence; .md files with no HTML mean Notion) — pass --from notion or --from confluence to skip detection. What's kept:

  • Notion: each page's markdown, with the trailing page ID stripped from its title. A linked database (CSV) becomes one entry with its rows rendered as a markdown table. A page's own Notion URL is kept when its export carries a URL/Link property.
  • Confluence: each page's HTML converted to markdown, so headings survive and citations can still point at a section. A page's original URL is kept when the export carries a <link rel="canonical">. Attachments are referenced by their zip-relative path, not uploaded.
  • Both: page hierarchy (the folder a page sat in) maps to a knowledge folder — pass --folder <name> to nest the whole import under one top-level folder.

Import identity is the page's path in the zip, scoped to the format, so re-running kb import on an updated export of the same space updates changed pages and removes ones no longer in the export — same diff behavior as kb sync. Small exports (≤20 pages) import inline; larger ones return a task the CLI polls to completion.

Troubleshooting

What's Next

Tools

Create custom functions clients can call over MCP

SDK: Knowledge Base

Ingest and search knowledge with @protoboxai/sdk

Search API

REST reference for knowledge search

Create Entry API

REST reference for creating knowledge entries

On this page