Code Intelligence MCP Server
apps/code-intel-mcp/ is the AST-based code intelligence
MCP server built under epic
AUT-3. It is
a sibling to the
GitHub MCP server — same Streamable
HTTP transport, same observability conventions — but exposes
tree-sitter-powered tools that return structured AST summaries instead
of raw source text. The scaffold is shipped and healthy; tool
implementations are in-progress.
| Attribute | Value |
|---|---|
| Service name | code-intel-mcp |
| Port (host + container) | 8091 |
| Transport | MCP Streamable HTTP (stateless, one server + transport per request) |
| Health endpoint |
GET /healthz →
{"status":"ok","valkey":"up"}
|
| Auth | None — internal-only service, not exposed outside amtp_net |
Current tools/list |
[] — tools pending AUT-35 through AUT-41
|
| Shared package |
@amtp/mcp-lib (packages/mcp-lib/)
— logger, health,
otel
|
| Jira epic | AUT-3 (assigned: Omar Zabin) |
Scaffold State #
Two phases have shipped. No tool implementations exist yet; that work starts at AUT-35.
Phase 1 — Scaffold Shipped (AUT-34) #
Delivered 2026-04-28 as AUT-34. Server structure copied from apps/github-mcp/ then stripped of GitHub-specific dependencies.
-
Copied from github-mcp:
tsconfig*.json,package.jsonscripts,Dockerfile(later flipped to repo-root build context), src/server.ts, src/index.ts, src/lib/telemetry.ts, src/lib/cache.ts. - Dropped (no GitHub API calls): github.ts, gitignore.ts, ignore-factory.ts, read-file-fetch.ts, search-code-fetch.ts, rate-limit.ts, binary-detect.ts, platform-excludes.ts, pipeline.ts, secrets.ts, size-filter.ts.
-
Added: empty src/tools/ directory,
compose service
code-intel-mcponamtp_netat port8091:8091, CI workflow .github/workflows/code-intel-mcp-ci-cd.yml,.env.exampleadditions (CODE_INTEL_MCP_PORT=8091).
Acceptance (met): server starts,
/healthz returns
{"status":"ok","valkey":"up"},
tools/list returns an empty array.
Phase 1.5 — Extract @amtp/mcp-lib
Shipped (2026-04-29)
#
After Phase 1, logger.ts, health.ts, and otel.ts existed identically in both apps/github-mcp/src/lib/ and apps/code-intel-mcp/src/lib/. This phase deduplicated them before drift could set in.
-
Repo became an npm workspace: root package.json
declares
workspaces: ["packages/*", "apps/code-intel-mcp", "apps/github-mcp"]. Per-app lockfiles deleted; rootpackage-lock.jsonis the single source of truth. -
New package packages/mcp-lib/
(
@amtp/mcp-lib) owns the three shared modules. Subpath exports:@amtp/mcp-lib/logger,@amtp/mcp-lib/health,@amtp/mcp-lib/otel. -
App-side wrappers:
logger.tsis a direct re-export;otel.tscallsinitOtel(serviceName)with the app-specific name (amtp-code-intel-mcp);health.tscallscreateHealthzHandler(redis)closing over the app-local ioredis singleton. -
cache.tsandtelemetry.tsstay app-local — both carry app-specific surface that does not belong in shared infra. -
Both
Dockerfiles switch build context to repo root so they canCOPY packages/mcp-lib/alongside the app.
@amtp/mcp-lib Workspace Package #
Located at packages/mcp-lib/. Shared by both
github-mcp and code-intel-mcp.
| Export path | Module | What it provides |
|---|---|---|
@amtp/mcp-lib/logger |
src/logger.ts | Structured JSON logger (pino or equivalent) |
@amtp/mcp-lib/health |
src/health.ts |
createHealthzHandler(redis) — Express
handler that pings Redis and returns
{"status":"ok","valkey":"up"}
|
@amtp/mcp-lib/otel |
src/otel.ts |
initOtel(serviceName) — bootstraps
OpenTelemetry SDK with OTLP HTTP exporter
|
AUT-3 Task Plan #
Eight tasks with a dependency tree rooted at
ast.summarize_file. Phases 1 and 1.5 are shipped. Phase
2 design questions must be answered before AUT-35 code lands.
| Key | Task | Depends on | Status |
|---|---|---|---|
| AUT-35 | tree-sitter for TS/JS/TSX/JSX | — | Planned |
| AUT-36 | tree-sitter for Python/Kotlin/Swift/Dart | scaffold from AUT-35 | Planned |
| AUT-37 | ast.summarize_file |
AUT-35 | Planned |
| AUT-38 | ast.extract_routes |
AUT-37 | Planned |
| AUT-39 | ast.extract_components |
AUT-37 | Planned |
| AUT-40 | ast.extract_selectors |
AUT-39 | Planned |
| AUT-41 | ast.find_symbol + repo index |
AUT-37 | Planned |
| AUT-42 | Benchmark the 85% claim | AUT-37 (minimum) | Planned |
The five tools form a dependency tree rooted at
summarize_file. Everything else is either a
specialization (routes/components/selectors operate on the same parsed
AST) or an extension (find_symbol indexes summaries;
benchmark measures them).
Phase 2 Design Questions #
1. WASM vs native tree-sitter #
web-tree-sitter (WASM) = no C compiler on self-hosted
runners, identical behaviour everywhere.
node-tree-sitter (native bindings, node-gyp) = faster,
but adds a compile step to CI.
Default: WASM. Defer the performance decision to AUT-42. Only switch to native if the benchmark proves WASM is the bottleneck.
2. Output JSON shape for ast.summarize_file
#
The downstream agents (Repo Crawler, Test Case Generator) are not built yet, but they will be coupled to this shape. Pick it now, document it in SCHEMA.md, and treat it as a contract. See the Output Schema Proposal below.
3. Cache key strategy #
github-mcp caches by
(repo, resolved_sha, args_hash). AST output is a pure
function of (content, language). Cache by
sha256(content) + ":" + language + ":" + TOOL_VERSION.
No GitHub ref involved. Validate with team before implementing.
Planned Tools #
| Tool name | Languages | Output summary | Jira |
|---|---|---|---|
ast.summarize_file |
TS, TSX, JS, JSX (v1); Python, Kotlin, Swift, Dart (v2) | imports, exports, declarations (signature only — body stripped) | AUT-37 |
ast.extract_routes |
TS/TSX (Next.js app + pages, SvelteKit, Flutter) | route paths, handler references, HTTP methods | AUT-38 |
ast.extract_components |
TS, TSX, JS, JSX | component name, props type, hooks used, event handlers, JSX children summary | AUT-39 |
ast.extract_selectors |
TS, TSX, JS, JSX |
test selectors with brittleness reason
(data-testid → role/name →
aria-label → CSS fallback)
|
AUT-40 |
ast.find_symbol |
all supported languages |
cross-file symbol index: [{path, kind, line}]
per symbol name. Valkey-backed, lazy-built, TTL 24 h.
|
AUT-41 |
Output Schema Proposal (ast.summarize_file)
#
Proposed top-level shape from apps/code-intel-mcp/PLAN.md § Phase 2. Must be ratified before AUT-37 lands. Body-stripping rule: keep node header (function signature, class header, interface body), drop body statements. This is where the ~85% token reduction comes from.
{
"path": "src/components/Button.tsx",
"language": "tsx",
"imports": [{ "source": "react", "names": ["useState"] }],
"exports": [{ "name": "Button", "kind": "function", "default": false }],
"declarations": [
{
"kind": "function", // function | class | interface | type | const | enum
"name": "Button",
"signature": "function Button(props: ButtonProps): JSX.Element",
"exported": true,
"async": false,
"line": 12
}
],
"jsx_root": true, // true for TSX/JSX files
"errors": [] // parser recovery notes
}
ast.summarize_file output shape —
apps/code-intel-mcp/PLAN.md § Phase 2.2
Design constraint: a 300-line TS file (~8,000 chars) must produce a summary of at most ~1,200 chars. If the schema grows past that, bodies are leaking in.
Config Reference #
| Variable | Default | Description |
|---|---|---|
CODE_INTEL_MCP_PORT |
8091 |
HTTP port the server listens on |
VALKEY_HOST |
valkey |
Hostname of the Valkey instance (cache + healthz probe) |
VALKEY_PORT |
6379 |
Valkey port |
VALKEY_PASSWORD |
— | Valkey AUTH password (required in production) |
OTEL_EXPORTER_OTLP_ENDPOINT |
http://otel-collector:4318 |
OTLP HTTP endpoint for traces / metrics |
OTEL_SERVICE_NAME |
amtp-code-intel-mcp |
Service name sent with every OTel span |
File Map #
-
src/
- index.tsEntry point — starts HTTP server
- server.tsMCP server wiring — stateless pattern (one McpServer + transport per request)
- tools/Empty — populated by AUT-35 through AUT-41
-
lib/
- cache.tsValkey-backed cache (app-local, TTLs TBD)
- telemetry.tsApp-local span helpers (app-specific tool spans + counters)
-
logger.tsRe-export of
@amtp/mcp-lib/logger -
otel.tsCalls
initOtel("amtp-code-intel-mcp")from@amtp/mcp-lib/otel -
health.tsCalls
createHealthzHandler(redis)from@amtp/mcp-lib/health
- DockerfileMulti-stage build; context = repo root to include packages/mcp-lib/
- PLAN.mdAUT-3 execution plan — 8 tasks, dependency tree, design decisions
-
package.jsonnpm workspace member —
@amtp/code-intel-mcp
For the shared library, see
@amtp/mcp-lib above. For the CI
workflow, see
Code Intel MCP Workflow.