Files
2026-04-04 22:50:19 +01:00

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:8000 and KB_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_KEY is 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_KEY is 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_KEY is 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_KEY is 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.

  • WHEN an agent calls kb_search with {"query": "pension revaluation", "top": 5}
  • THEN the MCP server SHALL POST to the engine's /api/v1/search endpoint and return the results with chunk text, scores, document metadata, and tags

Scenario: Search with tag filter

  • WHEN an agent calls kb_search with {"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_search with {"query": "error log", "fts_only": true}
  • THEN the MCP server SHALL pass fts_only: true to 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_addnote with {"text": "User prefers concise responses"}
  • THEN the MCP server SHALL submit the note to the engine's POST /api/v1/jobs endpoint and return the job ID

Scenario: Add a note with tags

  • WHEN an agent calls kb_addnote with {"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_start with {"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_chunk with {"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_chunk multiple times with sequential chunk_index values for the same upload_id
  • THEN the MCP server SHALL store each chunk and track the sequence

Scenario: Finish an upload

  • WHEN an agent calls kb_upload_finish with {"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/jobs endpoint with the tags from kb_upload_start, and return the job ID

Scenario: Upload with invalid upload_id

  • WHEN an agent calls kb_upload_chunk or kb_upload_finish with an upload_id that 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_finish within 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_note with {"document_id": 42, "text": "Updated preference: user prefers bullet points"}
  • THEN the MCP server SHALL send PATCH /api/v1/notes/42 to the engine and return the updated document

Scenario: Update a non-existent document

  • WHEN an agent calls kb_update_note with a document_id that 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_note with a document_id that 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_get with {"document_id": 42}
  • THEN the MCP server SHALL fetch GET /api/v1/documents/42 and return the document details with chunks

Scenario: Get by source path

  • WHEN an agent calls kb_get with {"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_status with no parameters
  • THEN the MCP server SHALL fetch GET /api/v1/status and 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_jobs with no parameters
  • THEN the MCP server SHALL fetch GET /api/v1/jobs and return the list of recent jobs

Scenario: Filter jobs by status

  • WHEN an agent calls kb_jobs with {"status": "failed"}
  • THEN the MCP server SHALL fetch GET /api/v1/jobs?status=failed and 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_delete is called with document_id=42
  • THEN the document, its chunks, embeddings, tag associations, and stored file SHALL be deleted
  • AND the response SHALL include "status": "deleted", the document_id, and the document title

Scenario: Document not found

  • WHEN kb_delete is called with a document_id that 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_search is 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