内容
# MCP 服务器
一个流式HTTP模块化服务器,提供文件系统、网页浏览和Shell命令执行等工具。
## 📋 功能列表
### 可用工具
| 工具 | 描述 |
|------|-----------|
| `file-glob` | 浏览目录并以分层结构列出文件/子目录 |
| `read-file` | 读取文本文件的内容 |
| `create-file` | 创建一个新文件并指定内容(支持覆盖) |
| `edit-file` | 编辑现有文件并替换特定文本(支持replaceAll) |
| `grep` | 在多个文件中搜索模式(文本/正则表达式)并支持通配符 |
| `scrape_url` | 抓取URL并提取HTML页面的可见文本 |
| `websearch` | 使用DuckDuckGo进行网页搜索并返回结果(标题、URL和摘要) |
| `execute_command` | 执行安全的Shell命令(允许命令白名单) |
---
## 🚀 安装
### 前置条件
- Node.js 18+
- npm 或 yarn
### 步骤
```bash
# 克隆仓库(如果适用)
git clone <your-repo-url>
cd mcp-http
# 安装依赖
npm install
# 构建项目
npm run build
```
---
## 📝 使用
### 开发模式
```bash
npm run dev
```
### 生产环境
```bash
npm run build
npm start
```
### 环境变量
| 变量 | 默认值 | 描述 |
|----------|--------|-----------|
| `PORT` | `3001` | HTTP服务器端口 |
---
## 🔧 MCP 配置
### 对于 Claude Desktop
将以下内容添加到 `claude_desktop_config.json` 文件中:
```json
{
"mcpServers": {
"web-scraper": {
"url": "http://localhost:3001/mcp"
}
}
}
```
### 对于其他 MCP 客户端
```json
{
"type": "http",
"url": "http://localhost:3001/mcp"
}
```
---
## 🛠️ 工具文档
### `file-glob`
浏览目录并列出文件和子目录。
**参数:**
```typescript
{
path: string, // 目录路径
maxDepth: number // 最大深度(1-10,默认为3)
}
```
**使用示例:**
```json
{
"name": "file-glob",
"arguments": {
"path": "/Users/rafaelss8/Projetos/Pessoal/mcp-http/src",
"maxDepth": 3
}
}
```
**响应:**
```json
{
"path": "/Users/rafaelss8/Projetos/Pessoal/mcp-http/src",
"maxDepth": 3,
"directories": ["(no subdirectories)"],
"files": ["index.ts"],
"summary": "Found 0 directory(ies) and 1 file(s)"
}
```
---
### `read-file`
读取文件内容。
**参数:**
```typescript
{
path: string, // 文件路径
encoding: string // 编码(默认为"utf-8")
}
```
**使用示例:**
```json
{
"name": "read-file",
"arguments": {
"path": "/Users/rafaelss8/Projetos/Pessoal/mcp-http/src/index.ts"
}
}
```
---
### `create-file`
创建新文件并指定内容。创建父目录如果它们不存在。除非设置`overwrite`为`true`,否则不会覆盖现有文件。
**参数:**
```typescript
{
path: string, // 文件路径
content: string, // 文件内容
encoding: string // 编码(默认为"utf-8")
}
```
**使用示例:**
```json
{
"name": "create-file",
"arguments": {
"path": "/Users/rafaelss8/Projetos/Pessoal/mcp-http/src/new-file.ts",
"content": "console.log('Hello World');"
}
}
```
**响应:**
```
File created successfully at: /Users/rafaelss8/Projetos/Pessoal/mcp-http/src/new-file.ts
```
---
### `edit-file`
编辑现有文件并替换特定文本。`oldText`必须与文件内容完全匹配。
**参数:**
```typescript
{
path: string, // 文件路径
oldText: string, // 要替换的文本(留空以追加)
newText: string, // 替换文本(留空以删除)
encoding: string // 编码(默认为"utf-8")
}
```
**使用示例:**
```json
{
"name": "edit-file",
"arguments": {
"path": "/Users/rafaelss8/Projetos/Pessoal/mcp-http/src/index.ts",
"oldText": "console.log('Hello')",
"newText": "console.log('Hello World')"
}
}
```
**响应:**
```
File edited successfully at: /Users/rafaelss8/Projetos/Pessoal/mcp-http/src/index.ts
Replaced text with: console.log('Hello World')
```
---
### `scrape_url`
抓取URL并返回页面可见文本。
**参数:**
```typescript
{
url: string, // 要抓取的URL
max_length: number // 最大字符数(100-500000,默认为10000)
}
```
**使用示例:**
```json
{
"name": "scrape_url",
"arguments": {
"url": "https://example.com",
"max_length": 10000
}
}
```
**响应:**
```
Page: Example Domain
URL: https://example.com
Example Domain
This domain is for use in illustrative examples in documents. You may use this
domain in examples without prior coordination or asking for permission.
```
---
## 🏗️ 架构
```
mcp-http/
├── src/
│ ├── index.ts # 入口点(bootstrap)
│ ├── server/
│ │ ├── express.ts # Express服务器配置 + CORS
│ │ └── mcpServer.ts # McpServer工厂
│ ├── tools/
│ │ ├── fsTools.ts # 文件系统工具(file-glob, read-file, create-file, edit-file, grep)
│ │ ├── webTools.ts # Web工具(scrape_url, websearch)
│ │ └── shellTools.ts # Shell工具(execute_command)
│ └── utils/
│ ├── fs.ts # FS实用工具(gitignore, exploreDirectory)
│ └── path.ts # 路径验证(anti path-traversal)
├── dist/ # 编译后的文件(构建后)
├── package.json # 依赖和脚本
├── tsconfig.json # TypeScript配置
└── README.md # 本文件
```
### 服务器流程
```
┌─────────────┐
│ Client │
│ (LLM/MCP) │
└──────┬──────┘
│ HTTP Request
▼
┌─────────────────┐
│ Express │
│ Middleware │
│ (CORS) │
└──────┬──────────┘
│
▼
┌─────────────────┐
│ StreamableHTTP │
│ ServerTransport│
└──────┬──────────┘
│
▼
┌─────────────────┐
│ McpServer │
│ (8 Tools) │
│ • file-glob │
│ • read-file │
│ • create-file │
│ • edit-file │
│ • grep │
│ • scrape_url │
│ • websearch │
│ • exec_command │
└─────────────────┘
```
### 最近的改进
- **模块化架构**:代码组织成单独的模块,按职责划分
- **安全验证**:防止路径穿越(`validatePathInWorkspace`)
- **有状态会话**:MCP传输存储在会话中以实现持久连接
- **create-file**:通过`overwrite`参数支持覆盖
- **edit-file**:通过`replaceAll`参数支持部分替换
---
## ⚙️ 可用脚本
| 命令 | 描述 |
|---------|-----------|
| `npm run build` | 编译TypeScript为JavaScript |
| `npm run dev` | 以开发模式启动服务器 |
| `npm start` | 以生产模式启动服务器 |
---
## 🔒 安全
### 安全限制
| 工具 | 限制 |
|------|------------|
| `file-glob` | 仅限读取,最大深度10层 |
| `read-file` | 仅限读取文本文件 |
| `create-file` | 默认不覆盖现有文件(`wx`标志)。使用`overwrite: true`强制覆盖 |
| `edit-file` | 在编辑前验证`oldText`存在 |
| `grep` | 尊重`.gitignore`,限制结果为1000个匹配 |
| `scrape_url` | 15秒超时,定义User-Agent |
| `websearch` | 10秒超时,使用DuckDuckGo作为搜索引擎 |
| `execute_command` | 命令白名单,可配置超时,限制在工作区内 |
### 路径验证(防路径穿越)
所有操作文件系统的工具都经过`validatePathInWorkspace`函数验证,确保:
- 解析路径保持在`workspaceRoot`内
- 阻止通过`../`尝试逃逸
- 不允许访问工作区外的敏感文件
---
## 📊 依赖
### 生产环境
- `@modelcontextprotocol/sdk` - 官方MCP SDK
- `express` - HTTP框架
- `cheerio` - HTML操作
- `zod` - 模式验证
### 开发环境
- `tsx` - TypeScript执行
- `typescript` - 类型检查
- `@types/*` - 类型定义
---
## 🐛 调试
### 服务器日志
服务器输出stderr日志:
```
[mcp] POST /mcp sessionId=xxx
[mcp] Request handled. Session: xxx
```
### 测试端点
```bash
curl -X POST http://localhost:3001/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'
```
---
## 📄 许可证
MIT
---
## 🤝 贡献
1. Fork项目
2. 创建分支(`git checkout -b feature/AmazingFeature`)
3. 提交更改(`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支(`git push origin feature/AmazingFeature`)
5. 打开Pull Request