Content
# 📘 MCP Server Development Guide (Master SOP)
**Version**: 1.0
**For**: MCP Developers (Python/Node.js)
**Objective**: To standardize the complete lifecycle of Model Context Protocol tools from development to release, avoiding common errors.
---
## Table of Contents
1. [🟢 Python Development Process (Recommended)](#1-python-development-process-recommended)
2. [🟡 Node.js Development Process](#2-nodejs-development-process)
3. [🔵 Client Configuration Guide (Cursor/Claude)](#3-client-configuration-guide-cursorclaude)
4. [🔴 Pitfall Guide and Best Practices (Must-Read)](#4-pitfall-guide-and-best-practices-must-read)
5. [📄 Appendix: Project README.md Template](#5-appendix-project-readmemd-template)
---
## 1. Python Development Process (Recommended)
Python with the `fastmcp` library is currently the most efficient development method and the focus of this SOP.
### 1.1 Directory Structure Specification (Core)
⚠️ **Warning**: Do not scatter code in the root directory! A package folder must be created; otherwise, `uvx` installation will not import modules correctly.
**Standard Structure Example:**
```plaintext
my-project-root/ # Project root directory
├── pyproject.toml # Core configuration file (must exist)
├── README.md # Project description document (displayed on PyPI after release)
└── my_tool_pkg/ # Source code package folder (suggest using underscores for naming)
├── __init__.py # Identifier file (must exist, content can be empty)
├── main.py # Entry file (defines MCP service)
└── utils.py # Business logic file
```
### 1.2 Code Writing Specification
Entry file (`main.py`) import rules:
Python
```python
from fastmcp import FastMCP
# ⚠️ Key point: relative imports must be used within the package
# ❌ Incorrect: import utils
# ✅ Correct: from . import utils
from . import utils
# Initialize service
mcp = FastMCP("My Tool Name")
@mcp.tool()
def my_feature(arg: str) -> str:
"""
Write a detailed functional description here.
AI relies entirely on this comment to understand the tool's role, so it must be detailed.
"""
return utils.process(arg)
```
Logging specification:
❌ **Prohibited**: Use `print()`; it will break the MCP JSON communication protocol, causing connection disconnection.
✅ **Required**: Use `sys.stderr.write("Log info...\n")` to print debug information.
### 1.3 Configuration File Details (pyproject.toml)
Please copy the following template and modify the fields according to the comments:
Ini, TOML
```ini
# ================= Build system configuration (keep default) =================
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
# ================= Project basic information =================
[project]
# 1. Package name: unique PyPI identifier, must be unique across the web. Suggested format: id-toolname
name = "jd-excel-mcp"
# 2. Version number: must increment with each release (e.g., 0.1.0 -> 0.1.1); otherwise, upload will fail
version = "0.1.0"
# 3. Description and author
description = "A powerful Excel MCP tool"
authors = [
{ name = "Your Name", email = "your@email.com" },
]
# 4. Dependency list: list all third-party libraries used in the code
dependencies = [
"fastmcp",
"pandas",
"openpyxl"
]
# ================= Command-line entry configuration (critical) =================
[project.scripts]
# Format: command name = "package folder name.file name: instance name.run"
# Left: command called by uvx runtime
# Right: Python interpreter path to find the object
your-tool-command = "my_tool_pkg.main:mcp.run"
# ================= Packaging target configuration (critical) =================
[tool.hatch.build.targets.wheel]
# Tell the packaging tool where the source code is; must match your package folder name
packages = ["my_tool_pkg"]
```
### 1.4 Local Debugging (Debug)
Before releasing to PyPI, test locally in Cursor to save time.
Cursor configuration (pointing to local files):
JSON
```json
{
"mcpServers": {
"LocalTest": {
"command": "python3",
"args": ["/your/project/absolute/path/my_tool_pkg/main.py"],
"env": { "PYTHONUTF8": "1" },
"type": "stdio"
}
}
}
```
### 1.5 Packaging and Release (Publish)
Ensure local testing passes, then follow the standard "modify version - clean - build - release" steps.
Modify version: Open `pyproject.toml` and change the version to the new one (e.g., 0.1.1).
Clean old builds (important to prevent leftover files):
Bash
```bash
rm -rf dist
```
Build new package:
Bash
```bash
python3 -m hatch build
```
(After success, a `.whl` file will be generated in the `dist/` directory)
Publish to PyPI:
Bash
```bash
python3 -m hatch publish
Username: __token__
Password: pypi-xxxxxxxx... (your API Token)
```
## 2. Node.js Development Process
Suitable for web integration or front-end developers.
### 2.1 Initialization
Bash
```bash
mkdir my-node-mcp && cd my-node-mcp
npm init -y
npm install @modelcontextprotocol/sdk zod
```
### 2.2 package.json Key Configuration
Ensure adding the `bin` field and `type: module`.
JSON
```json
{
"name": "my-node-tool",
"version": "1.0.0",
"type": "module",
"bin": {
"my-tool": "./build/index.js"
},
"dependencies": {
"@modelcontextprotocol/sdk": "...",
"zod": "..."
}
}
```
### 2.3 Release
Bash
```bash
npm login
npm publish --access public
```
## 3. Client Configuration Guide (Cursor/Claude)
Regardless of Python or Node.js, the configuration logic in Cursor/Claude after release is consistent. Use `uvx` (Python) or `npx` (Node) to run.
Recommended configuration (JSON):
JSON
```json
{
"mcpServers": {
"MyCloudTool": {
"command": "uvx",
"args": [
"--refresh", // 1. Force refresh cache (essential during development and debugging)
"your-package-name" // 2. PyPI package name
// or lock version: "your-package-name==0.1.5"
],
"env": {
"PYTHONUTF8": "1" // 3. Solve Chinese character encoding issues
},
"type": "stdio",
"timeout": 120 // 4. Prevent timeout during first dependency download
}
}
}
```
## 4. Pitfall Guide and Best Practices (Must-Read)
🛑 Common errors and solutions
### ModuleNotFoundError: No module named 'utils'
Cause: Used `import utils` in `main.py`.
Solution: Change to relative import `from . import utils`.
### 400 File already exists
Cause: Attempted to release a version that already exists.
Solution: Modify the `version` field in `pyproject.toml`.
### Release includes old files / Upload Failed
Cause: Did not delete the `dist/` folder before release, causing old package files to be included.
Solution: Always run `rm -rf dist` before each release.
### Cursor cannot find the tool / displays old tool
Cause: `uvx` used local cache and did not download the newly released version.
Solution: Add `--refresh` to the configuration `args` or specify the version number directly, e.g., `name==0.1.x`.
✅ Best practices
* Docstring is the soul: write clear comments for each `@mcp.tool` function; this is AI's only basis for identifying tool capabilities.
* Type Hint: strictly mark parameter types (e.g., `arg: str`, `limit: int`); AI generates JSON Schema based on this.
* Environment: always add `PYTHONUTF8: 1` to avoid crashes when processing Chinese data.
## 5. Appendix: Project README.md Template
Copy the following content to your project's README.md; PyPI homepage will display it automatically, making your project look very professional.
Markdown
```markdown
# 📊 [Project Name] - MCP Server
[](https://pypi.org/project/your-package-name/)
[](https://opensource.org/licenses/MIT)
This is a toolset based on [Model Context Protocol (MCP)](https://modelcontextprotocol.io/), allowing large models (Cursor, Claude) to directly call local functions, implementing [describe main functions, e.g., automate Excel operations].
## ✨ Feature List
* **Feature A**: [Describe the role of Feature A]
* **Feature B**: [Describe the role of Feature B]
## 🚀 Quick Start
### 1. Cursor / Claude Desktop Configuration
Add the following content to MCP `settings.json` without manually downloading code:
```json
{
"mcpServers": {
"MyTool": {
"command": "uvx",
"args": [
"--refresh",
"your-package-name"
],
"env": {
"PYTHONUTF8": "1"
},
"type": "stdio",
"timeout": 120
}
}
}
```
### 2. Manual Terminal Testing
Before configuration, it's recommended to run once in the terminal to cache the environment:
```bash
uvx your-package-name
```
## 🛠 Development and Contribution
1. Clone the repository
2. Install dependencies: `pip install -r requirements.txt`
3. Local debugging: `python3 my_pkg/main.py`
## 📄 License
MIT License
```