Introduction: MCP Servers for Developer Productivity
In the Productivity category of the Tech-MCP project, we find three MCP servers designed to automate repetitive tasks that every developer faces daily: code review, dependency management, and new project creation. These servers operate as pure functions, with no internal state or database, making them lightweight, predictable, and easy to integrate into any workflow.
The problem they solve is concrete: manual code reviews are slow and subjective, dependency vulnerabilities often go unnoticed, and the initial configuration of a new project requires time and attention to avoid mistakes. By automating mechanical checks, these servers allow developers to focus on business logic and architectural decisions.
The Three Productivity Servers
- code-review: static code analysis with detection of console.log, debugger, hardcoded credentials, and cyclomatic complexity
- dependency-manager: vulnerability scanning, license auditing, and unused dependency detection
- project-scaffolding: project and component generation from predefined templates (Node.js, Express, React, MCP)
Server 1: code-review
The code-review server provides static analysis tools oriented toward the
code review process. It automates mechanical checks that a human reviewer would tend to
overlook: forgotten debug statements, hardcoded credentials, overly complex functions,
and problematic patterns. Each detected issue is classified with a severity level
(error, warning, or info), allowing developers to
prioritize fixes.
Stateless Architecture
The server has no store or internal services. Each tool operates as a pure function that receives an input and produces a JSON result. There is no database, no cache, no shared state between calls. This architectural choice guarantees idempotency: the same request always produces the same result.
MCP Request
|
v
+---------------------+
| Tool Dispatcher |
+---------------------+
/ | \
v v v
analyze- check- suggest-
diff complexity improvements
| | |
v v v
parseDiff calculate checkMagicNumbers
detectIss Complexity checkLongFunctions
ues checkDeepNesting
checkDuplicatePatterns
checkUnusedVariables
Tool Table
| Tool | Description | Parameters |
|---|---|---|
analyze-diff |
Analyzes a git diff string to identify common issues in added code | diff (string) - The git diff string to analyze |
check-complexity |
Calculates cyclomatic complexity by counting decision points | code (string) - The code snippet; language (string) - The language |
suggest-improvements |
Suggests improvements for magic numbers, long functions, deep nesting | code (string) - The code snippet; language (string) - The language |
Tool: analyze-diff
The analyze-diff tool receives a string in git diff format and analyzes
it line by line, searching for problematic patterns. The internal flow follows these steps:
- The diff string is split into lines
- Modified file names are extracted from
+++headers - Hunk headers are parsed to track line numbers
- Each added line (
+) is tested against issue patterns - Consecutive blocks of over 50 added lines are flagged
Patterns Detected by analyze-diff
- console-statement (warning):
console.log,console.debug,console.info,console.warn,console.error,console.trace,console.dir - todo-comment (info): comments containing
TODO,FIXME,HACK,XXX,TEMP - debugger-statement (error):
debuggerstatements left in the code - alert-statement (warning):
alert()calls - hardcoded-credential (error): password, secret, api_key, token hardcoded in the source
- empty-catch (warning): empty catch blocks that silently swallow errors
- large-addition (info): consecutive blocks with over 50 added lines
Example request and response for analyzing a diff containing issues:
// Request
{
"tool": "analyze-diff",
"arguments": {
"diff": "--- a/src/app.ts\n+++ b/src/app.ts\n@@ -10,3 +10,5 @@\n+console.log('debug');\n+const password = 'secret123';\n+debugger;"
}
}
// Response
{
"stats": { "filesChanged": 1, "linesAdded": 3, "linesRemoved": 0 },
"totalIssues": 3,
"issuesBySeverity": { "error": 2, "warning": 1, "info": 0 },
"issues": [
{ "type": "console-statement", "severity": "warning", "line": 10 },
{ "type": "hardcoded-credential", "severity": "error", "line": 11 },
{ "type": "debugger-statement", "severity": "error", "line": 12 }
]
}
Tool: check-complexity
The check-complexity tool calculates the cyclomatic complexity of a
code snippet by counting decision points. Complexity starts at 1 (the main path) and
increments for each branching construct found.
The code is first cleaned of comments and strings to avoid false positives, then
standard decision patterns are counted: if, else if, for,
while, case, catch, &&,
||, ?:.
Multi-language Support
The tool recognizes language-specific patterns, extending the base analysis:
| Language | Additional Patterns |
|---|---|
| Python | elif, except, and, or |
| Rust | match, => |
| Java | Standard patterns (if, for, while, switch/case) |
| TypeScript | Standard patterns + ternary and logical operators |
The calculated complexity is automatically classified into four levels:
- <= 5: Low - simple and readable code
- <= 10: Moderate - manageable complexity
- <= 20: High - candidate for refactoring
- > 20: Very high - requires urgent decomposition
// Request
{
"tool": "check-complexity",
"arguments": {
"code": "function process(data) {\n if (data.valid) {\n for (const item of data.items) {\n if (item.active && item.count > 0) {\n switch(item.type) {\n case 'A': break;\n case 'B': break;\n }\n }\n }\n }\n}",
"language": "javascript"
}
}
// Response
{
"totalComplexity": 7,
"rating": "moderate - manageable complexity",
"breakdown": [
{ "pattern": "if", "count": 2, "description": "If statements" },
{ "pattern": "for", "count": 1, "description": "For loops" },
{ "pattern": "case", "count": 2, "description": "Switch case branches" },
{ "pattern": "&&", "count": 1, "description": "Logical AND operators" }
],
"lineCount": 12,
"language": "javascript"
}
Tool: suggest-improvements
The suggest-improvements tool runs five independent checks on the source code,
looking for patterns that indicate potential quality and maintainability issues:
- Magic numbers: numbers with 2+ digits not declared as constants (excluding common values like 0, 1, 2, 10, 100, 1000, 24, 60, 1024)
- Long functions: functions with more than 30 lines, detected by counting curly braces
- Deep nesting: more than 4 levels of curly brace nesting (deduplicated every 5 lines)
- Duplicate code: identical lines (more than 10 characters) appearing 3 or more times
- Unused variables: variables declared but referenced only once in the code
Suggestions are sorted by severity: high > medium > low.
// Request
{
"tool": "suggest-improvements",
"arguments": {
"code": "function calc(x) {\n const result = x * 3.14159;\n const temp = 42;\n return result * 86400;\n}",
"language": "typescript"
}
}
// Response
{
"totalSuggestions": 2,
"suggestionsBySeverity": { "high": 0, "medium": 2, "low": 0 },
"suggestions": [
{ "type": "magic-number", "severity": "medium", "message": "Magic number 3.14159 found" },
{ "type": "magic-number", "severity": "medium", "message": "Magic number 86400 found" }
]
}
Tool Registration in the Server
The code-review server tools are registered following the standard Tech-MCP pattern.
Each tool declares its input schema with Zod and implements a handler that returns
the result as JSON text content:
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: 'analyze-diff',
description: 'Analyze a git diff string for common issues in added code',
inputSchema: {
type: 'object',
properties: {
diff: { type: 'string', description: 'The git diff string to analyze' }
},
required: ['diff']
}
},
{
name: 'check-complexity',
description: 'Calculate cyclomatic complexity of a code snippet',
inputSchema: {
type: 'object',
properties: {
code: { type: 'string', description: 'The code snippet' },
language: { type: 'string', description: 'Programming language' }
},
required: ['code', 'language']
}
},
{
name: 'suggest-improvements',
description: 'Suggest improvements for magic numbers, long functions, deep nesting',
inputSchema: {
type: 'object',
properties: {
code: { type: 'string', description: 'The code snippet' },
language: { type: 'string', description: 'Programming language' }
},
required: ['code', 'language']
}
}
]
}));
Events Published by code-review
The server publishes two events on the EventBus, consumable by other servers in the Tech-MCP suite:
| Event | Emitted by | Payload |
|---|---|---|
code:commit-analyzed |
analyze-diff |
{ commitHash, files, stats: { filesChanged, linesAdded, linesRemoved } } |
code:review-completed |
suggest-improvements |
{ files, issues, suggestions } |
The server does not subscribe to any events: it is purely reactive to tool calls. The
standup-notes and agile-metrics servers can consume these events
to aggregate code quality metrics and generate automatic reports.
Server 2: dependency-manager
The dependency-manager server is dedicated to managing and analyzing dependencies of a Node.js project. It addresses three critical problems in modern software development: security vulnerabilities in dependencies, packages declared but never imported, and copyleft license incompatibilities that may impose restrictions on software distribution.
Architecture and System Dependencies
Unlike code-review which operates entirely through regex, the
dependency-manager server interacts with the filesystem and child processes.
It remains stateless nonetheless: no data is retained between calls.
projectPath
|
+-- package.json <--- read by all 3 tools
|
+-- node_modules/ <--- read by license-audit
| +-- pkg-a/
| | +-- package.json ("license" field)
| +-- pkg-b/
| +-- package.json
|
+-- src/ <--- scanned by find-unused
+-- index.ts
+-- app.ts
+-- utils/
Tool Table
| Tool | Description | Parameters |
|---|---|---|
check-vulnerabilities |
Runs npm audit --json and groups vulnerabilities by severity |
projectPath (string) - Absolute path to the project directory |
find-unused |
Analyzes imports in source files to find unused dependencies | projectPath (string) - Absolute path to the project directory |
license-audit |
Reads licenses of every dependency from node_modules and flags copyleft ones |
projectPath (string) - Absolute path to the project directory |
Tool: check-vulnerabilities
The check-vulnerabilities tool is a structured wrapper around npm audit --json.
The operational flow includes:
- Verify the existence of
package.jsonin the specified path - Execute
npm audit --jsonwith a 60-second timeout - Handle non-zero exit codes (npm audit exits with an error if it finds vulnerabilities)
- Parse the JSON output in npm v7+ format
- Group by severity:
critical,high,moderate,low,info - Publish a
code:dependency-alertevent for each critical or high vulnerability
// Request
{
"tool": "check-vulnerabilities",
"arguments": {
"projectPath": "/home/user/my-project"
}
}
// Response
{
"project": "my-project",
"totalVulnerabilities": 5,
"severityCounts": {
"high": 2,
"moderate": 2,
"low": 1
},
"vulnerabilities": {
"high": [
{
"name": "lodash",
"severity": "high",
"title": "Prototype Pollution",
"url": "https://github.com/advisories/GHSA-xxxx",
"range": "<4.17.21",
"fixAvailable": { "name": "lodash", "version": "4.17.21" }
}
]
},
"metadata": {
"totalDependencies": 142,
"devDependencies": 38,
"prodDependencies": 104
}
}
Tool: find-unused
The find-unused tool performs a recursive scan of source files to identify
dependencies declared in package.json but never actually imported in the code.
The analysis covers:
- ES module imports:
import ... from 'package' - CommonJS:
require('package') - Dynamic imports:
import('package') - Scoped packages: correct handling of
@scope/package
The directories node_modules, dist, build, .git,
and coverage are automatically excluded from scanning. Analyzed files include
the extensions .ts, .js, .tsx, and .jsx.
// Request
{
"tool": "find-unused",
"arguments": {
"projectPath": "/home/user/my-project"
}
}
// Response
{
"project": "my-project",
"sourceFilesScanned": 47,
"summary": {
"totalDependencies": 12,
"totalDevDependencies": 8,
"unusedDependencies": 2,
"unusedDevDependencies": 1
},
"unusedDependencies": ["moment", "lodash"],
"unusedDevDependencies": ["@types/lodash"],
"note": "Dependencies may be used in config files, scripts, or other non-source files."
}
Tool: license-audit
The license-audit tool examines the licenses of every dependency by directly
reading the package.json files inside node_modules. This check
is particularly relevant for commercial projects, where using copyleft licenses could
impose unwanted restrictions.
Detected Copyleft Licenses
- GPL: versions 2.0, 3.0, -only, -or-later
- AGPL: versions 1.0, 3.0
- LGPL: versions 2.0, 2.1, 3.0
- Others: MPL-2.0, EUPL, CPAL-1.0, OSL-3.0, CC-BY-SA-4.0
// Request
{
"tool": "license-audit",
"arguments": {
"projectPath": "/home/user/my-project"
}
}
// Response
{
"project": "my-project",
"summary": {
"totalDependenciesChecked": 20,
"uniqueLicenses": 4,
"copyleftCount": 1,
"notFoundInNodeModules": 0
},
"copyleftWarnings": [
{ "name": "some-gpl-lib", "version": "2.1.0", "license": "GPL-3.0" }
],
"byLicense": {
"MIT": [{ "name": "express", "version": "4.21.0" }],
"ISC": [{ "name": "glob", "version": "10.3.0" }],
"GPL-3.0": [{ "name": "some-gpl-lib", "version": "2.1.0" }]
}
}
Events Published by dependency-manager
| Event | Emitted by | Payload | Condition |
|---|---|---|---|
code:dependency-alert |
check-vulnerabilities |
{ package, severity, advisory } |
For each vulnerability with critical or high severity |
Like code-review, this server does not subscribe to any events. The
standup-notes and agile-metrics servers can receive alerts to
track vulnerability trends over time.
Server 3: project-scaffolding
The project-scaffolding server automates the creation of new projects and
components from predefined templates. Every new project normally requires manually creating
package.json, tsconfig.json, folder structures, and boilerplate
files: a repetitive and error-prone process that this server completely eliminates.
Available Templates
The server offers four built-in templates covering the most common use cases in modern TypeScript development:
| Template | Description | Generated Files |
|---|---|---|
node-typescript |
Node.js with TypeScript, ESM, and Vitest | package.json, tsconfig.json, src/index.ts, .gitignore, README.md |
express-api |
Express REST API with TypeScript, routing, and middleware | package.json, tsconfig.json, src/index.ts, src/app.ts, src/routes/health.ts, src/middleware/error-handler.ts, .gitignore, README.md |
react-app |
React application with TypeScript and Vite | package.json, tsconfig.json, vite.config.ts, index.html, src/main.tsx, src/App.tsx, src/App.css, .gitignore, README.md |
mcp-server |
Model Context Protocol server with TypeScript | package.json, tsconfig.json, src/index.ts, src/tools.ts, .gitignore, README.md |
Tool Table
| Tool | Description | Parameters |
|---|---|---|
list-templates |
Lists all available templates with name, description, and file structure | None |
scaffold-project |
Generates an entire project from a template with placeholder substitution | template (string), projectName (string), outputDir (string), options? (object: author, description, license) |
scaffold-component |
Generates a single component/service/controller/model file | type (enum: component, service, controller, model), name (string), outputDir (string), language (enum: typescript, javascript) |
Tool: scaffold-project
The scaffold-project tool generates an entire project from a selected template.
The core mechanism is placeholder substitution: each template file contains
placeholders like {{projectName}},
{{author}}, {{description}},
and {{license}} that are replaced with the provided values.
1. Template validation
|
v
2. Prepare placeholder values
{ projectName, author, description, license }
|
v
3. For each file in the template:
a. Calculate path: outputDir/projectName/relativePath
b. Create directory (mkdir recursive)
c. Substitute placeholders in content
d. Write file to disk
|
v
4. Return list of created files
// Request
{
"tool": "scaffold-project",
"arguments": {
"template": "express-api",
"projectName": "user-service",
"outputDir": "/home/user/projects",
"options": {
"author": "Mario Rossi",
"description": "User management microservice",
"license": "MIT"
}
}
}
// Response
{
"template": "express-api",
"projectName": "user-service",
"outputDir": "/home/user/projects/user-service",
"filesCreated": [
"package.json", "tsconfig.json", "src/index.ts", "src/app.ts",
"src/routes/health.ts", "src/middleware/error-handler.ts",
".gitignore", "README.md"
],
"totalFiles": 8
}
Tool: scaffold-component
The scaffold-component tool generates individual files for components, services,
controllers, or models. It supports both TypeScript and JavaScript and produces code with
a standard structure ready for use:
Generatable Component Types
| Type | Generated File | Content |
|---|---|---|
component |
Name.tsx / Name.jsx | React component with props interface (TypeScript) |
service |
Name.service.ts / .js | Class with CRUD methods: findAll, findById, create, update, delete |
controller |
Name.controller.ts / .js | Express controller with handlers getAll, getById, create, update, delete |
model |
Name.model.ts / .js | Interface + factory functions create/update (TS) or plain functions (JS) |
// Request
{
"tool": "scaffold-component",
"arguments": {
"type": "service",
"name": "User",
"outputDir": "/home/user/projects/user-service/src/services",
"language": "typescript"
}
}
// Response
{
"message": "Generated service file: /home/user/projects/user-service/src/services/User.service.ts",
"filePath": "/home/user/projects/user-service/src/services/User.service.ts"
}
Event Bus Integration
The project-scaffolding server neither publishes nor subscribes to events.
It is a purely generative server that operates on explicit user request. However,
generated projects can be immediately analyzed by the other productivity servers:
- dependency-manager: to verify vulnerabilities and licenses of the newly generated project's dependencies
- code-review: to analyze the quality of code generated from templates
- codebase-knowledge: to map the new project's structure with
architecture-map
Interactions Between Productivity Servers
The three productivity servers collaborate in a complementary way. While independent, the output of one can feed the inputs of others, creating an automated workflow:
+----------------------+ +---------------------+
| project-scaffolding | generates project ---> | dependency-manager |
| | for analysis | (check-vulnerab.) |
+----------------------+ +---------------------+
|
| generates code ---> +---------------------+
+-------------------------> | code-review |
| (analyze/suggest) |
+---------------------+
+------------------+ code:commit-analyzed +-------------------+
| code-review | -----------------------------> | standup-notes |
| | code:review-completed | agile-metrics |
+------------------+ -----------------------------> +-------------------+
+---------------------+ code:dependency-alert +-------------------+
| dependency-manager | --------------------------> | standup-notes |
| | | agile-metrics |
+---------------------+ +-------------------+
Event Summary
| Server | Event | Consumers |
|---|---|---|
code-review |
code:commit-analyzed |
standup-notes, agile-metrics |
code-review |
code:review-completed |
standup-notes, agile-metrics |
dependency-manager |
code:dependency-alert |
standup-notes, agile-metrics |
project-scaffolding |
None | - |
Common Pattern: Stateless Servers and Pure Analysis
All three productivity servers share a fundamental architectural pattern: they are completely stateless. They use no database, maintain no cache, and have no internal services with persistent state. Every tool call is independent and self-contained.
This approach offers several advantages:
- Idempotency: the same request always produces the same result, facilitating testing and debugging
- Scalability: no shared state bottleneck, servers can be instantiated in parallel
- Simplicity: no database migrations, no session management, no cleanup needed
- Reliability: a crash causes no data loss because there is no state to preserve
The code-review server operates entirely through regex and pattern counting.
The dependency-manager server reads from the filesystem and invokes
npm audit as an external process. The project-scaffolding server
writes files to disk from in-memory templates. None of the three requires additional
infrastructure configuration.
Conclusions
The three Tech-MCP productivity servers demonstrate how MCP can automate repetitive
tasks in software development without requiring complex infrastructure. The
code-review server automatically detects common issues in code reviews,
dependency-manager keeps vulnerabilities and licenses under control, and
project-scaffolding eliminates boilerplate when creating new projects.
The stateless pattern adopted by all three servers makes them particularly well-suited for integration into CI/CD pipelines and automated workflows, where predictability and the absence of side effects are fundamental requirements.
In the next article, we will explore the DevOps servers in the Tech-MCP suite:
docker-compose for container management, log-analyzer for
application log analysis, and cicd-monitor for monitoring build and deploy
pipelines. We will see how these servers integrate with the productivity servers through
the EventBus to create a fully automated development workflow.
The complete source code for all three servers is available in the Tech-MCP GitHub repository.







