fw-context-mcp

fw-context-mcp

Exposes tools for AI assistants to query a persistent SQLite+FTS5 index of C/C++ symbols parsed from real build commands, enabling sub-millisecond lookup, full-text search, and natural-language explanation without hallucination.

Category
访问服务器

README

fw-context

Build-aware code intelligence for embedded firmware — a tool that lets AI assistants understand your C/C++ codebase without hallucinating function names, missing overloads, or guessing which #ifdef branch is active.

What it does

fw-context parses your actual build (compile_commands.json) with libclang — the same parser your IDE uses — and stores every C/C++ symbol in a full-text-searchable SQLite + FTS5 database on disk. An MCP server then exposes this index as tools that AI assistants (Claude Code, OpenCode) can call directly: sub-millisecond lookups, zero hallucination, real C/C++ understanding.

Once indexed, your AI assistant can answer questions like:

"What does modem_parser_oob_init do and who calls it?"

"Find all functions related to BLE pairing failure handling."

"Show me the definition of ZCfgDataManager — not the declaration, the actual implementation."

"Is the index up to date, or did I forget to re-index after my last edit?"

"Where is reset_slot_error_lock used across the entire project?"

The assistant resolves these by querying the index — no grepping through files, no guessing from training data, no reading 8000 Mbed OS headers into context.

Why not just use LSP?

LSP servers (clangd, ccls) are designed for interactive editing — go-to-definition, autocomplete, hover info. They're excellent at that. But they have limitations for AI-assisted code exploration:

  • No full-text search across the codebase. LSP can find a symbol by name, but not "all functions related to modem initialization."
  • No persistent index. The LSP index lives in memory; restart the server and it rebuilds from scratch. fw-context's index is a SQLite file — it survives reboots, and your AI assistant reads it in milliseconds.
  • No AI-oriented interface. LSP speaks a protocol designed for editors, not for AI agents. fw-context's MCP tools are purpose-built for the assistant's workflow: lookup, search, explain, re-index.
  • Grep is blind to build context. grep -r doesn't know which translation units are actually compiled, which #ifdef branch is active, or whether a match is a definition or just a forward declaration. fw-context knows all three.

fw-context doesn't replace LSP — it complements it. Use clangd for editing, fw-context for AI-assisted exploration.

Three components

Component Runs as Purpose
CLI (fw-context) User command Index build, status checks, project management
Indexer Called by CLI libclang parses every translation unit from compile_commands.json, extracts symbols with qualified names, signatures, and locations, stores them in SQLite + FTS5
MCP server (fw-context-mcp) Subprocess started by AI assistant Exposes 12 tools over JSON-RPC 2.0 (stdin/stdout); optionally calls a local Ollama model for natural-language search and symbol explanation

Key characteristics

  • Zero daemon. No background process — the index is a file on disk that the MCP server reads on-demand. Each tool call opens the DB, runs a query, and closes.
  • Ollama is optional. explain_symbol and smart_search can use a local LLM for natural-language queries, but when Ollama is disabled, the AI assistant processes results with its own model. Everything else works without any LLM at all.
  • Incremental by default. After the first index, only files with changed modification time are re-parsed. Editing one file and running fw-context index takes under a second.
  • Auto-reindex on query. search_code and lookup_symbol detect stale files in their results and re-index them on the fly — so the typical edit→search workflow requires no manual steps.
  • Offline-first. The index lives at ~/.fw-context/index/. No cloud account needed. Ollama runs locally if you choose to use it.

Supported ecosystems

Works with any embedded build system that produces compile_commands.json: Mbed OS, Zephyr RTOS, PlatformIO (Arduino, ESP-IDF, STM32Cube), FreeRTOS, bare-metal ARM, and anything else compiled with GCC or Clang. No LSP server, no c_cpp_properties.json, no manual configuration — it uses the real compiler flags, so it sees what your compiler sees, #ifdefs and all.

First indexing depends on project size — from seconds for small bare-metal projects (50–200 files) to 15–20 minutes for large Mbed OS codebases with thousands of framework headers pulled in through #include. Subsequent runs are incremental — only changed files are re-parsed, so they finish in seconds.

