Skip to main content
Glama
README.md
# alpine-mcp

An [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server for the complete Alpine.js v3 documentation. It ships a commit-pinned snapshot of the official Markdown and uses [Tobi Lütke's qmd](https://github.com/tobi/qmd) for local full-text search.

[Website](https://alpine-mcp.billynoyes.co.uk/) · [npm](https://www.npmjs.com/package/alpine-mcp)

## Tools

| Tool | Purpose |
|------|---------|
| `search_alpine_docs` | Search individual documentation pages with qmd's BM25 index |
| `read_alpine_doc` | Read a complete page returned by search |

The server also exposes each page as an `alpine://docs/<path>.md` resource. The original combined `alpine://directives`, `alpine://magics`, `alpine://globals`, and `alpine://plugins` resources remain available for compatibility.

## Installation

alpine-mcp requires Node.js 22 or newer.

### Claude Desktop

Add to your `claude_desktop_config.json`:

- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "alpine": {
      "command": "npx",
      "args": ["-y", "alpine-mcp"]
    }
  }
}
```

Restart Claude Desktop.

### Claude Code

```sh
claude mcp add alpine -- npx -y alpine-mcp
```

### OpenAI Codex

```sh
codex mcp add alpine -- npx -y alpine-mcp
```

Or add it directly to `~/.codex/config.toml`:

```toml
[mcp_servers.alpine]
command = "npx"
args = ["-y", "alpine-mcp"]
```

### Cursor

Add to `~/.cursor/mcp.json` or `.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "alpine": {
      "command": "npx",
      "args": ["-y", "alpine-mcp"]
    }
  }
}
```

### Windsurf

Add to `~/.codeium/windsurf/mcp_config.json`:

```json
{
  "mcpServers": {
    "alpine": {
      "command": "npx",
      "args": ["-y", "alpine-mcp"]
    }
  }
}
```

### VS Code

Add to `.vscode/mcp.json` in your workspace for GitHub Copilot. If the file already exists, merge the `alpine` entry into its top-level `servers` object:

```json
{
  "servers": {
    "alpine": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "alpine-mcp"]
    }
  }
}
```

### Cline and Roo Code

Add a local stdio server through the extension's MCP settings using `npx` as the command and `-y alpine-mcp` as the arguments.

### Any MCP client

```sh
npx -y alpine-mcp
```

Each server process builds a small temporary qmd index at startup. Search is lexical and does not download qmd's optional embedding or reranking models.

## Usage

Once registered, ask your AI assistant questions such as:

- *"How do I use x-transition with custom CSS classes?"*
- *"What modifiers does x-on support?"*
- *"How do I persist state across page loads with Alpine?"*
- *"Show me how to use the Focus plugin for a modal."*

## Documentation updates

The generator resolves an Alpine branch, tag, or SHA to one immutable commit, downloads that commit's GitHub archive, and atomically replaces `docs/` only after every page has been extracted and validated. One upstream Markdown page becomes one local file, so new and removed Alpine pages are discovered without a hand-maintained manifest. `docs/.source.json` records the exact source commit.

Refresh from Alpine's current `main`:

```sh
npm run generate
```

Refresh from a specific release or commit:

```sh
ALPINE_REF=v3.14.9 npm run generate
```

A weekly GitHub Actions workflow runs the same generator and opens or updates a documentation-only pull request on `automation/update-alpine-docs`. It never pushes directly to protected `main` or creates version tags.

The repository must enable **Settings → Actions → General → Allow GitHub Actions to create and approve pull requests** and **Settings → General → Allow auto-merge**. No additional access-token secret is needed.

The updater runs unattended. GitHub holds `pull_request` workflow runs for PRs opened with `GITHUB_TOKEN` until a maintainer approves them, so that run shows as waiting for approval and can be ignored. The updater instead dispatches `ci.yml` on the documentation branch; the dispatched run reports the required `validate` check on the PR's head commit and needs no approval. It then enables squash auto-merge, so a passing update lands on `main` by itself and a failing one stays open for investigation.

After a docs update merges, bump and commit the package version and publish a matching GitHub Release to ship it to npm. Installed packages use their bundled snapshot; they do not fetch upstream docs at startup. Published builds use committed Markdown rather than making network requests during packaging.

## Publishing

Publishing a GitHub Release automatically validates, builds, and publishes the matching version to npm with provenance. The release tag must match the version in `package.json`, including the `v` prefix—for example, package version `2.0.0` must use tag `v2.0.0`. Pre-releases are published under npm's `next` dist-tag; regular releases use `latest`.

Merge the publishing workflow into the default branch before creating the tag and GitHub Release. npm trusted publishing must authorize `BillyNoyes/alpine-mcp`, the `publish.yml` workflow, and the `npm` GitHub environment. The workflow uses GitHub OIDC to obtain a short-lived publishing credential, so it does not require an npm access-token secret.

## Project structure

- `src/index.ts` initializes the catalog, qmd index, and MCP transport.
- `src/server/` defines the MCP server and registers resource and tool handlers.
- `src/documents/` owns documentation discovery and resource retrieval.
- `src/search/` owns qmd lifecycle and search-result snippets.
- `scripts/docs/` contains the fetch, archive, corpus, and generation pipeline.
- `site/` contains the Vite, Alpine.js, and Tailwind GitHub Pages site.

## Development

```sh
git clone https://github.com/BillyNoyes/alpine-mcp.git
cd alpine-mcp
npm install
npm test
npm run typecheck
npm run build
```

For local MCP configuration, run `node /path/to/alpine-mcp/build/index.js`.

Documentation is sourced from the [official Alpine.js repository](https://github.com/alpinejs/alpine/tree/main/packages/docs/src/en) and redistributed under Alpine's MIT license, included at `docs/ALPINE-LICENSE.txt`.

## License

MIT

TDQS

A3.7/5.0

Scored across 2 tools

Disambiguation5/5

search_alpine_docs and read_alpine_doc have clearly distinct purposes: finding relevant pages versus retrieving full content. No overlap or ambiguity exists between them.

Naming Consistency5/5

Both tools follow the same verb_noun convention with snake_case (search_alpine_docs, read_alpine_doc). The pattern is perfectly consistent and predictable.

Tool Count3/5

With only 2 tools, the server is borderline per the calibration scale, though the narrow scope (documentation search/read) justifies a minimal surface. It feels slightly thin but not unreasonable.

Completeness5/5

For an Alpine.js documentation server, search and read cover the full user workflow end-to-end. There are no obvious gaps in the stated purpose—discovery via search and retrieval via read are complete.

Maintenance

ActivityMaintained
ResponsivenessNo issues