Merge pull request #1617 from CREDO23/feature-okf

[Feat] Serve the knowledge base in Open Knowledge Format (OKF)
This commit is contained in:
Rohan Verma 2026-07-21 15:39:59 -07:00 committed by GitHub
commit 08d431454f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 1249 additions and 24 deletions

View file

@ -61,13 +61,17 @@ class SurfSenseClient:
json: Any | None = None,
data: dict[str, Any] | None = None,
files: Any | None = None,
headers: dict[str, str] | None = None,
) -> Any:
"""Send a request and return the parsed body, or raise ``ToolError``."""
"""Send a request and return the parsed body, or raise ``ToolError``.
``headers`` overrides the client defaults for this call.
"""
# Omit unset query params: sending them empty makes the API parse ""
# as a value (e.g. int("") on folder_id) and fail.
if params is not None:
params = {key: value for key, value in params.items() if value is not None}
headers = self._auth_headers()
headers = {**self._auth_headers(), **(headers or {})}
try:
response = await self._http.request(
method,

View file

@ -123,11 +123,19 @@ def register(mcp: FastMCP, client: SurfSenseClient, context: WorkspaceContext) -
Use this after surfsense_search_knowledge_base or
surfsense_list_documents to open a specific document search results
only include the matching passages, this returns the whole text.
The markdown form is an Open Knowledge Format (OKF) concept: a YAML
frontmatter block (type, title, tags, resource, timestamp) followed by
the document body.
"""
document = await client.request("GET", f"/documents/{document_id}")
if response_format == "json":
document = await client.request("GET", f"/documents/{document_id}")
return clip(to_json(document))
return _render_document(document)
concept = await client.request(
"GET",
f"/documents/{document_id}",
headers={"Accept": "text/markdown"},
)
return clip(concept if isinstance(concept, str) else str(concept))
def _join(values: list[str] | None) -> str | None:
@ -169,14 +177,3 @@ def _render_document_list(result: dict | None) -> str:
+ (" · more available_" if has_more else "_")
)
return "\n".join(lines)
def _render_document(document: dict) -> str:
content = clip(document.get("content", "") or "(empty)")
return (
f"# {document.get('title', 'Untitled')} (id {document.get('id')})\n"
f"- type: {document.get('document_type')}\n"
f"- workspace: {document.get('workspace_id')}\n"
f"- updated: {document.get('updated_at')}\n\n"
f"{content}"
)

View file

@ -0,0 +1,68 @@
"""surfsense_get_document round-trips through the real tool registration.
The markdown form must ask the backend for the OKF concept via content
negotiation (``Accept: text/markdown``) and pass it through untouched; the JSON
form must leave the default ``application/json`` Accept in place. This is the
only coverage of the MCP-side glue that forwards the header.
"""
from __future__ import annotations
import asyncio
from unittest.mock import MagicMock
import httpx
from mcp.server.fastmcp import FastMCP
from mcp_server.core.client import SurfSenseClient
from mcp_server.features.knowledge_base import search_tools
_CONCEPT = "---\ntype: Note\ntitle: T\n---\n\nBody."
def _client_recording(seen: dict) -> SurfSenseClient:
async def handler(request: httpx.Request) -> httpx.Response:
seen["path"] = request.url.path
seen["accept"] = request.headers.get("accept")
if "text/markdown" in (seen["accept"] or ""):
return httpx.Response(
200, text=_CONCEPT, headers={"content-type": "text/markdown"}
)
return httpx.Response(200, json={"id": 1, "title": "T"})
client = SurfSenseClient(
api_base="http://test/api/v1", timeout=5, fallback_api_key="ss_pat_x"
)
client._http = httpx.AsyncClient(
base_url="http://test/api/v1",
headers={"Accept": "application/json"},
transport=httpx.MockTransport(handler),
)
return client
def _call_get_document(client: SurfSenseClient, **arguments) -> str:
mcp = FastMCP("test")
search_tools.register(mcp, client, MagicMock())
blocks = asyncio.run(mcp.call_tool("surfsense_get_document", arguments))
return "".join(block.text for block in blocks)
def test_markdown_requests_okf_concept_and_passes_it_through():
seen: dict = {}
text = _call_get_document(_client_recording(seen), document_id=1)
assert seen["path"] == "/api/v1/documents/1"
assert "text/markdown" in seen["accept"]
assert text == _CONCEPT
def test_json_keeps_default_accept():
seen: dict = {}
text = _call_get_document(
_client_recording(seen), document_id=1, response_format="json"
)
assert seen["path"] == "/api/v1/documents/1"
assert seen["accept"] == "application/json"
assert '"id": 1' in text