Skip to content

Commit 3ab9d09

Browse files
tae2089claude
andcommitted
Map the default namespace to the shared docs root in get_doc_content
An explicit namespace:"default" resolved files under namespaces/default/ while resolvedRagIndexPath and retrieve_docs treat default as the shared docs root, so the same document was reachable with namespace omitted but not with it spelled out. Route default through the shared branch. Also drop the redundant retrieveDocsFromDB keep-alive var. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 2b2d3ae commit 3ab9d09

2 files changed

Lines changed: 30 additions & 3 deletions

File tree

internal/mcp/handler_docs.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,10 @@ func (h *handlers) getDocContent(ctx context.Context, request mcp.CallToolReques
216216
return mcp.NewToolResultError("invalid file_path: path traversal not allowed"), nil
217217
}
218218

219+
// The default namespace maps to the shared docs root, mirroring resolvedRagIndexPath
220+
// and retrieve_docs; only named namespaces resolve under namespaces/<ns>/.
219221
var resolvedPath string
220-
if namespace != "" {
222+
if namespace != "" && ctxns.Normalize(namespace) != ctxns.DefaultNamespace {
221223
if err := validateNamespacePath(namespace, filePath); err != nil {
222224
return mcp.NewToolResultError(err.Error()), nil
223225
}
@@ -326,8 +328,6 @@ type retrieveDocsResponse = retrieval.Response
326328
// @intent keep MCP retrieve_docs result decoding compatible while sharing the canonical retrieval DTO.
327329
type retrieveDocsResult = retrieval.Result
328330

329-
var _ = (*handlers).retrieveDocsFromDB
330-
331331
// @intent build a retrieve_docs response from persisted graph nodes and annotation tags.
332332
// @requires SearchBackend and DB must be configured, and ctx must carry the desired namespace.
333333
// @ensures returned results are grouped one-per-file in first-seen FTS order and keep retrieve_docs' stable JSON shape.

internal/mcp/handler_docs_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,33 @@ func TestGetDocContent_PathTraversal(t *testing.T) {
295295
}
296296
}
297297

298+
func TestGetDocContent_DefaultNamespaceReadsSharedDocs(t *testing.T) {
299+
deps := setupTestDeps(t)
300+
deps.RagIndexDir = t.TempDir()
301+
302+
content := "# Shared Doc\nfrom shared docs root"
303+
docPath := filepath.Join(deps.RagIndexDir, "docs", "shared-doc.md")
304+
if err := os.MkdirAll(filepath.Dir(docPath), 0o755); err != nil {
305+
t.Fatal(err)
306+
}
307+
if err := os.WriteFile(docPath, []byte(content), 0o644); err != nil {
308+
t.Fatal(err)
309+
}
310+
311+
// "default" must resolve to the shared docs root, matching resolvedRagIndexPath
312+
// and retrieve_docs (contentNamespace maps default to shared), not namespaces/default/.
313+
result := callTool(t, deps, "get_doc_content", map[string]any{
314+
"namespace": "default",
315+
"file_path": "docs/shared-doc.md",
316+
})
317+
if result.IsError {
318+
t.Fatalf("default namespace should read shared docs, got error: %v", getTextContent(result))
319+
}
320+
if got := getTextContent(result); got != content {
321+
t.Errorf("want %q, got %q", content, got)
322+
}
323+
}
324+
298325
func TestGetDocContent_NotFound(t *testing.T) {
299326
deps := setupTestDeps(t)
300327
result := callTool(t, deps, "get_doc_content", map[string]any{

0 commit comments

Comments
 (0)