9.7 KiB
MCP Server
Purpose
The MCP server provides a Model Context Protocol interface to the kb engine, exposing knowledge base operations as native MCP tools over Streamable HTTP transport. It runs as a separate Docker container alongside the engine, translating MCP tool calls into engine HTTP API calls.
Requirements
Requirement: MCP server transport and deployment
The MCP server SHALL expose tools via Streamable HTTP transport. It SHALL run as a Docker container, configured to connect to the kb engine's HTTP API. It SHALL read KB_ENGINE_URL and KB_API_KEY from environment variables to connect to the engine.
Scenario: MCP server starts and connects to engine
- WHEN the MCP server container starts with
KB_ENGINE_URL=http://engine:8000andKB_API_KEY=secret - THEN it SHALL begin accepting MCP connections over Streamable HTTP and use the configured URL and API key for all engine API calls
Scenario: Engine unreachable at startup
- WHEN the MCP server starts but cannot reach the engine at
KB_ENGINE_URL - THEN it SHALL start and accept connections, but tool calls SHALL return errors indicating the engine is unreachable
Scenario: Docker Compose deployment
- WHEN the MCP server is deployed via Docker Compose alongside the engine
- THEN it SHALL connect to the engine via the Docker network using the service name (e.g.
http://engine:8000)
Requirement: MCP server authentication
The MCP server SHALL require Bearer token authentication from calling agents via the KB_MCP_API_KEY environment variable. This is independent of the engine's KB_API_KEY.
Scenario: Valid MCP API key
- WHEN
KB_MCP_API_KEYis set and a calling agent provides a matching Bearer token - THEN the MCP server SHALL process the request normally
Scenario: Missing MCP API key when required
- WHEN
KB_MCP_API_KEYis set and a calling agent connects without a Bearer token - THEN the MCP server SHALL reject the connection with an authentication error
Scenario: Invalid MCP API key
- WHEN
KB_MCP_API_KEYis set and a calling agent provides a non-matching Bearer token - THEN the MCP server SHALL reject the connection with an authentication error
Scenario: MCP auth disabled
- WHEN
KB_MCP_API_KEYis not set - THEN the MCP server SHALL accept all connections without authentication
Requirement: Search tool
The MCP server SHALL expose a kb_search tool that queries the knowledge base via the engine's search API.
Scenario: Basic search
- WHEN an agent calls
kb_searchwith{"query": "pension revaluation", "top": 5} - THEN the MCP server SHALL POST to the engine's
/api/v1/searchendpoint and return the results with chunk text, scores, document metadata, and tags
Scenario: Search with tag filter
- WHEN an agent calls
kb_searchwith{"query": "email preferences", "tags": ["agent:mybot"]} - THEN the MCP server SHALL include the tags in the filter and POST to the engine's search endpoint
Scenario: Search with mode override
- WHEN an agent calls
kb_searchwith{"query": "error log", "fts_only": true} - THEN the MCP server SHALL pass
fts_only: trueto the engine search endpoint
Requirement: Add note tool
The MCP server SHALL expose a kb_addnote tool that submits a text note to the engine for ingestion.
Scenario: Add a note
- WHEN an agent calls
kb_addnotewith{"text": "User prefers concise responses"} - THEN the MCP server SHALL submit the note to the engine's
POST /api/v1/jobsendpoint and return the job ID
Scenario: Add a note with tags
- WHEN an agent calls
kb_addnotewith{"text": "User prefers concise responses", "tags": ["agent:mybot", "feedback"]} - THEN the MCP server SHALL submit the note with exactly those tags to the engine
Requirement: Chunked file upload tools
The MCP server SHALL expose a three-step chunked file upload pattern for transferring files from remote agents to the engine.
Scenario: Start an upload
- WHEN an agent calls
kb_upload_startwith{"filename": "report.pdf", "total_size": 5242880, "tags": ["insurance"]} - THEN the MCP server SHALL create a staging entry, generate a UUID
upload_id, and return{"upload_id": "<uuid>"}
Scenario: Upload a chunk
- WHEN an agent calls
kb_upload_chunkwith{"upload_id": "<uuid>", "data": "<base64-encoded-data>", "chunk_index": 0} - THEN the MCP server SHALL decode the base64 data and write it to the staging area for the given upload
Scenario: Upload multiple chunks in sequence
- WHEN an agent calls
kb_upload_chunkmultiple times with sequentialchunk_indexvalues for the sameupload_id - THEN the MCP server SHALL store each chunk and track the sequence
Scenario: Finish an upload
- WHEN an agent calls
kb_upload_finishwith{"upload_id": "<uuid>"} - THEN the MCP server SHALL reassemble the chunks in order, forward the complete file as a multipart upload to the engine's
POST /api/v1/jobsendpoint with the tags fromkb_upload_start, and return the job ID
Scenario: Upload with invalid upload_id
- WHEN an agent calls
kb_upload_chunkorkb_upload_finishwith anupload_idthat does not exist - THEN the MCP server SHALL return an error indicating the upload ID is not found
Scenario: Abandoned upload cleanup
- WHEN an agent starts an upload but does not call
kb_upload_finishwithin 10 minutes - THEN the MCP server SHALL clean up the staged chunks and remove the upload tracking entry
Scenario: MCP server restart during upload
- WHEN the MCP server container restarts while an upload is in progress
- THEN the in-progress upload SHALL be lost and the agent SHALL need to restart from
kb_upload_start
Requirement: Update note tool
The MCP server SHALL expose a kb_update_note tool that updates an existing note in place via the engine's note mutation endpoint.
Scenario: Update an existing note
- WHEN an agent calls
kb_update_notewith{"document_id": 42, "text": "Updated preference: user prefers bullet points"} - THEN the MCP server SHALL send
PATCH /api/v1/notes/42to the engine and return the updated document
Scenario: Update a non-existent document
- WHEN an agent calls
kb_update_notewith adocument_idthat does not exist - THEN the MCP server SHALL return an error indicating the document was not found
Scenario: Update a non-note document
- WHEN an agent calls
kb_update_notewith adocument_idthat refers to a PDF - THEN the MCP server SHALL return an error indicating that only notes can be updated
Requirement: Get document tool
The MCP server SHALL expose a kb_get tool that retrieves document details from the engine.
Scenario: Get by document ID
- WHEN an agent calls
kb_getwith{"document_id": 42} - THEN the MCP server SHALL fetch
GET /api/v1/documents/42and return the document details with chunks
Scenario: Get by source path
- WHEN an agent calls
kb_getwith{"source_path": "memory/feedback_testing.md"} - THEN the MCP server SHALL query the engine's documents endpoint filtered by source path and return matching documents
Requirement: Status tool
The MCP server SHALL expose a kb_status tool that returns engine health and statistics.
Scenario: Get engine status
- WHEN an agent calls
kb_statuswith no parameters - THEN the MCP server SHALL fetch
GET /api/v1/statusand return engine version, model info, device info, document counts, and queue state
Requirement: Jobs tool
The MCP server SHALL expose a kb_jobs tool that returns ingestion job status.
Scenario: List recent jobs
- WHEN an agent calls
kb_jobswith no parameters - THEN the MCP server SHALL fetch
GET /api/v1/jobsand return the list of recent jobs
Scenario: Filter jobs by status
- WHEN an agent calls
kb_jobswith{"status": "failed"} - THEN the MCP server SHALL fetch
GET /api/v1/jobs?status=failedand return matching jobs
Requirement: Delete document tool
The MCP server SHALL expose a kb_delete tool that permanently deletes a document from the knowledge base. The tool SHALL accept a document_id (required integer). Deletion SHALL remove the document, its chunks, embeddings, tags, and any stored file on disk.
The tool SHALL return a confirmation response including the deleted document's ID and title.
Scenario: Successful deletion
- WHEN
kb_deleteis called withdocument_id=42 - THEN the document, its chunks, embeddings, tag associations, and stored file SHALL be deleted
- AND the response SHALL include
"status": "deleted", thedocument_id, and the documenttitle
Scenario: Document not found
- WHEN
kb_deleteis called with adocument_idthat does not exist - THEN the tool SHALL return an error response indicating the document was not found
Requirement: Tags-only document organisation
The MCP server SHALL NOT maintain any collection abstraction. Documents SHALL be returned as-is from the engine with all tags visible. No tag stripping or collection field injection SHALL occur. Namespace isolation (e.g. separating agent memory from user documents) is achieved via tag conventions communicated through system prompts or tool descriptions.
Scenario: Search results show all tags
- WHEN
kb_searchis called and a result has tags["agent:mybot", "collection:documents", "draft"] - THEN all three tags SHALL be returned as-is — no stripping of
collection:*tags
Scenario: Add note with explicit tags only
- WHEN
kb_addnote(text="hello", tags=["agent:mybot", "memory"])is called - THEN the note SHALL be created with exactly those two tags — no default tags added