{
  "markdown": "<div align=\"center\">\n\n# CodeHealth MCP\n\n**Codebase health analysis that works everywhere.** Dead code, circular dependencies, coupling issues, and architectural drift — exposed as MCP tools for Claude Desktop, Cursor, Windsurf, and Slack.\n\n[![MCP](https://img.shields.io/badge/MCP-Protocol-00C4B4?logo=modelcontextprotocol&logoColor=white)](https://modelcontextprotocol.io)\n[![Node.js](https://img.shields.io/badge/Node.js-18+-339933?logo=node.js&logoColor=white)](https://nodejs.org)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-Listed-00C4B4?logo=modelcontextprotocol&logoColor=white)](https://github.com/modelcontextprotocol/registry)\n[![awesome-mcp-servers](https://img.shields.io/badge/awesome--mcp--servers-Listed-blue)](https://github.com/appcypher/awesome-mcp-servers)\n\n</div>\n\n---\n\n## The Problem\n\nDead code, circular dependencies, excessive coupling, and architectural drift are invisible in day-to-day work. Static analysis tools produce noise in CI dashboards nobody checks. CodeHealth MCP brings these insights into the tools developers actually use — via the Model Context Protocol.\n\n---\n\n## What CodeHealth MCP Does\n\n7 analysis tools, available in any MCP-compatible client:\n\n| Tool | What It Finds |\n|------|--------------|\n| `analyze_dead_code` | Unused functions, classes, modules with file:line + fix suggestions |\n| `detect_circular_deps` | Module import cycles via DFS with impact assessment |\n| `analyze_coupling` | Fan-out per module, tight cluster detection, refactoring suggestions |\n| `detect_architectural_drift` | Layer boundary violations (UI→Data, Business→UI, etc.) |\n| `full_health_scan` | All four analyses + 0–100 health score + prioritized action items |\n| `explain_finding` | AI-powered detailed explanation of any finding |\n| `check_mcp_health` | Remote MCP handshake, silent-exception / JSON-RPC error-shape probe, Streamable HTTP reason codes, schema drift, secret scan — HTTP 200 is not healthy |\n\n---\n\n## Where It Works\n\n| Client | How to Add |\n|--------|-----------|\n| **Claude Desktop** | Add to `claude_desktop_config.json` |\n| **Cursor / Windsurf** | Add to MCP settings |\n| **Slack** | Built-in Agent Builder integration with Block Kit UI |\n| **Any MCP client** | Standard MCP server (stdio) or remote Streamable HTTP |\n\n### Claude Desktop Config (stdio)\n\n```json\n{\n  \"mcpServers\": {\n    \"codehealth\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/codehealth-mcp/mcp-server/index.js\"]\n    }\n  }\n}\n```\n\n### Remote Streamable HTTP (Glama / hosted)\n\nPublic HTTPS + `streamable-http` is required to list CodeSentinel as a [Glama remote connector](https://glama.ai/mcp/faq).\n\n**Live production:** MCP `https://codesentinel-rho.vercel.app/mcp` · health `https://codesentinel-rho.vercel.app/health`. Auth uses env `MCP_BEARER_TOKEN` (Bearer) — never commit the secret.\n\n```bash\nexport MCP_BEARER_TOKEN=\"replace-with-a-long-random-secret\"\nnpm run mcp:http\n```\n\nLocal default: `http://127.0.0.1:8787/mcp` (health: `GET /health`). Production is **HTTPS**.\n\n```json\n{\n  \"mcpServers\": {\n    \"codesentinel\": {\n      \"type\": \"streamable-http\",\n      \"url\": \"https://codesentinel-rho.vercel.app/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer ${MCP_BEARER_TOKEN}\"\n      }\n    }\n  }\n}\n```\n\nCursor / Claude remote connectors use the same `url` + `Authorization` header. Unauthenticated `/mcp` returns **HTTP 401**. `LLM_API_KEY` and other provider keys stay on the server and are never echoed.\n\n### Deploy on Vercel (public HTTPS)\n\nStateless Streamable HTTP (JSON request/response) runs on **Vercel Fluid Compute**. No sticky sessions. Production host: **`codesentinel-rho.vercel.app`**.\n\n```bash\nnpx vercel          # preview\nnpx vercel env add MCP_BEARER_TOKEN     # required for /mcp — fail-closed Bearer auth\nnpx vercel env add LLM_API_KEY          # optional, server-side only\nnpx vercel env add DAYTONA_API_KEY      # optional, isolated GitHub scans\nnpx vercel env add GITHUB_TOKEN         # optional, private repo fetch\nnpx vercel --prod\n# GET /health must be 200 even if MCP_BEARER_TOKEN is not set yet.\n```\n\nLive MCP endpoint:\n\n`https://codesentinel-rho.vercel.app/mcp`\n\nHealth: `https://codesentinel-rho.vercel.app/health`.\n\nTurn **off** Vercel Deployment Protection on the production host, or Glama/clients cannot complete `initialize`.\n\n### Glama connector fields (live production)\n\n| Field | Value |\n|-------|--------|\n| Type | Connector (remote MCP) |\n| Server URL | `https://codesentinel-rho.vercel.app/mcp` |\n| Transport | `streamable-http` |\n| Auth | API Key / Bearer |\n| Header | `Authorization` |\n| Header value | `Bearer $MCP_BEARER_TOKEN` (same secret as the Vercel env — never commit) |\n\nSee [`docs/mcp-http.md`](docs/mcp-http.md) for Vercel env vars, Fluid Compute notes, and Docker/Fly fallback.\n\n---\n\n## Quick Start\n\n```bash\ngit clone https://github.com/Cubiczan/codesentinel.git\ncd codesentinel\nnpm install\ncp .env.sample .env\n# Edit .env with your LLM API key (and MCP_BEARER_TOKEN for HTTP mode)\nnpm start\n```\n\nHTTP MCP (same tools, Bearer auth):\n\n```bash\nexport MCP_BEARER_TOKEN=\"replace-with-a-long-random-secret\"\nnpm run mcp:http\nnpm run mcp:http:smoke\n```\n\n### Use in Claude Desktop\n\n```\nRun a full health scan on /path/to/my/repo\n```\n\n```\nFind circular dependencies in the frontend\n```\n\n```\nCheck coupling metrics in src/services\n```\n\n```\nCheck MCP health on https://example.com/mcp\n```\n\n### Remote MCP protocol health (not HTTP uptime)\n\nA remote MCP endpoint can return **HTTP 200** while `initialize`, `tools/list`,\nor the SSE stream fails. CodeSentinel probes the protocol itself:\n\n- Synthetic Streamable HTTP / legacy SSE handshake (`initialize` + `tools/list`)\n- Known-bad `tools/call` error-shape probe (alarm on HTTP 200 empty/swallowed protocol)\n- Streamable HTTP diagnostic matrix with reason codes (`WRONG_METHOD`,\n  `WRONG_ACCEPT`, `MISSING_SESSION`, `GET_VS_POST`, `SESSION_STICKY_MISMATCH`)\n- Canonical tool-schema hash and drift alarms\n- Discovery-latency metrics\n- Secret scanning of tool descriptions/schemas before they enter agent context\n\n```bash\nnpm test\nnpm run mcp:health -- https://example.com/mcp\n```\n\nLibrary: `src/lib/mcp-health`. Analyzer: `lib/analyzers/mcp-health.js`.\nFull write-up: [`docs/mcp-health.md`](docs/mcp-health.md).\n\n### Daytona sandbox scans (optional)\n\nSet `DAYTONA_API_KEY` (and optionally `GITHUB_TOKEN` for private repos). MCP tools and Slack analysis will shallow-clone GitHub URLs in a Daytona VM and return live import-graph findings instead of demo data.\n\n```\nfull_health_scan repo_path=https://github.com/org/repo\n```\n\n### Use in Slack\n\nAdd the Slack app manifest, enable Agent Builder, and @CodeHealth in any channel.\n\n---\n\n## Architecture\n\n```\n┌──────────────────────────────────────────┐\n│          MCP CLIENT (any)                │\n│  Claude Desktop, Cursor, Slack, etc.     │\n└──────────────────┬───────────────────────┘\n                   │ MCP Protocol (stdio or Streamable HTTP)\n┌──────────────────▼───────────────────────┐\n│         CODEHEALTH MCP SERVER            │\n│                                          │\n│  🔧 analyze_dead_code                    │\n│  🔧 detect_circular_deps                 │\n│  🔧 analyze_coupling                     │\n│  🔧 detect_architectural_drift           │\n│  🔧 full_health_scan                     │\n│  🔧 explain_finding                      │\n│  🔧 check_mcp_health                     │\n│                                          │\n│  ┌──────────────────────────────────┐    │\n│  │       Analysis Engine            │    │\n│  │  dead-code | circular-deps       │    │\n│  │  coupling | drift | mcp-health   │    │\n│  └──────────────────────────────────┘    │\n│                                          │\n│  ┌──────────────────────────────────┐    │\n│  │       LLM Provider               │    │\n│  │  Deepseek / OpenAI / Anthropic   │    │\n│  └──────────────────────────────────┘    │\n└──────────────────────────────────────────┘\n```\n\n---\n\n## Slack Integration\n\nCodeHealth MCP ships with a full Slack Agent Builder app featuring:\n\n- **Block Kit UI** — Severity-coded findings, health scores, actionable suggestions\n- **Thread-based conversations** — Follow-up analysis in threads\n- **Suggested prompts** — One-click analysis triggers\n- **MCP server** — Same tools, available everywhere\n\n### Demo Sandbox (Devpost judges)\n\nThe live demo workspace is **[codehealthdemo.slack.com](https://codehealthdemo.slack.com/)** — the **CodeSentinel** agent (App ID `A0BEHRDN5TQ`) is installed and authorized there. Mention it in any channel:\n\n```\n@CodeSentinel run a full health scan on https://github.com/icohangar-ops/codesentinel\n```\n\nSandbox configuration:\n\n**Live agent response in the sandbox** — a real `@CodeSentinel` mention in `#general` triggering a Daytona-sandboxed repo scan:\n\n![CodeSentinel responding in #general](docs/sandbox-setup/04-agent-response.png)\n\n| App credentials & App ID | Agent capability enabled | Socket Mode enabled |\n|---|---|---|\n| ![App Basic Information](docs/sandbox-setup/01-app-basic-info.png) | ![Agent enabled](docs/sandbox-setup/02-agent-enabled.png) | ![Socket Mode enabled](docs/sandbox-setup/03-socket-mode.png) |\n\n---\n\n## Adding Custom Analyzers\n\nEach analyzer follows a simple interface:\n\n```javascript\nfunction analyze(repoInfo) {\n  return {\n    type: \"your_analysis_type\",\n    findings: [\n      {\n        type: \"finding_type\",\n        severity: \"critical\" | \"warning\" | \"info\",\n        file: \"path/to/file.ts\",\n        line: 42,\n        name: \"symbol_name\",\n        reason: \"Why this is a problem\",\n        suggestion: \"How to fix it\",\n      },\n    ],\n    stats: { /* summary metrics */ },\n  };\n}\n```\n\nAdd a new analyzer in `lib/analyzers/`, register it in `analysis-engine.js`, and it's automatically available in Slack and via MCP.\n\n---\n\n## Roadmap\n\n- [ ] Real AST analysis — ts-morph for TypeScript, tree-sitter for multi-language\n- [ ] GitHub App — Automatic analysis on PRs with inline comments\n- [ ] Historical trends — Track health score over time per repo\n- [ ] Custom architecture rules — Define layer boundaries via config\n- [ ] Team dashboards — Aggregate health in Slack Canvas\n\n---\n\n## Project Structure\n\n```\ncodehealth-mcp/\n├── app.js                    # Bolt app entry (Slack)\n├── manifest.json             # Slack app manifest\n├── lib/\n│   ├── analysis-engine.js    # Analysis orchestrator + health score\n│   ├── intent-parser.js      # NLP intent classification\n│   ├── block-kit-builder.js  # Rich Slack UI\n│   ├── llm-provider.js       # Multi-provider LLM\n│   └── analyzers/            # dead-code, circular-deps, coupling, drift, mcp-health\n├── src/lib/\n│   ├── resilience/           # safeFetch / retry\n│   └── mcp-health/           # handshake, silent probe, Streamable reason codes, CLI\n├── mcp-server/\n│   ├── index.js              # MCP stdio entry (unchanged tools)\n│   ├── http.js               # Streamable HTTP (stateless, Bearer auth)\n│   ├── create-server.js      # Shared tool registration\n│   └── package.json\n├── docs/mcp-http.md          # Remote / Glama / Fly / Railway / Vercel notes\n├── test/                     # handshake / silent-probe / streamable-diag / HTTP transport / secrets\n└── functions/                # Slack function definitions\n```\n\n---\n\n## Community & Registry\n\nCodeHealth MCP is listed in the following directories:\n\n- **[awesome-mcp-servers](https://github.com/appcypher/awesome-mcp-servers)** – A curated list of MCP servers.\n- **[MCP Registry](https://github.com/modelcontextprotocol/registry)** – Official registry for Model Context Protocol servers.\n- **[Glama](https://glama.ai/mcp/faq)** – Remote connectors must be public HTTPS speaking `streamable-http` (see [`docs/mcp-http.md`](docs/mcp-http.md)).\n\n---\n\n## License\n\nMIT. See [`LICENSE`](./LICENSE).\n",
  "bytes": 11826,
  "sha": "7e8271afa1ebb29fea3e7af4f355b26d3689f10e222d36cd073b26a23253fec7",
  "repo_slug": "icohangar-ops/codesentinel",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_icohangar_ops_codesentinel_mcp_3ca157e2/readme"
}