Labsco
PierreJanineh logo

TechDebtMCP

โ˜… 7

from PierreJanineh

MCP server for analyzing and managing technical debt in codebases via the Model Context Protocol

๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅโœ“ VerifiedFreeAdvanced setup

Tech Debt MCP

Tech Debt MCP Server

Add to MCP -brightgreen)

16 Tools ยท 2 Resources ยท 14 Languages ยท 10 Dependency Ecosystems

A Model Context Protocol (MCP) server for analyzing technical debt across multiple programming languages. Designed to integrate with GitHub Copilot, Claude, Cursor, and other MCP-compatible tools.

Features

  • Multi-language support: JavaScript, TypeScript, Python, Java, Swift, Kotlin, Objective-C, C++, C, C#, Go, Rust, Ruby, PHP
  • Comprehensive analysis: Detects various types of tech debt including code quality issues, security vulnerabilities, and maintainability problems
  • SQALE Metrics: Calculate technical debt with SQALE rating system (A-E scale)
  • SwiftUI Analysis: Specialized checks for SwiftUI patterns, state management, memory leaks, view nesting, and concurrency issues
  • Custom Rules: Define your own pattern-based checks with regex support
  • Dependency Analysis: Parse package manifests across 10 ecosystems (npm, pip, Maven/Gradle, Cargo, Go Modules, Composer, Bundler, NuGet, C/C++, Swift)
  • Inline Suppression: Suppress false positives with // techdebt-ignore-next-line or block comments
  • Config Validation: Validate .techdebtrc.json configuration files for schema correctness
  • Actionable recommendations: Provides prioritized suggestions for addressing technical debt
  • Flexible filtering: Filter results by severity, category, or language
  • Security hardened (v2.0.2): Path traversal prevention on all tool and resource path inputs, ReDoS-safe custom-rule regex validation, regex-injection escaping in SwiftUI checks, absolute-path sanitization in all error messages, and CodeQL SAST scanning on every push/PR

Supported Languages

LanguageExtensionsKey Checks
JavaScript.js, .mjs, .cjs, .jsxconsole.log, debugger, eslint-disable, usage of dynamic code execution, var usage
TypeScript.ts, .tsx, .mts, .ctsany type, @ts-ignore, non-null assertions, type assertions
Python.py, .pyw, .pyibare except, print statements, global usage, dynamic code execution
Java.javaSystem.out, printStackTrace, empty catch, @SuppressWarnings
Swift.swiftforce unwrap (!), force cast (as!), force try, retain cycles, SwiftUI patterns
Kotlin.kt, .kts!!, lateinit abuse, @Suppress, unchecked casts
Objective-C.m, .mm, .hNSLog, retain cycles, deprecated methods, massive view controllers
C++.cpp, .cc, .hpp, .hraw pointers, C-style casts, goto, using namespace std
C.c, .hmalloc without free, goto, unsafe functions, null checks
C#.csConsole.WriteLine, async void, empty catch, dispose pattern
Go.goignored errors, blank imports, fmt.Print, panic, global variables
Rust.rsunwrap, expect, unsafe, allow attributes, panic, println
Ruby.rbputs, binding.pry, rubocop disable, dynamic code execution, global variables
PHP.phpvar_dump, print_r, die/exit, dynamic code execution, error suppression

Tools

Every tool declares a tool annotation โ€” Read tools are side-effect-free (readOnlyHint: true); Write tools mutate server session state (destructiveHint: true).

CategoryToolTypeDescription
Analysisanalyze_projectReadAnalyze entire project โ€” filter by language, category, severity, maxFiles
analyze_fileReadAnalyze a single file
get_debt_summaryReadQuick summary with health score and issue counts
get_sqale_metricsReadSQALE rating, remediation time, debt ratio, breakdowns
Filteringget_recommendationsReadPrioritized fix suggestions (configurable limit)
get_issues_by_severityReadIssues filtered by severity level
get_issues_by_categoryReadIssues filtered by debt category
list_supported_languagesReadAll languages with their checks
Custom Rulesadd_custom_ruleWriteAdd regex-based tech debt rule
remove_custom_ruleWriteRemove a custom rule by ID
list_session_custom_rulesReadList rules added via add_custom_rule this session (does not include .techdebtrc.json customPatterns)
execute_custom_rulesReadRun custom rules against code or file
validate_custom_patternReadTest a pattern before adding it
Dependenciescheck_dependenciesReadScan package manifests across 10 ecosystems
get_vulnerability_reportReadOffline dependency inventory for CVE review
validate_configReadValidate .techdebtrc.json schema

Debt categories used throughout: dependency ยท code-quality ยท architecture ยท documentation ยท testing ยท security ยท performance ยท maintainability

