Skip to main content

Project Knowledge Base (per-project documents)v1.23.1#

Store, version, and query your own documents inside a project. Items are isolated per project: composite key (item_id, project_id). Ingest via text, URL fetch, or file upload (PDF, TXT, MD, 5 MB max). Query with natural language via gc_kb_query or pull structured diffs with gc_kb_diff.

Item visibility & per-key access control

Items with visibility='private' are readable only by the gc_ key that created them — other keys in the same project cannot read, edit, or delete them. This enforces cross-key isolation within a project without creating separate projects.

A project-bound key can also be scoped to a kb_item_allowlist (configured in the dashboard under Keys). When set, the key can only query, get, edit, or delete the specific item IDs on that list — all other items in the project are invisible to it. This is the recommended pattern for multi-agent setups where each agent should only see its own slice of the knowledge base.

Requires Pro or higher plan.

MCP tools

gc_kb_ingest(name, content, type)        // type: "text" | "url" | "file"
      gc_kb_query(query_text, k?)              // semantic search across items
      gc_kb_list(limit?, cursor?)              // list items in your project
      gc_kb_get(item_id)                       // fetch one item
      gc_kb_edit(item_id, content)             // creates a new version
      gc_kb_diff(item_id, from_version_id, to_version_id)
      gc_kb_delete(item_id)
      // Project scope comes from your API key — mint a project-bound key first.

gc_kb_query response shape

Each result in the results array contains:

  • raw_text — the actual content of the matched chunk. Read this field.
  • text — a compressed skeleton with [HIDDEN] and anchor markers, for navigation only. Do not treat this as the source text.
  • item_id — the KB item the chunk belongs to (use with gc_kb_get to fetch the full item).
  • score — cosine similarity score (higher = more relevant).

File upload

From the dashboard at /dashboard/knowledge: drag-drop or click to select a file (PDF, TXT, MD, max 5 MB). Upload progress is tracked in-page; ingestion status polls every 2 seconds with a 5-minute timeout. Files larger than 5 MB must be split before upload. Supported ingest modes: text (paste), url (fetch by URL), and file (binary upload).

Convert local files (PDF, DOCX, PPTX) into the Knowledge Hub

The gotcontext Claude Code plugin bundles markitdown, a local MCP server (Microsoft MarkItDown) that runs on your own machine. It exposes one tool, convert_to_markdown(uri), that turns a local PDF, Word doc, PowerPoint, or spreadsheet into Markdown. Conversion runs locally, so the file is never uploaded to our servers. The kb-ingest-file MCP prompt scripts the whole convert-then-store workflow for you.

// 1. Convert a local file to Markdown (runs on YOUR machine):
      convert_to_markdown({ uri: "file:///home/me/report.pdf" })

      // 2. Store the Markdown in your Knowledge Hub (Pro+):
      gc_kb_ingest({ name: "report.pdf", content: "<markdown from step 1>", type: "document" })

      // Or just run the "kb-ingest-file" MCP prompt, which does both steps.
      // uri also accepts http/https/data URIs for remote documents.

Requires uv (install), or run pip install markitdown-mcp and point the plugin's markitdown server command at markitdown-mcp.

By tier: converting a file to Markdown runs on your own machine and works on any plan (the converter is local, not a metered gotcontext tool). Storing the result in your Knowledge Hub uses gc_kb_ingest, which requires Pro or higher.

Agent plan collaboration (change-proposals)

Turn a document into a plan that agents edit the way engineers use a pull request. Create it with gc_kb_ingest(type='plan'). An agent proposes a change against a specific version; the proposal is signed with the agent's A2A peer identity; and nothing lands until you, the owner, merge it. Peers cannot edit a plan item directly through gc_kb_edit; gc_plan_propose is the only peer write path onto a plan. Each merge creates a new version with the contributing agent recorded against it, so gc_plan_blame gives you a full attributed history. Review the same inbox from the dashboard at /dashboard/knowledge/agents.

gc_plan_propose(item_id, base_version_id, diff, title, rationale?, proposer_peer_id?)
      // signed change-proposal against a plan version; server signs the receipt
      gc_plan_list_proposals(project_id?, item_id?, status?)  // owner-scoped inbox
      gc_plan_get_proposal(proposal_id)                       // full diff + rationale
      gc_plan_decide(proposal_id, decision)                   // decision: "merge" | "reject" (owner-only)
      gc_plan_blame(item_id)                                  // per-version author + proposal trail
      // Requires a project-bound gc_ key; an unbound key returns { error: "no_project_selected" }.

A stale base_version_id (the plan moved on since the agent read it) is refused at gc_plan_decide time with a stale_base conflict carrying the current version id, so an agent can never silently overwrite newer work. Also on the REST API: GET /v1/plans/proposals, GET /v1/plans/proposals/{id}, GET /v1/plans/items/{id}/versions, and POST /v1/plans/proposals/{id}/decide.

Cross-agent task delegation (A2A)

One of your agents can hand a unit of work to another of your agents, even across machines or CLIs, over the Linux Foundation Agent2Agent (A2A) protocol. The requester creates a task assigned to a registered peer; the task stays a draft until you, the owner, approve it, so nothing reaches the assignee un-reviewed. The assignee then claims the task with an Ed25519 signed proof of its identity, does the work, and returns a signed result you can verify came from exactly that peer. Register peers first at /dashboard/knowledge/agents.

gc_a2a_task_create(assignee_peer_id, task_type, title, payload, requester_peer_id?)
      // task_type: "research" | "action" | "debate_position"; lands as a draft
      gc_a2a_task_approve(task_id, requester_peer_id?)         // draft -> pending (owner gate)
      gc_a2a_task_inbox()                                      // assignee polls for approved tasks
      gc_a2a_task_claim(task_id, from_peer_id, proof_jws)      // signed claim + time-boxed lease
      gc_a2a_task_complete(task_id, from_peer_id, proof_jws, result_payload)  // signed result
      gc_a2a_task_status(task_id)                              // poll one task
      gc_a2a_task_cancel(task_id, requester_peer_id?)          // owner cancels

The owner-side tools resolve the acting peer from the calling gc_ key; if the key is not bound to a peer, pass requester_peer_id explicitly. Claim and complete are also on the REST API for a remote peer to call directly, signed-proof-gated (no key needed): POST /a2a/v1/tasks/claim and POST /a2a/v1/tasks/complete. Requires the Pro plan or higher.

Where to next

Quickstart
Connect your MCP client and run your first compression in under two minutes.
Recipes
Copy-paste tool sequences for the workflows you'll run most.
Troubleshooting
Symptom-to-fix for the errors people actually hit.
Glossary
Plain-language definitions for skeleton, fidelity, profiles, and the rest.