Supported ecosystems

fw-context auto-detects your build system and source roots from the project structure. The only hard requirement is compile_commands.json — if your toolchain can produce one, fw-context can index it.

Ecosystem Auto-detection Typical indexed scope Index time (first run) Notes
Mbed OS mbed-os/, mbed_app.json 2 000–9 000 files<br>20 000–80 000 symbols 5–20 min Framework + your code; #include chain pulls in large parts of mbed-os
Zephyr RTOS west.yml, prj.conf 1 000–15 000 files<br>10 000–100 000+ symbols 3–20 min West workspace includes modules, drivers, subsystems
PlatformIO platformio.ini 500–10 000 files<br>5 000–80 000 symbols 1–15 min Arduino (~500 files), ESP-IDF (~10 000), STM32Cube, Teensy…
Bare-metal / FreeRTOS Any build with bear 50–2 000 files<br>500–20 000 symbols 5 s–3 min No OS framework overhead; only your code + RTOS kernel headers
Custom / in-house RTOS Any build with bear Scales to 10 000+ files<br>100 000+ symbols 10–30 min Proprietary toolchains that emit compile_commands.json work too

The indexer auto-detects source directories (src, lib, app, include, drivers, modules, zephyr, mbed-os) from your project structure and compile_commands.json entries. Framework symbols your code actually #includes are indexed automatically — no manual configuration needed.

What problem it solves

AI coding assistants are great at Python, JavaScript, and Go — languages with mature LSP servers, static analysis, and training data. Embedded firmware is different:

  • Proprietary codebases the model has never seen — no training data.
  • Massive dependency trees — Mbed OS ships ~8 000 C++ files, Zephyr workspace contains 15 000+ source files across subsystems and drivers, and ESP-IDF adds ~10 000 more. Too large to read into context.
  • Build-time macros and #ifdefs that change which code is actually compiled.
  • Custom build systems (mbed compile, west build, pio run) whose include paths, defines, and compiler flags are opaque until you run them.

Without an index, the assistant resorts to grep — slow, imprecise, and blind to which translation units are actually part of the build. It hallucinates function names, misses overloads, and can't tell a definition from a declaration.

fw-context solves this by parsing your actual build. It reads compile_commands.json (the exact same compilation database your build system produces), parses every translation unit with libclang (the same parser as your IDE), and stores the extracted symbols in a SQLite + FTS5 database on disk. Your AI assistant then queries this database through an MCP server — sub-millisecond lookups, zero hallucination, real C/C++ understanding.

How it works, at a glance

  1. Your build system         2. fw-context index            3. AI assistant
  ┌──────────────────┐        ┌─────────────────────┐        ┌──────────────────┐
  │ bear / west / pio │  ──→  │ libclang parses      │  ──→  │ lookup_symbol(…) │
  │ compile_commands  │        │ every .c/.cpp in TU │        │ search_code(…)   │
  │ .json             │        │ SQLite + FTS5 db    │        │ explain_symbol(…)│
  └──────────────────┘        └─────────────────────┘        └──────────────────┘

Key technologies

Tool Role
libclang C/C++ parser — traverses AST for each translation unit, extracts symbols with their qualified names, signatures, docstrings, and location. Uses the exact compiler flags from compile_commands.json (include paths, defines, standards) so it sees what the compiler sees.
SQLite + FTS5 Storage and full-text search. The symbols table stores name, kind, signature, file/line, docstring, and definition-vs-declaration flag. The FTS5 index covers 6 columns: name (original C++ name), qualified_name (full namespace::class::method), signature (parameter types), docstring (documentation comments), file_path (relative path from project root, for module context), and name_tokens (camelCase/snake_case split for sub-token search — e.g. onConnectionCompleteon connection complete). FTS5 enables fast prefix/phrase/keyword queries without loading entire files.
MCP SDK JSON-RPC 2.0 server framework. Handles protocol initialization, message framing, and tool registration. The server is stateless between calls — each tool invocation opens the DB, runs the query, and closes.
httpx Async HTTP client for calling Ollama's REST API (/api/chat, /api/tags). Used by smart_search and explain_symbol.
Ollama (optional) Local LLM runtime. Two models are used: qwen2.5-coder:14b for natural-language-to-FTS5 translation, query understanding, and symbol explanation; mxbai-embed-large:latest for semantic embedding search (Phase 4 — cosine similarity between query and 15K+ symbol descriptions). Both models auto-pull on first use. When disabled, the AI assistant processes results with its own LLM — no Ollama required.
bear LD_PRELOAD-based build interception. Wraps your build command (bear -- python3 build_app.py) to produce compile_commands.json. Required once per build config change.

