MCP Servers

A collection of Model Context Protocol servers, templates, tools and more.

MCP server by sofia-open-source

Created 3/7/2026
Updated about 5 hours ago
Repository documentation and setup instructions

analyze-coverage-mcp

MCP Server NPM Version codecov License: MIT

MCP server that bridges LCOV coverage reports to AI agents. It runs locally and gives agents precise, structured visibility into test coverage — which lines are hit, which branches are missed, and where to focus testing efforts.

What is LCOV?

LCOV is a standard text format for code coverage data. It records which lines, functions, and branches were executed during tests. The format is widely supported by test runners (Vitest, Jest, Istanbul, etc.) and is typically written to lcov.info. Each record describes coverage for a source file: line hits, branch hits, and function hits.

Tools

| Tool | Description | |------|-------------| | get_coverage_overview | Aggregated and per-file coverage stats (lines, functions, branches %). Supports filtering by directory prefix, threshold, and sort order. | | list_uncovered_regions | Uncovered lines (merged into ranges) and uncovered branches for a specific file. | | get_annotated_source | Full source file annotated line-by-line with [COVERED], [NOT COV], or [NO DATA]. Supports start_line/end_line windowing. |

The server also watches lcov.info for changes (polling every 1 s) and auto-reloads — so coverage stays current while tests run in watch mode.

Requirements

All MCP tools (get_coverage_overview, list_uncovered_regions, get_annotated_source) require these parameters in every call. They identify which coverage report to load and how to resolve source file paths.

| Parameter | Requirement | |-----------|-------------| | lcov_path | Must be an absolute path. The file must exist on disk. | | project_root | Must be an absolute path. In single projects, use the directory where tests run (same as package root below). In monorepos, you can use the repo root — the MCP derives the package root from lcov_path. |

Expected project structure

The directory where tests run (the package root) must have this layout:

<package_root>/          ← same as project_root in single projects; in monorepos, parent of coverage/ (e.g. apps/app-api)
├── coverage/
│   └── lcov.info
└── src/
    └── ...

src/ and coverage/ must be siblings under the package root. In single projects, pass that directory as project_root. In monorepos, project_root can be the repo root; the MCP infers the package root from the lcov_path location.

If your structure differs, use source_root or additional_roots (see Path resolution and file locations).

Installation

From npm

Configure MCP

{
  "mcpServers": {
    "analyze-coverage": {
      "command": "npx",
      "args": [
        "-y",
        "@sofia-open-source/analyze-coverage-mcp"
      ]
    }
  }
}

From source

Build and install

pnpm bundle # generates js bundle in ./analyze-coverage-mcp with shebang node executable
chmod +x ./analyze-coverage-mcp # make it executable
cp ./analyze-coverage-mcp ~/.local/bin/analyze-coverage-mcp # available in $PATH

Configure MCP

{
  "mcpServers": {
    "analyze-coverage": {
      "command": "analyze-coverage-mcp"
    }
  }
}

Development

# Install dependencies
pnpm install

# Run in watch mode (no build needed)
pnpm dev

# Type-check and build
pnpm build

# Run tests
pnpm test

# Run tests with coverage
pnpm test:coverage

How it works

  1. The agent calls get_coverage_overview with lcov_path and project_root to load the report.
  2. The LCOV file is parsed in-memory into a Map<filename, FileCoverage> and cached.
  3. Subsequent tool calls reuse the cache (identified by lcov_path + project_root) or trigger a reload via refresh_coverage.
  4. Source paths are resolved with fallbacks: project_root + path, common prefix stripping (src/, lib/, etc.), and when lcov is in coverage/, the parent directory is used for monorepos. See Path resolution and file locations.

Generating LCOV reports

The MCP server reads lcov.info files. Here’s how to generate them with common test runners:

Vitest

Install the coverage provider:

pnpm add -D @vitest/coverage-v8

Configure vitest.config.ts:

import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    coverage: {
      provider: 'v8',
      reporter: ['text', 'lcov'],
      reportsDirectory: './coverage',
    },
  },
})

Run tests with coverage:

pnpm vitest run --coverage

Output: ./coverage/lcov.info

Jest

Install Istanbul (used by Jest for coverage):

pnpm add -D jest @types/jest

Configure jest.config.js or package.json:

