Codacy MCP Server

Codacy MCP Server

A Model Context Protocol server for Codacy, reimagined with the Vurb.ts framework to provide structured perception for AI agents, featuring grouped tool exposition, guardrails, and prompt templates.

Category
访问服务器

README

Codacy MCP Server — Vurb.ts Edition

The official Codacy MCP Server reimagined with the Vurb.ts framework — structured perception for AI agents.

Vurb.ts License TypeScript


11 Tools - 44 actions available on-demand

<img width="538" height="111" alt="image" src="https://github.com/user-attachments/assets/903fd134-6ebe-4dc2-92eb-fc70aea917e7" />

3 Prompts MCP prompts — code-review, security-audit, repo-health

<img width="337" height="239" alt="image" src="https://github.com/user-attachments/assets/428a84c3-3a66-49c2-be71-8a0127d3d982" />

<br> <br>

[!IMPORTANT]

🤖 Zero lines of human code.

An AI agent (Antigravity, Opus 4.6) read a framework's llms.txt and a 488-line skill file. That's all it knew about Vurb.ts. From that, it built a complete production codebase from scratch: 11 tools · 44 actions · 12 models · 11 presenters · 3 prompts · 105 tests No human wrote a single line.

The thesis of Vurb.ts: if an AI agent can learn a framework from its llms.txt and produce production-grade code on the first attempt — the framework is doing its job.

[!NOTE]

📐 Designed for agents, not for humans.

Traditional frameworks optimize for human ergonomics — tutorials, documentation, months of learning curve. Vurb.ts inverts this entirely. Its fluent API, llms.txt, and skill system were designed so that an AI agent can become productive in a single context window. The learning curve isn't short — it's zero. The agent reads the spec, understands the patterns, and ships. This codebase is the proof.


Why Vurb.ts?

The original Codacy MCP Server is a solid, production-grade implementation. This edition rebuilds it using the Vurb.ts MVA (Model · View · Agent) pattern — a framework designed specifically for MCP servers that gives AI agents structured, high-fidelity perception instead of raw JSON dumps.

Key advantages of the Vurb.ts approach:

  • 🧠 Structured Perception — Presenters transform raw API data into optimized, LLM-readable formats with semantic annotations, HATEOAS navigation links, and severity-based suggestions
  • 🛡️ Guardrails — Middleware (requireAuth), egress limits, idempotent mutation markers, and DLP redaction (secrets are stripped before reaching the wire)
  • 📋 Prompt Templates — First-class support for MCP prompts (code-review, security-audit, repo-health) with dynamic argument injection
  • 🔄 State Sync — Declarative cache invalidation policies ensure mutations automatically refresh dependent queries
  • 🧩 Fluent API — Each tool action is defined as a composable, type-safe chain — no manual JSON schemas or handler wiring
  • 📦 Zero Code Generation — No auto-generated OpenAPI client; a lightweight typed HTTP client is all that's needed
  • 🗂️ Grouped Exposition — 44 actions exposed as 11 namespace tools, avoiding context window explosion

Capability Matrix

Capability Original Vurb.ts
Security & DLP
Auth middleware with self-healing errors
Secret redaction before wire (DLP)
Egress size limits per action
Safe process execution (execFileSync) for analysis
Determinism & Guardrails
Typed input schemas (Zod)
Idempotent mutation markers
Declarative cache invalidation
.instructions() with common-mistake guardrails
Tool-redirection hints (cross-agent navigation)
LLM Optimization
Grouped tool exposition (−78% context tokens)
HATEOAS navigation links in responses
Severity-aware action suggestions
Presenter-formatted tables (vs raw JSON)
MCP Protocol
tools/list
tools/call
prompts/list + prompts/get
State sync / cache control headers
Developer Experience
Auto-discovery (zero manual imports)
Fluent builder API
Test suite (105 tests)
Hot-reload dev server

Grouped Tool Exposition — Solving Context Explosion

This is the single most important architectural difference between the two implementations.

The Problem