What gets indexed

The indexer extracts every definition and declaration from the translation units in compile_commands.json:

Symbol kind Example
Function void uart_init(int baudrate)
Method bool Modem::connect(const char *apn)
Constructor / Destructor BleManager::BleManager()
Class / Struct class BoxManager { … }
Enum enum class State { IDLE, ACTIVE }
Enum constant State::IDLE
Typedef / Using using Callback = void(*)(int); typedef uint32_t tick_t
Variable / Field int _counter; static constexpr size_t BUFFER_SIZE
Namespace namespace zbox { … }

All have qualified names (e.g. zbox::BleManager::start_advertising), signatures, and file + line locations.

Each symbol is stored in the FTS5 index with 6 searchable columns:

FTS5 column Content
name Original C++ name
qualified_name Full namespace::class::method
signature Parameter types
docstring Documentation comments
file_path Relative path from project root (module context)
name_tokens camelCase/snake_case split — onConnectionCompleteon connection complete

Source roots are auto-detected from your project structure (src, lib, app, include, modules, zephyr, mbed-os) and compile_commands.json entries — OS and framework symbols your project actually #includes are indexed automatically. No manual configuration needed.

Quick start

# 1. Clone and install
git clone git@github.com:turbyho/fw-context-mcp.git ~/.fw-context/src
# or from the primary server:
# git clone git@git.montyho.com:turbyho/fw-context-mcp.git ~/.fw-context/src
uv venv ~/.fw-context/.venv --python 3.12
uv pip install --python ~/.fw-context/.venv/bin/python ~/.fw-context/src/
echo 'export PATH="$HOME/.fw-context/.venv/bin:$PATH"' >> ~/.bashrc

# 2. Register with your AI assistant
fw-context init

# 3. Generate compile_commands.json, then index
cd your-firmware-project
bear --output compile_commands.json -- python3 build_app.py --profile release     # Mbed OS
fw-context index compile_commands.json

# Set as default for the project:
echo 'compile_commands = "compile_commands.json"' >> .fw-context/config.toml

# Done. Restart your AI assistant and start asking it about your code.

Installation & setup

For detailed prerequisites, installation steps, Ollama setup, and AI assistant integration, see Installation guide.

The short version:

git clone git@github.com:turbyho/fw-context-mcp.git ~/.fw-context/src
uv venv ~/.fw-context/.venv --python 3.12
uv pip install --python ~/.fw-context/.venv/bin/python ~/.fw-context/src/
echo 'export PATH="$HOME/.fw-context/.venv/bin:$PATH"' >> ~/.zshrc
fw-context init

Day-to-day workflow

compile_commands.json  ──→  fw-context index  ──→  AI assistant tools
        ↑                                              │
   bear / west / pio                                   │
        │                                      lookup · search · explain
   your build system

1. Generate compile_commands.json

Mbed OS:

bear -- python3 build_app.py --profile release --type DEV

Zephyr:

west build -b <board> -- -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
fw-context index build/compile_commands.json

PlatformIO:

pio run --target compiledb

2. Index the project

Run from the project root:

fw-context index

First run depends on project size — small projects finish in seconds, large Mbed OS codebases with 50 000+ symbols can take 15–20 minutes. Subsequent runs are incremental — only files with changed modification time are re-parsed.

Source roots are auto-detected by default. The indexer scans your project for common source directories (src, lib, app, include, modules) and OS/framework directories (zephyr, mbed-os), then supplements with directories discovered from compile_commands.json. This means OS symbols your project actually uses are indexed automatically — no manual config needed.

# Custom source roots (override auto-detection)
fw-context index --source-roots src lib vendor

