elixir-context gives coding CLIs project-wide context for Elixir codebases: it
indexes modules, functions, docs, specs, Phoenix templates, and call edges into
a local SQLite database, then serves search and call-graph queries over the
Model Context Protocol (MCP).
An assistant editing one file can see that file but not the rest of the
project. Grep finds text; it cannot answer "who calls this function", "which
clause handles this message", or "show me the definitions that match this
concept". elixir-context answers those questions from an index that stays
local to your machine:
- Full-text search over module/function names,
@doc,@spec, and body keywords, with a ripgrep fallback for code the index has not seen yet. - Caller and callee queries with clause-level attribution, including
GenServer.call/castdispatch to the matchinghandle_call/handle_castclause. - One searchable entry per Phoenix
.heextemplate (components, assigns, calls). - An incremental watcher that re-indexes changed
.ex/.exsfiles. - No service, account, or network dependency: one SQLite file plus an MCP stdio server.
- Node.js 20 or newer.
- An Elixir project that builds with Mix (
mixonPATH). - The exporter uses
Jason; it is installed throughMix.install/1if the target project does not already depend on it.
The package is not published on npm yet; install from the repository:
git clone https://github.com/fosferon/elixir-context.git
cd elixir-context
npm installnpm install also fetches the better-sqlite3 native module and the ripgrep
binary used for the fallback path.
Build an index for an Elixir project:
node scripts/build.js \
--project ~/code/my_app \
--data ~/code/my_app/.elixir_contextAsk a question from the command line:
node scripts/query.js \
--db ~/code/my_app/.elixir_context/ec.sqlite \
--q "MyApp.Accounts" \
--k 5Register the MCP server with your coding CLI:
{
"mcpServers": {
"elixir-context": {
"command": "node",
"args": [
"/absolute/path/to/elixir-context/scripts/mcp-stdio.js",
"--root", "/absolute/path/to/my_app",
"--db", "/absolute/path/to/my_app/.elixir_context/ec.sqlite"
]
}
}
}The server exposes elixir_context_search, elixir_context_pack_context,
elixir_context_callers_of, elixir_context_calls_from,
elixir_context_refresh, elixir_context_index_status, and
elixir_context_health.
Keep the index fresh while you work:
node scripts/watch.js \
--root ~/code/my_app \
--db ~/code/my_app/.elixir_context/ec.sqliteThe watcher tracks .ex/.exs changes. Rebuild after .heex template
changes.
Flags take precedence over environment variables. The most useful settings:
| Setting | Flag | Environment | Purpose |
|---|---|---|---|
| Project root | --project, --root |
PROJECT_ROOT |
Elixir project to index or serve. |
| Data directory | --data |
DATA_DIR |
Where the index files live (build.js, npm scripts). |
| Database | --db |
ELIXIR_CONTEXT_DB |
SQLite file used by query, watch, and the MCP server. |
| Exporter | --exporter |
EXPORTER |
Path to export.exs for custom export logic. |
See docs/setup.md for the full workflow, npm script variants, and troubleshooting. docs/design.md covers the search pipeline and its trade-offs.
To use the locally linked CLI directly:
./bin/elixir-context.js --helpnpm test # unit + integration tests
bash scripts/public_guard_test.sh # public-content guard fixturesThe integration tests need elixir on PATH; without it they are skipped and
the test run prints how many were skipped.
Enable the pre-push content guard once per clone:
git config core.hooksPath .githooksThe hook scans every commit being pushed. Built-in patterns always run. If
PUBLIC_GUARD_EXTRA_FILE is set, or ~/.config/fosferon/public-guard-extra.txt
exists, the hook also checks those client-name extras and fails if they cannot
be loaded; otherwise it prints that extras were not checked. CI supplies the
extras from a repository secret on canonical pushes and same-repo pull
requests; fork pull requests and Dependabot runs check the built-in patterns
only. Extra entries are extended regular expressions, so escape any regex
metacharacters in a name.
MIT © 2025-2026 Fosferon