Skip to main content

trelix-mcp

MCP server for trelix v3.5.1 — semantic code search with streaming /ask endpoint and REST API integration for Claude Code, Cursor, Windsurf, and Continue.dev.

⚠️ Breaking Change in v2.4.0

search_code now returns a pagination envelope instead of a bare list:

# v2.3.x (old)
results = search_code(query="auth", repo_path="/repo")
for r in results:  # results was list[dict]
    print(r["symbol"])

# v2.4.0 (new)
response = search_code(query="auth", repo_path="/repo")
for r in response["results"]:  # now dict with pagination
    print(r["symbol"])
# Paginate: pass response["next_cursor"] as cursor= for next page

Install

pip install trelix-mcp

Unpinned on purpose. trelix-mcp carries the core version stamp and is published only by a core v* tag, so the newest trelix-mcp is always the one built alongside the newest trelix. To pin in your own requirements.txt, pin all four distributions to the same version — see the FAQ.

To use Bedrock embeddings or synthesis (no extra API key beyond AWS credentials):

pip install trelix-mcp "trelix[bedrock]"

Other optional LLM provider extras:

pip install trelix-mcp "trelix[anthropic]"   # Anthropic Claude direct
pip install trelix-mcp "trelix[vertex]"      # Google Vertex AI / Gemini
pip install trelix-mcp "trelix[litellm]"     # 100+ providers via LiteLLM
pip install trelix-mcp "trelix[llm-all]"     # all LLM providers

Usage

Claude Code

claude mcp add trelix -- trelix-mcp

Or install the Claude Code plugin, which launches a pinned published release of this server through uvx and adds a skill that says when to use it: claude plugin marketplace add sairam0424/trelix, then claude plugin install trelix@trelix (see docs/integrations/claude-code-plugin.md in the repository).

To list only the everyday search and indexing tools, add --tools core (the default is --tools full, every tool):

claude mcp add trelix -- trelix-mcp --tools core

To confine the server to one or more repository roots, add --root PATH (repeatable; TRELIX_ALLOWED_REPO_ROOTS, os.pathsep-separated and read from the process environment, adds more; a blank --root value is a startup error). Every repo_path, federation_add_repo path and trelix://repo/... URI must then lie inside a root, or the call answers an error: repo_path is not inside an allowed repository root, or path is not inside an allowed repository root for federation_add_repo. A repository inside a root whose .trelix store is a symlink, or cannot be examined, is refused with the same error. federation_list_repos and federation_search_all then list and search only the registered repos inside the roots and report the others as repos_outside_roots, and federation_remove_repo answers an alias whose repo is outside them as an unregistered one. Without the flag and the variable, nothing is confined.

claude mcp add trelix -- trelix-mcp --root /Users/you/myrepo

Streamable HTTP (remote clients)

For a client that cannot spawn the process, serve Streamable HTTP instead of stdio. A root is required, and a token guards everything but GET/HEAD /health:

TRELIX_MCP_AUTH_TOKEN=... trelix-mcp --transport http --root /Users/you/myrepo
claude mcp add --transport http trelix http://127.0.0.1:8766/mcp --header "Authorization: Bearer $TRELIX_MCP_AUTH_TOKEN"

Defaults: --host 127.0.0.1, --port 8766, --path /mcp, stateless. TRELIX_MCP_AUTH_TOKEN (fallback TRELIX_API_AUTH_TOKEN) is the token and TRELIX_MCP_ALLOWED_HOSTS (fallback TRELIX_API_ALLOWED_HOSTS) adds hostnames to the Host/Origin guard, which is always on; a non-loopback --host needs a token or --allow-unauthenticated. Add --stateful for a client that opens a server-initiated GET stream. stdio with no flags is unchanged. Every flag, error text and proxy note: docs/MCP_GUIDE.md, section 19.

Cursor (~/.cursor/mcp.json)

{
  "mcpServers": {
    "trelix": {
      "command": "trelix-mcp",
      "args": []
    }
  }
}

Continue.dev (.continue/config.json)

{
  "mcpServers": [
    {
      "name": "trelix",
      "command": "trelix-mcp",
      "args": []
    }
  ]
}

Configuration

Set environment variables before starting the MCP server. All variables are optional — defaults work out of the box with the local embedding provider and openai chat provider.

Embedding provider

# Local sentence-transformers — no API key (default)
TRELIX_EMBEDDER_PROVIDER=local

# Local BGE Code — EXPERIMENTAL: pooling unverified, no quality claim, no API key
TRELIX_EMBEDDER_PROVIDER=bge-code

# Local Nomic Code — competitive code embeddings, no API key
TRELIX_EMBEDDER_PROVIDER=nomic-code

# Azure OpenAI embeddings
TRELIX_EMBEDDER_PROVIDER=azure
AZURE_API_KEY=...
AZURE_ENDPOINT=https://<resource>.openai.azure.com/

# Voyage AI — best API-based code embeddings (CoIR 56.26)
TRELIX_EMBEDDER_PROVIDER=voyage
VOYAGE_API_KEY=...

# AWS Bedrock Cohere — strong code retrieval, no extra key beyond AWS creds
TRELIX_EMBEDDER_PROVIDER=bedrock-cohere
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
AWS_REGION=us-east-1

# AWS Bedrock Titan v2 — configurable 256/512/1024 dims
TRELIX_EMBEDDER_PROVIDER=bedrock-titan
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
AWS_REGION=us-east-1

Chat / synthesis provider (used by index_codebase contextual chunking and synthesis)

# OpenAI (default)
TRELIX_LLM_PROVIDER=openai
OPENAI_API_KEY=sk-...

# Azure GPT-4o
TRELIX_LLM_PROVIDER=azure
AZURE_API_KEY=...
AZURE_ENDPOINT=https://<resource>.openai.azure.com/

# AWS Bedrock — Claude Sonnet 4.6 default with auto-fallback to Haiku
TRELIX_LLM_PROVIDER=bedrock
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
AWS_REGION=us-east-1
# Optional overrides:
TRELIX_LLM_BEDROCK_PRIMARY_MODEL=us.anthropic.claude-sonnet-4-6
TRELIX_LLM_BEDROCK_FALLBACK_MODEL=us.anthropic.claude-haiku-4-5-20251001-v1:0

# Anthropic direct
TRELIX_LLM_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...

# Google Vertex AI / Gemini
TRELIX_LLM_PROVIDER=vertex
GOOGLE_CLOUD_PROJECT=my-project
GOOGLE_CLOUD_LOCATION=us-central1

# LiteLLM — 100+ providers
TRELIX_LLM_PROVIDER=litellm
TRELIX_LLM_MODEL=bedrock/claude-3-5-sonnet

Resource subscription limits

# Max concurrent resource subscriptions across all clients — caps unbounded
# growth from a client that subscribes repeatedly without ever unsubscribing
TRELIX_MCP_MAX_SUBSCRIBERS=1000

# Auto-evict a subscription after this many seconds of inactivity
TRELIX_MCP_SUBSCRIPTION_TTL_SECONDS=3600

Result size limits

# Largest page a list tool returns: k (and agent_list_sessions's limit) is clamped to 1..this
TRELIX_MCP_MAX_K=50

# Budget, in characters, for a list result. Over it the tail is dropped and the response says
# so; the whole response (both copies a client is sent) is at most twice this. 0 turns the cut off.
TRELIX_MCP_MAX_RESULT_CHARS=15000

Both are read on every call. A blank value means the default; a value that is not an integer (of at least 1 for TRELIX_MCP_MAX_K, at least 0 for TRELIX_MCP_MAX_RESULT_CHARS) stops trelix-mcp at start-up with exit code 2. See Result size.

Retriever cache

# Most Retrievers kept across tool calls, one per repository (search_code and graph_search_mcp
# reuse them; each may hold an embedding model with the local provider). Past this bound the
# least recently used one is dropped, not closed, and the next call for that repo rebuilds it.
TRELIX_MCP_RETRIEVER_CACHE_SIZE=8

Read on every call. A blank value means the default; a value that is not an integer of at least 1 stops trelix-mcp at start-up with exit code 2 and makes a tool call return an error.

Tools

tools/list returns the tools in a fixed order and marks each one with MCP annotation hints; the server also sends short instructions that tell a model to index first and which search tool to use next. Only search_code, get_symbol and blast_radius are marked readOnlyHint: true, agent_clear_session and federation_remove_repo are marked destructiveHint: true, and every tool has openWorldHint: false. The read-only hint means the index database is left alone, not the whole repository directory: the caveats (query telemetry, the migration of an index written by an older trelix, the search_code trace files under .trelix/debug/) and the full table are in docs/MCP_GUIDE.md, section 8.

--tools full (default) lists all 15 tools. --tools core lists seven: index_codebase, search_code, get_symbol, blast_radius, build_knowledge_graph, graph_search_mcp and ask_agent. The other eight are hidden, not removed. (repo_map and exact_search do not exist in this server, so core does not list them.)

