name: fux-mcp
description: Serve a Fux index over MCP with fux mcp — the fux_search, fux_passage and fux_related tools, the [mcp] output defaults, registering the server in Claude Code, Codex, VS Code/Copilot or Kiro with a command the client can launch, and fixing a server that shows no tools. Use when asked to "use fux over MCP", "add fux as an MCP server" or when fux tools are not showing. Writes client config only when explicitly asked.
Fux over MCP — fux mcp
fux mcp is a long-running stdio server: the client spawns it, sends
newline-delimited JSON-RPC on stdin, and reads one JSON line per reply on
stdout. One process serves one repository — the one it finds from its
working directory. A human never runs it interactively except to test it.
Resolve the fux command first — see the fux-usage skill (fux → uv run fux → ./.venv/bin/fux, on Windows .venv\Scripts\fux.exe → python -m fux).
1 · MCP or the CLI?
The MCP surface is three tools, deliberately smaller than the CLI.
| you need | over MCP | on the CLI |
|---|---|---|
| ranked documents + confidence | fux_search | fux ask --json |
| the text of lines in a file | fux_passage | read the file |
| a document's links in and out, archived / superseded | fux_related | fux explain (outbound only) |
| a fetched, re-scored, cited answer with a freshness verdict | ❌ not exposed | fux answer |
| a query neighbourhood, routes, communities | ❌ | fux graph, fux path (fux-graph) |
| fused -q phrasings, --why, receipts | ❌ | the CLI flags |
If you have a shell and need anything in the ❌ rows, run the CLI. MCP's advantage is a warm process with no per-call start-up, and a client with no shell.
2 · The tools
fux_search — query (required), k, expand
{"results": [{"path": "docs/retry-policy.md", "title": "Retry policy", "score": 3.706,
"sha": "f9421e09…", "archived": false, "superseded": false,
"headings": ["Retry and backoff"]}],
"ranked_by": "accelerator",
"confidence": {"band": "partial", "answerable": true, "missing": ["mtls"], "verified": "unverified",
"coverage": 0.5, "separation": 0.4, "separation_floor": 0.1,
"doc_coverage": 1.0, "doc_coverage_floor": 0.0, "support": 1},
"next": "call fux_passage with a path to read a span, or fux_related for neighbours"}
Read confidence before results — treat a null confidence like none:
| band | do |
|---|---|
| grounded | use the results and cite them |
| partial | answer, but name every term in missing — or retry with expand (below) |
| weak | the top hits are not separable — report the candidates, not a conclusion |
| none (answerable: false) | do not answer from these results. Say what was searched and stop |
kdefaults to the server's resolved[mcp] top(§3), and the tool schema advertises that value. An explicitkwins.expandis words you expect the document to use when they differ from the question's. Scored below the query's own terms; a document matching only them is never returned. Use it after apartialwith non-emptymissing.- Results are documents, not spans.
headings(at most three,[]is a real answer) tells you where to look;fux_passagereads it. archived: true— follow thefux-archived-resultspolicy.superseded: true— it has been declared replaced; prefer its successor.ranked_byisacceleratororscan; results are identical either way.
fux_passage — path (required), line_start, line_end
Returns {"path", "line_start", "line_end", "sha", "text"}.
pathis repo-root relative, exactly asfux_searchreturned it — nofile:prefix.- Lines are 1-based and inclusive; omit both to read the whole file. A
line_startpast the end returns emptytext, not an error. - It reads the working-tree file now. Compare its
shawith the onefux_searchreturned: different means the file changed since it was indexed — the ranking is behind; say so. (The hash is fux's own, not a git sha.) - ⚠ It cannot read a URL document (
… is not a file in this repository), and on a PDF, DOCX or other binary it returns undecoded bytes. Usefux answeron the CLI. - It refuses any path that resolves outside the repository.
fux_related — path (required)
{"path": "docs/decisions/storage.md", "title": "Storage", "archived": false, "superseded": true,
"outbound": [{"path": "docs/runbook-rollback.md", "kind": "ref"}, {"path": "tag:storage", "kind": "tag"}],
"inbound": [{"path": "docs/decisions/storage-v2.md", "kind": "supersedes"}]}
- Accepts the
pathfromfux_search, or an id withfile:/url:. ⚠ A URL document needs theurl:prefix — a bare URL is looked up as a file. kindisref(link),supersedes,tag, orcode(a quoted file path). An inboundsupersedesmeans this document was replaced by that one.- Outbound targets keep a
url:ortag:prefix when they have one;file:is dropped. archivedandsupersededdescribe this document only, not its neighbours — callfux_relatedon a neighbour before relying on it.- No grades, communities or routes here — that is the CLI (
fux-graph).
A tool that fails answers with isError: true and a one-line reason
('x' is not in the index). Act on the reason; do not retry unchanged.
3 · Output defaults — [mcp] top is the only knob
[mcp]in.fux/output.tomlconfigures this server, and it inherits nothing from[cli]. Its one key istop.bandandjsonare refused there — the confidence block is unconditional and a result is always JSON.- Read once, at start-up. After editing
.fux/output.toml, restart the server. Index changes (fux ingest,fux build) are picked up on the next call. - No file → the built-in default (5). A file that exists but has no
[mcp] top→ the server refuses to start (§6). fux mcp --no-output-configignores the file entirely. In a client config it goes inargs:["run", "fux", "mcp", "--no-output-config"].
Offline, always. No tool fetches anything: fux_search ranks from the
committed index (hence verified: "unverified"), fux_related reads the
index, fux_passage reads a local file. Freshness is the sha comparison above.
4 · The command the CLIENT launches — the ladder problem
The client spawns the server with its own PATH and working directory, not
your shell's. A fux that works in your terminal can be command not found
for the client. Probe with the ladder, then write the rung that answered:
| rung that answered | command | args |
|---|---|---|
| uv run fux --version | uv | ["run", "fux", "mcp"] |
| ./.venv/bin/fux --version | /abs/path/to/repo/.venv/bin/fux | ["mcp"] |
| python -m fux --version | the absolute path of that python | ["-m", "fux", "mcp"] |
| fux --version | fux, or its absolute path if the client cannot find it | ["mcp"] |
The repository is found from the working directory — the nearest ancestor
holding fux.toml or .git. There is no flag or environment variable for it.
Where a client has cwd, set it; where it does not, use
["run", "--directory", "/abs/path/to/repo", "fux", "mcp"] with uv — in a
user-scope config only (see below).
- ⚠ Committed config is shared.
.mcp.json,.vscode/mcp.json,.kiro/settings/mcp.jsonand.codex/config.tomlreach every teammate — an absolute path works on one machine. Preferuv run fux mcpthere. - On Windows the venv binary is
.venv\Scripts\fux.exe; escape the backslashes in JSON.
Test the exact command before registering it, from the directory the client will use:
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | uv run fux mcp
Pass: two JSON lines — "serverInfo": {"name": "fux", …}, then a tools list
naming fux_search, fux_passage, fux_related. No JSON on stdout and an
error: line on stderr is a start-up failure — §6 names each one.
5 · Register it
Only when asked. Each writes a config file; say which file you changed.
Claude Code — project scope writes .mcp.json at the repo root:
claude mcp add --scope project fux -- uv run fux mcp
{"mcpServers": {"fux": {"type": "stdio", "command": "uv", "args": ["run", "fux", "mcp"]}}}
Check with claude mcp list or /mcp. A project server must be approved in an
interactive session before its tools appear.
Codex — ~/.codex/config.toml (user scope, so the absolute cwd below never
reaches a teammate):
[mcp_servers.fux]
command = "uv"
args = ["run", "fux", "mcp"]
cwd = "/abs/path/to/repo"
startup_timeout_sec = 30
codex mcp add fux -- uv run fux mcp adds it from the command line; set cwd in the
[mcp_servers.fux] table. In a committed .codex/config.toml, omit cwd and
launch Codex from the repo root. The default start-up timeout is 10 s — raise it if uv
has to sync on first launch. Check with /mcp.
VS Code / GitHub Copilot — .vscode/mcp.json:
{"servers": {"fux": {"type": "stdio", "command": "uv", "args": ["run", "fux", "mcp"], "cwd": "${workspaceFolder}"}}}
Start it from MCP: List Servers, accept the trust prompt, and use Show Output for its log.
Kiro — .kiro/settings/mcp.json (workspace; wins over ~/.kiro/settings/mcp.json):
{"mcpServers": {"fux": {"command": "uv", "args": ["run", "fux", "mcp"], "disabled": false}}}
Kiro has no cwd key — if the server cannot find the repo, put the --directory
form from §4 in the user file ~/.kiro/settings/mcp.json, never the committed
workspace one. Check the MCP server panel.
6 · Troubleshooting
| symptom (client log / test output) | cause | fix |
|---|---|---|
| command not found, ENOENT, "failed to connect" | the client's PATH lacks fux or uv | an absolute command (§4) |
| error: no fux.toml or .git found … | launched outside the repo | set cwd, or uv run --directory |
| error: .fux/pii.toml is missing … | the repo never ran fux setup | ask a human — setup writes committed files |
| error: .fux/output.toml does not set … naming [mcp] | the file predates the key | add [mcp] with top = 5, or --no-output-config |
| connected, but no tools | not approved / not trusted / disabled / Codex timed out | approve in the client; raise startup_timeout_sec |
| tools work, results are from another repo | the nearest .git above cwd is a different repo | point cwd at the right root |
| k default did not change after editing | [mcp] is read once | restart the server |
| client reports parse or protocol errors | something else writes to stdout | launch fux directly, not via a wrapper that prints |
Don't
- Don't answer from
fux_searchwhenanswerableisfalse, or skipmissingonpartial. - Don't pass a bare URL to
fux_related— prefixurl:. - Don't expect
fux_passageto fetch — it reads local files; URL documents needfux answer. - Don't write a bare
fuxinto a GUI client's config without testing that the client can launch it. - Don't commit an absolute path into a shared config file.
- Don't assume a neighbour is live because the document you asked about is.
- Don't reach for MCP when a shell is there and you need
answer,graphorpath.
Related skills: fux-usage, fux-search, fux-answer, fux-graph, fux-config, fux-index, fux-pii, fux-archived-results.
Expert Next.js App Router
Developpement
Un skill qui transforme Claude en expert Next.js App Router.
Générateur de README
Developpement
Crée des README.md professionnels et complets pour vos projets.
Rédacteur de Documentation API
Developpement
Génère de la documentation API complète au format OpenAPI/Swagger.