loading…
Search for a command to run...
loading…
An MCP server that standardizes and binds development tool patterns, enabling AI assistants like Claude Code to generate code more efficiently with fewer errors
An MCP server that standardizes and binds development tool patterns, enabling AI assistants like Claude Code to generate code more efficiently with fewer errors and better autocorrection.
CI Status codecov npm version License Node.js Version Documentation
An MCP (Model Context Protocol) server that standardizes and binds specific patterns for development tools, enabling Claude Code to generate code more efficiently with fewer errors and better autocorrection capabilities.
Alpha - This project is in early development and actively evolving.
🎉 Major Milestone: Complete Language Support - We now have comprehensive support for both Go (13 tools) and Node.js/TypeScript (14 tools), making this a powerful DevTools server for modern development workflows. With intelligent caching, AI-powered suggestions, and zero-configuration onboarding, we're ready for the 0.0.1 release!
npm run docs:api)This MCP server creates a standardized interface between development tools and AI assistants like Claude Code. By establishing consistent patterns and best practices, it helps:
The onboarding wizard automatically detects your project type and generates optimal MCP DevTools configuration with zero user input required.
Quick Start:
# Run complete onboarding (auto-detects everything)
mcp-devtools onboarding_wizard
# Preview changes without writing files
mcp-devtools onboarding_wizard --dry-run true
# Detect project type only
mcp-devtools detect_project
Available Tools:
onboarding_wizard - Complete automated setup workflow
.mcp-devtools.json configurationdetect_project - Analyze project characteristics
generate_config - Preview configuration without writing
validate_setup - Validate existing configuration
rollback_setup - Restore previous configuration
.mcp-devtools-backups/Example Output:
## Onboarding Wizard Results
**Status:** ✅ Success
**Duration:** 2847ms
**Configuration:** /path/to/project/.mcp-devtools.json
**Backup:** /path/to/project/.mcp-devtools-backups/2025-11-04T10-30-00.json
### ⚠️ Skipped Tools (2)
- eslint
- markdownlint-cli
### 💡 Recommendations
#### High Priority
- **Install missing required tools** (tool)
Install eslint and markdownlint-cli for complete linting support
### Validation
**Score:** 95/100
**Errors:** 0
**Warnings:** 2
Configuration Options:
| Parameter | Type | Default | Description |
|---|---|---|---|
directory |
string | cwd |
Working directory to analyze |
interactive |
boolean | false |
Enable interactive prompts (planned) |
autoInstall |
boolean | false |
Automatically install missing tools (planned) |
generateConfig |
boolean | true |
Generate .mcp-devtools.json file |
validateSetup |
boolean | true |
Run validation after setup |
backupExisting |
boolean | true |
Backup existing config before overwriting |
dryRun |
boolean | false |
Preview changes without writing files |
skipToolVerification |
boolean | false |
Skip tool installation checks |
Safety Features:
make lint with optional directory and target specificationmake test with optional test patterns/targetsmake depend or equivalent dependency installationmake build or make allmake cleanCore Tools:
Advanced Features:
nodejs_project_info - Comprehensive Node.js project analysis with smart caching
nodejs_test - Run tests with Jest, Vitest, or Mocha
nodejs_lint - ESLint integration with auto-fix
--fix flagnodejs_format - Prettier code formatting
nodejs_check_types - TypeScript type checking
nodejs_install_deps - Dependency management
nodejs_version - Version detection with 1hr caching
nodejs_security - Security vulnerability scanning
--fix flagnodejs_build - Build orchestration
nodejs_scripts - Script management with caching
nodejs_benchmark - Performance benchmarking
nodejs_update_deps - Dependency updates
nodejs_compatibility - Compatibility checking with 2hr caching
nodejs_profile - Performance profiling
actionlint - Validate GitHub Actions workflow files for syntax errors and best practices
A comprehensive linter for GitHub Actions workflow files that helps catch errors before pushing to GitHub. Validates workflow syntax, action parameters, expression syntax, and shell scripts within run blocks.
Features:
${{ }} syntax)run: blocksParameters:
directory - Working directory containing workflows (default: project root)files - Specific workflow files or glob patterns (default: .github/workflows/*.{yml,yaml})format - Output format: default, json, or sarifshellcheck - Enable shellcheck integration (default: true)pyflakes - Enable pyflakes for Python (default: false)verbose - Enable verbose outputignore - Array of rule patterns to ignoretimeout - Command timeout in milliseconds (default: 60000)Common Use Cases:
Example Output:
.github/workflows/ci.yml:25:15: property "timeout" not defined in action 'actions/checkout@v4' [action]
.github/workflows/ci.yml:42:9: shellcheck reported issue SC2086: Double quote to prevent globbing [shellcheck]
jq_query - Process JSON data using jq filter syntax without requiring approval
Use this instead of Bash(jq ...) for all JSON processing. This tool provides the full power
of jq for JSON manipulation without requiring user approval for each query, making it perfect for
parsing API responses, extracting fields, filtering arrays, and transforming data structures.
Why Use jq_query:
Parameters:
input - JSON string or already-parsed object/array (required)filter - jq filter expression (required), e.g., ".[] | .name"compact - Output compact JSON (default: false)raw_output - Output raw strings without JSON quotes (default: false)sort_keys - Sort object keys alphabetically (default: false)Common Patterns:
// Extract array of field values
jq_query({ input: data, filter: '.[] | .name' })
// Filter by condition
jq_query({ input: data, filter: '.[] | select(.status == "active")' })
// Transform structure
jq_query({ input: data, filter: '{name, id}' })
// Pretty-print minified JSON
jq_query({ input: minifiedJSON, filter: '.' })
// Get array length
jq_query({ input: data, filter: 'length' })
// Complex transformations
jq_query({
input: apiResponse,
filter: '.data.users | map({name: .user_name, id: .user_id})'
})
Features:
Installation Requirements:
jq must be installed on the system. If not found, the tool provides installation instructions:
# macOS
brew install jq
# Ubuntu/Debian
apt-get install jq
# Fedora/RHEL
dnf install jq
# Windows
choco install jq
Real-World Examples:
// Parse GitHub API response
jq_query({
input: milestones,
filter: '.[] | select(.title | contains("2025-Q2")) | .number'
})
// Extract specific fields from array
jq_query({
input: issues,
filter: '[.[] | {title, number, state}]'
})
// Count matching items
jq_query({
input: data,
filter: '[.[] | select(.status == "open")] | length'
})
code_review - Automated code review analysis on Git changes
Analyzes Git diffs to identify potential issues in code changes including security vulnerabilities, performance concerns, and maintainability problems. Provides severity-based categorization and actionable feedback.
Features:
generate_pr_message - Generate PR messages from Git changes
Automatically generates conventional commit-formatted PR messages by analyzing commit history and changed files. Supports GitHub PR templates for consistent documentation.
Features:
.github/pull_request_template.md.github/PULL_REQUEST_TEMPLATE.md.github/PULL_REQUEST_TEMPLATE/pull_request_template.mddocs/pull_request_template.mdPULL_REQUEST_TEMPLATE.mdanalyze_command - Execute a command and analyze results with AI-powered smart suggestions
Executes a command and provides intelligent, context-aware recommendations based on the execution result. Helps identify issues, suggests fixes, and provides workflow optimization tips.
Features:
Parameters:
command - Command to execute and analyze (required)directory - Working directory for the commandtimeout - Command timeout in millisecondsargs - Additional command argumentscontext - Optional context for better suggestions:tool - Tool being used (e.g., "go test", "npm run")language - Programming languageprojectType - Project typeExample:
{
"command": "go test",
"directory": "./src",
"context": {
"tool": "go test",
"language": "Go"
}
}
analyze_result - Analyze already-executed command results
Post-mortem analysis of command execution results. Useful for analyzing failures from external tools or historical command runs.
Parameters:
command - Command that was executed (required)exitCode - Exit code from execution (required)stdout - Standard output from commandstderr - Standard error from commandduration - Execution duration in millisecondscontext - Optional context (same as analyze_command)get_knowledge_base_stats - Get statistics about the smart suggestions knowledge base
Returns information about available failure patterns and their categorization.
Parameters:
category - Optional filter by category (security, performance, dependencies, etc.)Knowledge Base Categories:
Supported Languages & Tools:
ensure_newline - Validate and fix POSIX newline compliance
Ensures text files end with a proper newline character, as required by POSIX standards. This addresses a common pain point where AI coding assistants frequently create or modify files without proper trailing newlines, causing linting failures and git diff noise.
Modes:
check - Report files without trailing newlines (read-only, non-destructive)fix - Automatically add missing newlines to files (safe, preserves line ending style)validate - Exit with error if non-compliant files found (CI/CD mode)Key Features:
tail or od)Why This Matters:
The get_current_datetime tool provides rich temporal context optimized for LLM awareness. This helps AI
assistants understand the current date and time with confidence, especially when the system date is near or
past the LLM's training cutoff.
Key Features:
Use Cases:
Example Usage:
// Get current datetime with full context
{
"timezone": "America/Chicago"
}
Example Output:
## Current Date & Time
**Tuesday, November 12, 2025 at 7:21 PM CST**
### Date Information
- **Year:** 2025
- **Quarter:** Q4 (October 1, 2025 - December 31, 2025)
- **Month:** November (11)
- **Day:** Tuesday, November 12
- **Day of Year:** 316 of 365
- **ISO Week:** 46
### Time Information
- **Time:** 19:21:00
- **Timezone:** America/Chicago (CST)
- **UTC Offset:** -06:00
- **DST Active:** No
### Relative Information
- **Days Remaining in Year:** 49
- **Weeks Remaining in Year:** 7
- **Days in Current Month:** 30
### Technical Details
- **ISO 8601:** 2025-11-12T19:21:00.000Z
- **Unix Timestamp:** 1762994460
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
timezone |
string | System timezone | IANA timezone (e.g., 'America/New_York', 'UTC', 'Asia/Tokyo') |
include_calendar |
boolean | true |
Include calendar information (quarter, week, etc.) |
Supported Timezones:
All IANA timezone identifiers are supported, including:
UTC - Coordinated Universal TimeAmerica/New_York - US EasternAmerica/Chicago - US CentralAmerica/Los_Angeles - US PacificEurope/London - UKEurope/Paris - Central EuropeanAsia/Tokyo - Japan Standard TimeAsia/Shanghai - China Standard Timedotenv_environment - Load and parse environment variables from .env files
Makes environment variables visible to AI assistants through MCP context, enabling better debugging and configuration assistance. Automatically masks sensitive values (passwords, tokens, API keys) while exposing configuration safely.
Features:
Why This Matters:
golangci-lint, staticcheck (for enhanced Go support)git clone https://github.com/rshade/mcp-devtools-server.git
cd mcp-devtools-server
npm install
npm run build
npm start
Most linting tools are installed automatically via npm. However, some tools require separate installation:
yamllint (Python-based YAML linter):
# macOS (via Homebrew)
brew install yamllint
# Linux (Ubuntu/Debian)
sudo apt-get install yamllint
# Linux (Fedora/RHEL)
sudo dnf install yamllint
# Any platform (via pip)
pip install yamllint
# Verify installation
yamllint --version
actionlint (GitHub Actions workflow validator):
# macOS (via Homebrew)
brew install actionlint
# Linux (download binary)
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
# Or via go install
go install github.com/rhysd/actionlint/cmd/actionlint@latest
# Verify installation
actionlint --version
You can use either make commands or npm scripts (Makefile is a thin wrapper around npm):
# View all available commands
make help
# Setup and build
make install # Install dependencies
make build # Build TypeScript
make install-mcp # Install to Claude Desktop
# Development
make dev # Run in development mode
make start # Start production server
# Testing
make test # Run tests
make test-watch # Run tests in watch mode
make test-coverage # Run tests with coverage
# Linting
make lint # Run all linters
make lint-ts # Run TypeScript linting
make lint-md # Run Markdown linting
make lint-yaml # Run YAML linting
make lint-commit # Validate commit message format
# Documentation
make docs-api # Generate API docs (TypeDoc)
make docs-dev # Start docs dev server
make docs-build # Build documentation
make docs-preview # Preview built docs
# CI/CD
make check # Run all linters and tests
make all # Complete CI pipeline
# Or use npm scripts directly
npm run dev # Run in development mode
npm run lint # Run TypeScript linting
npm test # Run tests
npm run clean # Clean build artifacts
The MCP DevTools Server is available as Docker images for easy deployment and consistent environments across different systems.
# Pull the latest image
docker pull ghcr.io/rshade/mcp-devtools-server:latest
# Run with stdio (for MCP protocol)
docker run -i --rm ghcr.io/rshade/mcp-devtools-server:latest
Update your Claude Desktop configuration (~/.claude/claude_desktop_config.json):
{
"mcpServers": {
"mcp-devtools-server": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-v",
"/path/to/your/project:/workspace",
"-w",
"/workspace",
"ghcr.io/rshade/mcp-devtools-server:latest"
]
}
}
}
Replace /path/to/your/project with your actual project directory.
For local development with hot-reload:
# Start development server
docker compose up mcp-devtools-dev
# Run tests
docker compose run --rm mcp-devtools-test
# Run linters
docker compose run --rm mcp-devtools-lint
# Production-like testing
docker compose up mcp-devtools
docker-compose.yml features:
Build your own image with custom tools:
# Extend the base image
FROM ghcr.io/rshade/mcp-devtools-server:latest
# Install additional tools
RUN apk add --no-cache \
docker-cli \
kubectl
# Copy custom configuration
COPY .mcp-devtools.json /app/
Build and run:
docker build -t my-mcp-devtools:latest .
docker run -i --rm my-mcp-devtools:latest
The project includes automated Docker builds via GitHub Actions:
Available image tags:
latest - Latest stable releasev1.2.3 - Specific version tagsmain-abc123 - Branch-specific builds with commit SHAdev - Development builds (not published)Control Docker behavior with environment variables:
# Set log level
docker run -i --rm \
-e LOG_LEVEL=debug \
ghcr.io/rshade/mcp-devtools-server:latest
# Set Node environment
docker run -i --rm \
-e NODE_ENV=production \
ghcr.io/rshade/mcp-devtools-server:latest
Mount your project directory to work with your code:
docker run -i --rm \
-v "$(pwd):/workspace" \
-w /workspace \
ghcr.io/rshade/mcp-devtools-server:latest
--user flag to match host user ID:docker run -i --rm \
--user $(id -u):$(id -g) \
-v "$(pwd):/workspace" \
ghcr.io/rshade/mcp-devtools-server:latest
-i (interactive) flag is setdocker logs <container_id>command is "docker" not "docker run"args array formatting in claude_desktop_config.jsondocker pull ghcr.io/rshade/mcp-devtools-server:latestBuild the project first:
npm run build
Add to your Claude Desktop configuration file (~/.claude/claude_desktop_config.json):
{
"mcpServers": {
"mcp-devtools-server": {
"command": "node",
"args": ["/absolute/path/to/mcp-devtools-server/dist/index.js"],
"env": {
"LOG_LEVEL": "info"
}
},
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"]
}
}
}
Replace /absolute/path/to/mcp-devtools-server with your actual project path.
Example configuration files:
examples/claude-desktop-config.json for a complete example.mcp.json file in the project root is a template you can copyRestart Claude Desktop after updating the configuration.
Create a .mcp-devtools.json file in your project root:
{
"commands": {
"lint": "make lint",
"test": "make test",
"build": "make build",
"clean": "make clean"
},
"linters": ["eslint", "markdownlint", "yamllint"],
"testRunner": "jest",
"timeout": 300000
}
The MCP server automatically provides guidance to Claude via system prompt instructions (src/instructions.md).
These instructions help Claude:
Key behaviors enabled:
.mcp-devtools.json and offers to run onboarding_wizard if missingmake_lint, eslint, etc. instead of Bash(make lint)analyze_command for automatic failure analysisproject_status before starting work to understand available toolingThe instructions are token-efficient (< 100 lines) and focus on operational guidance rather than marketing content.
// Run make lint
await callTool('make_lint', {});
// Run make test with specific target
await callTool('make_test', { target: 'unit-tests' });
// Run all linters
await callTool('lint_all', { fix: true });
// Get project status
await callTool('project_status', {});
// Run Go tests with coverage and race detection
await callTool('go_test', {
coverage: true,
race: true,
verbose: true
});
// Build Go application with specific tags
await callTool('go_build', {
tags: ["integration", "postgres"],
verbose: true
});
// Format Go code
await callTool('go_fmt', {
write: true,
simplify: true
});
// Lint Go code with custom config
await callTool('go_lint', {
config: ".golangci.yml",
fix: true
});
// Vet Go code for issues
await callTool('go_vet', { package: "./..." });
// Tidy Go modules
await callTool('go_mod_tidy', { verbose: true });
// Run benchmarks with memory profiling
await callTool('go_benchmark', {
benchmem: true,
benchtime: '10s',
cpu: [1, 2, 4]
});
// Execute code generation
await callTool('go_generate', {
run: 'mockgen',
verbose: true
});
// Cross-compile for different platforms
await callTool('go_build', {
goos: 'linux',
goarch: 'arm64',
ldflags: '-X main.version=1.0.0',
output: './bin/app-linux-arm64'
});
// Manage Go workspaces
await callTool('go_work', {
command: 'use',
modules: ['./moduleA', './moduleB']
});
// Scan for vulnerabilities
await callTool('go_vulncheck', {
mode: 'source',
json: true
});
// Check all TypeScript and JavaScript files for missing newlines
await callTool('ensure_newline', {
patterns: ['src/**/*.ts', 'src/**/*.js'],
mode: 'check',
exclude: ['node_modules/**', 'dist/**']
});
// Fix all markdown files (automatically adds trailing newlines)
await callTool('ensure_newline', {
patterns: ['**/*.md'],
mode: 'fix',
exclude: ['node_modules/**']
});
// Validate in CI/CD pipeline (exits with error if non-compliant)
await callTool('ensure_newline', {
patterns: ['**/*'],
mode: 'validate',
exclude: ['node_modules/**', '.git/**', 'dist/**', '*.min.js'],
maxFileSizeMB: 5
});
// Check specific file types only
await callTool('ensure_newline', {
patterns: ['**/*'],
fileTypes: ['*.ts', '*.go', '*.md', '*.json'],
mode: 'check'
});
// Fix files after AI code generation
await callTool('ensure_newline', {
patterns: ['src/**/*.ts', 'test/**/*.ts'],
mode: 'fix',
skipBinary: true // default: true
});
// Load default .env file with masking (default behavior)
await callTool('dotenv_environment', {});
// Load specific .env file
await callTool('dotenv_environment', {
file: '.env.production'
});
// Load without masking (for debugging - use carefully!)
await callTool('dotenv_environment', {
mask: false
});
// Load with custom mask patterns
await callTool('dotenv_environment', {
maskPatterns: ['CUSTOM_SECRET', 'INTERNAL']
});
// Include process.env variables
await callTool('dotenv_environment', {
includeProcessEnv: true
});
// Full control example
await callTool('dotenv_environment', {
file: '.env.staging',
directory: '/path/to/project',
mask: true,
maskPatterns: ['CUSTOM_SECRET'],
includeProcessEnv: false
});
// Run tests with coverage
await callTool('run_tests', {
coverage: true,
pattern: "*.test.js"
});
// Lint specific files
await callTool('markdownlint', {
files: ["README.md", "docs/*.md"],
fix: true
});
// Build with parallel jobs
await callTool('make_build', { parallel: 4 });
Add EOL validation to your GitHub Actions workflow:
name: Lint
on: [push, pull_request]
jobs:
validate-eol:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install MCP DevTools Server
run: |
git clone https://github.com/rshade/mcp-devtools-server.git
cd mcp-devtools-server
npm install
npm run build
- name: Validate EOL compliance
run: |
# Use the ensure_newline tool in validate mode
# This will exit with error if any files lack trailing newlines
node mcp-devtools-server/dist/index.js ensure_newline \
--patterns "**/*.ts" "**/*.js" "**/*.md" \
--mode validate \
--exclude "node_modules/**" "dist/**"
Add to your .git/hooks/pre-commit or use with Husky:
#!/bin/bash
# Automatically fix missing newlines before commit
npx mcp-devtools-server ensure_newline \
--patterns "**/*.ts" "**/*.js" "**/*.go" "**/*.md" \
--mode fix \
--exclude "node_modules/**" "vendor/**" "dist/**"
# Stage any files that were fixed
git add -u
The MCP DevTools Server is built on a modular, secure architecture:
🏗️ View Complete Architecture Documentation
The MCP DevTools Server supports an extensible plugin architecture that allows you to add custom tools and integrations without modifying the core codebase.
Plugins extend the server with additional functionality:
A reference implementation demonstrating best practices for plugin development. Provides Git stacked branch management tools.
Tools Provided:
git_spice_branch_create - Create new stacked branchesgit_spice_branch_checkout - Checkout existing branchesgit_spice_stack_submit - Submit entire stack as pull requestsgit_spice_stack_restack - Rebase stack on latest changesgit_spice_log_short - View current stack visualizationgit_spice_repo_sync - Sync with remote and cleanup merged branchesExample Configuration:
{
"plugins": {
"enabled": ["git-spice"],
"git-spice": {
"defaultBranch": "main",
"autoRestack": false,
"jsonOutput": true,
"timeout": 60000
}
}
}
Usage Example:
// Create a new feature branch
await callTool('git_spice_branch_create', {
name: 'feature/add-authentication',
base: 'main'
});
// Create a stacked branch on top of the first
await callTool('git_spice_branch_create', {
name: 'feature/auth-service',
base: 'feature/add-authentication'
});
// View the stack
await callTool('git_spice_log_short', {});
// Submit all as PRs
await callTool('git_spice_stack_submit', { draft: false });
See the git-spice User Guide for detailed documentation.
┌─────────────────────────────────────┐
│ MCP DevTools Server │
│ ┌───────────────────────────────┐ │
│ │ Plugin Manager │ │
│ │ - Discovery │ │
│ │ - Registration │ │
│ │ - Tool Routing │ │
│ └───────────┬───────────────────┘ │
│ │ │
│ ┌───────────┴───────────────────┐ │
│ │ Plugin 1 │ Plugin 2 │ │
│ │ ┌─────┐ │ ┌─────┐ │ │
│ │ │Tool1│ │ │Tool3│ │ │
│ │ │Tool2│ │ │Tool4│ │ │
│ │ └─────┘ │ └─────┘ │ │
│ └──────────────┴────────────────┘ │
│ │ │
│ ┌───────────┴───────────────────┐ │
│ │ Shared ShellExecutor │ │
│ │ (Security Layer) │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
src/plugins/*-plugin.tsinitialize() with contextregisterTools() to get tool listhandleToolCall()shutdown() on server exitTools are automatically prefixed with plugin name to prevent conflicts:
Plugin: git-spice
Tool: branch_create
Result: git_spice_branch_create
Copy the template:
cp examples/plugins/custom-plugin-example.ts src/plugins/my-tool-plugin.ts
Update metadata:
metadata: PluginMetadata = {
name: 'my-tool',
version: '1.0.0',
description: 'Integration with my-tool',
requiredCommands: ['my-tool'],
tags: ['utility'],
};
Implement a tool:
async registerTools(): Promise<PluginTool[]> {
return [{
name: 'execute',
description: 'Execute my-tool command',
inputSchema: {
type: 'object',
properties: {
args: { type: 'array', items: { type: 'string' } }
}
}
}];
}
Build and test:
npm run build
node dist/index.js
Your plugin will be auto-discovered and loaded!
All plugins must implement the Plugin interface:
export class MyPlugin implements Plugin {
// Metadata (required)
metadata: PluginMetadata = {
name: 'my-plugin',
version: '1.0.0',
description: 'My custom plugin',
requiredCommands: ['my-command'],
tags: ['utility'],
};
// Lifecycle methods (required)
async initialize(context: PluginContext): Promise<void> {
// Validate required commands are available
// Initialize any state
}
async registerTools(): Promise<PluginTool[]> {
// Return array of tool definitions
}
async handleToolCall(toolName: string, args: unknown): Promise<unknown> {
// Route to appropriate tool method
}
// Optional methods
async validateConfig?(config: unknown): Promise<boolean> { }
async shutdown?(): Promise<void> { }
async healthCheck?(): Promise<PluginHealth> { }
}
Every plugin receives a context with:
interface PluginContext {
config: Record<string, unknown>; // Plugin configuration
projectRoot: string; // Project directory
shellExecutor: ShellExecutor; // Secure command execution
logger: winston.Logger; // Scoped logger
utils: PluginUtils; // Helper functions
}
src/utils/shell-executor.tseval() or Function()Example:
import { z } from 'zod';
const MyToolArgsSchema = z.object({
input: z.string().min(1).describe('Input parameter'),
verbose: z.boolean().optional().describe('Verbose output'),
});
private async myTool(args: unknown): Promise<MyToolResult> {
// 1. Validate input
const validated = MyToolArgsSchema.parse(args);
// 2. Execute through ShellExecutor
const result = await this.context.shellExecutor.execute(
`my-command ${validated.input}`,
{
cwd: this.context.projectRoot,
timeout: 60000,
}
);
// 3. Return structured result
if (result.success) {
return { success: true, output: result.stdout };
} else {
return {
success: false,
error: result.stderr,
suggestions: this.generateSuggestions(result.stderr),
};
}
}
Create tests in src/__tests__/plugins/your-plugin.test.ts:
import { describe, it, expect, beforeEach } from '@jest/globals';
import { YourPlugin } from '../../plugins/your-plugin.js';
describe('YourPlugin', () => {
let plugin: YourPlugin;
let mockContext: PluginContext;
beforeEach(() => {
plugin = new YourPlugin();
mockContext = createMockContext();
});
it('should initialize successfully', async () => {
await expect(plugin.initialize(mockContext)).resolves.not.toThrow();
});
it('should execute tool successfully', async () => {
const result = await plugin.handleToolCall('my_tool', {
input: 'test'
});
expect(result).toMatchObject({ success: true });
});
});
Coverage Goals:
The server provides comprehensive error handling with:
Contributions are welcome! This project is built on continuous learning and improvement.
Please read our Contributing Guidelines for detailed information on how to contribute to this project.
For detailed instructions, see CONTRIBUTING.md.
Command not found errors
Permission denied
Timeout errors
EOL/Newline validation issues
ensure_newline with mode: 'fix' to automatically correctvalidate mode in CI/CD to catch issues before commitEnable debug logging:
LOG_LEVEL=debug npm start
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
This project represents an ongoing effort to improve the developer experience when working with AI-powered coding assistants. All feedback and contributions help shape better development practices for the community.
Current Status: MVP 0.0.1 Released ✅
Active Development: 2025-Q2 - Plugin Architecture & Performance
Quick Overview:
Run in your terminal:
claude mcp add mcp-devtools-server -- npx Security
Low riskAutomated heuristic from public metadata — not a security guarantee.