Tool Description
search_code(query, repo_path, k=10, cursor=0, detail="detailed") Hybrid semantic+BM25 search with cursor pagination; detail="concise" returns a one-line signature instead of each body
index_codebase(repo_path, provider="local") Index a repo (run once); emits progress notifications
get_symbol(qualified_name, repo_path, max_body_chars=20000) Get the source of a symbol by qualified name; a longer body is cut and body_truncated is true (0 = no limit)
blast_radius(symbol_name, repo_path, limit=100) Direct callers + importers of a symbol, from the call/import graph (no embedding model, ~60-120 ms); limit is 1 to 500
build_knowledge_graph(repo_path) Build code property graph
graph_search_mcp(query, repo_path, k=10, detail="detailed") Search via knowledge graph
subscribe_resource(uri, subscription_id) Register a subscription for a trelix:// resource URI (v2.5.0+); no notification is delivered yet, see Resource Subscriptions
unsubscribe_resource(subscription_id) Cancel a resource subscription (v2.5.0+)

Multi-Repo Federation Tools (v2.8.0)

Tool Description
federation_list_repos(config_path=None) List all repos registered for federated search
federation_add_repo(alias, path, weight=1.0, config_path=None) Register a repo for federated search (absolute path required)
federation_remove_repo(alias, config_path=None) Unregister a repo by alias
federation_search_all(query, k=10, cursor=0, config_path=None, detail="detailed") Search across all registered repos with RRF-weighted fusion; repos_unindexed names the registered repos skipped for having no index

Persistent Agent Session Tools (v2.8.0)

Tool Description
ask_agent(query, repo_path, session_id=None) Multi-turn ReAct Q&A with persistent memory (pass session_id to resume)
agent_list_sessions(repo_path, limit=50) List recent agent sessions for a repo (limit is clamped to 1..TRELIX_MCP_MAX_K)
agent_clear_session(repo_path, session_id) Delete a persisted agent session and all its turn history

Resource Subscriptions (v2.5.0)

trelix-mcp has tools for registering interest in a resource, but it does not push index change notifications yet: see the status note below. Register a URI with the subscribe_resource tool.

# Subscribe to a repo manifest
subscribe_resource(
    uri="trelix://repo//path/to/repo/manifest",
    subscription_id="my-sub-001"
)
# → the URI is registered; no notification is delivered yet (see below)

# Cancel the subscription
unsubscribe_resource(subscription_id="my-sub-001")

The server does not advertise resources.subscribe (it reports false) and does not serve the resources/subscribe request: subscribe_resource and unsubscribe_resource are ordinary tools that record URIs in an in-memory registry inside the trelix-mcp process. URIs follow the scheme trelix://repo/{repo_path}/manifest. The notify_file_changed() hook (wired into FileWatcher._do_reindex since v2.7.0) would fire per-URI notifications with the subscriptionId in params._meta, but it runs in the trelix watch process, where this registry is empty, and nothing starts a watcher inside trelix-mcp — so no notification is delivered today.

Subscriptions are capped and TTL'd by default — see Resource subscription limits (TRELIX_MCP_MAX_SUBSCRIBERS, default 1000; TRELIX_MCP_SUBSCRIPTION_TTL_SECONDS, default 3600). Subscriptions older than the TTL are swept on the next registry access. If the registry is at capacity, subscribe_resource does not raise — it returns {"subscribed": false, "uri": ..., "subscription_id": ..., "error": "..."} so callers can handle rejection gracefully.

Pagination

search_code supports cursor-based pagination for large codebases:

# Fetch page 1
page1 = search_code(query="authentication", repo_path="/repo", k=10)
print(page1["total_available"])  # total results
print(page1["results"])          # this page's results

# Fetch page 2 if more results exist
if page1["next_cursor"] is not None:
    page2 = search_code(query="authentication", repo_path="/repo", k=10, cursor=page1["next_cursor"])

next_cursor is null after the last page, and a negative cursor is an error result.

Result size

A tool result costs a client's context twice (FastMCP sends a dict result as a text block and again as structuredContent), so these bound it:

  • k (and limit on agent_list_sessions) is clamped to 1..TRELIX_MCP_MAX_K (default 50); page_size in the response is the value used.
  • A list result is cut to fit TRELIX_MCP_MAX_RESULT_CHARS (default 15,000; 0 turns it off) by dropping the tail. The budget counts both copies a client is sent, so the whole response is at most twice the budget (30,000 characters by default) and its text under the budget. A cursor-paged response (search_code, federation_search_all) sets truncated and omitted and points next_cursor at the first dropped result, so paging loses and repeats nothing. A bare array (blast_radius, graph_search_mcp) keeps the JSON array as its first text block and adds a note block and _meta.trelix (total_available, omitted). One result is always kept, so a single result longer than the budget is returned whole.
  • detail="concise" drops each body; get_symbol cuts a body over max_body_chars and reports body_truncated; agent_list_sessions cuts each session's query (its most recent prompt) to 300 characters and reports query_truncated.

