Skip to content

MCP: authored synonym matches the graph but search returns no canonical documents #62

Closed

Description

@AlexMikhalev

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)
PY

Use 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) and risk (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 Hazard to the actual synonyms:: 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

  1. AlexMikhalev commented on Oct 15, 2026

    @AlexMikhalev
    ContributorAuthor

    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 reports terraphim_mcp_server 1.21.20, SHA-256 7013f3ca0fee65005002168098118987288ea17086b0b5bd47fdf6bfd2ca2275.

    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 Risk concept with synonyms:: Concern and three corpus files containing only Risk. search(query="Concern", role="project", limit=20) now returns the same three resource URIs and actual contents as search(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.

  2. added a commit that references this issue on Oct 15, 2026
    e1cd8e0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions