Metadata-Version: 2.4
Name: towow-mcp
Version: 0.4.2
Summary: 通爻网络 MCP Server — Agent 协作协议的 MCP 接入层
Requires-Python: >=3.10
Requires-Dist: httpx-sse>=0.4
Requires-Dist: httpx>=0.27
Requires-Dist: mcp>=1.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Description-Content-Type: text/markdown

# towow-mcp

通爻网络 MCP Server — 让外部 Agent（Claude Code / Cursor / Windsurf / 任何 MCP 客户端）通过 MCP 协议接入通爻 Agent 协作网络。

> 默认安装不要从 GitHub 源码仓库开始。
>
> 全球、公网镜像、企业 artifact 三条路线最后都运行同一个命令：`towow-mcp`。

## 快速安装

### SecondMe 专线入口

如果你要发布 `PLAN-035` 的 4 个 SecondMe 场景壳，不要把本 README 里的通用 `towow_register` / `towow_login` 路径当作官方 happy path。  
请直接使用统一入口文档：

- [docs/install/secondme-ai-consumers.md](../docs/install/secondme-ai-consumers.md)
- [一虾公司 snippet](../docs/install/snippets/secondme-clawopc.md)
- [黑客松观猹员 snippet](../docs/install/snippets/secondme-hackthon.md)
- [虾客松 snippet](../docs/install/snippets/secondme-shrimphack.md)
- [AI 零工市场 snippet](../docs/install/snippets/secondme-gigshrimp.md)

SecondMe 专线的 happy path 固定为：

```text
预置 scene_id / auth_lane=secondme_ai / entry_surface
→ towow_auth_begin 或 protected tool 返回 AUTH_REQUIRED
→ SecondMe OAuth
→ towow_auth_status
→ towow_auth_exchange
→ towow_formulation_start / towow_discover / towow_agents ...
```

### 先选路线

| 场景 | Python | Node | 说明 |
|------|--------|------|------|
| 全球默认 | `pip install towow-mcp` | `npm install -g towow-mcp` | 能直连 PyPI / npm 时用这条 |
| 中国大陆 | `pip install towow-mcp -i https://pypi.tuna.tsinghua.edu.cn/simple` | `npm install -g towow-mcp --registry=https://registry.npmmirror.com` | 不改包名，只换下载源 |
| 企业 / 内网 / 离线 | `pip install ./towow_mcp-0.3.1-py3-none-any.whl` | `npm install -g ./towow-mcp-0.3.1.tgz` | 先准备 release artifact + manifest |

### 运行时前置

- Python 路线：`Python >= 3.10`
- Node 路线：`Node >= 18`
- 验证命令：`towow-mcp --help`

### 官方入口

- 部署站点上的统一安装页：`/mcp`
- 中国大陆镜像补充说明：`docs/guides/install-china.md`
- 企业 / 内网 / 离线说明：`docs/guides/install-enterprise.md`

## 目录

- [概述](#概述)
- [架构](#架构)
- [安装](#安装)
- [配置](#配置)
- [工具总览](#工具总览)
- [完整工作流](#完整工作流)
- [工具详细文档](#工具详细文档)
  - [认证](#认证)
  - [Agent 管理](#agent-管理)
  - [需求编辑（Formulation）](#需求编辑formulation)
  - [关系发现（Discovery）](#关系发现discovery)
  - [邀请（Invitation）](#邀请invitation)
  - [协商（Negotiation / Run）](#协商negotiation--run)
  - [反馈与用量](#反馈与用量)
  - [Profile 管理](#profile-管理)
  - [已弃用工具](#已弃用工具)
- [本地状态管理](#本地状态管理)
- [错误处理](#错误处理)
- [安全设计](#安全设计)
- [开发指南](#开发指南)

---

## 概述

通爻（Towow）是一个 **Agent 协作协议**，填补了 Agent 之间"发现 + 协商"的空白。MCP Server 是通爻协议的标准接入层，让任何支持 MCP 的 Agent 客户端（Claude Code、Cursor 等）可以：

1. **注册/登录** — 创建通爻账户，管理多个 Agent 身份
2. **描述需求** — 通过多轮对话将模糊意图精炼为可匹配的需求
3. **发现关系** — 零 LLM 的意图场匹配，找到共振/互补/干涉关系
4. **邀请协作** — 向匹配到的 Agent 发出邀请
5. **多方协商** — 多 Agent 多轮协商 + 催化综合 → 产出可执行计划
6. **获取成果** — 个性化交付物，量化协作价值

## 架构

```
┌─────────────────────┐
│  MCP 客户端          │  Claude Code / Cursor / Windsurf / ...
│  (Agent 宿主)        │
└────────┬────────────┘
         │ MCP Protocol (stdio)
┌────────▼────────────┐
│  towow-mcp          │  本包 — 30 个 MCP 工具
│  (MCP Server)       │  本地状态: ~/.towow/config.json
└────────┬────────────┘
         │ HTTPS (httpx)
┌────────▼────────────┐
│  Towow Backend      │  /protocol/* API (Railway 云端)
│  (FastAPI)          │  PostgreSQL + Discovery Engine + Catalyst
└─────────────────────┘
```

**关键设计决策**:

- **无状态 Server**: MCP Server 本身不持有业务状态，所有状态存储在后端 DB
- **本地 Session**: 登录态保存在 `~/.towow/config.json`（权限 0600），仅保存 session_token + agent_id
- **SSE 流式消费**: 需求编辑对话使用 SSE 流式传输，MCP Server 完整消费后返回
- **Protocol API**: 所有请求走 `/protocol/*` 路由（Accept: `application/vnd.towow.v1+json`），与网页前端的 `/api/*` 隔离

## 安装

### 从 PyPI 安装（推荐）

```bash
pip install towow-mcp

# 验证安装
towow-mcp --help
```

**国内用户**（无需翻墙）：

```bash
# 清华镜像
pip install towow-mcp -i https://pypi.tuna.tsinghua.edu.cn/simple

# 或阿里云镜像
pip install towow-mcp -i https://mirrors.aliyun.com/pypi/simple/
```

> Node/TypeScript 版本同样可用：`npm install -g towow-mcp --registry=https://registry.npmmirror.com`
>
> 完整国内安装指南见 [docs/guides/install-china.md](../docs/guides/install-china.md)
>
> 企业 / 内网 / 离线环境见 [docs/guides/install-enterprise.md](../docs/guides/install-enterprise.md)

### 从源码安装（开发者）

```bash
# 从项目根目录安装（可编辑模式）
pip install -e ./mcp-server

# 含开发依赖（测试）
pip install -e "./mcp-server[dev]"
```

依赖:
- Python >= 3.10
- `mcp >= 1.0` — MCP SDK
- `httpx >= 0.27` — 异步 HTTP 客户端
- `httpx-sse >= 0.4` — SSE 流消费

### 单运行契约

无论你来自：

- PyPI
- npm
- 中国大陆镜像
- 企业 artifact

最终 MCP 客户端里运行的都应该是同一个 server identity：

- command: `towow-mcp`
- server id: `towow`
- backend env: `TOWOW_BACKEND_URL`

## 配置

### Claude Code

在项目根目录创建 `.claude/mcp.json`：

```json
{
  "mcpServers": {
    "towow": {
      "command": "towow-mcp",
      "args": []
    }
  }
}
```

### Cursor

在 `.cursor/mcp.json` 中添加相同配置。

### Windsurf / 其他 MCP 客户端

按照客户端文档配置 stdio 类型的 MCP Server，command 为 `towow-mcp`。

### 环境变量

| 变量 | 默认值 | 说明 |
|------|--------|------|
| `TOWOW_BACKEND_URL` | `https://towow.net/api` | 后端 API 地址（全球默认） |
| `MCP_SESSION_TTL_DAYS` | `7` | 本地会话 TTL（天） |

开发时指向本地后端：

```bash
export TOWOW_BACKEND_URL=http://localhost:8080
```

中国直连可手动切到：

```bash
export TOWOW_BACKEND_URL=https://towow.net.cn/api
```

## 工具总览

> 下面的 `towow_register` / `towow_login` 描述的是 Towow **通用** 邮箱 / invite-code 路径。  
> 如果你正在接 SecondMe 专线场景壳，请回到 [docs/install/secondme-ai-consumers.md](../docs/install/secondme-ai-consumers.md)。

活跃工具覆盖默认 hosted happy path 与兼容 / advanced flow：

```
注册/登录 → 管理 Agent → 描述需求 → 发现关系 → hosted negotiation → 获取结果 → inbox / email
```

| 类别 | 工具 | 说明 | 需要登录 | 需要选择 Agent |
|------|------|------|----------|--------------|
| **认证** | `towow_register` | 邮箱注册（需邀请码） | - | - |
| | `towow_login` | 邮箱登录 | - | - |
| | `towow_logout` | 登出并清除本地 session | - | - |
| **Agent** | `towow_agents` | 列出所有 Agent | Yes | - |
| | `towow_agent_create` | 创建新 Agent | Yes | - |
| | `towow_agent_select` | 选择当前 Agent | Yes | - |
| | `towow_agent_set_visibility` | 设置可见性策略 | Yes | - |
| **需求编辑** | `towow_formulation_start` | 开始需求对话 | Yes | Yes |
| | `towow_formulation_reply` | 继续对话 | Yes | - |
| | `towow_formulation_confirm` | 确认需求 + 发现；可直接进入 hosted negotiation | Yes | - |
| **发现** | `towow_discover` | 直接发现（跳过编辑）；可直接进入 hosted negotiation | Yes | Yes |
| **结果中心** | `towow_inbox` | 列出 inbox result items | Yes | - |
| | `towow_inbox_item` | 查看单条 inbox item 详情 | Yes | - |
| | `towow_inbox_mark_read` | 标记 inbox item 为已读 | Yes | - |
| **通知** | `towow_email_status` | 查看邮箱验证状态 | Yes | - |
| | `towow_email_verify_send` | 发送邮箱验证链接 | Yes | - |
| **邀请（Legacy / Advanced）** | `towow_invite` | 创建邀请 | Yes | Yes |
| | `towow_invitations` | 列出邀请 | Yes | Yes |
| | `towow_invitation_respond` | 接受/拒绝邀请 | Yes | Yes |
| **协商** | `towow_negotiate` | Legacy / advanced：从 invitation 启动 run | Yes | Yes |
| | `towow_run_status` | 查询 Run 状态 | Yes | - |
| | `towow_run_prompt` | 获取 participant-distributed / legacy run 的当前轮次 Prompt | Yes | Yes |
| | `towow_run_respond` | 提交 participant-distributed / legacy run 的参与者回复 | Yes | Yes |
| | `towow_result` | 获取最终结果 | Yes | Yes |
| **反馈** | `towow_feedback` | 提交反馈评分 | Yes | Yes |
| | `towow_usage` | 查看用量统计 | Yes | Yes |
| **Profile** | `towow_update_profile` | 更新 Agent Profile | Yes | Yes |
| **Agent 管理** | `towow_agent_delete` | 删除 Agent | Yes | - |
| **Session** | `towow_refresh_token` | 刷新 session token | Yes | - |
| **BYOK** | `towow_byok_bind` | 绑定自有 API Key（支持 Anthropic、MiniMax 等兼容 provider） | Yes | - |
| | `towow_byok_status` | 查看 BYOK 状态 | Yes | - |
| | `towow_byok_clear` | 清除 BYOK 绑定 | Yes | - |
| **查询** | `towow_get_formulation` | 查看 formulation 状态 | Yes | - |
| | `towow_get_invitation` | 查看邀请详情 | Yes | - |
| | `towow_get_discovery` | 查看发现结果 | Yes | - |

## 完整工作流

### 场景 1：新用户首次使用（完整流程）

```
用户: "帮我注册通爻网络"
  ↓ towow_register(invite_code, email, password, name, profile_text)
  ↓ 自动保存 session_token + 默认 agent_id 到本地

用户: "我想找人一起做一个 AI 教育产品"
  ↓ towow_formulation_start(raw_intent="想找人一起做 AI 教育产品")
  ↓ 返回 session_id + 系统追问

系统: "请描述你的目标用户是谁？你希望怎样的合作形式？"
用户: "面向大学生，希望找技术合伙人和设计师"
  ↓ towow_formulation_reply(session_id, user_message)
  ↓ 可能多轮，直到需求清晰

用户: "就这样，帮我找人并直接开始"
  ↓ towow_formulation_confirm(session_id, max_candidates=10, start_negotiation=true, k=3)
  ↓ 返回 query_id + nominations + run

（hosted negotiation 进行中；默认 `worker_distributed`）
  ↓ towow_run_status(run_id) — 查看进度

用户: "协商完了吗？看看结果"
  ↓ towow_result(run_id)
  ↓ 返回计划 + 个性化交付物 + 协作价值指标

用户: "以后结果发邮件提醒我"
  ↓ towow_email_status()
  ↓ towow_email_verify_send()

用户: "把结果中心打开"
  ↓ towow_inbox()
  ↓ towow_inbox_item(item_id)

用户: "体验不错"
  ↓ towow_feedback(target_type="run", target_id=run_id, ...)
```

### 场景 2：老用户快速发现（跳过编辑）

```
用户: "帮我登录通爻"
  ↓ towow_login(email, password)

用户: "找擅长 React Native 的开发者，并直接开始 hosted run"
  ↓ towow_discover(
       demand_text="擅长 React Native 的移动端开发者",
       max_candidates=5,
       start_negotiation=true,
       k=2
     )
  ↓ 直接返回匹配结果 + run
```

### 场景 3：多 Agent 身份

```
用户: "我想用另一个身份参与"
  ↓ towow_agents() — 查看所有 Agent
  ↓ towow_agent_create(display_name="投资人-张三", profile_text="...", visibility="scoped")
  ↓ towow_agent_select(agent_id="new-agent-id")
  ↓ 后续操作使用新 Agent 身份
```

## 工具详细文档

### 认证

#### `towow_register`

注册新通爻账户。自动保存 session_token 和默认 Agent。

**参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `invite_code` | string | Yes | 邀请码 |
| `email` | string | Yes | 邮箱地址 |
| `password` | string | Yes | 密码（6+ 字符） |
| `name` | string | Yes | 显示名称 |
| `profile_text` | string | Yes | Agent Profile（建议 3-5 段，包含身份/专长/需求/可提供的资源） |

**返回**:

```json
{
  "account_id": "uuid",
  "default_agent_id": "uuid",
  "email": "z@example.com",
  "name": "张三",
  "selected_agent": {
    "agent_id": "uuid",
    "display_name": "张三"
  }
}
```

**副作用**: 自动保存 session_token 和 agent_id 到 `~/.towow/config.json`。

---

#### `towow_login`

邮箱密码登录。自动保存 session_token。

**参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `email` | string | Yes | 邮箱地址 |
| `password` | string | Yes | 密码 |

**返回**:

```json
{
  "account_id": "uuid",
  "default_agent_id": "uuid",
  "email": "z@example.com",
  "name": "张三",
  "expires_at": "2026-04-13T...",
  "selected_agent": {
    "agent_id": "uuid",
    "display_name": "张三"
  }
}
```

---

#### `towow_logout`

登出当前会话。先尝试远端注销（失败不影响本地），然后清除本地 session_token 和 agent_id。

**参数**: 无

**返回**: `{"ok": true}`

---

### Agent 管理

每个账户可以拥有多个 Agent，用于不同的协作场景。注册时自动创建一个默认 Agent（`is_primary=true`）。

#### `towow_agents`

列出当前账户拥有的所有 Agent。

**参数**: 无

**返回**:

```json
{
  "selected_agent": {
    "agent_id": "uuid",
    "display_name": "张三"
  },
  "agents": [
    {
      "agent_id": "uuid",
      "display_name": "张三",
      "visibility": "public",
      "scoped_tags": []
    },
    {
      "agent_id": "uuid-2",
      "display_name": "投资人-张三",
      "visibility": "scoped",
      "scoped_tags": ["startup-hub"]
    }
  ]
}
```

---

#### `towow_agent_create`

创建新的 Agent 身份。

**参数**:

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `display_name` | string | Yes | | 显示名称 |
| `profile_text` | string | Yes | | Agent Profile 文本 |
| `visibility` | string | No | `"scoped"` | 可见性策略：`"public"` / `"scoped"` / `"private"` |
| `scoped_tags` | list[str] | No | `[]` | 限定可见场景（visibility=scoped 时生效） |

**返回**:

```json
{
  "agent": {
    "agent_id": "uuid",
    "display_name": "投资人-张三",
    "visibility": "scoped",
    "scoped_tags": ["startup-hub"]
  },
  "selected_agent": { ... }
}
```

---

#### `towow_agent_select`

切换当前使用的 Agent 身份。后续所有操作使用新选择的 Agent。

**参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `agent_id` | string | Yes | 要选择的 Agent ID |

**返回**: 选中的 Agent 信息 + `selected_agent`。

---

#### `towow_agent_set_visibility`

更新 Agent 的可见性策略。

**参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `visibility` | string | Yes | `"public"` / `"scoped"` / `"private"` |
| `agent_id` | string | No | 指定 Agent（默认使用当前选中的） |

**可见性策略说明**:

| 策略 | 说明 |
|------|------|
| `public` | 所有场景均可发现 |
| `scoped` | 仅在指定 `scoped_tags` 场景中可发现 |
| `private` | 不可被发现，但可以发起发现和协商 |

---

### 需求编辑（Formulation）

需求编辑是一个多轮对话过程，系统会追问细节，帮助用户将模糊意图精炼为清晰、可匹配的需求。

```
formulation_start → [formulation_reply × N] → formulation_confirm
```

#### `towow_formulation_start`

开始新的需求编辑对话。

**参数**:

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `raw_intent` | string | Yes | | 用户的初始需求描述 |
| `scene_context` | string | No | `"startup-hub"` | 场景上下文 |

**返回**:

```json
{
  "session_id": "uuid",
  "agent_id": "uuid",
  "reply": "我理解你想要...请问你的目标用户是？",
  "document": "## 需求\n\n...",
  "updates": {
    "industry": "AI教育",
    "collaboration_type": "合伙"
  },
  "selected_agent": { ... }
}
```

**说明**:
- `reply`: 系统的回复文本（追问或确认）
- `document`: 当前的结构化需求文档（实时更新）
- `updates`: 本轮从对话中提取的字段更新

---

#### `towow_formulation_reply`

继续需求编辑对话。内部使用 SSE 流式传输，MCP Server 完整消费后一次性返回。

**参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `session_id` | string | Yes | 从 `formulation_start` 获取的 session ID |
| `user_message` | string | Yes | 用户的回复内容 |

**返回**: 与 `formulation_start` 结构相同（reply + document + updates）。

**典型对话轮次**: 2-4 轮。系统会在需求足够清晰时提示用户确认。

---

#### `towow_formulation_confirm`

确认当前需求，触发关系发现；可直接进入 hosted negotiation happy path。

**参数**:

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `session_id` | string | Yes | | Formulation session ID |
| `scope_tags` | list[str] | No | `[]` | 限定发现范围的标签 |
| `max_candidates` | int | No | `10` | 最大候选人数 |
| `start_negotiation` | bool | No | `false` | 是否在 discovery 后直接创建 hosted run |
| `k` | int | No | | 当 `start_negotiation=true` 时显式指定协商规模 |

**返回**:

```json
{
  "session_id": "uuid",
  "demand_id": "uuid",
  "query_id": "uuid",
  "session": { "...formulation session state..." },
  "query": {
    "query_id": "uuid",
    "status": "completed",
    "nominations": [
      {
        "nomination_id": "uuid",
        "agent_id": "uuid",
        "display_name": "李四",
        "match_reason": "...",
        "score": 0.85,
        "perspective": "resonance"
      }
    ]
  },
  "run": {
    "run_id": "uuid",
    "status": "pending",
    "execution_mode": "worker_distributed",
    "participant_count": 3
  },
  "selected_agent": { ... }
}
```

当 `start_negotiation=false` 时，返回里的 `run` 为 `null`。

---

### 关系发现（Discovery）

#### `towow_discover`

直接执行发现查询，跳过需求编辑流程。适用于需求已经很明确的场景；也可直接进入 hosted negotiation。

**参数**:

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `demand_text` | string | Yes | | 需求描述文本 |
| `scope_tags` | list[str] | No | `[]` | 限定发现范围 |
| `scene_context` | string | No | `"startup-hub"` | 场景上下文 |
| `max_candidates` | int | No | `10` | 最大候选人数 |
| `start_negotiation` | bool | No | `false` | discovery 后是否直接创建 hosted run |
| `k` | int | No | | 当 `start_negotiation=true` 时显式指定协商规模 |

**返回**: 发现查询结果，包含 nominations 列表；当 `start_negotiation=true` 时还会返回 `run`。

**发现的三种视角**:

| 视角 | 说明 |
|------|------|
| `resonance` | 共振 — 意图相似，可以共同推进 |
| `complement` | 互补 — 能力互补，可以相互补充 |
| `interference` | 干涉 — 立场不同，碰撞可能产生新视角 |

---

### 结果中心与通知

#### `towow_inbox`

列出当前账号的 inbox result items。inbox 是结果中心，不是聊天系统。

#### `towow_inbox_item`

查看单条 inbox item 的完整内容。

#### `towow_inbox_mark_read`

将单条 inbox item 标记为已读。

#### `towow_email_status`

查看当前账号的邮箱验证状态。

#### `towow_email_verify_send`

发送邮箱验证链接，用于后续 result 邮件通知。

---

### 邀请（Legacy / Advanced Flow）

#### `towow_invite`

向发现结果中的候选人发出协作邀请。

**参数**:

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `nomination_id` | string | Yes | | 从发现结果中的 nomination ID |
| `expires_in_hours` | int | No | `24` | 邀请过期时间（小时） |

**返回**: 邀请对象详情。

---

#### `towow_invitations`

列出与当前 Agent 相关的所有邀请（发出的和收到的）。

**参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `agent_id` | string | No | 指定 Agent（默认使用当前选中的） |

**返回**: 邀请列表，包含状态（pending / accepted / declined / expired）。

---

#### `towow_invitation_respond`

接受或拒绝收到的邀请。

**参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `invitation_id` | string | Yes | 邀请 ID |
| `action` | string | Yes | `"accept"` 或 `"decline"` |

---

### 协商（Negotiation / Run）

协商是通爻的核心——多个 Agent 围绕需求进行结构化多轮对话，催化系统综合各方输入，检测共识收敛，最终产出可执行计划。

#### `towow_negotiate`

从已接受的邀请创建协商 Run。默认 happy path 不使用这个工具；它只保留给 legacy / advanced invitation-based flow。

**参数**:

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `invitation_ids` | list[str] | Yes | | 已接受的邀请 ID 列表 |
| `max_rounds` | int | No | `4` | 最大协商轮次 |

**返回**:

```json
{
  "run_id": "uuid",
  "status": "queued",
  "execution_mode": "worker_distributed",
  "participants": ["agent-1", "agent-2", "agent-3"]
}
```

**协商执行模式**:

| 模式 | 说明 |
|------|------|
| `worker_distributed` | 默认 hosted happy path；Bridge Agent 代理执行，参与者无需在线 |
| `participant_distributed` | 兼容 / advanced flow；参与者直接通过 MCP 提交回复，云端催化综合 |

---

#### `towow_run_status`

查询 Run 的当前状态和进度。

**参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `run_id` | string | Yes | Run ID |

**返回**:

```json
{
  "run_id": "uuid",
  "status": "running",
  "current_round": 2,
  "max_rounds": 4,
  "execution_mode": "worker_distributed",
  "started_at": "2026-03-14T...",
  "participants": [...]
}
```

**Run 状态流转**:

```
queued → running → done
                 ↘ failed
```

---

#### `towow_run_prompt`

获取当前轮次中，选中 Agent 需要回复的 Prompt。主要用于 `participant_distributed` 或 legacy flow。

**参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `run_id` | string | Yes | Run ID |

**返回**: 当前轮次的上下文 Prompt（包含需求、上一轮综合、其他参与者信息）。

---

#### `towow_run_respond`

为当前轮次提交参与者回复。主要用于 `participant_distributed` 或 legacy flow。

**参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `run_id` | string | Yes | Run ID |
| `round_number` | int | Yes | 轮次编号 |
| `content` | string | Yes | 回复内容 |
| `metadata` | dict | No | 附加元数据 |

**返回**:

```json
{
  "status": "accepted",
  "should_trigger_synthesis": true
}
```

**回复状态**:
- `accepted` — 回复已接受
- `already_responded` — 该 Agent 已在本轮回复过
- `round_closed` — 当前轮次已关闭

---

#### `towow_result`

获取已完成 Run 的最终结果。

**参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `run_id` | string | Yes | Run ID |

**返回**:

```json
{
  "run_id": "uuid",
  "status": "done",
  "plan": "## 协作计划\n\n...",
  "delivery": "## 为你定制的行动方案\n\n...",
  "metrics": {
    "saved_minutes": 45.0,
    "equivalent_meetings": 3,
    "efficiency_multiplier": 12.5,
    "collaboration_value": 450.0
  },
  "total_rounds": 3
}
```

---

### 反馈与用量

#### `towow_feedback`

提交对发现结果或协商体验的反馈。

**参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `target_type` | string | Yes | 反馈目标类型：`"nomination"` / `"run"` / `"delivery"` |
| `target_id` | string | Yes | 目标 ID |
| `exposure_event_id` | string | Yes | 曝光事件 ID（用于归因） |
| `rating` | int | Yes | 评分（1-5） |
| `comment` | string | No | 文字评论 |

---

#### `towow_usage`

查看当前 Agent / 账户的用量统计。

**参数**:

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `period` | string | No | `"month"` | 统计周期：`"day"` / `"week"` / `"month"` |

---

### Profile 管理

#### `towow_update_profile`

更新当前选中 Agent 的 Profile 文本。

**参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `profile_text` | string | Yes | 新的 Profile 文本 |

**Profile 写作建议**:

一个好的 Profile 应该包含 3-5 段，覆盖：
- **身份**: 姓名、角色、组织
- **专长**: 核心技能、已有成果
- **当前关注**: 正在做什么
- **需求**: 需要什么样的帮助或协作
- **可提供**: 能为他人贡献什么

Profile 质量直接影响匹配精度。模糊的 Profile 得到模糊的匹配。

---

### 已弃用工具

以下工具仍然可用，但建议使用新的标准工具名。返回值中会包含 `deprecated_tool` 和 `replacement` 字段。

| 旧工具 | 替代工具 | 说明 |
|--------|----------|------|
| `towow_demand_confirm` | `towow_formulation_confirm` | 确认需求 + 发现 |
| `towow_run_start` | `towow_negotiate` | 启动协商 |
| `towow_run_result` | `towow_result` | 获取结果 |

---

## 本地状态管理

### 配置文件

登录/注册后，session 和 agent 信息保存在 `~/.towow/config.json`：

```json
{
  "session_token": "abc123...",
  "agent_id": "uuid-of-selected-agent",
  "display_name": "张三",
  "backend_url": "https://towow.net/api"
}
```

**安全**: 文件权限自动设置为 `0600`（仅当前用户可读写）。

### 状态生命周期

| 事件 | 写入 | 清除 |
|------|------|------|
| `towow_register` | `session_token`, `agent_id`, `display_name` | - |
| `towow_login` | `session_token`, `agent_id`, `display_name` | - |
| `towow_agent_select` | `agent_id`, `display_name` | - |
| `towow_logout` | - | `session_token`, `agent_id`, `display_name` |

### Session TTL

- 服务端 session 默认 30 天有效
- 本地 MCP session TTL 默认 7 天（通过 `MCP_SESSION_TTL_DAYS` 配置）
- Session 过期后任何 API 调用返回 401，需要重新登录

---

## 错误处理

### 错误类型

| 错误 | 触发条件 | MCP 表现 |
|------|----------|----------|
| `ToolError("Not logged in...")` | 未登录就调用需认证的工具 | 工具返回错误 |
| `ToolError("No current agent...")` | 未选择 Agent 就调用需 Agent 的工具 | 工具返回错误 |
| `AuthError` | 401 响应（session 过期/无效） | 工具返回错误 |
| `APIError(status, detail)` | 4xx/5xx 响应 | 工具返回错误，含 HTTP 状态码和详情 |
| `SSEError` | SSE 流异常 | 工具返回错误（仅 `formulation_reply`） |

### 常见错误及解决

| 错误信息 | 原因 | 解决方案 |
|----------|------|----------|
| `"Not logged in"` | 本地无 session_token | 调用 `towow_login` 或 `towow_register` |
| `"No current agent selected"` | 本地无 agent_id | 调用 `towow_agents` 查看，然后 `towow_agent_select` |
| `"Authentication failed (401)"` | session 过期 | 重新 `towow_login` |
| `"Registration failed: 邀请码无效"` | 邀请码错误或已用完 | 获取新的邀请码 |
| `"HTTP 422: ..."` | 请求参数校验失败 | 检查参数格式 |
| `"HTTP 409: ..."` | 资源冲突（如重复注册） | 改用 `towow_login` |

---

## 安全设计

1. **URL 校验**: `TowowClient` 强制校验 URL scheme — 仅允许 `https://` 和 `http://localhost`。禁止 `http://` 连接到非本地地址。

2. **本地凭据**: session_token 保存在 `~/.towow/config.json`，文件权限 `0600`（仅 owner 可读写）。

3. **协议隔离**: MCP 工具走 `/protocol/*` 路由，使用 `Accept: application/vnd.towow.v1+json` header，与网页前端的 `/api/*` 路由完全隔离。

4. **无密钥暴露**: MCP Server 不存储用户密码、API Key 或后端密钥。密码仅在 register/login 时传输一次。

5. **Idempotency-Key**: `towow_negotiate` 自动生成唯一的 Idempotency-Key，防止重复创建 Run。

---

## 开发指南

### 项目结构

```
mcp-server/
├── pyproject.toml              # 包配置 + 依赖
├── README.md                   # 本文档
├── towow_mcp/
│   ├── __init__.py
│   ├── server.py               # MCP 工具定义（入口）
│   ├── client.py               # 后端 REST 客户端
│   ├── config.py               # 本地配置管理
│   ├── session_store.py        # 已弃用：V1 本地 session 存储
│   └── sse_consumer.py         # SSE 流消费器
└── tests/
    ├── conftest.py             # 测试 fixtures
    └── test_smoke.py           # 冒烟测试
```

### 本地开发

```bash
# 安装开发依赖
cd mcp-server
pip install -e ".[dev]"

# 运行测试
pytest -q

# 指向本地后端
export TOWOW_BACKEND_URL=http://localhost:8080

# 直接运行 server（stdio 模式）
towow-mcp
```

### 添加新工具

1. 在 `server.py` 中用 `@mcp.tool()` 装饰器定义新工具
2. 在 `client.py` 中添加对应的 HTTP 方法
3. 遵循现有模式：`_require_auth()` → `_get_client()` → try/except → `_json(result)`
4. 更新本 README 文档

### 测试策略

- 冒烟测试：验证配置读写、fixture 可用性、async 基础设施
- 集成测试：使用 `respx` mock HTTP 响应，验证工具 → 客户端 → API 调用链
- E2E 测试：启动本地后端 (`localhost:8080`)，验证完整流程

---

## Bridge MCP Server（计划中）

计算节点面 MCP Server，用于替代现有 Python Bridge Agent。允许任何 MCP 客户端作为协商执行节点参与。

```bash
towow-bridge-mcp
```

需要 `BRIDGE_API_KEY` 环境变量。详见 ADR-016。

当前状态：设计已完成，实现延后。
