Repository navigation
MCP: authored synonym matches the graph but search returns no canonical documents #62
Description
The released Rust MCP recognizes Concern as an authored Risk synonym, but search("Concern") returns zero documents from a Risk-only corpus. search("Risk") returns all three actual source documents. This prevents qualifying the Rust MCP synonym-to-document workflow for editor/PKM integrations.
Reproduced with the published terraphim_mcp_server-v1.21.18-rc.1, macOS arm64, through official Python MCP SDK 1.30.0. The executable reports terraphim_mcp_server 1.21.18; executable SHA-256 is 9a86ddf05c0367a25578901e8d7b6aa5bc9bf6a85be737e1232ae62134c31098.
Portable fixture
Keep concept notes outside the searched corpus. This script creates three distinct source notes and configures the same lowercase role name everywhere:
mcp_fixture="$(mktemp -d)"
python3 - "$mcp_fixture" <<'PY'
import json, sys
from pathlib import Path
p = Path(sys.argv[1]).resolve()
for name in ['concepts', 'corpus', '.terraphim', 'settings']:
(p / name).mkdir()
(p / 'concepts/Risk.md').write_text(
'# Risk\nsynonyms:: Concern\n\n'
'A possible event that could affect the project outcome.\n')
for n, text in enumerate([
'Risk: supplier delays could affect the launch date.',
'Risk decision: approve a second supplier as the mitigation.',
'Risk action: review lead times every Friday.',
], 1):
(p / f'corpus/decision-{n}.md').write_text(text + '\n')
haystack = {'location': str(p / 'corpus'), 'service': 'Ripgrep',
'read_only': True, 'atomic_server_secret': None,
'extra_parameters': {}}
role = {'name': 'kiloproject', 'shortname': 'kiloproject',
'relevance_function': 'terraphim-graph', 'terraphim_it': True,
'theme': 'lumen', 'haystacks': [haystack], 'extra': {},
'kg': {'automata_path': None, 'public': False, 'publish': False,
'knowledge_graph_local': {
'input_type': 'markdown', 'path': str(p / 'concepts')}}}
(p / '.terraphim/role-kiloproject.json').write_text(json.dumps(role))
# Override the profile's unrelated remote-backed roles. This is supported
# project configuration, not a modified server or search implementation.
defaults = {}
for name in ['Default', 'Engineer', 'System Operator']:
defaults[name] = {'name': name, 'relevance_function': 'title-scorer',
'terraphim_it': False, 'theme': 'lumen', 'kg': None,
'haystacks': [haystack], 'extra': {}}
(p / '.terraphim/config.json').write_text(json.dumps({
'selected_role': 'kiloproject', 'default_role': 'kiloproject',
'roles': defaults}))
(p / 'settings/settings.toml').write_text(
'server_hostname = "127.0.0.1:8000"\n'
'api_endpoint = "http://localhost:8000/api"\ninitialized = true\n'
'default_data_path = ' + json.dumps(str(p / 'data')) + '\n'
'[profiles.memory]\ntype = "memory"\n')
print(p)
PYUse the installed released executable's absolute path as the MCP client's command and these argv elements:
--profile server --config-dir <printed fixture directory>
For isolated test persistence, set TERRAPHIM_SETTINGS_PATH to the fixture's settings directory and TERRAPHIM_DATA_PATH to its data directory. The memory operator was confirmed in actual stderr. These settings do not imply that the server never reads the current user's existing device settings. No credentials or provider are required.
After MCP initialization, make these tools/call requests:
{"name":"build_autocomplete_index","arguments":{"role":"kiloproject"}}
{"name":"find_matches","arguments":{"text":"Concern and Risk","role":"kiloproject","return_positions":true}}
{"name":"search","arguments":{"query":"Concern","role":"kiloproject","limit":3}}
{"name":"search","arguments":{"query":"Risk","role":"kiloproject","limit":3}}Actual saved outputs
- Index:
Autocomplete index built successfully with 2 terms for role 'kiloproject'. - Matches:
concern (pos: 0-7)andrisk (pos: 12-16). - Concern search:
Found 0 documents matching your query. - Risk search:
Found 3 documents matching your query.The three embedded resources contain the exact source-note text above. - Repeating Concern after Risk still returns zero. Adding
Hazardto the actualsynonyms::note and restarting produces three graph terms and a Hazard match, but Hazard document search also returns zero.
Expected and regression acceptance
Concern should retrieve the same relevant Risk source documents with original text and source identity. Verify graph loading independently, zero literal baseline, three canonical documents and three synonym documents against a clean real filesystem. Keep the graph notes outside the corpus; inserting the synonym into the searched notes would conceal the failure. Verify the eventual released executable as well as source tests.
The actual search schema exposes only query/role/limit/skip. Inspection of the exact release's middleware dependency 1.21.0 indicates that initial retrieval receives the unchanged plain-text query; KG path scoring affects ordering, not synonym expansion. No supported released configuration switch was found for this fixture. This is a bounded diagnosis, not a proposed replacement server.
For comparison, the released Continue 0.1.1 adapter with terraphim-grep 1.21.20 retrieves these same three Risk passages for Concern using an editor-exported graph. That passing route does not qualify this Rust MCP method. Native Kilo acceptance and any new implementation are separate work.
Related, separately reproduced defect: autocomplete role isolation. It has a distinct cause and acceptance test.
Activity
AlexMikhalev commentedon Oct 15, 2026
Released in terraphim_mcp_server-v1.21.20-rc.1, built by CI run 38703538266 from merged PR #65 (
62550fe8416c1063ea20dd089d595488722bc574).I downloaded all seven public assets without authentication and verified all six binary checksums against
checksums.txt. The released macOS ARM64 binary reportsterraphim_mcp_server 1.21.20, SHA-2567013f3ca0fee65005002168098118987288ea17086b0b5bd47fdf6bfd2ca2275.All eight real stdio protocol regression tests passed against that downloaded binary (zero failed/ignored). Other platform assets were checksum verified, not executed in this qualification. This does not claim native Kilo acceptance or the separate memory/learning tools tracked in #64.
For this defect, the public fixture has a
Riskconcept withsynonyms:: Concernand three corpus files containing onlyRisk.search(query="Concern", role="project", limit=20)now returns the same three resource URIs and actual contents assearch(query="Risk", ...). The tests also verify union ranking/pagination, duplicate removal, exact-concept expansion, unchanged free-text behaviour, and actual alias snippets.Regression source: test_mcp_role_contract.rs at the released commit.
feat: expose explicit local agent memory and learning MCP tools (#66)