Analysis โ€” parameter reference
ToolParameterTypeRequiredConstraints / defaultDescription
analyze_projectpathstringโœ“absolute filesystem pathProject root directory
languagesstring[]Filter to specific languages
categoriesstring[]see categories aboveFilter by debt categories
severityenumlow / medium / high / criticalMinimum severity level
maxFilesintegermin: 1Cap on files analyzed
analyze_filepathstringโœ“absolute filesystem pathFile to analyze
get_debt_summarypathstringโœ“absolute filesystem pathProject root directory
get_sqale_metricspathstringโœ“absolute filesystem pathProject root directory
developmentTimenumberhoursEstimated dev time for debt-ratio calc

get_sqale_metrics returns a SQALE rating (A-E) with star visualization, total remediation time, debt ratio, and breakdowns by severity and category.

Filtering โ€” parameter reference
ToolParameterTypeRequiredConstraints / defaultDescription
get_recommendationspathstringโœ“absolute filesystem pathProject root directory
limitintegerdefault: 5, min: 1Max recommendations to return
get_issues_by_severitypathstringโœ“absolute filesystem pathProject root directory
severityenumโœ“low / medium / high / criticalSeverity to filter by
get_issues_by_categorypathstringโœ“absolute filesystem pathProject root directory
categoryenumโœ“see categories aboveDebt category to filter by
list_supported_languagesโ€”โ€”โ€”โ€”No parameters
Custom Rules โ€” parameter reference
ToolParameterTypeRequiredConstraints / defaultDescription
add_custom_ruleidstringโœ“Unique rule identifier
patternstringโœ“max 1,000 charsRegex pattern to match
messagestringโœ“Issue title/message
severityenumโœ“low / medium / high / criticalSeverity level
categoryenumโœ“see categories aboveDebt category
suggestionstringHow to fix the issue
languagesstring[]Restrict to specific languages
flagsstringallowed: d g i m s u v y; u / v mutually exclusiveRegex flags
remove_custom_ruleidstringโœ“Rule ID to remove
list_session_custom_rulesโ€”โ€”โ€”โ€”No parameters. Renamed from list_custom_rules (TEC-51) to clarify scope: only session-registered rules.
execute_custom_rulespathstringโ—absolute path, max 500,000 bytesFile to analyze
codestringโ—1-500,000 charsSource code to analyze directly
languagestringmust be a supported language ID (same set as list_supported_languages)Filter rules by language
validate_custom_patternidstringโœ“Unique rule identifier
patternstringโœ“max 1,000 charsRegex to validate
messagestringโœ“Issue title/message
severityenumโœ“low / medium / high / criticalSeverity level
categoryenumโœ“see categories aboveDebt category

โ— execute_custom_rules requires either path or code, not both required. An empty string "" for path is treated the same as omitting the field.

Dependencies โ€” parameter reference
ToolParameterTypeRequiredConstraints / defaultDescription
check_dependenciespathstringโœ“absolute filesystem pathProject root directory
includeDevbooleandefault: trueInclude dev/test dependencies
get_vulnerability_reportpathstringโœ“absolute filesystem pathProject root directory
includeDevbooleandefault: falseInclude dev dependencies
validate_configpathstringโœ“absolute filesystem pathProject root directory or direct path to .techdebtrc.json

check_dependencies detects manifests for npm, pip, Maven/Gradle, Cargo, Go Modules, Composer, Bundler, NuGet, C/C++ (CMakeLists.txt, conanfile.txt/py, vcpkg.json), and Swift Package Manager. get_vulnerability_report produces an offline dependency inventory โ€” see ROADMAP.md for planned online CVE lookup.

Resources

Two MCP resources expose read-only tech debt data as JSON. Both use RFC 6570 URI templates: the {+projectPath} syntax is reserved expansion, which allows the variable to contain the / characters of an absolute filesystem path without percent-encoding.

URI templateDescription
debt://summary/{+projectPath}Health score, debt score, issue counts, and SQALE metrics
debt://issues/{+projectPath}Filterable list of all tech debt issues; supports severity, category, and limit query params

Concrete examples โ€” substitute {+projectPath} with an absolute path. Note the double slash: the template's trailing / plus the path's leading / produce //, which is valid URI syntax.

debt://summary//Users/you/projects/myapp
debt://issues//Users/you/projects/myapp
debt://issues//Users/you/projects/myapp?severity=high&limit=50
debt://issues//Users/you/projects/myapp?category=security

Testing interactively โ€” the easiest way to exercise tools and resources is the MCP Inspector:

npm run build
npx @modelcontextprotocol/inspector node dist/index.js

Open the URL it prints, switch to the Resources tab, and read a template URI with your absolute project path.

SQALE Metrics

Tech Debt MCP uses SQALE methodology to quantify technical debt:

RatingDebt RatioQuality
Aโ‰ค5%Excellent
B6-10%Good
C11-20%Fair
D21-50%Poor
E>50%Critical

Effort-to-time mapping: trivial (โ‰ค5m) ยท small (5-30m) ยท medium (30m-2h) ยท large (2-4h) ยท xlarge (4h+)

SwiftUI Analysis

14 specialized checks for SwiftUI apps covering state management (excessive @State, @ObservedObject misuse, environment value safety), memory & lifecycle (Combine retain cycles, timer cleanup, task cancellation, closure retain cycles), performance (missing .id() modifiers, expensive body calculations, deep nesting, GeometryReader misuse), and best practices (AnyView type erasure, deprecated NavigationLink, main thread safety).

View all SwiftUI checks with examples

State Management Issues

  • Excessive @State Variables - Detects views with >5 @State variables that should use a ViewModel
  • @ObservedObject Misuse - Flags @ObservedObject with initialization (should use @StateObject)
  • Environment Value Safety - Detects force unwrapping of @Environment values

Memory & Lifecycle

  • Combine Circular References - Finds missing [weak self] in Combine sinks
  • Missing Timer Cleanup - Detects Timers without cleanup in onDisappear
  • Missing Task Cancellation - Flags async Tasks without cancellation handling
  • Retain Cycles in Closures - Detects self captures in onChange/onReceive without [weak self]

Performance & View Hierarchy

  • Missing .id() Modifiers - Detects ForEach without stable identifiers
  • Expensive View Body Calculations - Flags reduce/sort/filter in view bodies
  • Deep View Nesting - Warns when nesting depth exceeds 6 levels
  • GeometryReader Misuse - Detects GeometryReader at view root

SwiftUI Best Practices

  • AnyView Type Erasure - Suggests using generics or @ViewBuilder instead
  • Deprecated NavigationLink - Flags old-style NavigationLink patterns
  • Main Thread Safety - Ensures UI updates happen on main thread

Example Issues Detected

// Excessive @State - should use ViewModel
struct UserView: View {
  @State private var firstName = ""
  @State private var lastName = ""
  @State private var email = ""
  @State private var phone = ""
  @State private var address = ""
  @State private var city = ""  // 6+ @State variables!
}

// @ObservedObject with initialization
struct ContentView: View {
  @ObservedObject var viewModel = UserViewModel()  // Should be @StateObject!
}

// Missing Timer cleanup
struct TimerView: View {
  var body: some View {
    Text("Hello")
      .onAppear {
        Timer.scheduledTimer(...)  // Missing .onDisappear cleanup!
      }
  }
}

// Retain cycle in Combine
publisher
  .sink { value in
    self.updateUI(value)  // Missing [weak self]!
  }

Example Output

# Tech Debt Analysis Report

## Health Score: 72/100

### Issues by Severity
| Severity | Count |
|----------|-------|
| Critical | 2 |
| High | 15 |
| Medium | 45 |
| Low | 120 |

## Top Recommendations

1. **Address Critical Issues Immediately**
   Fix 2 critical security issues.

2. **Clean Up TODO/FIXME Comments**
   Found 45 TODO comments - consider creating tracked issues.

Code Quality

Tech Debt MCP practices what it preaches โ€” built with AI-assisted vibe coding, it maintains an A rating by regularly scanning itself. Internal refactors (e.g., nesting reduction in customRulesEngine.validatePattern via extracted helper โ€” #146) are driven by self-scan findings.

Self-Scan Results (v2.0.2, April 2026)

  • SQALE Rating: A (Excellent)
  • Debt Score: 5/100 (Target: โ‰ค5/100)
  • Total Issues: 13 (0 critical, 0 high, 6 medium, 7 low)
  • Remediation Time: 14 hours
  • Health Score: 95/100

Down from 118 issues / 42.4 health in the v2.0.1 baseline after the v2.0.2 security hardening, ruleExclusions config, nesting refactors (#113, #118, #131, #146), and custom-rules handler extraction (#145). Remaining debt: 5 nesting hotspots (4 in server / core modules + 1 in eslint.config.mjs), 7 type-assertion usages at system boundaries, and 1 non-null assertion. See TECH_DEBT_SCAN.md for per-issue detail.

Development

npm install --include=dev --ignore-scripts  # Install dependencies (incl. devDependencies)
npm run typecheck  # Type-check without emitting output
npm run lint       # Lint source files
npm run build      # Compile TypeScript
npm run dev        # Run with ts-node
npm run watch      # Watch mode
npm test           # Run tests

Documentation

Privacy

Tech Debt MCP runs entirely on your machine. Once installed, it reads files you pass it, returns issues to your MCP client over the local stdio transport, and does nothing else โ€” the server itself makes no outbound network calls, has no telemetry, no analytics, and uses no third-party services. Installation via npm/npx does contact the npm registry as standard package-manager behavior; the MCPB bundle ships pre-installed and needs no further network access. See PRIVACY.md or the hosted policy at https://pierrejanineh.github.io/TechDebtMCP/privacy for details.

Releases

  • Latest:
  • Releases: GitHub Releases
  • Roadmap: See ROADMAP.md for planned features
  • Security: escapeRegExp() (src/utils/regexUtils.ts) must be used when interpolating captured strings into new RegExp() โ€” see issue #128; handler output uses basename() / getRelativePath() to prevent absolute filesystem path leakage in intentional messages, and raw err.message strings from filesystem operations are sanitized before being returned to clients โ€” see issue #129