PocketMCP
PocketMCP 是一个轻量级的、本地优先的MCP(模型上下文协议)服务器,它使用Transformers.js和MiniLM在本地自动监视文件夹、块和嵌入文件,将向量存储在SQLite+SQLite vec中,并向VS Code和Cursor公开语义搜索功能。专为在初始型号下载后无外部依赖性的小型机器(我在16GB RAM的Intel N100上运行)而设计。
特性
- 🔍 语义搜索:按含义查找内容,而不仅仅是关键字
- 📁 自动摄入:监视文件夹并自动处理新的/更改的文件
- 📄 多格式支持:PDF、DOCX、Markdown和纯文本文件
- ⚡ 本地优先:在初始模型下载后完全脱机运行
- 🗄️ SQLite存储:具有sqlite-vec扩展的快速、可靠的矢量存储
- 🔧 MCP集成:通过MCP协议原生支持VS代码和游标
- 🌐 web界面:内置网络测试仪,用于验证和手动测试
- 💾 高效:专为资源受限的环境而设计
- 🔄 实时:具有智能并发限制的取消暂停文件监视
- 📊 智能细分:页面感知PDF处理和节感知DOCX处理
- 🛡️ 稳健的错误处理:妥善处理加密、损坏或超大文件
建筑
flowchart TD
subgraph "MCP Clients"
A[VS Code]
B[Cursor]
end
subgraph "Web Interface"
W1[React Frontend
:5173]
W2[Express API
:5174]
end
subgraph "PocketMCP Server"
C[MCP Server
stdio transport]
D[File Watcher
chokidar]
E[Text Chunker
~1000 chars]
F[Embeddings
Transformers.js
MiniLM-L6-v2]
G[SQLite + sqlite-vec
Vector Database]
end
subgraph "File System"
H[Watch Directory
./kb/]
I[Data Directory
./data/]
end
A -.->|MCP Tools| C
B -.->|MCP Tools| C
W1 -->|HTTP API| W2
W2 -->|Database Access| G
C --> D
D -->|File Changes| E
E -->|Text Chunks| F
F -->|384-dim Vectors| G
G -.->|Search Results| C
D -.->|Monitors| H
G -.->|Stores in| I
classDef mcpClient fill:#e1f5fe
classDef webInterface fill:#fff3e0
classDef server fill:#f3e5f5
classDef storage fill:#e8f5e8
class A,B mcpClient
class W1,W2 webInterface
class C,D,E,F,G server
class H,I storage性能和限制
- 甜蜜点:中等硬件上的10K-100K块
- 查询延迟:低于100毫秒 `top_k kb/test.md
echo "This is a sample document for testing PocketMCP." >> kb/test.md
### 4.启动服务器
Development - MCP server + web interface
pnpm dev
Production - MCP server only
pnpm build && pnpm start
第一次运行时,服务器将下载MiniLM模型(~100MB),然后处理watch目录中的任何文件。
## Web测试器
PocketMCP包括一个用于测试和验证的全面web界面。
### 接入点
- **web界面**: http://127.0.0.1:5173
- **API服务器**: http://127.0.0.1:5174
- **健康检查**: http://127.0.0.1:5174/health
### 特性
#### 📊 数据库诊断面板
- 实时数据库状态监控
- 表计数和向量维度
- SQLite WAL模式验证
- 错误检测和报告
- 一键式烟雾测试
#### 🔍 搜索面板
- 交互式语义搜索测试
- LIKE与矢量搜索模式
- 可配置的结果计数(前K)
- 详细结果检查
- 性能指标(响应时间)
#### 📄 文档面板
- 浏览所有索引文档
- 分页支持
- 文档元数据显示
- 创建和更新时间戳
#### 🔎 块查看器
- 详细的块检测模式
- 全文内容显示
- 元数据和偏移信息
- 复制到剪贴板功能
### API终点
|端点|方法|描述|
|----------|--------|-------------|
| `/health` |GET|服务器健康检查|
| `/api/db/diag` |GET |数据库诊断|
| `/api/search` |POST |语义搜索|
| `/api/chunk/:id` |GET |获取特定块|
| `/api/docs` |GET |列出文档|
### API使用示例
**搜索文档:**
curl -X POST http://127.0.0.1:5174/api/search \ -H "Content-Type: application/json" \ -d '{"query": "machine learning", "top_k": 5, "mode": "like"}'
**获取诊断:**
curl http://127.0.0.1:5174/api/db/diag | jq .
## 🔧 MCP客户端集成
### 光标集成
1. 打开 **光标设置** → **主控程序**
1. 添加新服务器:
{ "command": "pnpm", "args": ["dev:mcp"], "cwd": "/path/to/PocketMCP", "env": { "TRANSPORT": "stdio", "SQLITE_PATH": "./data/index.db", "WATCH_DIR": "./kb" } }
### VS代码集成
添加到MCP设置中:
{ "mcpServers": { "pocketmcp": { "command": "pnpm", "args": ["dev:mcp"], "cwd": "/path/to/PocketMCP", "env": { "TRANSPORT": "stdio", "SQLITE_PATH": "./data/index.db", "WATCH_DIR": "./kb" } } } }
### HTTP传输(Web客户端)
对于web客户端或远程访问:
{ "mcpServers": { "pocketmcp": { "transport": "http", "url": "http://localhost:8001/mcp" } } }
## 📚 api参考
### MCP工具
#### `search`
使用语义搜索搜索类似内容。
{ "query": "machine learning algorithms", "top_k": 5, "filter": { "doc_ids": ["doc_123", "doc_456"] } }
#### `upsert_documents`
以编程方式插入或更新文档。
{ "docs": [ { "text": "Your document content here...", "external_id": "my_doc_1", "title": "Important Notes", "metadata": {} } ] }
#### `delete_documents`
按ID删除文档。
{ "doc_ids": ["doc_123"], "external_ids": ["my_doc_1"] }
#### `list_documents`
列出所有带页码的文档。
{ "page": { "limit": 20 } }
### MCP资源
PocketMCP提供用于访问特定块的资源URI:
- **格式**: `mcp+doc://#`
- **退货**:完整的块数据,包括文本、偏移量和元数据
## 配置
### 环境变量
|变量|默认值|描述|
|----------|---------|-------------|
| `SQLITE_PATH` | `./data/index.db` |SQLite数据库文件的路径|
| `WATCH_DIR` |(无)|要监视文件更改的目录|
| `MODEL_ID` | `Xenova/all-MiniLM-L6-v2` |用于嵌入的拥抱人脸模型|
| `CHUNK_SIZE` | `1000` |目标块大小(以字符为单位)|
| `CHUNK_OVERLAP` | `120` |字符块之间的重叠|
| `PDF_MAX_PAGES` | `300` |PDF文件中可处理的最大页数|
| `PDF_MIN_TEXT_CHARS` | `500` |PDF中所需的最小文本字符数|
| `DOC_MAX_BYTES` | `10000000` |DOCX文件的最大文件大小(10MB)|
| `DOCX_SPLIT_ON_HEADINGS` | `false` |按标题拆分DOCX文档(h1/h2)|
| `NODE_ENV` | `development` |环境模式|
| `VERBOSE_LOGGING` | `false` |启用详细日志|
| `DEBUG_DOTENV` | `false` |启用dotenv调试输出|
| `API_PORT` | `5174` |Web API服务器端口|
| `API_BIND` | `127.0.0.1` |API服务器绑定地址|
| `TRANSPORT` | `both` |MCP传输模式(stdio/http/两者)|
| `HTTP_HOST` | `0.0.0.0` |HTTP服务器绑定地址|
| `HTTP_PORT` | `8001` |MCP服务器端口|
| `LOG_LEVEL` | `info` |日志记录级别(调试/信息/警告/错误)|
### 可用脚本
|脚本|描述|
|--------|-------------|
| `pnpm dev` |启动web界面+API服务器进行测试|
| `pnpm dev:mcp` |启动MCP服务器(传输+文件监视)|
| `pnpm build` |构建所有组件|
| `pnpm start` |启动生产MCP服务器(传输+文件监视)|
| `pnpm setup` |从模板创建.env|
| `pnpm clean` |清理构建工件和数据库|
### 观看目录
- **`WATCH_DIR` 是可选的** -如果未设置,则仅手动文档会中断工作
- **支持的文件**: `.md`, `.txt`, `.pdf`, `.docx`
- **文件过滤**:自动忽略临时文件, `.DS_Store`, `node_modules`等等。
- **嵌套目录**:递归地监视所有子目录
### 文档处理
**加工管道:** 文件→ 片段→ 块
1. **文件**:包含元数据的顶级文件
1. **片段**:逻辑划分(PDF页面、DOCX部分等)
1. **块**:针对嵌入进行了优化的文本片段(~1000个字符)
**状态类型:** `ok`, `skipped`, `needs_ocr`, `too_large`, `error`
### 支持的文件类型
- **降价** (`.md`)
- **纯文本** (`.txt`)
- **可移植文档格式** (`.pdf`)-仅基于文本,无OCR
- **文档** (`.docx`)-Microsoft Word文档
**笔记:**
- 跳过加密/密码保护的文件
- 超出限制的大文件标记为 `too_large`
- 需要OCR的扫描PDF标记为 `needs_ocr`
## 发展
### 项目结构
PocketMCP/ # Monorepo root ├── package.json # Workspace configuration ├── pnpm-workspace.yaml # pnpm workspace setup ├── .env # Environment variables ├── .env.sample # Environment template ├── apps/ │ ├── api/ # Express API server │ │ ├── src/ │ │ │ ├── server.ts # Main API server │ │ │ └── db.ts # Database manager │ │ └── package.json │ └── web/ # React + Vite frontend │ ├── src/ │ │ ├── App.tsx # Main app component │ │ ├── store.ts # Zustand state management │ │ ├── api.ts # API client │ │ └── components/ # UI components │ └── package.json ├── src/ # Original MCP server │ ├── server.ts # MCP server and main entry point │ ├── db.ts # SQLite database with sqlite-vec │ ├── embeddings.ts # Transformers.js embedding pipeline │ ├── chunker.ts # Text chunking with sentence awareness │ ├── ingest.ts # Generic document ingestion │ ├── file-ingest.ts # File-specific ingestion logic │ └── watcher.ts # File system watcher with debouncing ├── data/ # SQLite database storage ├── kb/ # Default watch directory (configurable) └── README.md
### 开发命令
Install and setup
pnpm install pnpm setup
Development
pnpm dev # Web interface + API pnpm dev:mcp # MCP server only
Production
pnpm build pnpm start
Testing
curl http://127.0.0.1:5174/health
## 部署
### Docker(推荐)
**快速入门:**
Pull and run with all services (MCP + API + Web UI)
docker run -d \ --name pocketmcp \ --restart unless-stopped \ -p 8001:8001 \ -p 5174:5174 \ -p 5173:5173 \ -v pocketmcp_data:/app/data \ -v pocketmcp_kb:/app/kb \ -v pocketmcp_cache:/app/.cache \ ghcr.io/kailash-sankar/pocketmcp:latest
**接入点:**
- **MCP服务器**: `http://localhost:8001`
- **API服务器**: `http://localhost:5174`
- **Web用户界面**: `http://localhost:5173`
**Docker编写:**
git clone https://github.com/kailash-sankar/PocketMCP.git cd PocketMCP cp .env.sample .env docker-compose up -d
### Portainer堆叠
1. 首选 **堆栈** → **添加堆栈**
1. 姓名: `pocketmcp`
1. 粘贴此配置:
version: '3.8' services: pocketmcp: image: ghcr.io/kailash-sankar/pocketmcp:latest container_name: pocketmcp restart: unless-stopped ports: - "8001:8001" # MCP Server - "5174:5174" # API Server - "5173:5173" # Web UI volumes: - pocketmcp_data:/app/data - pocketmcp_kb:/app/kb - pocketmcp_cache:/app/.cache environment: - NODE_ENV=production - TRANSPORT=both - SQLITE_PATH=/app/data/index.db - WATCH_DIR=/app/kb healthcheck: test: ["CMD", "curl", "-f", "http://localhost:5173/health"] interval: 30s timeout: 10s retries: 3 start_period: 60s
volumes: pocketmcp_data: pocketmcp_kb: pocketmcp_cache:
### 直接安装
Clone and setup
git clone https://github.com/kailash-sankar/PocketMCP.git cd PocketMCP pnpm install pnpm setup
Configure environment
cp .env.sample .env
Edit .env with your settings
Create content directory
mkdir -p kb
Build and start
pnpm build pnpm start
**接入点:**
- **MCP服务器**: `http://localhost:8001`
- **API服务器**: `http://localhost:5174`
- **Web用户界面**: `http://localhost:5173`
## 故障排除
### 模型下载问题
如果嵌入模型下载失败:
- 检查初始下载的互联网连接
- 模型缓存位置: `~/.cache/huggingface/transformers/`
- 清除缓存,必要时重试
### SQLite扩展问题
如果 `sqlite-vec` 无法加载:
- 确保 `sqlite-vec` npm包已安装
- 检查您的系统是否支持所需的SQLite版本
- 如果vec0虚拟表失败,系统会自动回退到常规SQLite表
### 文件监视问题
- **未检测到文件**:检查文件扩展名并忽略模式
- **CPU使用率高**:使用较大的值增加去抖动时间 `debounceMs` 价值观
- **权限错误**:确保对监视和数据目录的读/写访问权限
### Web界面问题
- **无法访问API**:确保API服务器正在端口5174上运行
- **找不到数据库**:检查 `SQLITE_PATH` 环境变量
- **CORS 错误**:API服务器包含用于本地开发的CORS头
### 内存问题
- 减少 `CHUNK_SIZE` 降低内存使用率
- 通过减少同时处理的文件数量 `maxConcurrency`
- 考虑使用较小的嵌入模型(尽管这需要更改代码)
### 常见错误消息
**“提供的参数值太多”**
- 这是sqlite-vec虚拟表的一个已知问题,现在已通过自动回退修复
**“加载sqlite-vec扩展失败”**
- 系统自动回退到具有JSON嵌入的常规SQLite表
**“数据库文件不存在”**
- 首先运行MCP服务器以创建数据库,或检查 `SQLITE_PATH`
## 许可证
MIT许可证-有关详细信息,请参阅许可证文件。
## 贡献
1. 分叉存储库
1. 创建要素分支
1. 进行更改
1. 如果适用,添加测试
1. 提交拉取请求
## 致谢
- **sqlite-vc** 用于快速向量相似性搜索
- **Transformers.js** 用于本地嵌入生成
- **模型上下文协议** 用于标准化工具集成
- **拥抱脸** 对于MiniLM模型
- **反应+快速** 现代网络界面
- **尾风CSS** 追求美观、灵敏的造型