io.github.jean-johnson-zwix/arm-code-mcp
MCP server for Arm64 Linux performance: parse perf output, suggest NEON intrinsics, audit deps.
Open source Open in the app JSON README (API)
About
MCP server for Arm64 Linux performance: parse perf output, suggest NEON intrinsics, audit deps.
Details
- Kind
- MCP servers
- Topic
- No topic detected
- Publisher
- jean-johnson-zwix
- Origin
- official
- Category
- ferramentas
- Transport
- local
- Version
- 0.1.0
- Last push
- 2026-05-01T06:27:00Z
- Repository state
- ativo
- Language
- Python
- License
- NOASSERTION
- Added
- 2026-08-29 04:00:15
- Updated
- 2026-08-29 04:00:15
- Origin id
io.github.jean-johnson-zwix/arm-code-mcp
README
# arm-code-mcp
An MCP server that helps AI assistants optimize Linux workloads on Arm64.
It parses `perf report` output, recommends NEON SIMD intrinsics for hot loops,
and audits Python dependency manifests for arm64 wheel availability —
all offline, all structured, all callable from Claude Code, GitHub Copilot, and Codex.
---
## What's inside
- **`analyze_perf_output`** — parse `perf report --stdio` into a ranked list of hot symbols
- **`suggest_neon_intrinsic`** — semantic + keyword search over 110 curated NEON intrinsics
- **`check_arm64_deps`** — flag packages in `requirements.txt`, `pyproject.toml`, or `Dockerfile` that lack arm64 wheels or require special handling
---
## Prerequisites
- Docker
- An MCP-compatible AI assistant (Claude Code, GitHub Copilot, Codex)
---
## Quick start
```bash
docker pull jeannjohnson/arm-code-mcp:latest
```
Add to your MCP client config (e.g. `~/.claude/mcp.json`):
```json
{
"mcpServers": {
"arm-code-mcp": {
"command": "docker",
"args": ["run", "--rm", "-i", "jeannjohnson/arm-code-mcp:latest"]
}
}
}
```
Restart your client. All three tools are now available.
---
## Tools
### `analyze_perf_output`
Parse raw `perf report --stdio` output and return the top hot symbols, ranked by overhead.
```python
analyze_perf_output(
perf_report_text: str, # raw stdout of `perf report --stdio`
top_n: int = 10, # max symbols to return
min_overhead_pct: float = 0.5, # ignore symbols below this %
) -> dict
```
Example response:
```json
{
"summary": {
"total_samples": 5432100,
"total_events": null,
"command": "myapp"
},
"hot_symbols": [
{"overhead_pct": 24.17, "samples": 1245, "command": "myapp",
"module": "myapp", "symbol": "process_buffer"},
{"overhead_pct": 12.34, "samples": 636, "command": "myapp",
"module": "libc-2.31.so", "symbol": "__memcpy_avx_unaligned_erms"}
],
"warnings": []
}
```
---
### `suggest_neon_intrinsic`
Recommend NEON intrinsics for a hot loop using hybrid semantic + exact-name retrieval
over a curated knowledge base of 110 intrinsics.
```python
suggest_neon_intrinsic(
operation_description: str, # e.g. "32-bit float multiply-accumulate"
target_arch: str = "armv8-a", # "armv8-a" | "armv8.2-a" | "armv9-a"
top_k: int = 5,
) -> dict
```
Example response:
```json
{
"matches": [
{
"intrinsic": "vmlaq_f32",
"signature": "float32x4_t vmlaq_f32(float32x4_t a, float32x4_t b, float32x4_t c)",
"header": "<arm_neon.h>",
"min_arch": "armv8-a",
"description": "Multiply-accumulate: a + (b * c), lane-wise, 4x f32.",
"score": 0.9142
}
],
"notes": "Filtered to armv8-a. KB contains 110 entries (103 compatible)."
}
```
---
### `check_arm64_deps`
Scan a dependency manifest and flag packages with known arm64 compatibility issues.
Fully offline — no network calls, fast, deterministic.
```python
check_arm64_deps(
file_content: str, # raw text of the manifest
file_type: str = "requirements.txt", # "requirements.txt" | "pyproject.toml" | "Dockerfile"
) -> dict
```
Example response:
```json
{
"checked": ["numpy", "tensorflow", "cupy-cuda12x", "faiss-cpu", "requests"],
"issues": [
{"package": "cupy-cuda12x", "severity": "error",
"message": "GPU-only package with no arm64 wheel. Use cupy with ROCm or a CPU fallback."},
{"package": "tensorflow", "severity": "warning",
"message": "Official TensorFlow PyPI wheels are x86-only before 2.10; use tensorflow-aarch64 or build from source."},
{"package": "faiss-cpu", "severity": "warning",
"message": "No official arm64 wheel on PyPI; build from source or use the conda-forge package."},
{"package": "numpy", "severity": "info",
"message": "arm64 wheels available from PyPI since 1.21.0. Ensure version >= 1.21.0."}
],
"summary": "Checked 5 package(s): 1 error(s), 2 warning(s), 1 info(s)."
}
```
Severity levels:
| Level | Meaning |
|---|---|
| `error` | No arm64 wheel exists (e.g. GPU-only packages) |
| `warning` | Wheel exists but requires a workaround or alternative source |
| `info` | Wheel available; version constraint or system-lib note applies |
---
## Configuration
All env vars are optional. The server works with no configuration.
| Variable | Default | Description |
|---|---|---|
| `ARM_CODE_MCP_LOG_LEVEL` | `INFO` | Log verbosity: `DEBUG`, `INFO`, `WARNING` |
| `ARM_CODE_MCP_KB_PATH` | bundled JSONL | Override path to `neon_intrinsics.jsonl` |
| `ARM_CODE_MCP_CACHE_DIR` | `~/.cache/arm-code-mcp` | Embedding cache directory |
Pass env vars to the container:
```bash
docker run --rm -i \
-e ARM_CODE_MCP_LOG_LEVEL=DEBUG \
jeannjohnson/arm-code-mcp:latest
```
---
## Evaluation
`suggest_neon_intrinsic` is evaluated against 15 hand-curated (query, expected intrinsic) pairs
using the real `all-MiniLM-L6-v2` embedding model. Current baseline:
| Metric | Score |
|---|---|
| hit@1 | 0.667 |
| hit@3 | 0.933 |
| hit@5 | 1.000 |
| MRR | 0.817 |
The regression guard exits non-zero if hit@3 drops below 0.70.
Run the eval harness locally:
```bash
uv sync
make eval
```
See [`eval/README.md`](eval/README.md) for methodology and known limitations.
---
## Development
```bash
git clone https://github.com/jean-johnson-zwix/arm-code-mcp
cd arm-code-mcp
uv sync
make test # 78 tests
make lint # ruff check + format
make eval # real model, 15 gold queries
```
Makefile targets:
| Target | Description |
|---|---|
| `make setup` | `uv sync` + pre-commit install |
| `make test` | Run the full test suite |
| `make lint` | ruff check + ruff format --check |
| `make eval` | Run the NEON retrieval eval harness |
| `make docker-build` | Build `arm-code-mcp:dev` locally |
| `make docker-run` | Run the local dev image over stdio |
Multi-arch images (`linux/amd64` + `linux/arm64`) are built and pushed automatically
by `.github/workflows/release.yml` on `v*.*.*` tags.
---
## Knowledge base maintenance
The NEON intrinsics knowledge base lives in `src/arm_code_mcp/kb/data/neon_intrinsics.jsonl`
(110 entries). To add intrinsics or refresh after a model upgrade, see [`docs/kb-refresh.md`](docs/kb-refresh.md).
---
## Roadmap
**Tools**
- `parse_flamegraph` — extract hot paths from Linux perf flamegraph SVG
- `suggest_sve2_intrinsic` — extend retrieval to SVE2 intrinsics (Neoverse V2, Cortex-X4)
**Eval**
- Multi-query paraphrase expansion for each gold pair
- Reranking pass over semantic candidates
- Larger gold set (50+ queries) for lower metric variance
---
## Demo
Coming soon.
---
## Contributing
Stars, forks, and issues are welcome. Open a PR or file an issue on
[GitHub](https://github.com/jean-johnson-zwix/arm-code-mcp).
Good first issues:
- Add more NEON intrinsic entries to `kb/data/neon_intrinsics.jsonl`
- Add gold eval queries for SVE2 intrinsics
- Add `parse_flamegraph` tool for Linux perf flamegraph SVG files
---
## License
Apache 2.0 — same as [`arm/mcp`](https://github.com/arm/mcp).