内容
握
<p align=" <a href="pypi.org/project/handshake-server/" target="_blank src="https://img/pypi/v/handshake-mcp-server?color=blue"PyPI"></a>
a href="https:///sudhxnva/handcp-server/actions/workflows/ target="_blank"><="https://github.comxnva/handshake-m/actions/workflows/ci.yml?branch=master" alt="CI 状态"></a>
<a href="https://github.comxnva/handshake-m/actions/workflows/publish.yml="_blank"><img src://github.com/sudh/handshake-mcp-server/publish.yml/badge.svg="发布"></a>
a href="https:///sudhxnva/handcp-server/blob/master/LICENSE" target="_blank"><img src="https://img.shields.io/badge/License-Apache%202.ightgreen?labelColorf" alt="许可证"></a>
</p>
通过这个握手 MCP 服务器,像 Claude 这样的 AI 助手可以 [Handshake](https://handshake.com) 账户 — 领先的学生实习和。搜索工作,主,探索活动,并学生或雇主资料,所有这些都可以在 AI 聊天中完成。
## 安装方法
[](#-uvx-设置-推荐)
[](#-docker-设置)
[](#-本地开发-贡献)
<!-- 添加演示视频 -->
##
```
在旧金中找到软件工程实习机会```
Handshake 本周到来的活动?
```
职位发布 12345678 的详细信息 — 它是否赞助签证?
```
```
在 Handshake 上为 Google 显示雇主```
## 功能与工具
| 工具 | 描述 | 状态------|-------------|-------- `get_student_profile`用户 ID 获取学生的个人资料(教育、经验、技能等) | 工作中 |
| `get_employer_profile` | 获取雇主概述、开放职位和评论 | 工作中 |
search_employers`关键词搜索雇主 | |
| `get_job | 获取完整的职位发布信息,包含元数据(薪水、签证、日期) | 工作中 |
| `search_jobs` | 按关键词、地点、类型和排序筛选搜索职位 | 工作中 |
| `get_event_details` | 获取职业博览会和信息会议的活动详细信息 | 工作中 |
| `search_events` | 搜索即将到来的活动 | 工作中 |
| `close_session` | 关闭浏览器会话并释放资源 | 工作中 |
> [!IMPORTANT]
> Handshake 是一个 **学生门控平台** — 您必须拥有有效的学生账户并登录后,工具才会生效。运行 `uvx handshake-mcp-server --login`(或设置向导)进行身份验证。
<br/>
## 🚀 uvx 设置(推荐)
**前提条件:** [安装 uv](https://docs.astral.sh/uv/getting-started/installation/) 和有效的 Handshake 学生账户。
### 1. 安装 Patchright Chromium 浏览器(一次性)
```bash
uvx --from handshake-mcp-server patchright install chromium
```
### 2. 运行设置向导
```bash
uvx handshake-mcp-server setup
```
向导会询问您是否要使用 Docker 或本地模式,处理登录,并打印注册服务器与 MCP 客户端的确切 `claude mcp add-json` 命令。
### 3. 使用 MCP 客户端注册
设置完成后,粘贴向导打印的命令。例如:
```bash
# 本地模式(在您的机器上打开一个浏览器窗口)
claude mcp add-json handshake '{"command":"uvx","args":["handshake-mcp-server"]}'
# Docker 模式(在容器中无头运行)
claude mcp add-json handshake '{"command":"uvx","args":["handshake-mcp-server","docker"]}'
```
或手动添加到您的 MCP 客户端配置(`claude_desktop_config.json` 或等效):
```json
{
"mcpServers": {
shake": {
"command": "uvx",
args": ["handshake-mcp-server"]
}
}
}
```
重启您的 MCP 客户端。完成。
> [!NOTE]
> 服务器在其整个生命周期中保持单个 Chromium 浏览器 这避免了重新身份验证的开销,并使后续工具调用更快。借助-headless`,在会话期间保持可见。这是正常的。
### uvx 设置帮助
<details>
<summary><b>🔧选项</b></summary>
| 标志 | 描述 |
|------|-------------|
| `--login` | 打开浏览器进行手动登录,保存个人资料,然后退出 |
| `--logout` | 清除保存的身份验证个人资料并退出 |
| `--status` | 检查当前会话状态并退出 |
| `--no-headless` | 在有头(可见)模式下运行浏览器 |
| `--virtual-display` | 通过 Xvfb 虚拟帧缓冲区运行(仅限 Linux) |
| `--vnc-login` | 启动基于浏览的 noVNC 网络服务器 |
| `--vnc-port` | noVNC 服务器的端口(默认:6080) |
| `--transport` | MCP 传输:`stdio`(默认)或 `streamable-http` |
| `--host` | HTTP 主机(默认:127.0.0.1) |
| `--port` | HTTP 端口(默认:8000) |
| `--log-level` | `DEBUG`、`INFO`、`WARNING` 或 `ERROR`(默认:WARNING) |
**HTTP 模式示例:**
```bash
uvx handshake-mcp-server --transport streamable-http --host 127.0.0.1 --port 8000
```
</details>
<details>
<summary><b>❗ 故障排除</b></summary>
**登录问题:**
- 确保您拥有有效的 Handshake 学生账户
- Handshake 可能会在首次登录时显示验证码 — `--login` 打开浏览器,以便您手动解决
- 如果您的会话过期,请重新运行 `uvx handshake-mcp-server --login`
**Cloudflare 检测:**
- Handshake 使用 Cloudflare 机器人保护。在任何具有 GUI 的桌面上,请始终使用 `--no-headless`(设置向导会自动执行此操作)
- 在无头 Linux 服务器上,使用 `--virtual-display` 避免无头指纹
- 有关详细信息,请参阅 [Cloudflare 机器人检测](#cloudflare-机器人检测)
**会话问题:**
- 浏览器个人资料存储在 `~/.handshake-mcp/profile/`
- 运行 `uvx handshake-mcp-server --status` 检查您的会话是否仍然有效
- 运行 `uvx handshake-mcp-server --logout` 清除个人资料并重新开始
**:**
- 确保已安装 uv:`curl -LsSf https://astral.sh/uv/install.sh | sh`
- 安装 Chromium 浏览器:`uvx handshake-mcp-server` 将在首次运行时自动安装
</details>
<br/>
## 🐳 Docker 设置
**前提条件:** [Docker://www.docker.com/) 已安装并正在运行。不需要其他依赖项。
Docker 在容器中运行服务器,使用 Xvfb 虚拟显示 — 您的机器上没有浏览器窗口。浏览器个人资料(cookie/存储在命名的 Docker 卷(`handshake-profile`)中,并在容器重启后持续存在。
### 1. 一次性登录
```bash
docker compose build
docker compose run --rm -p 6080:6080 handshake-mcp --vnc-login
```
在浏览器中打开 `http://localhost:6080/vnc.html` 并手动登录到 Handshake。
### 2. 启动服务器
```bash
docker compose up -d
```
MCP 服务器现在可在 `http://127.0.0.1:8000/mcp`(streamable-http 传输)上使用。
### 3. 配置您的 MCP 客户端
```json
{
"mcpServers": "handshake": {
"command": "docker "args": [
"run", "--rm", "-i",
"-v", "handshake-profile:/home/pwuser/.handshake-mcp",
"handshake-mcp-server",
"--transport", "stdio",
"--virtual-display"
]
}
}
}
```
### Docker 设置帮助
<details>
<summary><b>🔧 有用命令</b></summary>
```bash
docker compose logs -f # 尾随服务器日志
docker compose run --rm handshake-mcp --status # 检查会话有效性
docker compose down # 停止服务器
docker rmi -f handshake-mcp-server && docker volume rm -f handshake-profile # 完全重置
```
</details>
<details>
<summary><b>❗ 故障排除</b></summary>
**登录问题:**
- 在启动 `--vnc-login` 后 5 分钟内打开 `http://localhost:6080/vnc.html`
- 如果会话过期,请重复一次性登录步骤
- Chromium 可能会在容器终止后在个人资料目录中留下锁定文件(`SingletonLock`)— 服务器在下次启动时会自动清理这些文件
**Docker 问题:**
- 检查 Docker 是否正在运行:`docker ps`
- 拉取新代码后重新构建:`docker compose build`
- 完全重置:`docker rmi -f handshake-mcp-server && docker volume rm -f handshake-profile`
</details>
<br/>
## 🐍 本地设置(开发和贡献)
欢迎贡献!请参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 获取架构指南和 PR 检查清单。请在提交 PR 之前 [打开问题](https://github.com/sudhxnva/handshake-mcp-server/issues) 讨论您的更改。
**前提条件:** [Git](https://git-scm.com/downloads) 和 [uv](https://docs.astral.sh/uv/) 已安装。
```bash
# 1. 克隆仓库
git clone https://github.com/sudhxnva/handshake-mcp-server
cd handshake-mcp-server
# 2. 安装依赖项
uv sync --group dev
# 3. 安装 Chromium 浏览器
uv run patchright install chromium
# 4. 登录(打开浏览器窗口)
uv run -m handshake_mcp_server --login --no-headless
# 5. 启动服务器
uv run -m handshake_mcp_server --no-headless
```
### 本地设置帮助
<details>
<summary><b>🔧 开发命令</b></summary>
```bash
uv run ruff check . # 检查代码规范
uv run ruff check . --fix # 检查代码规范并自动修复
uv run ruff format . # 格式化代码
uv run ty check # 类型检查
uv run pytest # 测试
uv run pytest --cov # 测试并生成覆盖率报告
```
**用于本地开发的 Claude Desktop 配置:
```json
{
"mcpServers": {
"handshake": {
"command": "uv",
"args": ["--directory", "/path/to/handshake-mcp-server", "run", "-m", "handshake_mcp_server"]
}
}
}
```
</details>
<details>
<summary><b>❗ 故障排除</b></summary>
**爬取问题:**
- 使用 `--no-headless` 观察浏览器操作并调试爬取问题
- 添加 `--log-level DEBUG` 获取详细日志
**Python/Patchright 问题:**
- 需要 Python 3.12+:`python --version`
- 重新安装 Patchright:`uv run patchright install chromium`
- 重新安装依赖项:`uv sync --reinstall`
</details>
<br/>
## Cloudflare 机器人检测
Patchright 在 `headless=True` 时 **不** 绕过 Cloudflare 的无头指纹 — 该模式使用 `-headless-shell` 二进制文件,容易被检测。
| 环境 | 解决方案 |
|---|---|
| 具有 GUI 的桌面(macOS、Windows、Linux) | 使用 `--no-headless` — 打开一个真正的浏览器窗口 |
| 无头 Linux 服务器 | 使用 `--virtual-display` — Chrome 在 Xvfb 虚拟显示上运行非无头 |
| Docker | 默认 CMD 已经使用 `--virtual-display` |
Cloudflare 挑战页面会自动被检测到,如果无法解决,则会引发 `RateLimitError`。
<br/>
## 工具返回格式
所有爬取工具均返回:
```json
{
"url": "string",
"sections": { "section_name": "raw text content" },
"references": { "section_name": [{ "kind": "job", "url": "/jobs/123", "text": "..." }] },
"section_errors": { "section_name": { "error_type": "...", "error_message": "..." } },
"unknown_sections": ["invalid_section_name"]
}
```
`get_job_details` 还返回一个包含结构化字段的 `metadata` 键:
```json
{
"metadata": {
"id": "123", "title": "软件工程师实习生", "company": "Acme Corp",
"salary": 3000, "salary_type": "hourly",
"work_type": "hybrid", "locations": ["旧金山,CA"],
"job_type": "internship", "employment_type": "part_time",
"start_date": "2025-06-01", "end_date": "2025-08-31",
"deadline": "2025-03-01", "posted_at": "2025-01-15",
"work_auth_required": false, "accepts_opt": true, "accepts_cpt": false,
"will_sponsor": true, "apply_url": "https://..."
}
}
```
> [!NOTE]
> GraphQL API 中的薪水值以 **分** 为单位 — 除 100 后得到美元。
`search_jobs` 还返回 `jobs`(卡级元数据列表)和 `job_ids`。`search_employers` 返回 `employer_ids`。`search_events` 返回 `event_ids`。
<br/>
## 致谢
使用 [FastMCP](https://gofastmcp.com/) 和 [Patchright](https://github.com/Kaliiiiiiiiii-Vinyzu/patchright-python) 构建。灵感来自 [linkedin-mcp-server](https://github.com/stickerdaniel/linkedin-mcp-server) 的架构。
请遵守 [Handshake 的服务条款](https://joinhandshake.com/tos/)。网页抓取可能会违反平台条款。本工具仅供个人使用。
## 许可证
Apache-2.0 — [LICENSE](