Skip to main content
Glama
lichtblick-docs-mcp

lichtblick-docs-mcp

Official
README.md
# @lichtblick/docs-mcp

MCP server exposing the Lichtblick documentation and the @lichtblick/suite extension API to AI agents

## Tools

| Tool                 | Purpose                                                                 |
| -------------------- | ----------------------------------------------------------------------- |
| `docs_search`        | Full-text search over docs and guides, returns sections with URL anchor |
| `docs_fetch`         | Full markdown of a page, by path or URL                                 |
| `docs_list`          | All pages with path and summary, optionally filtered by section         |
| `extension_api_get`  | TypeScript declaration and doc comments of a `@lichtblick/suite` symbol |
| `extension_api_list` | All symbols exported by `@lichtblick/suite`                             |

Each page is also exposed as an MCP resource: `lichtblick-docs://<path>`.

## How it works

- **Docs**: on first use, reads `llms.txt` from the docs site (generated by `docusaurus-plugin-llms`), fetches
  each page's `.md` route (generated by `docusaurus-plugin-copy-page-button`) and builds an in-memory
  [MiniSearch](https://github.com/lucaong/minisearch) index of `##`/`###` sections. No build step or release is needed when the docs change.
- **Extension API**: parses the TypeScript sources shipped in the pinned `@lichtblick/suite` dependency, following
  the re-exports of `src/index.ts`.
- **Transport**: stdio. The client spawns the process; no port is opened. All tools are read-only.

## Setup

Requires Node.js 22.12+ with `npx` on the `PATH` seen by the client. The client starts the server with `npx`, which
downloads the pre-built package from npm: nothing is cloned or compiled on your machine. Pin a version (replace
`0.1.0` with the [latest release](https://www.npmjs.com/package/@lichtblick/docs-mcp)) so updates are explicit.

### VS Code (GitHub Copilot)

Add the server to `.vscode/mcp.json` in a workspace, or to the user configuration (**MCP: Open User
Configuration**):

```json
{
  "servers": {
    "lichtblick-docs": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@lichtblick/docs-mcp@0.1.0"]
    }
  }
}
```

Start it from **MCP: List Servers** (or the **Start** action shown above the entry) and use Copilot Chat in agent
mode.

### Cursor

Add to `~/.cursor/mcp.json` (all projects) or `.cursor/mcp.json` (one project):

```json
{
  "mcpServers": {
    "lichtblick-docs": {
      "command": "npx",
      "args": ["-y", "@lichtblick/docs-mcp@0.1.0"]
    }
  }
}
```

### Claude Code

```bash
claude mcp add lichtblick-docs --scope user -- npx -y @lichtblick/docs-mcp@0.1.0
```

Or add the Cursor snippet above to `.mcp.json` at the project root.

### Agent instructions

Agents sometimes answer from memory or the web even when the server is available. Copy
[agent-instructions.md](agent-instructions.md) into the repository's `.github/copilot-instructions.md`, `AGENTS.md`
or `CLAUDE.md` so they call the tools first.

### Notes

- **Updates**: change the pinned version in the configuration and restart the server. Unpinned
  (`@lichtblick/docs-mcp`) uses whatever version is in the npm cache.
- **Checking that it is used**: the chat shows each tool call (for example `docs_search`) with its input and output.
  If the agent answers from the web instead, ask it to use the Lichtblick docs tools, or reference a tool directly
  (`#docs_search` in VS Code). The server also logs every tool call to stderr, shown in the client's MCP output log.
- **Verifying the package**: `npm audit signatures` only checks packages installed in the current project, not
  packages run with `npx`. To verify the provenance of this package, install the pinned version in a temporary
  project and audit it there:

  ```sh
  mkdir /tmp/verify-docs-mcp && cd /tmp/verify-docs-mcp
  npm init -y && npm install @lichtblick/docs-mcp@0.1.0
  npm audit signatures
  ```

## Configuration

| Variable                   | Default                                    | Description                                                                 |
| -------------------------- | ------------------------------------------ | --------------------------------------------------------------------------- |
| `LICHTBLICK_DOCS_SITE_URL` | `https://lichtblick-suite.github.io/docs/` | Public docs URL; `llms.txt` links are resolved against it                   |
| `LICHTBLICK_DOCS_SOURCE`   | value of `LICHTBLICK_DOCS_SITE_URL`        | URL or local Docusaurus `build/` directory to read `llms.txt` and pages from |
| `LICHTBLICK_DOCS_LOG`      | (on)                                       | Logs every tool call to stderr as JSON; `off` disables logging            |

To test unpublished docs, build the docs repo and point `LICHTBLICK_DOCS_SOURCE` at its `build/` folder. Variables
go in the `env` object of the server entry in the client configuration.

### Logging

stdout carries the MCP protocol, so logs go to stderr as one JSON object per line:

- `ready`: server version and docs source.
- `docs_index`: pages and sections indexed, duration, and the pages that were skipped with the reason.
- `tool_call`: tool, arguments, duration in ms and whether it failed.

### Checking the docs

`npx @lichtblick/docs-mcp check` fetches every page listed in `llms.txt` of `LICHTBLICK_DOCS_SOURCE` and exits with
code 1 if any of them does not resolve to its `.md` page. CI runs it on every PR against the published docs.

## Development

```bash
npm install
npm run build
npm test              # vitest
npm run test:coverage # vitest with coverage (80% threshold)
npm run test:smoke    # check every llms.txt page of the published docs (needs a build)
npm run typecheck
npm run dev           # tsc --watch
npm run inspect       # MCP Inspector UI
```

Open this folder in VS Code; [.vscode/mcp.json](.vscode/mcp.json) registers the local build. Start it from
**MCP: List Servers**.

## Releasing

1. Add the changes under a new `## [<version>]` heading in [CHANGELOG.md](CHANGELOG.md) and bump `version` with
   `npm version <patch|minor|major> --no-git-tag-version`.
2. Merge to `main`, then push a matching tag: `git tag v<version> && git push origin v<version>`.
3. The [release workflow](.github/workflows/release.yml) tests the package, publishes it to npm with provenance
   (trusted publishing, no npm token) and creates the GitHub release from the changelog entry.

## Known limitations

- `docusaurus-plugin-llms` writes file-based URLs into `llms.txt` and ignores `slug`/`id` front matter. The pages
  that returned 404 for this reason were fixed in the docs repository; the `check` smoke test fails if it happens
  again. Until it is fixed, such a page is listed but skipped, and reported in the `docs_index` log.
- Docs are fetched once per server process; restart the server to pick up documentation changes.
- The extension API only covers what `@lichtblick/suite` exports; it is updated by bumping the dependency and
  releasing a new version.

TDQS

A4.4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a distinct role: docs_list browses the page index, docs_search finds sections by keyword, docs_fetch reads a full page, and the two extension_api tools split symbol discovery from symbol retrieval. The descriptions explicitly state the hand-off relationships (list/search → fetch, list → get), leaving no realistic misselection.

Naming Consistency5/5

Names follow a predictable resource_action pattern in snake_case, split into two clean namespaces: docs_* (list/search/fetch) and extension_api_* (list/get). The only variance is fetch vs get across the two namespaces, which is justified by their different semantics (full page vs symbol declaration).

Tool Count5/5

Five tools is tightly scoped to the two jobs of the server: documentation lookup and extension API reference. Every tool earns its place, with no redundant or filler operations.

Completeness4/5

The docs surface is complete (enumerate, search, retrieve) and the API surface covers symbol enumeration and declaration lookup. A minor gap is that the extension API can only be queried by exact symbol name after listing, with no full-text/typeahead search over declarations, which could slow discovery for loosely-named symbols.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues