内容
# freelancer-mcp
用于 [freelancer.com](https://www.freelancer.com) 账户的Go命令行工具和MCP服务器。登录一次,将会话保存在磁盘上,然后浏览项目、投标、给客户发消息、编辑个人资料、跟踪里程碑,所有这些都可以在终端或AI代理中完成。
两个可执行文件:
| 二进制文件 | 用途 |
| --- | --- |
| `freelancer` | 人类和脚本的命令行工具 |
| `freelancer-mcp` | 为AI代理提供标准输入输出的模型上下文协议服务器(45种工具) |
适用于 freelancer.com 及其区域域名(freelancer.co.id, freelancer.com.au, …),它们共享一个账户系统和一个API。
## 要求
- Go 1.23 或更新版本
- 一个 freelancer.com 账户(与网页应用使用相同的端点)
## 安装
```bash
go install github.com/igun997/freelancer-mcp/cmd/freelancer@latest
go install github.com/igun997/freelancer-mcp/cmd/freelancer-mcp@latest
```
从源码编译:
```bash
git clone git@github.com:igun997/freelancer-mcp.git
cd freelancer-mcp
make build # bin/freelancer 和 bin/freelancer-mcp,版本号从git记录
make check # gofmt + vet + 测试
```
## 快速开始
```bash
bin/freelancer login --user you@example.com # 输入密码
bin/freelancer whoami # 确认会话
bin/freelancer quota # 本月剩余投标次数
bin/freelancer projects --query golang --limit 5
bin/freelancer messages threads --unread
```
然后将AI代理指向同一个会话:
```bash
bin/freelancer-mcp # 标准输入输出MCP服务器
```
## 登录
```bash
freelancer login --user you@example.com # 输入密码
freelancer login --user you@example.com --password-stdin < pass.txt
freelancer login --user you@example.com --otp 123456 # 双因素认证账户
```
登录流程与网页应用一致:
1. `GET www.freelancer.com/auth/device` 返回一个短期的设备令牌。
2. `POST www.freelancer.com/ajax-api/auth/login.php` 返回 `{token, user, userRole}`。
3. 之后的每个调用都携带 `freelancer-auth-v2: <user_id>;<token>`。
正常密码登录无需cookie、无需浏览器、无需验证码。认证哈希值不透明且无过期时间,因此命令行工具通过调用 `/users/0.1/self/` 验证它。
会话状态存储在 `~/.config/freelancer/session-<profile>.json`,目录权限为 `0700`,文件权限为 `0600`。使用 `--profile NAME` 管理多个账户。
`--save-credentials` 将用户和密码存储在该文件中,以便命令行工具和MCP服务器在令牌被拒绝时自动重新登录。密码以明文写入;任何可以读取该文件或其备份的人都可以以您的身份登录。可以使用 `freelancer session forget-credentials` 删除它。
## 命令行工具
```bash
# 个人资料
freelancer profile show
freelancer profile update --tagline "后端 & API 工程师" --hourly-rate 25
freelancer profile update --summary-file bio.txt # 100字符以上
freelancer profile skills # 当前技能
freelancer profile skills --add 248 # Golang
freelancer profile skills --set 3,248,305 # 替换列表
freelancer profile avatar --file me.png --width 400 --height 400
freelancer profile cv --section experience --list
freelancer profile cv --section experience \
--add '{"title":"后端工程师","company":"Acme","start_date":"2021-03","end_date":"present"}'
freelancer profile schools --country ID --query komputer # 学校ID用于教育条目
freelancer profile cv --section education \
--add '{"school_id":3997,"country_code":"ID","degree":"Bachelor of Information Systems","start_date":"2015-09","end_date":"2019-09"}'
freelancer profile role employer # 切换活动角色
freelancer profile currency --id 1 # 美元
freelancer profile portfolio
freelancer profile reputation
# 寻找工作
freelancer skills --query golang # 技能名称 -> 工作ID
freelancer projects --query golang --types fixed --min-budget 250 --limit 10
freelancer projects --jobs 248,305 --full
freelancer project get --id 40608147
freelancer project bids --id 40608147
freelancer freelancers --query golang --limit 5
# 投标
freelancer quota
freelancer limits # 可以投标的项目,什么阻止了其他项目
freelancer bid place --project 40608147 --amount 250 --days 7 --proposal-file pitch.md
freelancer bid update --id 165487951 --amount 300
freelancer bid retract --id 165487951
freelancer bids --status active,in_progress
freelancer bid award --id 165487951 # 雇主方
# 消息
freelancer messages threads --unread
freelancer messages show --thread 123456 --limit 30
freelancer messages send --thread 123456 --message "马上开始,今晚草稿"
freelancer messages send --thread 123456 --file build.zip
freelancer messages read --thread 123456
freelancer messages new --members 987654 --context-type project --context 40608147 --message "你好"
# 金钱和交付
freelancer money balances
freelancer money invoices
freelancer money payout-accounts
freelancer money membership
freelancer milestones list
freelancer milestones requests
freelancer milestones request --project 40608147 --bid 165487951 --amount 125 --description "第一阶段"
# 其他
freelancer notifications --limit 10
freelancer notifications --saved-searches
freelancer reviews
freelancer currencies
freelancer api --query 'balance_details=true' /users/0.1/self/
freelancer api --method PUT --data '{"tagline":"Go开发"}' /users/0.1/self/profile
```
在任何命令上添加 `--json` 以获取机器可读的输出。命令行工具无法封装的内容都可以通过 `freelancer api` 访问;`docs/api-notes.md` 列出了网页应用本身使用的路径。
## MCP服务器
```bash
freelancer-mcp # 标准输入输出,使用默认配置文件
freelancer-mcp --profile work
```
客户端配置,例如Claude Desktop或任何支持MCP的代理:
```json
{
"mcpServers": {
"freelancer": {
"command": "freelancer-mcp",
"args": ["--profile", "default"]
}
}
}
```
工具组:
- **账户** — `freelancer_whoami`, `freelancer_profile_get`, `freelancer_profile_update`, `freelancer_profile_skills`, `freelancer_profile_cv`, `freelancer_schools_search`, `freelancer_profile_picture_upload`, `freelancer_portfolio_list`, `freelancer_account_settings`, `freelancer_reputation`, `freelancer_reviews`, `freelancer_currencies`, `freelancer_skills_search`, `freelancer_freelancers_search`
- **工作** — `freelancer_projects_search`, `freelancer_project_get`, `freelancer_project_bids`, `freelancer_projects_mine`, `freelancer_project_post`, `freelancer_bids_list`, `freelancer_bid_quota`, `freelancer_bid_place`, `freelancer_bid_update`, `freelancer_bid_action`, `freelancer_manage_bids`
- **消息** — `freelancer_threads_list`, `freelancer_messages_list`, `freelancer_messages_search`, `freelancer_message_send`, `freelancer_thread_action`, `freelancer_thread_new`, `freelancer_thread_attachments`, `freelancer_notifications`, `freelancer_saved_searches`
- **金钱** — `freelancer_balances`, `freelancer_invoices`, `freelancer_payout_accounts`, `freelancer_membership`, `freelancer_milestones_list`, `freelancer_milestone_requests_list`, `freelancer_milestone_request_create`, `freelancer_milestone_request_action`, `freelancer_milestone_release`
- **限制** — `freelancer_account_limits`(剩余投标次数,美元上限,精选访问权限,阻止因素)
- **紧急出口** — `freelancer_api_call`
需要确认的操作,例如花费钱、消耗配额或无法撤销的操作,需要 `confirm=true`: `freelancer_bid_place`, `freelancer_project_post`, `freelancer_milestone_release`, 和 `freelancer_bid_action` 用于撤销、授予、撤销、拒绝。
## 平台说明
- **投标配额和上限。** 免费账户每月获得少量额度,价值 **$2,500 美元或以上的项目需要通过 Freelancer 验证**,精选项目需要 5 条评论、付费会员或验证。`freelancer limits` 报告所有这些,包括当前阻止您的内容,以免您在 API 拒绝的项目上花费投标。
- **货币。** 每个项目都有自己的货币;投标金额以项目的货币为单位,对于按小时计费的项目,它是每小时费率。在比较预算之前使用 `currency.exchange_rate` 进行转换。
- **个人资料写入。** `PUT /users/0.1/self/profile` 接受三个字段:`tagline`, `profile_description`, `hourly_rate`。其他账户设置位于单独的端点(`self/account`, `self/primary_currency`, `self/operating_areas`)。
- **简历日期。** Freelancer 存储 epoch 秒,但重新解释为 GMT+7,因此月初日期显示为上个月。传递 `"YYYY-MM"`, `"YYYY-MM-DD"`, 或 `"present"`,客户端为您锚定月中。对于教育条目,需要从 `freelancer profile schools` 获取 `school_id`;纯粹的学校名称被 API 丢弃。
- **冷消息。** Freelancer 拒绝向没有共享项目上下文的用户发起新线程。
- **实时。** 网页应用在 `notifications.freelancer.com` 使用 SockJS 通道;此客户端改为轮询。
`docs/api-notes.md` 记录了身份验证流程、调用约定和端点映射。`docs/_raw-endpoints.txt` 和 `docs/_raw-endpoint-payloads.txt` 是从网页应用包中提取的原始清单,涵盖了比赛、小组、任务和企业路由,这些路由尚未有专用的命令。
## 环境
| 变量 | 用途 |
| --- | --- |
| `FREELANCER_USER`, `FREELANCER_PASSWORD` | 登录凭证 |
| `FREELANCER_PROFILE` | 默认配置文件名称 |
| `FREELANCER_SESSION_DIR` | 会话存储目录 |
| `FREELANCER_API_BASE`, `FREELANCER_WEB_BASE` | 端点重写 |
| `FREELANCER_USER_AGENT`, `FREELANCER_LANGUAGE` | 请求标识 |
| `FREELANCER_TIMEOUT` | 请求超时,例如 `45s` |
## 开发
```bash
make check # gofmt, vet, 测试
make test # go test -race ./...
make build
```
测试是密封的:它们在 `httptest` 服务器和临时会话目录上运行,因此 `go test ./...` 永远不会触及真实账户。
## 免责声明
非官方客户端。它使用与 freelancer.com 网页应用相同的端点和文档化的 `/api/**/0.1/**` 路由。请使用您自己的账户,并遵守 Freelancer 的服务条款。