mcp工作流服务器
当您以自然语言向Claude Code发出请求时,FastAPI服务器会自动检测Global/Team/Project Rules并将其反映到请求中,并基于规则验证生成的结果的系统。
______________________________________________________________________
实施状态
- \[x\]FastAPI服务器(
/get_rules,/health) - \[x\]Hook1(UserPromptSubmit)-rules自动注入
- \[x\]Hook2(PostToolUse)-Claude自我验证请求(不需要单独的API密钥)
- \[x\]Rule Engine-global/team/project层合并和优先级
- \[x\]rules-repo-扫描整个目录(可分离多个yaml文件)
- \[x\]Ralph管道-
claude -p重复运行+Stop Hook判断完成 - \[x\]支持WORKFLOW_MODE-interactive/ralph/off模式
服务器可以通过ngrok外部连接。 WORKFLOW_SERVER_URL 将服务器地址更改为环境变量。______________________________________________________________________
体系结构
개발자가 Claude Code에 프롬프트 입력
│
▼
┌─────────────────────────────────────┐
│ Hook 1 - UserPromptSubmit │
│ inject_rules_hook.py │
│ .workflow.yaml 탐색 (상위 탐색) │
│ POST /get_rules {team, project} │
│ ↓ │
│ FastAPI Server │
│ global/team/project rules 로드 │
│ ↓ │
│ plain text stdout → 컨텍스트 주입 │
└─────────────────────────────────────┘
│
▼
Claude가 rules를 인지한 상태로 요청 처리
위반 요청은 이 단계에서 사전 거부
│
▼
Claude가 코드 작성 (Edit/Write/MultiEdit)
│
▼
┌─────────────────────────────────────┐
│ Hook 2 - PostToolUse │
│ validate_hook.py │
│ .workflow.yaml 탐색 (상위 탐색) │
│ POST /get_rules {team, project} │
│ ↓ │
│ FastAPI Server │
│ rules 존재 확인 │
│ ↓ │
│ additionalContext JSON → │
│ "방금 코드 rules 검토해줘" 주입 │
└─────────────────────────────────────┘
│
▼
Claude가 방금 작성한 코드 재검토
위반 발견 시 즉시 수정 (이중 안전망)队员们各自 ~/.claude/settings.json只需在中注册hook即可。服务器URL为 WORKFLOW_SERVER_URL 可以更改为环境变量。
______________________________________________________________________
项目结构
mcp-workflow-server/
├── server/ # 서버 코드 (공용 서버에 배포)
│ ├── api_server.py # FastAPI 서버 (/get_rules, /health)
│ ├── config.py # 환경변수 로드 (RULES_REPO_PATH)
│ ├── rule_engine/ # 핵심 로직
│ │ ├── loader.py # yaml 로드 + 캐싱 (디렉토리 전체 스캔)
│ │ └── merger.py # global → team → project 우선순위 병합
│ └── rules-repo/ # 실제 rules 파일들
│ ├── global/
│ │ ├── security.yaml
│ │ └── code-style.yaml
│ ├── teams/
│ │ └── dev-team-1/
│ │ └── rules.yaml
│ └── projects/
│ └── sample-project/
│ └── rules.yaml
│
├── client/ # 팀원 로컬에 설치하는 코드
│ └── hooks/
│ ├── inject_rules_hook.py # Hook 1 - UserPromptSubmit
│ └── validate_hook.py # Hook 2 - PostToolUse
│
├── requirements.txt
└── .workflow.yaml # 이 레포 자체의 team/project 설정 (테스트용)呼叫流:
client/hooks/ → server/api_server.py → server/rule_engine/ → server/rules-repo/______________________________________________________________________
服务器安装(管理员)
1.需要Python3.10+
brew install python@3.132.创建venv并安装软件包
/opt/homebrew/bin/python3.13 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt3.启动FastAPI服务器
# 포그라운드
.venv/bin/python server/api_server.py
# 백그라운드
nohup .venv/bin/python server/api_server.py > /tmp/workflow-server.log 2>&1 &
# 포트 변경 시
PORT=27842 .venv/bin/python server/api_server.py确认动作:
curl http://localhost:27842/health
# {"status":"ok"}______________________________________________________________________
团队成员登录(客户端)
团队成员如何在服务器已经漂浮的情况下进行连接。
1.复制记录克隆或client/hooks/文件
git clone https://github.com/your-org/mcp-workflow-server.git或 client/hooks/inject_rules_hook.py, client/hooks/validate_hook.py 只复制两个文件。
hook文件只使用标准库,因此无需安装单独的软件包。
2.~/.claude/settings.json注册
{
"hooks": {
"UserPromptSubmit": [{
"hooks": [{
"type": "command",
"command": "/path/to/python /path/to/client/hooks/inject_rules_hook.py"
}]
}],
"PostToolUse": [{
"matcher": "Edit|Write|MultiEdit",
"hooks": [{
"type": "command",
"command": "/path/to/python /path/to/client/hooks/validate_hook.py"
}]
}]
},
"env": {
"WORKFLOW_SERVER_URL": "http://team-server:27842"
}
}/path/to/python更改为您环境中的python路径。WORKFLOW_SERVER_URL更改为服务器地址。
3.在项目根目录中添加.workflow.yaml
在要工作的项目根目录中 .workflow.yaml 创建文件:
team: dev-team-1
project: my-project团队名称/项目名称是服务器的 rules-repo/teams/, rules-repo/projects/ 必须与目录名匹配。
4.确认动作
重新启动Claude Code后,输入任何提示即可确认注入了rules:
[WORKFLOW RULES - 적용: project=my-project, team=dev-team-1, global]
- [sec-001] ...
...
[/WORKFLOW RULES]
### 5. Hook 비활성화 (원상복구)
hook을 제거하고 싶으면 `~/.claude/settings.json`을 아래 내용으로 교체:
{ "model": "sonnet" }
______________________________________________________________________
## Rules结构
### 分层优先级
Project Rules (가장 높음 - 덮어씀) ↓ Team Rules ↓ Global Rules (가장 낮음)
如果发生相同的id冲突,则优先应用子(更具体)规则。
### yaml格式
rules: - id: sec-001 description: "raw SQL query 금지, ORM만 사용" severity: error # error | warning
### rules-repo文件结构
global/teams/projects全部扫描目录。与文件名无关 `.yaml`/`.yml` 全部加载。
rules-repo/ ├── global/ │ ├── security.yaml # 파일명 자유 │ └── code-style.yaml ├── teams/ │ └── dev-team-1/ │ ├── rules.yaml # 파일명 자유 │ └── style.yaml # 여러 파일로 분리 가능 └── projects/ └── sample-project/ ├── rules.yaml └── db.yaml # 여러 파일로 분리 가능
### 团队/项目自动检测顺序
从客户端(hook)检测并发送到服务器:
1. 从cwd到父目录 `.workflow.yaml` 导航←要应用team rules,必须
1. fallback→仅应用global rules
`.workflow.yaml` 示例:
team: dev-team-1 project: sample-project
______________________________________________________________________
## 动作方式
### 钩子1-用户提示提交(规则주입)
1. 提示传送时自动启动
1. Hook脚本从cwd到父目录 `.workflow.yaml` 导航→提取team/project
1. `POST /get_rules {team, project}` 向服务器发送请求
1. 服务器加载并合并rules→返回plain text
1. 将返回Hook脚本的rules自动注入stdout输出→Claude上下文
1. Claude在知道rules的情况下处理请求→提前拒绝违规请求
- **注意**: `additionalContext` JSON格式不起作用。仅plain text起作用。
### Hook2-PostToolUse(双重验证)
1. Edit/Write/MultiEdit完成后启动
1. Hook脚本从cwd到父目录 `.workflow.yaml` 导航→提取team/project
1. `POST /get_rules {team, project}` 发送并验证是否存在rules
1. `hookSpecificOutput.additionalContext` 用JSON向Claude注入验证请求
1. **根据rules重新检查Claude刚刚编写的代码&如果违反,立即更正** (双安全网)
- 在Hook1中,事后再次捕获未过滤的违规
- 无需单独的API调用,无需ANTHROPIC_API_KEY
- **注意**: `hookSpecificOutput.additionalContext` 只使用JSON格式。plain text不起作用。
### API端点
|端点|方法|说明|
|---|---|---|
| `/health` GET检查服务器状态
| `/get_rules` POST返回基于team/project的rules
______________________________________________________________________
## 演示测试问题
可以通过以下问题验证rules是否真实反映。
|问题|确认点|
|---|---|
|“请创建用户登录函数”| bcrypt散列(sec-001)、JWT到期(sec-002)|
|“在users表中创建通过电子邮件查询用户的函数”|使用SQLAlchemy ORM(sec-003)|
|“创建用户生成API端点”|认证中间件(team-001)、标准响应格式(team-004)、type hint(style-003)|
|“创建User DB模型”| BaseModel继承(proj-001)、Pydantic模式(proj-003)
|“请创建用户存储在数据库中的函数”|事务处理(proj-002)、try/except错误处理(team-003)|
|“请在配置文件中输入DB密码”|环境变量管理(sec-004)|
______________________________________________________________________