The original server registers 24 flat tools in the MCP tools/list response. Every one of them — with its full name, description, and JSON Schema — is injected into the LLM's system prompt at the start of every conversation. This means the model must process ~4,000 tokens of tool definitions before the user even types a word.

At 44 actions, a flat approach would be even worse — ~7,000+ tokens consumed permanently just by tool schemas, leaving less room for actual conversation and reasoning.

The Solution: toolExposition: 'grouped'

Vurb.ts introduces grouped tool exposition. Instead of exposing 44 individual tools, the MCP server advertises only 11 namespace routers:

Original (flat)                    Vurb.ts (grouped)
─────────────────────              ──────────────────────
codacy_list_organizations          codacy_organizations     → 2 actions
codacy_list_organization_repos     codacy_repositories      → 3 actions
codacy_list_repository_issues      codacy_issues            → 7 actions
codacy_search_org_srm_items        codacy_security          → 6 actions
codacy_search_repo_srm_items       codacy_tools             → 6 actions
codacy_list_files                  codacy_files             → 4 actions
codacy_get_file_issues             codacy_pull_requests     → 6 actions
codacy_get_file_coverage           codacy_commits           → 3 actions
codacy_get_file_clones             codacy_overview          → 2 actions
codacy_get_file_with_analysis      codacy_quality           → 3 actions
codacy_list_repository_pull_reqs   codacy_cli               → 2 actions
codacy_get_repository_pull_req     ──────────────────────
codacy_list_pull_request_issues    11 tools in system prompt
                                   44 actions available on-demand
codacy_get_pr_files_coverage
codacy_get_pr_git_diff
codacy_get_repository_analysis
codacy_list_tools
codacy_list_repo_tools
codacy_get_pattern
codacy_list_repo_tool_patterns
codacy_get_issue
codacy_setup_repository
codacy_cli_analyze
codacy_cli_install
─────────────────────
24 tools in system prompt

How the LLM Navigates

The model interacts with the 11 namespace tools using an action parameter. It works like a progressive disclosure pattern:

Step 1 — Discovery. The LLM sees 11 high-level tools with concise descriptions. Each tool's schema has an action enum listing available actions:

codacy_security → actions: [search_org, search_repo, dashboard, sbom_search, ossf_scorecard, ignore]

Step 2 — Selection. When the user asks "show me security vulnerabilities in my repo", the LLM picks codacy_security with action: "search_repo". The remaining 43 action schemas are never loaded into context.

Step 3 — Navigation. Presenters include HATEOAS-style links in their response, guiding the LLM to the next logical tool:

🔗 Next steps: codacy_issues.list (for code quality) · codacy_security.dashboard (for summary)

Context Window Impact

Metric Original (flat) Vurb.ts (grouped)
Tools in tools/list 24 11
Actions available 24 44 (+83%)
JSON Schema surface (tool definitions) 29,316 chars across 718 lines Derived from fluent chain — no hand-written schemas

Fewer tools in the system prompt means the LLM spends less context budget on tool schemas and more on actual reasoning — a critical advantage for models with limited context windows.


Developer Experience — Side by Side

The same security search tool in both implementations:

<table> <tr> <th>❌ Without Vurb.ts — 3 files, ~160 lines</th> <th>✅ With Vurb.ts — 1 file, 26 lines</th> </tr> <tr> <td>

// tools/searchSecurityItemsTool.ts (124 lines)
export const searchRepositorySecurityItemsTool = {
  name: toolNames.CODACY_LIST_REPOSITORY_SRM_ITEMS,
  description: `Tool to list security...
   \n ${rules}
   \n ${generalRepositoryMistakes}`,
  inputSchema: {
    type: 'object',
    properties: {
      ...repositorySchema,
      ...getPaginationWithSorting('...'),
      options: {
        type: 'object',
        properties: {
          priorities: {
            type: 'array',
            items: { type: 'string',
              enum: ['Low','Medium','High','Critical']
            },
          },
          scanTypes: { /* ... 20 more lines */ },
          categories: { /* ... 15 more lines */ },
          statuses: { /* ... 8 more lines */ },
        },
      },
    },
    required: ['provider','organization','repository'],
  },
};

