Skip to main content
Glama
README.md
# AOSP-MCP

[![CI](https://github.com/itznotabug/aosp-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/itznotabug/aosp-mcp/actions/workflows/ci.yml)
[![npm version](https://img.shields.io/npm/v/%40itznotabug%2Faosp-mcp)](https://www.npmjs.com/package/@itznotabug/aosp-mcp)
[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
![Improved w/: Claude | Codex](https://img.shields.io/badge/Improved%20w%2F-Claude%20%7C%20Codex-blueviolet.svg)

A [Bun](https://bun.sh)-powered Model Context Protocol (MCP) server for searching and reading Android source code via
`cs.android.com`. Built for coding agents: compact ripgrep-style results, response caching, request coalescing, and
pagination designed around agent token budgets.

Works with `Claude Code`, `Cursor`, `VS Code Copilot`, `Zed`, `Gemini CLI`, `Codex CLI`, `Windsurf`, and any other MCP
client with stdio support.

## Preview

![aosp-mcp example output](https://raw.githubusercontent.com/itznotabug/aosp-mcp/main/preview.png)

## Features

- **Code search** across AOSP, AndroidX/Jetpack, Android Studio, and Android LLVM, with regex and
  `file:` / `class:` / `function:` / `symbol:` / `content:` / `lang:` operators
- **File reading** with line numbers, `startLine`/`endLine` ranges, and continuation hints for large files
- **Symbol suggestions** to resolve partial class/method/file names
- **Fast**: server ready in ~46 ms under Bun (`bunx --bun`) or ~130 ms under Node (`bun run bench` reproduces these two
  numbers on your machine; medians of 9 runs; bunx/npx package-resolution overhead is extra); measured separately at ~
  111 ms for the Node-only predecessor as shipped, making the bun-to-bun rewrite ~20% faster; TLS warm-up on boot;
  repeat queries served from the in-memory cache in under a millisecond (measured end-to-end over stdio); one fast retry
  on transient upstream failures
- **Token-efficient**: concise-by-default search results, deduplicated matches, snippet caps, and short pagination
  handles; measured search and large-file payloads run 50-85% smaller (~70% typical) than the predecessor's

## Installation

The recommended launcher is `bunx` ([Bun](https://bun.sh) 1.3+); `npx` (Node 20.3+) also works.

### Claude Code

```bash
claude mcp add aosp -- bunx --bun -y @itznotabug/aosp-mcp
```

<details>
<summary><b>Cursor</b> (<code>~/.cursor/mcp.json</code>) / <b>Windsurf</b> (<code>~/.codeium/windsurf/mcp_config.json</code>)</summary>

```json
{
  "mcpServers": {
    "aosp": {
      "command": "bunx",
      "args": [
        "--bun",
        "-y",
        "@itznotabug/aosp-mcp"
      ]
    }
  }
}
```

</details>

<details>
<summary><b>VS Code Copilot</b> (<code>.vscode/mcp.json</code>)</summary>

```json
{
  "servers": {
    "aosp": {
      "type": "stdio",
      "command": "bunx",
      "args": [
        "--bun",
        "-y",
        "@itznotabug/aosp-mcp"
      ]
    }
  }
}
```

</details>

<details>
<summary><b>Zed</b> (<code>settings.json</code>)</summary>

```json
{
  "context_servers": {
    "aosp": {
      "command": "bunx",
      "args": [
        "--bun",
        "-y",
        "@itznotabug/aosp-mcp"
      ]
    }
  }
}
```

</details>

<details>
<summary><b>Codex CLI</b> (<code>~/.codex/config.toml</code>)</summary>

```toml
[mcp_servers.aosp]
command = "bunx"
args = ["--bun", "-y", "@itznotabug/aosp-mcp"]

[mcp_servers.aosp.env]
AOSP_MCP_MAX_RESULT_CHARS = "9000"
```

</details>

<details>
<summary><b>Gemini CLI</b> (<code>~/.gemini/settings.json</code>)</summary>

```json
{
  "mcpServers": {
    "aosp": {
      "command": "bunx",
      "args": [
        "--bun",
        "-y",
        "@itznotabug/aosp-mcp"
      ],
      "trust": true
    }
  }
}
```

</details>

### Troubleshooting

- **"Executable not found" in GUI-launched editors (macOS):** desktop apps often miss your shell PATH. Use the absolute
  path from `which bunx` (typically `~/.bun/bin/bunx`) as the command.
- **No Bun installed:** use `npx` with `-y @itznotabug/aosp-mcp` in any snippet above.
- **Clients that truncate large tool results:** lower `AOSP_MCP_MAX_RESULT_CHARS` (e.g. `9000`)
  to fit your client's limit, as in the Codex example.

## Tools

### search_android_code

| Parameter        | Required | Description                                                                                        |
|------------------|----------|----------------------------------------------------------------------------------------------------|
| `query`          | Yes      | Search query (regex plus `file:`, `class:`, `function:`, `symbol:`, `lang:`, `content:` operators) |
| `project`        | No       | `android`, `androidx`, `android-studio`, or `android-llvm` (default: all)                          |
| `pageSize`       | No       | Files per page (default 10, max 50)                                                                |
| `pageToken`      | No       | Continuation token from a previous result (e.g. `p1`)                                              |
| `contextLines`   | No       | Context lines around matches (default 1, max 10)                                                   |
| `responseFormat` | No       | `concise` (default) or `detailed`                                                                  |

### get_file_content

| Parameter    | Required | Description                                                       |
|--------------|----------|-------------------------------------------------------------------|
| `project`    | Yes      | Project id                                                        |
| `repository` | Yes      | Repository, e.g. `platform/superproject`                          |
| `branch`     | Yes      | Branch, e.g. `main`, `android-latest-release`                     |
| `path`       | Yes      | File path relative to the repository root                         |
| `startLine`  | No       | First line to return (1-based)                                    |
| `endLine`    | No       | Last line to return (inclusive; reads cap at 2000 lines per call) |

### suggest_symbols

| Parameter    | Required | Description                         |
|--------------|----------|-------------------------------------|
| `query`      | Yes      | Partial symbol or file name         |
| `maxResults` | No       | Max suggestions (default 7, max 20) |

### list_projects

No parameters. Returns the searchable projects (also as structured content).

## Configuration

| Environment variable         | Default  | Description                                                                       |
|------------------------------|----------|-----------------------------------------------------------------------------------|
| `AOSP_MCP_TIMEOUT_MS`        | `30000`  | Per-attempt upstream request timeout                                              |
| `AOSP_MCP_CACHE_TTL_MS`      | `60000`  | Search/suggest cache TTL (`0` disables)                                           |
| `AOSP_MCP_FILE_CACHE_TTL_MS` | `300000` | File-content cache TTL (`0` disables)                                             |
| `AOSP_MCP_MAX_RESULT_CHARS`  | `60000`  | Character budget per file-read result (minimum 1000; does not cap search results) |

MCP resources (`android://source?...`) intentionally return complete files and bypass the character budget. Cached
entries are keyed by the full request, so a cache hit is always the answer to the same question; TTLs only bound how
long a just-changed branch head can serve a slightly older revision.

## Development

```bash
bun install        # dependencies
bun run dev        # run the server from TypeScript source
bun test           # test suite (100% coverage thresholds enforced)
bun run lint       # Biome + the strict.grit lint plugin
bun run typecheck  # tsc
bun run build      # bundle to dist/
bun run smoke      # stdio handshake against the built bundle
```

Tests run against captured live API fixtures (`tests/fixtures/`) with the network mocked, plus end-to-end MCP
client/server tests over an in-memory transport. Refresh fixtures deliberately with
`bun scripts/fixtures.ts` when the upstream response shape changes.

## License

[Apache 2.0](LICENSE.md). See [NOTICE](NOTICE.md) for attribution.

*Based on [cs_android_mcp](https://github.com/steveday763/cs_android_mcp).*