The full description, with measured sizes, is in docs/MCP_GUIDE.md.

Errors

An invalid input is a tool error (isError: true, one text block, the session carries on) whose text names the argument, shows what was given and says what is valid: a repo_path that is blank, does not exist or is a file; a blank query, qualified_name, symbol_name, alias, session_id or config_path; a federation_add_repo path that is not an absolute directory or a weight that is not positive; a negative cursor or max_body_chars. A repository with no index answers No index found at <repo>/.trelix/index.db. Run trelix index <repo> first., and an argument of the wrong type or outside its choices is rejected by FastMCP itself, also as a tool error. subscribe_resource and unsubscribe_resource accept any string and are outside this contract. k and limit outside their range are clamped rather than rejected, and the federation tools keep their error key for a duplicate alias, a full registry, a non-blank config_path that is not a .json registry file inside ~/.config/trelix/ or <cwd>/.trelix/ (config_path is not inside an allowed config directory or config_path is not a repository registry) and a registry with nothing indexed. Every result, including an empty one ([], null), carries a text block that parses to its structured content. Over --transport http, an exception a tool did not expect answers isError: true with Error calling tool '<name>' (no path, no traceback) while every text above is unchanged. Details: docs/MCP_GUIDE.md, Errors.

Knowledge Graph Tools

Two tools expose the knowledge graph layer to AI agents:

build_knowledge_graph

Builds a Code Property Graph over an indexed repo. Returns node/edge counts, community count, and a summary of top architectural clusters.

build_knowledge_graph(repo_path="/path/to/repo")
→ {node_count: 4599, edge_count: 4945, community_count: 2409, community_summary: [...]}

Use this before graph_search_mcp for best results — or let graph_search_mcp call it automatically.

graph_search_mcp

Hybrid search: first retrieves semantic seeds, then expands via BFS over call/import/type edges.

graph_search_mcp(query="how does auth relate to the user model?", repo_path="/path/to/repo", k=10)
→ [{file, symbol, kind, score, source, body}, ...]

When to use graph_search_mcp instead of search_code:

  • "What does X depend on?"
  • "What would break if I change Y?"
  • "How does module A connect to module B?"
  • Architecture understanding queries where structural relationships matter

Install the knowledge graph extra for full functionality:

pip install trelix-mcp 'trelix[knowledge-graph]'

Watch Bridge (v2.7.0)

After each file re-index, trelix watch calls notify_file_changed(), which writes notifications/resources/updated for the URIs registered with subscribe_resource. No MCP client receives these notifications today. trelix watch is a separate process from trelix-mcp and its subscription registry is empty, and nothing in trelix-mcp starts a file watcher, so running trelix-mcp in one terminal and trelix watch /path/to/repo in another does not connect them. The notification can only reach a client when the watcher runs inside the stdio server process.

Registering a subscription to a repository's manifest URI works; subscribe_resource takes two required strings. There is no glob support:

subscribe_resource(uri="trelix://repo//path/to/repo/manifest", subscription_id="my-sub-001")

Once delivery works, a notification will carry only {"uri": ..., "_meta": {"subscriptionId": ...}} — no file paths and no stats. Call resources/read on that URI to see what changed.

Metadata

Release files for trelix-mcp 3.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for trelix-mcp 3.5.1
File Size Uploaded Provenance Actions
trelix_mcp-3.5.1.tar.gz 124.9 kB With provenance Details for trelix_mcp-3.5.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for trelix-mcp 3.5.1
File Interpreter ABI Platform Actions
trelix_mcp-3.5.1-py3-none-any.whl Python 3 none any Details for trelix_mcp-3.5.1-py3-none-any.whl

Total release size: 181.9 kB

Release files / trelix_mcp-3.5.1.tar.gz

Download URL trelix_mcp-3.5.1.tar.gz
Size 124.9 kB
Tags Source
SHA-256 checksum
How to use checksums
f986b6a2e8bb0e6fa8e0d814ec750be90644ad7024c448063ecae5537c7297fa
BLAKE2b-256 checksum
How to use checksums
e2a7ec044b9d1b1dace8115245b7cd62a86c0094dc4de20d702fe0f5c670aaad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

Release files / trelix_mcp-3.5.1-py3-none-any.whl

Download URL trelix_mcp-3.5.1-py3-none-any.whl
Size 57.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e389ea9152a05555d0e12ed2650f46ecfbceab29cec1a7431debf5ba283d5362
BLAKE2b-256 checksum
How to use checksums
302a495d8f693909fbf8109ffedfcde65791ebead8a5b49ea3e76354c249afd5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

Security for trelix-mcp 3.5.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for trelix_mcp-3.5.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

3.5.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page