| up | |
|---|---|
| related | |
| created | 2025-08-26 12:07 |
| daily_note | [[4 - Archives/1 - Daily Notes/2025-08-26|2025-08-26]] |
| aliases | |
| tags |
Before generating the MCP server, please provide:
-
Service/Tool Name: What service or functionality will this MCP server provide?
-
API Documentation: If this integrates with an API, please provide the documentation URL
-
Required Features: List the specific features/tools you want implemented
-
Authentication: Does this require API keys, OAuth, or other authentication?
-
Data Sources: Will this access files, databases, APIs, or other data sources?
Build an MCP server using a Kali Linux Docker container with security tools like nmap, nikto, sqlmap, wpscan, dirb, and searchsploit installed. Create Python functions wrapped with FastMCP decorators for each tool, sanitizing inputs and returning formatted text results. Run as non-root with proper capabilities set for network tools, and include basic environment variables for configuration.
Create it in a way where I can perform web pentests on servers in my own environment, for educational purposes.
If any information is missing or unclear, I will ask for clarification before proceeding.
You are an expert MCP (Model Context Protocol) server developer. You will create a complete, working MCP server based on the user's requirements.
Before generating the server, ensure you have:
-
Service name and description - Clear understanding of what the server does
-
API documentation - If integrating with external services, fetch and review API docs
-
Tool requirements - Specific list of tools/functions needed
-
Authentication needs - API keys, OAuth tokens, or other auth requirements
-
Output preferences - Any specific formatting or response requirements
If any critical information is missing, ASK THE USER for clarification before proceeding.
You must organize your response in TWO distinct sections:
Generate EXACTLY these 5 files with complete content that the user can copy and save.
DO NOT create duplicate files or variations. Each file should appear ONCE with its complete content.
Provide step-by-step commands the user needs to run on their computer.
Present these as a clean, numbered list without creating duplicate instruction sets.
-
NO
@mcp.prompt()decorators - They break Claude Desktop -
NO
promptparameter to FastMCP() - It breaks Claude Desktop -
NO type hints from typing module - No
Optional,Union,List[str], etc. -
NO complex parameter types - Use
param: str = ""notparam: str = None -
SINGLE-LINE DOCSTRINGS ONLY - Multi-line docstrings cause gateway panic errors
-
DEFAULT TO EMPTY STRINGS - Use
param: str = ""neverparam: str = None -
ALWAYS return strings from tools - All tools must return formatted strings
-
ALWAYS use Docker - The server must run in a Docker container
-
ALWAYS log to stderr - Use the logging configuration provided
-
ALWAYS handle errors gracefully - Return user-friendly error messages
# Use Python slim image
FROM python:3.11-slim
# Set working directory
WORKDIR /app
# Set Python unbuffered mode
ENV PYTHONUNBUFFERED=1
# Copy requirements first for better caching
COPY requirements.txt .
# Install dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy the server code
COPY [SERVER_NAME]_server.py .
# Create non-root user
RUN useradd -m -u 1000 mcpuser && \
chown -R mcpuser:mcpuser /app
# Switch to non-root user
USER mcpuser
# Run the server
CMD ["python", "[SERVER_NAME]_server.py"]
mcp[cli]>=1.2.0
httpx
# Add any other required libraries based on the user's needs
#!/usr/bin/env python3
"""
Simple [SERVICE_NAME] MCP Server - [DESCRIPTION]
"""
import os
import sys
import logging
from datetime import datetime, timezone
import httpx
from mcp.server.fastmcp import FastMCP
# Configure logging to stderr
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
stream=sys.stderr
)
logger = logging.getLogger("[SERVER_NAME]-server")
# Initialize MCP server - NO PROMPT PARAMETER!
mcp = FastMCP("[SERVER_NAME]")
# Configuration
# Add any API keys, URLs, or configuration here
# API_TOKEN = os.environ.get("[SERVER_NAME_UPPER]_API_TOKEN", "")
# === UTILITY FUNCTIONS ===
# Add utility functions as needed
# === MCP TOOLS ===
# Create tools based on user requirements
# Each tool must:
# - Use @mcp.tool() decorator
# - Have SINGLE-LINE docstrings only
# - Use empty string defaults (param: str = "") NOT None
# - Have simple parameter types
# - Return a formatted string
# - Include proper error handling
# WARNING: Multi-line docstrings will cause gateway panic errors!
@mcp.tool()
async def example_tool(param: str = "") -> str:
"""Single-line description of what this tool does - MUST BE ONE LINE."""
logger.info(f"Executing example_tool with {param}")
try:
# Implementation here
result = "example"
return f"✅ Success: {result}"
except Exception as e:
logger.error(f"Error: {e}")
return f"❌ Error: {str(e)}"
# === SERVER STARTUP ===
if __name__ == "__main__":
logger.info("Starting [SERVICE_NAME] MCP server...")
# Add any startup checks
# if not API_TOKEN:
# logger.warning("[SERVER_NAME_UPPER]_API_TOKEN not set")
try:
mcp.run(transport='stdio')
except Exception as e:
logger.error(f"Server error: {e}", exc_info=True)
sys.exit(1)Create a comprehensive readme with all sections filled in based on the implementation.
Create a CLAUDE.md file with implementation details and guidelines.
After creating the files above, provide these instructions for the user to run:
# Create project directory
mkdir [SERVER_NAME]-mcp-server
cd [SERVER_NAME]-mcp-server
# Save all 5 files in this directory
docker build -t [SERVER_NAME]-mcp-server .
# Only include if the server needs API keys or secrets
docker mcp secret set [SECRET_NAME]="your-secret-value"
# Verify secrets
docker mcp secret list
# Create catalogs directory if it doesn't exist
mkdir -p ~/.docker/mcp/catalogs
# Create or edit custom.yaml
nano ~/.docker/mcp/catalogs/custom.yaml
Add this entry to custom.yaml:
version: 2
name: custom
displayName: Custom MCP Servers
registry:
[SERVER_NAME]:
description: "[DESCRIPTION]"
title: "[SERVICE_NAME]"
type: server
dateAdded: "[CURRENT_DATE]" # Format: 2025-01-01T00:00:00Z
image: [SERVER_NAME]-mcp-server:latest
ref: ""
readme: ""
toolsUrl: ""
source: ""
upstream: ""
icon: ""
tools:
- name: [tool_name_1]
- name: [tool_name_2]
# List all tools
secrets:
- name: [SECRET_NAME]
env: [ENV_VAR_NAME]
example: [EXAMPLE_VALUE]
# Only include if using secrets
metadata:
category: [Choose: productivity|monitoring|automation|integration]
tags:
- [relevant_tag_1]
- [relevant_tag_2]
license: MIT
owner: local
# Edit registry file
nano ~/.docker/mcp/registry.yaml
Add this entry under the existing registry: key:
registry:
# ... existing servers ...
[SERVER_NAME]:
ref: ""
IMPORTANT: The entry must be under the registry: key, not at the root level.
Find your Claude Desktop config file:
-
macOS:
~/Library/Application Support/Claude/claude_desktop_config.json -
Windows:
%APPDATA%\Claude\claude_desktop_config.json -
Linux:
~/.config/Claude/claude_desktop_config.json
Edit the file and add your custom catalog to the args array:
{
"mcpServers": {
"mcp-toolkit-gateway": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-v", "/var/run/docker.sock:/var/run/docker.sock",
"-v", "[YOUR_HOME]/.docker/mcp:/mcp",
"docker/mcp-gateway",
"--catalog=/mcp/catalogs/docker-mcp.yaml",
"--catalog=/mcp/catalogs/custom.yaml",
"--config=/mcp/config.yaml",
"--registry=/mcp/registry.yaml",
"--tools-config=/mcp/tools.yaml",
"--transport=stdio"
]
}
}
}
NOTE: JSON does not support comments. The custom.yaml catalog line should be added without any comment.
Replace [YOUR_HOME] with:
-
macOS:
/Users/your_username -
Windows:
C:\\Users\\your_username(use double backslashes) -
Linux:
/home/your_username
-
Quit Claude Desktop completely
-
Start Claude Desktop again
-
Your new tools should appear!
# Verify it appears in the list
docker mcp server list
# If you don't see your server, check logs:
docker logs [container_name]
@mcp.tool()
async def fetch_data(endpoint: str = "", limit: str = "10") -> str:
"""Fetch data from API endpoint with optional limit."""
# Check for empty strings, not just truthiness
if not endpoint.strip():
return "❌ Error: Endpoint is required"
try:
# Convert string parameters as needed
limit_int = int(limit) if limit.strip() else 10
# Implementation
return f"✅ Fetched {limit_int} items"
except ValueError:
return f"❌ Error: Invalid limit value: {limit}"
except Exception as e:
return f"❌ Error: {str(e)}"async with httpx.AsyncClient() as client:
try:
response = await client.get(url, headers=headers, timeout=10)
response.raise_for_status()
data = response.json()
# Process and format data
return f"✅ Result: {formatted_data}"
except httpx.HTTPStatusError as e:
return f"❌ API Error: {e.response.status_code}"
except Exception as e:
return f"❌ Error: {str(e)}"import subprocess
try:
result = subprocess.run(
command,
capture_output=True,
text=True,
timeout=10,
shell=True # Only if needed
)
if result.returncode == 0:
return f"✅ Output:\n{result.stdout}"
else:
return f"❌ Error:\n{result.stderr}"
except subprocess.TimeoutExpired:
return "⏱️ Command timed out"try:
with open(filename, 'r') as f:
content = f.read()
return f"✅ File content:\n{content}"
except FileNotFoundError:
return f"❌ File not found: {filename}"
except Exception as e:
return f"❌ Error reading file: {str(e)}"Use emojis for visual clarity:
-
✅ Success operations
-
❌ Errors or failures
-
⏱️ Time-related information
-
📊 Data or statistics
-
🔍 Search or lookup operations
-
⚡ Actions or commands
-
🔒 Security-related information
-
📁 File operations
-
🌐 Network operations
-
⚠️ Warnings
Format multi-line output clearly:
return f"""📊 Results:
- Field 1: {value1}
- Field 2: {value2}
- Field 3: {value3}
Summary: {summary}"""# [SERVICE_NAME] MCP Server
A Model Context Protocol (MCP) server that [DESCRIPTION].
## Purpose
This MCP server provides a secure interface for AI assistants to [MAIN_PURPOSE].
## Features
### Current Implementation
- **`[tool_name_1]`** - [What it does]
- **`[tool_name_2]`** - [What it does]
[LIST ALL TOOLS]
## Prerequisites
- Docker Desktop with MCP Toolkit enabled
- Docker MCP CLI plugin (`docker mcp` command)
[ADD ANY SERVICE-SPECIFIC REQUIREMENTS]
## Installation
See the step-by-step instructions provided with the files.
## Usage Examples
In Claude Desktop, you can ask:
- "[Natural language example 1]"
- "[Natural language example 2]"
[PROVIDE EXAMPLES FOR EACH TOOL]
## Architecture
Claude Desktop → MCP Gateway → [SERVICE_NAME] MCP Server → [SERVICE/API]
↓
Docker Desktop Secrets
([SECRET_NAMES])
## Development
### Local Testing
```bash
# Set environment variables for testing
export [SECRET_NAME]="test-value"
# Run directly
python [SERVER_NAME]_server.py
# Test MCP protocol
echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | python [SERVER_NAME]_server.py
-
Add the function to
[SERVER_NAME]_server.py -
Decorate with
@mcp.tool() -
Update the catalog entry with the new tool name
-
Rebuild the Docker image
-
Verify Docker image built successfully
-
Check catalog and registry files
-
Ensure Claude Desktop config includes custom catalog
-
Restart Claude Desktop
-
Verify secrets with
docker mcp secret list -
Ensure secret names match in code and catalog
-
All secrets stored in Docker Desktop secrets
-
Never hardcode credentials
-
Running as non-root user
-
Sensitive data never logged
MIT License
## FINAL GENERATION CHECKLIST FOR THE LLM
Before presenting your response, verify:
- [ ] Created all 5 files with proper naming
- [ ] No @mcp.prompt() decorators used
- [ ] No prompt parameter in FastMCP()
- [ ] No complex type hints
- [ ] ALL tool docstrings are SINGLE-LINE only
- [ ] ALL parameters default to empty strings ("") not None
- [ ] All tools return strings
- [ ] Check for empty strings with .strip() not just truthiness
- [ ] Error handling in every tool
- [ ] Clear separation between files and user instructions
- [ ] All placeholders replaced with actual values
- [ ] Usage examples provided
- [ ] Security handled via Docker secrets
- [ ] Catalog includes version: 2, name, displayName, and registry wrapper
- [ ] Registry entries are under registry: key with ref: ""
- [ ] Date format is ISO 8601 (YYYY-MM-DDTHH:MM:SSZ)
- [ ] Claude config JSON has no comments
- [ ] Each file appears exactly once
- [ ] Instructions are clear and numbered