# Index a different project
fw-context index --project /path/to/other/project

# Verbose output — shows per-file progress
fw-context index -v

3. Use with your AI assistant

Once indexed, your assistant can:

  • "What does modem_parser_oob_init do?"lookup_symbol + explain_symbol
  • "Find functions related to BLE advertising"search_code or smart_search
  • "Is the index up to date?"get_active_build
  • "I changed main.cpp, re-index it"reindex_file

4. Keep the index current

After editing source files, the index stays accurate in three ways:

  • Automatic re-indexsearch_code and lookup_symbol detect stale files in their results and re-index them on the fly (up to 5 files, 30 s timeout), then re-run the query. No manual steps needed for typical edit→search workflows.
  • Automatic staleness detection — if compile_commands.json itself changed, or auto-reindex failed, tools return a clear warning with next steps.
  • On-demand re-index — run fw-context index (incremental, fast) or use reindex_file("src/main.cpp") via the MCP tool.
# Check if the index is stale
fw-context status

# Re-index changed files only
fw-context index

# Fresh start (after toolchain change, compiler upgrade, etc.)
fw-context reset
fw-context index

CLI & MCP tools

Full CLI reference, MCP tool catalog, and a detailed walkthrough of how each tool works internally: see Tools Reference.

Configuration

Complete configuration reference — global defaults, per-project overrides, source root auto-detection, and all [index] / [llm] / [project] settings: see Configuration.

Ollama & AI assistant setup

For Ollama installation, model selection (local and cloud), and AI assistant integration (Claude Code, OpenCode): see Installation guide.

Troubleshooting

"No index found"

Run fw-context index from the project root first. The index is per-project and stored under ~/.fw-context/index/.

Index is stale

Run fw-context index — it's incremental and picks up only changed files.

Symbols missing or incomplete

By default source roots are auto-detected from your project structure and compile_commands.json. If symbols from certain directories are missing:

  1. Check .fw-context/config.toml — explicit source_roots overrides auto-detection. Remove it to restore auto-detection, or add the missing directories.
  2. Make sure the file is listed in compile_commands.json.
  3. For PlatformIO frameworks (Arduino, ESP-IDF) whose sources live outside the project root (e.g. ~/.platformio/packages/), add them explicitly:
    source_roots = ["src", "lib", "/home/user/.platformio/packages/framework-arduinoespressif32"]
    

"Cannot connect to Ollama"

Ollama is optional. If you don't have it (no GPU, no cloud account), disable it in config:

# ~/.fw-context/config.toml
[llm]
enabled = false

Then explain_symbol returns the source code and prompt for the AI assistant to answer itself, and smart_search falls back to direct keyword search — no Ollama connection needed.

To use Ollama instead, install it from ollama.com and pull the models:

# LLM model — required for smart_search and explain_symbol
ollama pull qwen2.5-coder:14b

# Embedding model — required for semantic search (Phase 4)
ollama pull mxbai-embed-large:latest

Both models are auto-pulled on first use if not installed — but pre-pulling avoids a long delay during the first smart_search call.

Then verify:

fw-context check_ollama

clang.cindex error / libclang not found

# Ubuntu/Debian
sudo apt install libclang-dev

# macOS
brew install llvm
echo 'export PATH="/opt/homebrew/opt/llvm/bin:$PATH"' >> ~/.zshrc

"No module named fw_context_mcp" after install

Make sure ~/.fw-context/.venv/bin is in your PATH:

export PATH="$HOME/.fw-context/.venv/bin:$PATH"

Reset after toolchain upgrade

Delete the old index and rebuild:

fw-context reset -y
fw-context index

Directory layout

~/.fw-context/
├── config.toml          # global defaults (LLM model, db path)
├── .venv/               # Python virtual environment
│   └── bin/
│       ├── fw-context       # CLI entry point
│       └── fw-context-mcp   # MCP server entry point
└── index/
    └── <project-id>/
        └── index.db     # SQLite database with FTS5 index

Project-level:

your-firmware/
├── .fw-context/
│   └── config.toml      # per-project overrides (source roots, excludes)
└── compile_commands.json

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选