内容
<p align="center">
<a href="https://github.com/ChrQR/traggo-mcp-server">
<img height="300px" src="https://github.com/ChrQR/traggo-mcp-server/blob/main/assets/traggo_gopher_transparent.webp" />
</a>
</p>
# Traggo MCP 服务器
MCP 服务器,允许 AI 助手在 [Traggo](https://traggo.net/) 中跟踪时间。它将 MCP 工具调用代理到 Traggo 实例的 GraphQL API,并附带一个小型 Web UI,用于获取身份验证令牌。
## 工作原理
服务器有两个接口:
1. **Web 登录(`/login`)** - 使用 Traggo 用户名和密码登录,并获取 Traggo 设备令牌。该令牌显示在屏幕上,供您复制。
2. **MCP 端点(`/mcp`)** - 您的 MCP 客户端连接此处,并将令牌作为 `Authorization: Bearer <token>` 头部发送。每个工具调用都被转换为 Traggo GraphQL 请求(以 `Authorization: traggo <token>` 方案发送,这是 Traggo 期望的)。
服务器是无状态的 - 它不存储任何内容。Traggo 令牌是整个身份验证状态。
```
┌─────────────┐ Bearer <token> ┌──────────────┐ traggo <token> ┌────────────┐
MCP 客户端 │ POST /mcp │ ─────────────────► │ traggo-mcp │ ─────────────────► │ Traggo │
└─────────────┘ │ (此服务器)│ GraphQL │ 实例 │
└──────────────┘ └────────────┘
浏览器 ── GET/POST /login ──────────────► 返回设备令牌以复制
```
## 工具
| 工具 | 描述 |
|------|-------------|
| `start_timer` | 启动一个正在运行的计时器(打开时间范围),带有标签和备注。启动默认为现在。 |
| `stop_timer` | 通过 ID 停止正在运行的计时器。结束默认为现在。 |
| `add_timespan` | 记录一个已完成的具有明确开始/结束时间、标签和备注的时间范围。 |
| `update_timespan` | 通过 ID 编辑时间范围的开始、结束、标签和备注。 |
| `remove_timespan` | 通过 ID 删除时间范围。 |
| `list_timers` | 列出当前正在运行的计时器(查找要停止的 ID)。 |
| `list_timespans` | 列出已记录的时间范围,可选地在 RFC3339 时间范围内(查找要编辑的 ID)。 |
| `list_tags` | 列出所有标签定义(键、颜色、使用计数)。 |
| `create_tag` | 创建一个标签定义(键 + 十六进制颜色)。 |
| `update_tag` | 更改标签的颜色和可选地重命名它。 |
| `remove_tag` | 通过键删除标签定义。 |
| `ping_auth` | 诊断 - 回声令牌以验证身份验证线路。 |
标签是键/值对(例如 `{ "key": "project", "value": "traggo" }`)。时间是 RFC3339(例如 `2026-06-28T09:00:00Z`)。
## 运行
服务器需要一个环境变量:`TRAGGO_URL`,您的 Traggo 实例的基本 URL(不带尾部斜杠)。
```sh
export TRAGGO_URL=https://traggo.example.com
go run ./cmd/server
```
它监听 `:8080`。打开 <http://localhost:8080/login> 获取令牌,然后将您的 MCP 客户端指向 `http://localhost:8080/mcp`。
### 连接 MCP 客户端
使用指向 `/mcp` 的可流式 HTTP MCP 传输,并将令牌作为持有者凭证。例如,在支持 HTTP MCP 服务器的客户端中:
```json
{
"mcpServers": {
"traggo": {
"url": "http://localhost:8080/mcp",
"headers": { "Authorization": "Bearer <your-traggo-token>" }
}
}
}
```
## 开发
### 先决条件
- [Go](https://go.dev/) 1.26+
- [templ](https://templ.guide/) — `go install github.com/a-h/templ/cmd/templ@latest` (HTML 模板)
- [Bun](https://bun.sh/) — 通过 `bunx` 运行 Tailwind CLI
- [air](https://github.com/air-verse/air) — `go install github.com/air-verse/air@latest` (热重载,可选)
- [Dagger](https://dagger.io/) — 仅在构建/发布容器镜像时需要
### 热重载开发循环
```sh
export TRAGGO_URL=https://traggo.example.com
air
```
`air`(在 `.air.toml` 中配置)重新生成模板和 CSS,重新构建,并提供热重载到 <http://localhost:8090>(代理应用到 `:8080`)。
### 手动构建资产
如果您不使用 `air`:
```sh
templ generate # .templ → _templ.go
bunx @tailwindcss/cli -i ./app.css -o assets/output.css # 构建 CSS
go run ./cmd/server
```
### 项目布局
```
cmd/server/ 入口点:路由连接,启动 HTTP 服务器
internal/
auth/ Web 登录流程 → Traggo 设备令牌
mcp/ MCP 服务器:工具注册 + 持有者令牌中间件
traggo/ Traggo API 的 GraphQL 客户端(所有计时器/时间范围/标签操作)
views/ templ 组件和 Web UI 页面
assets/ 静态文件(生成的 CSS、图像)
.dagger/ 用于构建和发布容器镜像的 Dagger 模块
```
## 构建和发布镜像
容器镜像使用 [Dagger](https://dagger.io/) 构建 - 一个多阶段构建(在 `golang:1.26` 上编译,在 `wolfi-base` 上运行时),发布到容器注册表。注册表、凭证和镜像名称都是参数:
```sh
dagger call build \
--source . \
--registry registry.example.com \
--username you@example.com \
--registry-password env:REGISTRY_PASSWORD \
--image traggo-mcp:latest
```
`--source` 默认值为 `.` ,`--image` 默认值为 `traggo-mcp:latest`。该函数返回已发布的镜像引用。
## 贡献
欢迎贡献。要开始:
1. 复刻并克隆仓库。
2. 安装上述先决条件,并针对您控制的 Traggo 实例运行 `air`(或手动构建步骤)。
3. 进行更改。如果您触摸 `.templ` 文件,请运行 `templ generate`。如果您添加或更改依赖项,请运行 `go mod tidy`。
4. 确保 `go build ./...` 和 `go vet ./...` 通过。
5. 打开拉取请求,描述更改。
添加新工具时,模式为:
- 在 `internal/traggo/types.go` 中定义输入/输出类型(使用 `jsonschema` 结构体标签,以便 MCP 模式具有描述性)。
- 将操作函数添加到 `internal/traggo/service.go` (它通过共享的 `execute` 助手进行身份验证和错误处理)。
- 在 `internal/mcp/server.go` 中注册工具。
Traggo GraphQL 模式是可用操作和字段名称的真实来源。