{
  "jest": {
    "collectCoverage": true,
    "coverageReporters": ["text", "lcov"],
    "coverageDirectory": "coverage"
  }
}

Run tests with coverage:

pnpm jest --coverage

Output: ./coverage/lcov.info

Istanbul / nyc

pnpm add -D nyc

Configure package.json:

{
  "nyc": {
    "reporter": ["text", "lcov"],
    "report-dir": "coverage"
  }
}

Run tests with coverage:

pnpm nyc pnpm test

Output: ./coverage/lcov.info (or .nyc_output/lcov.info depending on config)

Other runners

Most runners support LCOV via plugins or built-in options. Ensure the reporter outputs lcov and that the path to lcov.info is passed as lcov_path to the MCP tools.

Inputs

All tools require:

| Field | Type | Description | |-------|------|-------------| | lcov_path | string | Absolute path to the lcov.info file generated by your test suite | | project_root | string | Absolute path to the root of the project being analysed |

Typical lcov_path values:

  • Vitest with @vitest/coverage-v8: <project>/coverage/lcov.info
  • Jest with --coverage: <project>/coverage/lcov.info
  • Istanbul/nyc: <project>/.nyc_output/lcov.info

Path resolution and file locations

See Requirements for parameter and structure requirements.

How paths work in LCOV

LCOV records store source file paths relative to the package that ran the tests. For example, if tests run from apps/app-api, paths look like src/core/auth/service.ts, not apps/app-api/src/core/auth/service.ts.

Monorepos

In monorepos, project_root is often the repo root (e.g. /repo), but LCOV paths are relative to the package root (e.g. apps/app-api). The MCP handles this automatically:

  • When lcov_path is inside a coverage/ directory (e.g. apps/app-api/coverage/lcov.info), the parent of that directory is used as a fallback source root.
  • So project_root can be the monorepo root; source files under apps/app-api/src/ are still resolved correctly.

Example: lcov_path: /repo/apps/app-api/coverage/lcov.info with project_root: /repo → sources resolve under /repo/apps/app-api/.

Source path resolution order

For get_annotated_source, the MCP resolves LCOV paths to filesystem paths in this order:

  1. Absolute path — if the LCOV path is already absolute.
  2. source_root + path — when source_root is provided (optional param).
  3. project_root + path — e.g. project_root/src/foo.ts.
  4. Stripped prefixes — if the path contains src/, lib/, dist/, or app/, tries project_root + the path from that segment onward.
  5. additional_roots — for each root in this optional array, tries root + path.
  6. Derived from lcov location — when lcov is in coverage/, tries the parent directory of coverage/ as root.

Flexible overrides (get_annotated_source)

When the automatic heuristics fail, use these optional parameters:

| Parameter | Description | |-----------|-------------| | source_root | Override root for resolving source files. Tried before project_root. Use when you know the package root (e.g. apps/app-api). | | additional_roots | Array of extra roots to try. For each, resolve(root, file_path) is attempted. Useful when sources live in multiple directories. |

Example: get_annotated_source with source_root: "/repo/apps/app-api" forces resolution under that directory, ignoring project_root for that call.

file_path matching

For list_uncovered_regions and get_annotated_source, file_path can be:

  • The exact path as it appears in the LCOV report (e.g. src/core/auth/service.ts).
  • A suffix that uniquely identifies the file (e.g. auth/service.ts or service.ts).
  • A filename if it is unique across the report (e.g. service.ts).

Use get_coverage_overview to list available paths when unsure.

Restrictions and pitfalls

  • Source file must exist on disk for get_annotated_source. That tool reads the source to annotate it. If resolution fails: "Source file not found on disk. Try setting project_root, source_root, or additional_roots to the directory containing your source files." list_uncovered_regions only uses coverage data and does not require the source file.
  • Use source_root or additional_roots when heuristics fail. When the automatic monorepo detection fails, pass source_root with the package root (e.g. apps/app-api), or use additional_roots to add extra search paths.
  • Paths are case-sensitive on most systems.

License

MIT

Quick Setup
Installation guide for this server

Install Package (if required)

npx @modelcontextprotocol/server-analyze-coverage-mcp

Cursor configuration (mcp.json)

{ "mcpServers": { "sofia-open-source-analyze-coverage-mcp": { "command": "npx", "args": [ "sofia-open-source-analyze-coverage-mcp" ] } } }