1. 系统概述
1.1 什么是 Jarvis 系统?
Jarvis 是一个基于 Claude Code SDK + 飞书 + 云服务器 的智能自动化平台,具备:
- 对话能力:通过飞书机器人与 Claude 对话,自然语言交互
- 工具能力:MCP 协议扩展能力,文件操作、数据库、API 调用
- 自动化:定时任务、事件触发、工作流编排
- 部署能力:/build 指令一键生成和部署网站
1.2 核心价值对比
| 传统方案 | Jarvis 方案 |
|---|---|
| 手动 SSH 登录服务器 | 飞书对话直接操作 |
| 手动编写部署脚本 | /build 自动生成部署 |
| 分散的工具和数据 | MCP 统一工具层 |
| 无记忆的单次对话 | 跨会话持久记忆 |
1.3 适用场景
- 个人/小团队的运维自动化
- 内容创作辅助(选题推荐、脚本生成)
- 快速原型开发和部署
- 数据采集和处理流水线
2. 架构原理
2.1 整体架构图
用户交互层
- 飞书 App (手机/桌面)
- 飞书 Web (浏览器)
- 本地 Claude Code CLI
↓ WebSocket / 本地进程
网关层 (Gateway)
- FeishuClient - 消息处理、会话管理
- ClaudeClient - Claude SDK 调用
- TaskExecutor - /build 任务执行
- Deployer - Nginx + PM2 部署
↓
智能层 (AI)
- Claude Agent SDK
- claude-opus-4-5
- claude-sonnet-4
↓ MCP 协议
工具层 (MCP)
- Bitable 多维表格
- Docx 云文档
- Video 下载器
- COS 云存储
↓
数据层
- 飞书 Bitable (数据中心)
- Tencent COS (媒体存储)
- 本地文件系统 (任务产物)
2.2 数据流向
用户发消息
│
▼
┌───────────────────┐
│ 飞书 WebSocket │ ← 长连接,实时接收消息
└─────────┬─────────┘
│
▼
┌───────────────────┐
│ FeishuClient │ ← 消息解析、文件下载、会话查找
└─────────┬─────────┘
│
▼
┌───────────────────┐
│ Claude SDK │ ← 调用 AI 模型 + MCP 工具
│ + MCP Servers │
└─────────┬─────────┘
│
├─────────────────┬─────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Bitable │ │ COS │ │ 文件系统 │
│ 写入记录 │ │ 上传文件 │ │ 生成代码 │
└──────────┘ └──────────┘ └──────────┘
│
▼
┌───────────────────┐
│ 格式化回复 │ ← Markdown → 飞书卡片
└─────────┬─────────┘
│
▼
┌───────────────────┐
│ 发送到飞书 │
└───────────────────┘
2.3 核心原理解析
2.3.1 MCP 协议
MCP (Model Context Protocol) 是 Anthropic 设计的工具扩展协议:
┌─────────────┐ stdio ┌─────────────┐
│ Claude │ ◄────────────► │ MCP Server │
│ 主进程 │ JSON-RPC │ (工具) │
└─────────────┘ └─────────────┘
工作原理:
- Claude 发现需要使用工具(如”查询数据库”)
- 通过 stdio 发送 JSON-RPC 请求到 MCP Server
- MCP Server 执行实际操作(调用 API、读写文件等)
- 返回结果给 Claude
- Claude 整合结果继续推理
为什么用 MCP?
- 安全隔离:工具运行在独立进程,不影响主进程
- 语言无关:任何语言都能写 MCP Server
- 热插拔:无需重启即可添加/移除工具
- 标准化:统一的工具描述和调用格式
2.3.2 Claude Agent SDK 与本地执行
重要澄清:架构图中”本地 Claude Code CLI”与 Gateway 之间的连接是本地进程调用,而非 SSH 远程连接。
┌───────────────────────────────────────────────────────┐
│ Cloud Server │
│ ┌─────────────────┐ ┌─────────────────────┐ │
│ │ jarvis-gateway │ │ Claude Code CLI │ │
│ │ (Node.js) │ │ (独立会话) │ │
│ │ │ │ │ │
│ │ ClaudeClient │ │ Agent SDK Runtime │ │
│ │ └─ Agent SDK ◄──┼──────┼─► 共享同一 SDK │ │
│ └────────┬────────┘ └─────────────────────┘ │
│ │ │
│ │ execSync + sudo │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 系统命令执行 │ npm run build / nginx -s reload │
│ └─────────────────┘ │
└───────────────────────────────────────────────────────┘
| 维度 | Claude Agent SDK | Claude Code CLI |
|---|---|---|
| 用途 | 程序化集成 | 交互式开发 |
| 调用方式 | JavaScript API | 终端命令 |
| 运行环境 | 嵌入应用进程 | 独立进程 |
| 典型场景 | Gateway 自动化 | 开发者本地调试 |
本地命令执行原理:
// Gateway 使用 execSync 执行系统命令
const { execSync } = require('child_process');
// 示例:执行构建任务
execSync('npm run build', {
cwd: '/home/jarvis/tasks/abc123',
timeout: 300000 // 5分钟超时
});
// 示例:Nginx 部署(需要 sudo 权限)
execSync('sudo nginx -s reload');为什么不是 SSH?
- Gateway 运行在同一台服务器上,无需远程连接
- 使用
child_process.execSync直接调用本地命令- 通过 sudoers 配置实现无密码权限提升
2.3.3 会话管理
// 每个飞书 chatId 对应一个 Claude sessionId
const sessionStore = {
"oc_abc123": {
sessionId: "sess_xyz789",
updatedAt: 1707654321000
}
}为什么需要会话?
- 上下文保持:Claude 能记住之前的对话
- 任务续接:中断后可以继续
- 成本优化:减少重复的上下文传输
2.3.4 任务执行器
/build 做一个倒计时网页
│
▼
┌─────────────────────┐
│ 1. 创建任务目录 │ tasks/abc123/
│ 2. 调用 Claude │ 生成代码
│ 3. 读取 meta.json │ 获取部署信息
│ 4. 调用 Deployer │ Nginx 配置
│ 5. 返回访问 URL │ https://t-abc123.mistprism.com
└─────────────────────┘
3. 环境准备
3.1 服务器要求
| 配置项 | 最低要求 | 推荐配置 |
|---|---|---|
| CPU | 1 核 | 2 核 |
| 内存 | 1 GB | 2 GB |
| 硬盘 | 20 GB | 50 GB SSD |
| 系统 | Ubuntu 20.04+ | Ubuntu 22.04 |
| 网络 | 公网 IP | 固定 IP + 域名 |
3.2 软件依赖安装
# 1. 安装 Node.js 20+
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
# 2. 安装 PM2(进程管理)
npm install -g pm2
# 3. 安装 Nginx
sudo apt install nginx -y
# 4. 安装 yt-dlp(视频下载)
sudo curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp
sudo chmod a+rx /usr/local/bin/yt-dlp
# 5. 安装 Claude Code CLI(可选,用于本地开发)
npm install -g @anthropic-ai/claude-code3.3 账号准备
| 服务 | 用途 | 获取方式 |
|---|---|---|
| Anthropic API | Claude 模型调用 | console.anthropic.com |
| 飞书开发者 | 机器人应用 | open.feishu.cn |
| 腾讯云 COS | 文件存储 | cloud.tencent.com |
| 域名 + SSL | HTTPS 访问 | 任意域名商 + Let’s Encrypt |
4. 核心组件部署
4.1 项目结构
jarvis-gateway/
├── src/
│ ├── index.js # 入口文件
│ ├── feishu.js # 飞书客户端
│ ├── claude.js # Claude SDK 封装
│ ├── session.js # 会话管理
│ ├── task-executor.js # 任务执行器
│ ├── deployer.js # 部署器
│ ├── mcp-bitable.mjs # 飞书 MCP Server
│ ├── mcp-video.mjs # 视频下载 MCP Server
│ └── mcp-cos.mjs # COS MCP Server
├── data/
│ └── sessions.json # 会话持久化
├── media/ # 临时媒体文件
├── downloads/ # 视频下载缓存
├── tasks/ # 构建任务输出
├── .env # 环境变量
└── package.json
4.2 环境变量配置
# .env 文件
# ====================
# 飞书配置
FEISHU_APP_ID=cli_xxxxxxxxxxxx
FEISHU_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxx
# Claude API
ANTHROPIC_BASE_URL=https://api.anthropic.com
ANTHROPIC_AUTH_TOKEN=sk-ant-api03-xxxxxxxxxxxx
# 可选:使用代理
# ANTHROPIC_BASE_URL=https://your-proxy.com
# 腾讯云 COS
COS_SECRET_ID=AKIDxxxxxxxxxxxxxxxx
COS_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxx
COS_BUCKET=your-bucket-123456789
COS_REGION=ap-hongkong
# 飞书日志表(可选)
CHAT_LOG_APP_TOKEN=HkTMbwNHqavfD6suRb0c8tNvn1f
CHAT_LOG_TABLE_ID=tblbjaSEI6jFVVnM4.3 Claude SDK 封装示例
import { query } from "@anthropic-ai/claude-code";
export async function chat(prompt, sessionId = null, mediaFiles = []) {
const options = {
model: process.env.CLAUDE_MODEL || "claude-opus-4-5-20251101",
// 绕过权限检查(开发环境)
dangerouslySkipPermissions: true,
// MCP 服务器配置
mcpServers: {
"feishu-bitable": {
command: "node",
args: ["src/mcp-bitable.mjs"],
},
"video-downloader": {
command: "node",
args: ["src/mcp-video.mjs"],
},
},
};
// 支持会话恢复
if (sessionId) {
options.resume = sessionId;
}
let result = { text: "", sessionId: null };
// 流式处理响应
for await (const message of query({ prompt, options })) {
if (message.type === "system" && message.subtype === "init") {
result.sessionId = message.sessionId;
}
if (message.type === "result") {
result.text = message.result;
}
}
return result;
}4.4 飞书消息处理示例
import * as lark from "@larksuiteoapi/node-sdk";
export class FeishuClient {
constructor() {
this.client = new lark.Client({
appId: process.env.FEISHU_APP_ID,
appSecret: process.env.FEISHU_APP_SECRET,
});
this.wsClient = null;
}
async start() {
// 建立 WebSocket 长连接
this.wsClient = new lark.WSClient({
appId: process.env.FEISHU_APP_ID,
appSecret: process.env.FEISHU_APP_SECRET,
loggerLevel: lark.LoggerLevel.info,
});
// 注册消息处理器
this.wsClient.on("im.message.receive_v1", (data) => {
this.handleMessage(data);
});
await this.wsClient.start();
}
async handleMessage(data) {
const message = data.event.message;
const chatId = message.chat_id;
const content = JSON.parse(message.content);
// 调用 Claude 处理
const response = await claude.chat(content.text, sessionStore.get(chatId));
// 更新会话
sessionStore.set(chatId, response.sessionId);
// 回复消息
await this.client.im.message.create({
params: { receive_id_type: "chat_id" },
data: {
receive_id: chatId,
msg_type: "text",
content: JSON.stringify({ text: response.text }),
},
});
}
}4.5 SystemD 服务配置
[Unit]
Description=Jarvis Gateway
After=network.target
[Service]
Type=simple
User=jarvis
WorkingDirectory=/home/jarvis/jarvis-gateway
ExecStart=/usr/bin/node src/index.js
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable jarvis
sudo systemctl start jarvis5. MCP 工具开发
5.1 MCP Server 基础结构
// mcp-example.mjs
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// 创建服务器
const server = new McpServer({
name: "example-server",
version: "1.0.0",
});
// 定义工具
server.tool(
"tool_name", // 工具名称
"Tool description for Claude", // 工具描述
{ // 参数 Schema (Zod)
param1: z.string().describe("参数1描述"),
param2: z.number().optional().describe("可选参数2"),
},
async ({ param1, param2 }) => { // 执行函数
try {
// 实际逻辑
const result = await doSomething(param1, param2);
return {
content: [{ type: "text", text: JSON.stringify(result) }],
};
} catch (err) {
return {
content: [{ type: "text", text: `Error: ${err.message}` }],
isError: true,
};
}
}
);
// 启动服务器
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
main();5.2 飞书云文档 MCP 工具
| 工具名 | 功能 | 参数 |
|---|---|---|
docx_create | 创建云文档 | title, folder_token? |
docx_get | 获取文档信息 | document_id |
docx_raw_content | 获取文档纯文本 | document_id |
docx_list_blocks | 列出文档块 | document_id |
docx_create_block | 添加内容块 | document_id, block_id, block_type, content |
docx_batch_update | 批量更新 | document_id, requests[] |
drive_list_files | 列出文件 | folder_token? |
drive_create_folder | 创建文件夹 | name, folder_token? |
drive_copy_file | 复制文件 | file_token, name, type |
drive_move_file | 移动文件 | file_token, folder_token |
drive_delete_file | 删除文件 | file_token, type |
5.3 注册 MCP 到 Claude
// claude.js 中配置
const options = {
mcpServers: {
"feishu": {
command: "node",
args: [path.join(__dirname, "mcp-bitable.mjs")],
env: {
FEISHU_APP_ID: process.env.FEISHU_APP_ID,
FEISHU_APP_SECRET: process.env.FEISHU_APP_SECRET,
},
},
"tencent-cos": {
command: "node",
args: [path.join(__dirname, "mcp-cos.mjs")],
env: {
COS_SECRET_ID: process.env.COS_SECRET_ID,
COS_SECRET_KEY: process.env.COS_SECRET_KEY,
COS_BUCKET: process.env.COS_BUCKET,
COS_REGION: process.env.COS_REGION,
},
},
},
};6. 飞书机器人配置
6.1 创建飞书应用
- 登录 飞书开放平台
- 创建企业自建应用
- 添加「机器人」能力
- 获取 App ID 和 App Secret
6.2 配置权限
| 权限名称 | 用途 |
|---|---|
im:message | 收发消息 |
im:message.group_at_msg | 群聊 @ 消息 |
bitable:app | 多维表格读写 |
docx:document | 云文档读写 |
drive:drive | 云盘读写 |
task:task | 任务管理 |
calendar:calendar | 日历管理 |
6.3 事件订阅
开启以下事件:
im.message.receive_v1- 接收消息card.action.trigger- 卡片交互
6.4 消息卡片配置
{
"config": {
"wide_screen_mode": true
},
"header": {
"title": { "tag": "plain_text", "content": "Jarvis" },
"template": "blue"
},
"elements": [
{
"tag": "div",
"text": { "tag": "lark_md", "content": "{{content}}" }
}
]
}7. 自动化运维
7.1 定时任务配置
# crontab -e
# 每2小时采集热搜
0 */2 * * * cd /home/jarvis/jarvis-gateway && node scripts/fetch-hot-to-bitable.js >> logs/fetch.log 2>&1
# 每天6点执行推荐系统
0 6 * * * cd /home/jarvis/jarvis-gateway && node agents/orchestrator.js >> logs/recommend.log 2>&1
# 每天3点自动更新 Claude Code
0 3 * * * npm update -g @anthropic-ai/claude-code >> /var/log/claude-update.log 2>&17.2 Nginx 部署权限
# /etc/sudoers.d/jarvis
jarvis ALL=(ALL) NOPASSWD: /usr/sbin/nginx -t
jarvis ALL=(ALL) NOPASSWD: /usr/sbin/nginx -s reload
jarvis ALL=(ALL) NOPASSWD: /bin/cp /home/jarvis/sites/*.conf /etc/nginx/sites-available/
jarvis ALL=(ALL) NOPASSWD: /bin/ln -sf /etc/nginx/sites-available/*.conf /etc/nginx/sites-enabled/7.3 SSL 证书自动续期
# Let's Encrypt 通配符证书
sudo certbot certonly --manual --preferred-challenges dns \
-d "*.mistprism.com" -d "mistprism.com"
# 自动续期
sudo certbot renew --dry-run8. 方案对比分析
8.1 三种方案概览
Jarvis (本方案) [推荐]
- 技术栈:Claude SDK + 飞书 + MCP
- 定位:专业开发者自动化
- 安全性:高
- 企业适用:是
- 代码能力:强
- 团队协作:飞书群聊
OpenClaw [不推荐]
- 技术栈:开源 AI 代理
- 定位:个人全能助手
- 安全性:极低 (512漏洞)
- 企业适用:否
- 多平台:13+ 消息渠道
- 成本:$5-50/月
Claude Code CLI
- 技术栈:官方命令行工具
- 定位:开发者本地工具
- 安全性:高
- 企业适用:适合
- 团队协作:单人
- 成本:$20-200/月
OpenClaw 安全警告
- 漏洞数量:512 个,其中 8 个严重级别
- 恶意插件:ClawHub 市场约 20% 为恶意
- RCE 风险:存在一键远程代码执行漏洞链
- Gartner 评价:“一个不可接受的网络安全风险”,建议企业立即禁用
8.2 详细对比表
| 维度 | Jarvis | OpenClaw | Claude CLI |
|---|---|---|---|
| 部署位置 | 云服务器 | 云/本地 | 本地 |
| 访问方式 | 飞书 App | WhatsApp/Telegram 等 | 终端 |
| 安全性 | 高(自建+官方 SDK) | 极低(512 漏洞) | 高(本地运行) |
| 持久记忆 | 跨会话 | 跨会话 | 单会话 |
| 定时任务 | Crontab | 内置 | 无 |
| 学习曲线 | 中等 | 低 | 低 |
8.3 Jarvis 方案安全优势
| 安全措施 | 实现方式 |
|---|---|
| 代码可控 | 自建 Gateway,完全掌控逻辑 |
| 工具隔离 | MCP 进程隔离 |
| 权限最小化 | NOPASSWD 仅限特定命令 |
| 数据主权 | 飞书企业版 + 自有 COS |
| 审计日志 | Bitable 记录所有操作 |
8.4 选型建议
| 场景 | 推荐方案 |
|---|---|
| 企业/团队自动化 | Jarvis |
| 个人学习/实验 | OpenClaw(注意风险) |
| 本地代码开发 | Claude Code CLI |
| 多平台消息整合 | 自建消息桥接(参考 OpenClaw 思路但不用其代码) |
9. 成本分析
9.1 固定成本(月度)
| 项目 | 费用 |
|---|---|
| 云服务器(2C4G) | ¥50-100 |
| 域名 | ¥5(年均) |
| SSL 证书 | 免费(Let’s Encrypt) |
| 飞书应用 | 免费 |
| 小计 | ¥55-105/月 |
9.2 变动成本(按使用量)
| 操作 | Token 消耗 | 成本估算 |
|---|---|---|
| 普通对话 | 2-5k | $0.01-0.02 |
| /build 简单网页 | 50k | $0.50 |
| /build 复杂应用 | 200k | $2.00 |
| 推荐系统(日) | 50k | $0.50 |
| COS 存储 | 10GB | ¥5/月 |
9.3 成本优化技巧
- 选对模型:日常用 Sonnet,复杂任务用 Opus
- 会话复用:减少上下文重传
- Batch API:批量任务节省 50%
- Prompt 缓存:重复 Prompt 减少 90%
10. 故障排查
10.1 常见问题
| 症状 | 可能原因 | 解决方案 |
|---|---|---|
| 机器人无响应 | WebSocket 断连 | systemctl restart jarvis |
| Claude 超时 | API 限流 | 检查账户额度,增加重试 |
| 部署失败 | Nginx 配置错误 | sudo nginx -t 检查语法 |
| MCP 工具失败 | 环境变量缺失 | 检查 .env 配置 |
10.2 日志查看
# 服务日志
journalctl -u jarvis -f
# 应用日志
tail -f /home/jarvis/jarvis-gateway/logs/*.log
# Nginx 日志
tail -f /var/log/nginx/error.log10.3 健康检查脚本
#!/bin/bash
# health-check.sh
# 检查服务状态
systemctl is-active jarvis || echo "Jarvis service is down!"
# 检查端口
curl -s http://localhost:3000/health || echo "Health endpoint failed!"
# 检查磁盘空间
df -h / | awk 'NR==2 {if ($5+0 > 90) print "Disk usage > 90%!"}'
# 检查内存
free -m | awk 'NR==2 {if ($3/$2*100 > 90) print "Memory usage > 90%!"}'11. 最佳实践
11.1 开发规范
- 模块化:每个 MCP Server 独立文件
- 错误处理:所有 API 调用加 try-catch
- 日志规范:关键操作记录到 Bitable
- 版本控制:Git 管理,敏感信息
.env不提交
11.2 安全规范
- 最小权限:API Key 只授必要权限
- 定期轮换:每季度更换敏感凭证
- 审计日志:所有操作留痕
- 备份策略:Bitable 定期导出
11.3 运维规范
- 监控告警:设置服务不可用告警
- 容量规划:定期清理临时文件
- 版本升级:Claude SDK 保持最新
- 文档同步:架构变更及时更新文档
附录 A:完整文件清单
jarvis-gateway/
├── src/
│ ├── index.js # 入口
│ ├── feishu.js # 飞书客户端 (25KB)
│ ├── claude.js # Claude SDK (3.5KB)
│ ├── session.js # 会话管理 (1KB)
│ ├── task-executor.js # 任务执行 (5KB)
│ ├── deployer.js # 部署器 (5KB)
│ ├── mcp-bitable.mjs # 飞书 MCP (30KB)
│ ├── mcp-video.mjs # 视频 MCP (8KB)
│ └── mcp-cos.mjs # COS MCP (10KB)
├── agents/
│ ├── orchestrator.js # 推荐系统主控
│ ├── skills/
│ │ ├── skill2-generator.js
│ │ ├── skill3-reviewer.js
│ │ └── skill4-rewriter.js
│ └── memory/
│ ├── skill_stats.json
│ ├── daily_history.json
│ └── preferences.json
├── scripts/
│ └── fetch-hot-to-bitable.js
├── docs/
│ └── SOP-Complete-Guide.md # 本文档
├── data/
│ └── sessions.json
├── .env
├── package.json
└── README.md
附录 B:快速启动清单
- 服务器准备(Ubuntu 22.04, 2C4G)
- 安装 Node.js 20+
- 安装 PM2, Nginx, yt-dlp
- 创建飞书应用,获取凭证
- 创建 Anthropic API Key
- 配置腾讯云 COS
- 克隆项目,配置 .env
-
npm install - 配置 SystemD 服务
- 配置 Nginx + SSL
- 测试飞书机器人
附录 C:联系方式
如有问题,可通过以下方式联系:
- 飞书:@Jarvis
- GitHub Issues:项目仓库