// handlers/security.ts (35 lines)
export const handler = async (args: any) => {
  const { provider, organization, repository,
    cursor, limit, sort, direction, options
  } = args;
  return await SecurityService.searchSecurityItems(
    provider, organization,
    cursor, limit, sort, direction,
    { ...options, repositories: [repository] }
  );
};

// index.ts — manual tool registration
codacy_search_repository_srm_items: {
  tool: Tools.searchRepositorySecurityItemsTool,
  handler: Handlers.searchRepoSecurityItemsHandler,
},

</td> <td>

// codacy_security.tool.ts — complete
export const searchRepo = security
  .query('search_repo')
  .describe('Search security findings within a repository.')
  .instructions(`Repo-level security search.
    Uses the organization-level API filtered by repo.
    Scan types: SAST, SCA, Secrets, IaC, CICD.
    DAST and PenTesting are org-level only.`)
  .fromModel(CodacyScopeModel, 'repo')
  .withOptionalEnum('priority', SEVERITY_LEVELS)
  .withOptionalEnum('category', SECURITY_CATEGORIES)
  .withOptionalEnum('scanType', REPO_SCAN_TYPES)
  .withOptionalEnum('status', SECURITY_STATUSES)
  .withOptionalNumber('cursor')
  .withOptionalNumber('limit')
  .egress(1 * 1024 * 1024)
  .returns(SecurityPresenter)
  .handle(async (input, ctx) => {
    const body = { repositories: [input.repository] };
    if (input.priority) body.priorities = [input.priority];
    if (input.category) body.categories = [input.category];
    return ctx.client.post(
      `organizations/${input.provider}/${input.organization}/security/search`,
      body,
      { cursor: input.cursor, limit: input.limit ?? 50 },
    );
  });

</td> </tr> </table>

What you don't write with Vurb.ts:

  • ❌ No JSON Schema objects — input types derived from fluent chain
  • ❌ No handler wiring — autoDiscover() replaces manual registration
  • ❌ No OpenAPI codegen — lightweight HTTP client replaces 3,000+ generated lines
  • ❌ No any types — full type inference from model to presenter

🔒 What Reaches the LLM — The Security Gap

The original server sends every API field directly to the LLM provider via JSON.stringify (index.ts:172). No filtering, no size limit, no redaction.

Here is what happens to each field from a Secrets detection scan:

API Field ❌ Without Vurb.ts ✅ With Vurb.ts How
title "Hardcoded AWS Secret Key" → sent to LLM "Hardcoded AWS Secret Key" → sent to LLM
priority "Critical" → sent to LLM 🔴 Crit → semantic badge Presenter
apiToken ⚠️ "cda_tk_9f8e7d6c5b4a3..." → sent to LLM [REDACTED] redactPII
internalId ⚠️ 948271 → sent to LLM Gone — never serialized Schema stripping
orgId ⚠️ "org_5f8a2b1d" → sent to LLM Gone — never serialized Schema stripping
suggestion.patchUrl ⚠️ "/api/v3/internal/patches/..." → sent to LLM Gone — never serialized Schema stripping
_links ⚠️ Full internal API surface → sent to LLM Gone — never serialized Schema stripping
247 findings All 247 dumped (1,000+ lines) Top results only agentLimit: 100
Response size Unbounded Max 1 MB .egress(1 * 1024 * 1024)
Next action LLM must guess → codacy_security.ignore suggestActions()

Architecture Comparison

<table> <thead> <tr> <th></th> <th>Original (codacy-mcp-server)</th> <th>Vurb.ts Edition (codacy-vurb)</th> </tr> </thead> <tbody> <tr> <td><strong>Pattern</strong></td> <td>Imperative — monolithic handler registry</td> <td>MVA — Model · View (Presenter) · Agent</td> </tr> <tr> <td><strong>Tool Definition</strong></td> <td>Manual JSON Schema objects per tool</td> <td>Fluent builder API (<code>.withString()</code>, <code>.withOptionalEnum()</code>)</td> </tr> <tr> <td><strong>Tool Registration</strong></td> <td>190-line <code>index.ts</code> mapping tools → handlers</td> <td><code>autoDiscover()</code> — zero manual imports</td> </tr> <tr> <td><strong>Tool Exposition</strong></td> <td>Flat — 24 individual tools in <code>tools/list</code></td> <td>Grouped — 11 namespace routers, 44 actions via <code>action</code> param (54% fewer tools in system prompt)</td> </tr> <tr> <td><strong>API Client</strong></td> <td>Auto-generated OpenAPI client (~3,000+ lines)</td> <td>Lightweight typed HTTP client (123 lines)</td> </tr> <tr> <td><strong>Response Format</strong></td> <td>Raw <code>JSON.stringify(result)</code></td> <td>Presenters with semantic tables, HATEOAS links, severity badges, and action suggestions</td> </tr> <tr> <td><strong>Auth Handling</strong></td> <td><code>noAuth</code> boolean flag + inline <code>if</code> check</td> <td><code>requireAuth</code> middleware with self-healing error messages</td> </tr> <tr> <td><strong>Security</strong></td> <td>No DLP or output sanitization</td> <td>DLP-ready: <code>SecurityPresenter</code> redacts secrets before wire</td> </tr> <tr> <td><strong>Prompts</strong></td> <td>Not supported</td> <td>3 MCP prompts — <code>code-review</code>, <code>security-audit</code>, <code>repo-health</code></td> </tr> <tr> <td><strong>Cache / State Sync</strong></td> <td>Not supported</td> <td>Declarative invalidation policies (mutations auto-refresh queries)</td> </tr> <tr> <td><strong>Egress Control</strong></td> <td>Not supported</td> <td>Per-action egress limits (e.g., 1 MB for issue lists, 2 MB for patches)</td> </tr> <tr> <td><strong>LLM Instructions</strong></td> <td>Embedded in tool <code>description</code> field</td> <td>Separate <code>.instructions()</code> with common mistakes, redirection rules, and guardrails</td> </tr> <tr> <td><strong>Mutation Safety</strong></td> <td>No markers</td> <td><code>.idempotent()</code> marker + <code>.invalidates()</code> cache busting</td> </tr> <tr> <td><strong>Tests</strong></td> <td>No test suite</td> <td>105 tests (prompts, presenters, structural invariants)</td> </tr> <tr> <td><strong>Dependencies</strong></td> <td>11 (including codegen, node-fetch, ESLint, Prettier, Husky)</td> <td>4 (<code>@vurb/core</code>, <code>@modelcontextprotocol/sdk</code>, <code>fast-redact</code>, <code>zod</code>)</td> </tr> </tbody> </table>


Metrics (verified)

Every number below was measured directly from the source code.

Metric Original Vurb.ts Diff
Source files (hand-written) 45 42 −3
Tool definitions (src/tools/) 718 lines
Handlers (src/handlers/) 424 lines
Agents (src/agents/ — tool + handler in one file) 763 lines −33% vs tools+handlers
Tools in tools/list response 24 11 −54%
Actions available to the LLM 24 44 +83%
MCP Prompts 0 3 +3
Test cases 0 105 +105
Runtime dependencies 6 4 −33%
Dev dependencies 9 3 −67%

Tool Actions (44)

codacy_organizations (2)

Action Description
list List organizations the authenticated user belongs to
list_repos List repositories in an organization

codacy_repositories (3)

Action Description
get Get repository details with analysis metrics
list_branches List branches of a repository
setup Add or follow a repository (multi-step orchestration)

codacy_issues (7)

Action Description
list Search and filter code quality issues
get Get detailed issue information
file_issues Get issues for a specific file
pr_issues Get issues in a pull request
quickfix_patch Download auto-fix patches
ignore Mark an issue as ignored
bulk_ignore Batch ignore multiple issues

codacy_security (6)

Action Description
search_org Search org-level security findings
search_repo Search repo-specific security findings
dashboard Get security dashboard summary
sbom_search Search SBOM dependencies
ossf_scorecard Get OSSF Scorecard for a package/repo
ignore Ignore a security finding

codacy_tools (6)

Action Description
list List all analysis tools available
repo_tools List tools configured for a repository
get_pattern Get a specific code pattern definition
repo_patterns List patterns for a tool in a repository
configure Enable/disable a tool for a repository
update_patterns Enable/disable specific patterns

codacy_files (4)

Action Description
list List files with analysis metrics
get Get file details with metrics
coverage Get line-by-line coverage
clones Get code duplication blocks

codacy_pull_requests (6)

Action Description
list List PRs with analysis status
get Get PR details with quality results
coverage Get file-level PR coverage
diff Get the Git diff
trigger_ai_review Trigger AI-powered code review
bypass Bypass the quality gate

codacy_commits (3)

Action Description
list List commits with analysis status
get Get commit details with delta statistics
issues Get issues introduced by a commit

codacy_overview (2)

Action Description
issues Aggregated issue overview with charts
categories Issue count breakdown by category

codacy_quality (3)

Action Description
get_settings Get quality gate thresholds for a repository
list_policies List gate policies for an organization
get_policy Get details of a specific gate policy

codacy_cli (2)

Action Description
analyze Run local analysis via CLI
install Install the CLI

Setup

Requirements

Configuration

Add to your MCP client configuration (Cursor, VS Code, Claude Desktop, etc.):

{
  "mcpServers": {
    "codacy": {
      "command": "node",
      "args": ["dist/server.js"],
      "env": {
        "CODACY_ACCOUNT_TOKEN": "<YOUR_TOKEN>"
      }
    }
  }
}

Development

npm install
npm run build      # Compile TypeScript
npm run dev        # Vurb dev server (hot-reload)
npm test           # Run 105 tests
npm run inspect    # MCP Inspector

Project Structure

src/
├── agents/              # Tool definitions (Fluent API)
│   ├── codacy_organizations.tool.ts
│   ├── codacy_repositories.tool.ts
│   ├── codacy_issues.tool.ts
│   ├── codacy_security.tool.ts
│   ├── codacy_tools.tool.ts
│   ├── codacy_files.tool.ts
│   ├── codacy_pull_requests.tool.ts
│   ├── codacy_commits.tool.ts
│   ├── codacy_overview.tool.ts
│   ├── codacy_quality.tool.ts
│   └── codacy_cli.tool.ts
├── models/              # Zod schemas (data contracts)
├── views/               # Presenters (LLM-optimized output)
├── middleware/           # Auth, validation
├── prompts/             # MCP prompt templates
├── utils/               # Constants, rules, types
├── context.ts           # API client + context factory
├── index.ts             # Registry
└── server.ts            # Entry point

Usage (MCP stdio)

This server runs as a stdio MCP transport — the AI client launches it as a subprocess and communicates via stdin/stdout.

Cursor / Windsurf / Claude Desktop

Add to your MCP configuration file:

  • Cursor: .cursor/mcp.json
  • Windsurf: .codeium/windsurf/mcp_config.json
  • Claude Desktop: claude_desktop_config.json
{
  "mcpServers": {
    "codacy": {
      "command": "node",
      "args": ["/absolute/path/to/codacy-vurb/dist/server.js"],
      "env": {
        "CODACY_ACCOUNT_TOKEN": "<YOUR_TOKEN>"
      }
    }
  }
}

VS Code (Copilot)

Add to your settings.json (Ctrl+Shift+PPreferences: Open User Settings (JSON)):

{
  "mcp": {
    "servers": {
      "codacy": {
        "command": "node",
        "args": ["/absolute/path/to/codacy-vurb/dist/server.js"],
        "env": {
          "CODACY_ACCOUNT_TOKEN": "<YOUR_TOKEN>"
        }
      }
    }
  }
}

Get your token

  1. Go to Codacy Account → Access Management
  2. Generate an Account API Token
  3. Paste it in the CODACY_ACCOUNT_TOKEN field above

Build & run

npm install
npm run build
# The server starts automatically when the MCP client launches it via stdio

License

Apache 2.0 — see LICENSE.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选