@amonstack/gitea-mcp 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -9
- package/README.zh-CN.md +46 -9
- package/dist/assets/instructions.md +63 -0
- package/dist/assets/resources/field-reference.md +48 -0
- package/dist/assets/resources/label-guide.md +47 -0
- package/dist/assets/resources/tool-cookbook.md +51 -0
- package/dist/assets/skills/gitea-create-issue/SKILL.md +21 -0
- package/dist/assets/skills/gitea-find-issues/SKILL.md +31 -0
- package/dist/assets/skills/gitea-label-issue/SKILL.md +28 -0
- package/dist/assets/skills/gitea-manage-labels/SKILL.md +22 -0
- package/dist/assets/skills/gitea-plan-milestones/SKILL.md +24 -0
- package/dist/assets/skills/gitea-resolve-repo/SKILL.md +18 -0
- package/dist/assets/skills/gitea-summarize-issue/SKILL.md +21 -0
- package/dist/assets/skills/gitea-update-issue/SKILL.md +21 -0
- package/dist/cli.js +23 -11
- package/dist/cli.js.map +1 -1
- package/dist/server.js +171 -26
- package/dist/server.js.map +1 -1
- package/dist/skills.d.ts +24 -0
- package/dist/skills.js +113 -0
- package/dist/skills.js.map +1 -0
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -97,6 +97,18 @@ Add to your opencode MCP configuration:
|
|
|
97
97
|
|
|
98
98
|
If you built from source, use `node /path/to/gitea-mcp/dist/cli.js` instead.
|
|
99
99
|
|
|
100
|
+
opencode also loads native **skills** — one per action (find, create, update,
|
|
101
|
+
label, summarize, plan milestones, resolve repo) — that teach the assistant the
|
|
102
|
+
safest workflow for that action, including pre-use checks and pitfalls. Install
|
|
103
|
+
them once:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
gitea-mcp skills install # global (~/.config/opencode/skills/)
|
|
107
|
+
gitea-mcp skills install --project # this project (./.opencode/skills/)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Then restart opencode. See [AI Guidance & Skills](#ai-guidance--skills) below.
|
|
111
|
+
|
|
100
112
|
### Other MCP Clients
|
|
101
113
|
|
|
102
114
|
Any client that supports stdio-based MCP servers can use `gitea-mcp`. After
|
|
@@ -160,6 +172,42 @@ gitea-mcp
|
|
|
160
172
|
| `list_my_repos` | List repositories accessible to the authenticated user |
|
|
161
173
|
| `resolve_repo` | Auto-detect `owner` and `repo` from a local git remote URL |
|
|
162
174
|
|
|
175
|
+
## AI Guidance & Skills
|
|
176
|
+
|
|
177
|
+
The server ships guidance so assistants use the tools correctly and safely,
|
|
178
|
+
through three channels:
|
|
179
|
+
|
|
180
|
+
- **`instructions` (on connect)** — a concise strategy the server sends during the
|
|
181
|
+
MCP handshake; capable clients inject it into the system prompt automatically.
|
|
182
|
+
- **Tool descriptions** — every tool's description flags its key risk (pagination,
|
|
183
|
+
label ID-vs-name, destructive scope) and a minimal usage example.
|
|
184
|
+
- **Prompts & resources** — workflow templates (`triage_issues`,
|
|
185
|
+
`summarize_issue`, `audit_labels`, `milestone_report`) and on-demand reference
|
|
186
|
+
docs (field reference, label guide, tool cookbook) for clients that surface them.
|
|
187
|
+
|
|
188
|
+
### opencode skills
|
|
189
|
+
|
|
190
|
+
For opencode, the server ships a set of **action-scoped skills** — one per
|
|
191
|
+
workflow, so the assistant loads only the guidance it needs (and never, say,
|
|
192
|
+
delete instructions while creating). Install them with the
|
|
193
|
+
`gitea-mcp skills install` command shown in the opencode section above.
|
|
194
|
+
|
|
195
|
+
| Skill | Invoke when |
|
|
196
|
+
|-------|-------------|
|
|
197
|
+
| `gitea-find-issues` | discovering / reading / triaging issues |
|
|
198
|
+
| `gitea-create-issue` | creating an issue (after a duplicate check) |
|
|
199
|
+
| `gitea-update-issue` | editing fields, closing, clearing assignee/milestone |
|
|
200
|
+
| `gitea-label-issue` | adding / replacing / removing / clearing labels on an issue |
|
|
201
|
+
| `gitea-manage-labels` | creating or editing label definitions |
|
|
202
|
+
| `gitea-summarize-issue` | reading and summarizing an issue's discussion |
|
|
203
|
+
| `gitea-plan-milestones` | creating / editing / closing milestones |
|
|
204
|
+
| `gitea-resolve-repo` | resolving owner/repo or listing repositories |
|
|
205
|
+
|
|
206
|
+
Each skill is a short, AI-facing action flow (purpose, when to use, when not to,
|
|
207
|
+
rules, and what to check first). Destructive single-tool actions (delete issue /
|
|
208
|
+
comment / label / milestone) are intentionally left to the tool descriptions so
|
|
209
|
+
they never contaminate a creative workflow.
|
|
210
|
+
|
|
163
211
|
## Development
|
|
164
212
|
|
|
165
213
|
```bash
|
|
@@ -177,15 +225,8 @@ npm ci
|
|
|
177
225
|
| `make test-integration` | Run integration tests (needs live Gitea instance) |
|
|
178
226
|
| `make dev` | Run directly with tsx |
|
|
179
227
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
```
|
|
183
|
-
src/
|
|
184
|
-
cli.ts # Entry point
|
|
185
|
-
server.ts # MCP server setup and tool registration
|
|
186
|
-
tools.ts # Zod input schemas for all tools
|
|
187
|
-
gitea-client.ts # REST client wrapping Gitea /api/v1 endpoints
|
|
188
|
-
```
|
|
228
|
+
For the full architecture — module layout, dependency graph, core patterns, and
|
|
229
|
+
the guide to adding a new tool — see [`docs/architecture.md`](docs/architecture.md).
|
|
189
230
|
|
|
190
231
|
## License
|
|
191
232
|
|
package/README.zh-CN.md
CHANGED
|
@@ -96,6 +96,17 @@ node dist/cli.js
|
|
|
96
96
|
|
|
97
97
|
如果从源码构建,将 `command` 改为 `node /path/to/gitea-mcp/dist/cli.js`。
|
|
98
98
|
|
|
99
|
+
opencode 还会加载原生**技能(skills)**——按动作拆分(查找、创建、更新、打
|
|
100
|
+
标签、总结、规划里程碑、解析仓库等),教会助手针对该动作的最安全工作流,含
|
|
101
|
+
使用前检查与各类陷阱。一次性安装:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
gitea-mcp skills install # 全局(~/.config/opencode/skills/)
|
|
105
|
+
gitea-mcp skills install --project # 仅当前项目(./.opencode/skills/)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
然后重启 opencode。详见下方 [AI 引导与技能](#ai-引导与技能)。
|
|
109
|
+
|
|
99
110
|
### 其他 MCP 客户端
|
|
100
111
|
|
|
101
112
|
任何支持 stdio 方式运行 MCP 服务端的客户端都可以使用。安装完成后设置环境
|
|
@@ -159,6 +170,39 @@ gitea-mcp
|
|
|
159
170
|
| `list_my_repos` | 列出当前用户可访问的仓库 |
|
|
160
171
|
| `resolve_repo` | 从本地 git 仓库的远程地址自动检测 `owner` 和 `repo` |
|
|
161
172
|
|
|
173
|
+
## AI 引导与技能
|
|
174
|
+
|
|
175
|
+
服务端内置了引导内容,让助手正确、安全地使用工具,分三个通道:
|
|
176
|
+
|
|
177
|
+
- **`instructions`(连接时)** —— 服务端在 MCP 握手时下发一份精炼策略;支持的
|
|
178
|
+
客户端会自动注入系统提示。
|
|
179
|
+
- **工具描述** —— 每个工具的描述都标出其关键风险(分页、标签 ID 与名称、破坏性
|
|
180
|
+
作用范围)和最小用法示例。
|
|
181
|
+
- **Prompts 与 Resources** —— 工作流模板(`triage_issues`、`summarize_issue`、
|
|
182
|
+
`audit_labels`、`milestone_report`)与按需参考文档(字段参考、标签指南、工具
|
|
183
|
+
食谱),供支持的客户端使用。
|
|
184
|
+
|
|
185
|
+
### opencode 技能
|
|
186
|
+
|
|
187
|
+
对 opencode,服务端内置了一组**按动作划分的技能**——每个工作流一个,助手只
|
|
188
|
+
加载所需指引(避免例如创建时把删除说明一并带入造成幻觉)。用上面 opencode
|
|
189
|
+
小节展示的 `gitea-mcp skills install` 命令安装。
|
|
190
|
+
|
|
191
|
+
| 技能 | 何时触发 |
|
|
192
|
+
|------|----------|
|
|
193
|
+
| `gitea-find-issues` | 发现 / 读取 / 分流 issues |
|
|
194
|
+
| `gitea-create-issue` | 创建 issue(先做查重) |
|
|
195
|
+
| `gitea-update-issue` | 编辑字段、关闭、清空负责人/里程碑 |
|
|
196
|
+
| `gitea-label-issue` | 为 issue 增加 / 替换 / 移除 / 清空标签 |
|
|
197
|
+
| `gitea-manage-labels` | 创建或编辑标签定义 |
|
|
198
|
+
| `gitea-summarize-issue` | 读取并总结某 issue 的讨论 |
|
|
199
|
+
| `gitea-plan-milestones` | 创建 / 编辑 / 关闭里程碑 |
|
|
200
|
+
| `gitea-resolve-repo` | 解析 owner/repo 或列出仓库 |
|
|
201
|
+
|
|
202
|
+
每个技能都是面向 AI 的简短动作流程(目的、何时用、何时不用、规则、先检查什么)。
|
|
203
|
+
破坏性的单工具操作(删除 issue / 评论 / 标签 / 里程碑)有意仅保留在工具描述里,
|
|
204
|
+
不会污染创建类工作流。
|
|
205
|
+
|
|
162
206
|
## 二次开发
|
|
163
207
|
|
|
164
208
|
```bash
|
|
@@ -176,15 +220,8 @@ npm ci
|
|
|
176
220
|
| `make test-integration` | 运行集成测试(需要可用的 Gitea 实例) |
|
|
177
221
|
| `make dev` | 通过 tsx 直接运行 |
|
|
178
222
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
```
|
|
182
|
-
src/
|
|
183
|
-
cli.ts # 入口文件
|
|
184
|
-
server.ts # MCP 服务端搭建与工具注册
|
|
185
|
-
tools.ts # 所有工具的 Zod 输入模式定义
|
|
186
|
-
gitea-client.ts # 封装 Gitea /api/v1 端点的 REST 客户端
|
|
187
|
-
```
|
|
223
|
+
完整的架构说明(模块布局、依赖关系、核心模式,以及新增工具的指引)请参阅
|
|
224
|
+
[`docs/architecture.md`](docs/architecture.md)。
|
|
188
225
|
|
|
189
226
|
## 许可证
|
|
190
227
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Gitea MCP — usage strategy
|
|
2
|
+
|
|
3
|
+
You manage Gitea issues, comments, labels, and milestones through this MCP server.
|
|
4
|
+
Every tool returns Gitea's JSON verbatim as text. Follow these rules to use them
|
|
5
|
+
correctly.
|
|
6
|
+
|
|
7
|
+
## Resolve owner/repo FIRST (most common failure)
|
|
8
|
+
|
|
9
|
+
Most tools target one repository and need both `owner` and `repo`. They resolve in
|
|
10
|
+
this order:
|
|
11
|
+
|
|
12
|
+
1. The `owner` / `repo` arguments you pass to the call.
|
|
13
|
+
2. `GITEA_DEFAULT_OWNER` / `GITEA_DEFAULT_REPO` env vars (set at server start).
|
|
14
|
+
3. The `resolve_repo` tool (detects owner/repo from a local git remote).
|
|
15
|
+
|
|
16
|
+
If neither argument nor env var is set, the call errors. Before a batch of work on a
|
|
17
|
+
repo you have not used this session, call `resolve_repo` (or confirm the env defaults)
|
|
18
|
+
once and reuse the result — do not guess.
|
|
19
|
+
|
|
20
|
+
## Labels: IDs vs names (critical gotcha)
|
|
21
|
+
|
|
22
|
+
Label endpoints are NOT consistent — mixing them up silently fails or hits the wrong label:
|
|
23
|
+
|
|
24
|
+
- `add_issue_labels`, `replace_issue_labels` → take label **names** (`string[]`).
|
|
25
|
+
- `remove_issue_label` → takes a label **ID** (`number`). You must `list_labels` first to get IDs.
|
|
26
|
+
- `create_issue` / `update_issue` `labels` field → takes label **IDs** (`number[]`).
|
|
27
|
+
|
|
28
|
+
Always `list_labels` before any label mutation so you use the right identifier, and
|
|
29
|
+
prefer `replace_issue_labels` (name-based) when you want a known final set.
|
|
30
|
+
|
|
31
|
+
## Comments use comment IDs, not issue numbers
|
|
32
|
+
|
|
33
|
+
`update_comment` and `delete_comment` take the comment `id`, NOT the issue `index`.
|
|
34
|
+
`list_comments` returns each comment's `id`. Never reuse an issue number where a
|
|
35
|
+
comment id is required.
|
|
36
|
+
|
|
37
|
+
## Pagination
|
|
38
|
+
|
|
39
|
+
List endpoints are 1-based: `page` starts at 1, `limit` max 100. To fetch everything,
|
|
40
|
+
page forward until a page returns fewer than `limit` items (or an empty page). Do not
|
|
41
|
+
assume one page is complete.
|
|
42
|
+
|
|
43
|
+
## Destructive operations — confirm before running
|
|
44
|
+
|
|
45
|
+
These are irreversible on most Gitea instances (no trash/recycle):
|
|
46
|
+
|
|
47
|
+
- `delete_issue`, `delete_label`, `delete_milestone`, `delete_comment`
|
|
48
|
+
- `clear_issue_labels`, `replace_issue_labels` (replaces the ENTIRE label set)
|
|
49
|
+
|
|
50
|
+
Confirm the target id/index and scope with the user before calling. For labels,
|
|
51
|
+
`replace_issue_labels` overwrites — read current labels first if any must survive.
|
|
52
|
+
|
|
53
|
+
## Search vs list
|
|
54
|
+
|
|
55
|
+
- `list_issues` — one repo, paginated, filterable by state/labels.
|
|
56
|
+
- `search_issues` — across ALL repos the token can see, by keyword/type/state. Use it
|
|
57
|
+
for "find issues about X" or duplicate detection, not for listing one repo.
|
|
58
|
+
|
|
59
|
+
## Error format
|
|
60
|
+
|
|
61
|
+
Failed calls throw `Gitea API error (<status>): <body>`. Read the status: 401/403 →
|
|
62
|
+
token scope/expiry; 404 → wrong owner/repo or no permission; 409 → conflict;
|
|
63
|
+
422 → validation. Do not retry blindly on 4xx.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Gitea object field reference
|
|
2
|
+
|
|
3
|
+
The shapes of the JSON objects these tools return (verbatim from the Gitea API).
|
|
4
|
+
Use this to read results correctly and pick the right identifier.
|
|
5
|
+
|
|
6
|
+
## Issue
|
|
7
|
+
- `id` (number) — internal id. NOT used by tools; tools use `number`.
|
|
8
|
+
- `number` (number) — the issue index shown in the URL (#42). This is the `index`
|
|
9
|
+
passed to get_issue / update_issue / delete_issue / comments tools.
|
|
10
|
+
- `title` (string), `body` (string?), `state` ("open" | "closed")
|
|
11
|
+
- `html_url`, `url` (string)
|
|
12
|
+
- `comments` (number) — comment COUNT, not the comments themselves
|
|
13
|
+
- `labels` (Label[])
|
|
14
|
+
- `assignee` (User?), `assignees` (User[]?)
|
|
15
|
+
- `milestone` (Milestone?)
|
|
16
|
+
- `repository` (Repository) — present on search_issues results
|
|
17
|
+
- `created_at`, `updated_at` (string ISO); `closed_at` (string?, when closed)
|
|
18
|
+
|
|
19
|
+
## Label
|
|
20
|
+
- `id` (number) — used by remove_issue_label / update_label / delete_label
|
|
21
|
+
- `name` (string) — used by add_issue_labels / replace_issue_labels
|
|
22
|
+
- `color` (string) — 6-digit hex, with or without "#"
|
|
23
|
+
- `description` (string?)
|
|
24
|
+
|
|
25
|
+
## User
|
|
26
|
+
- `id` (number), `login` (string), `full_name` (string?), `avatar_url` (string),
|
|
27
|
+
`email` (string?)
|
|
28
|
+
|
|
29
|
+
## Milestone
|
|
30
|
+
- `id` (number) — used by get/update/delete_milestone; also the `milestone` value on
|
|
31
|
+
create/update_issue
|
|
32
|
+
- `title` (string), `description` (string?), `state` ("open" | "closed")
|
|
33
|
+
- `open_issues` (number), `closed_issues` (number) — counts for progress
|
|
34
|
+
- `due_on` (string?, ISO)
|
|
35
|
+
|
|
36
|
+
## Comment
|
|
37
|
+
- `id` (number) — used by update_comment / delete_comment. NOT the issue number.
|
|
38
|
+
- `body` (string) — Markdown
|
|
39
|
+
- `html_url` (string), `created_at`, `updated_at` (string ISO)
|
|
40
|
+
- `user` (User) — comment author
|
|
41
|
+
|
|
42
|
+
## Repository (embedded on issues)
|
|
43
|
+
- `id` (number), `full_name` (string "owner/repo"), `name` (string),
|
|
44
|
+
`owner` ({ login: string })
|
|
45
|
+
|
|
46
|
+
## Repo (from list_my_repos)
|
|
47
|
+
- `id`, `full_name`, `name`, `owner` (User), `description?`, `html_url`,
|
|
48
|
+
`default_branch?`, `created_at`, `updated_at`
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Label management guide
|
|
2
|
+
|
|
3
|
+
Labels are the most error-prone area because endpoints mix **names** and **ids**.
|
|
4
|
+
|
|
5
|
+
## The name-vs-id matrix (memorize)
|
|
6
|
+
|
|
7
|
+
| Operation | Identifier | Type |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `add_issue_labels` | name | `string[]` |
|
|
10
|
+
| `replace_issue_labels` | name | `string[]` |
|
|
11
|
+
| `remove_issue_label` | **id** | `number` |
|
|
12
|
+
| `create_issue` / `update_issue` `.labels` | **id** | `number[]` |
|
|
13
|
+
| `update_label` / `delete_label` | **id** | `number` |
|
|
14
|
+
|
|
15
|
+
**Workflow rule:** call `list_labels` first and keep the `id`↔`name` map for the
|
|
16
|
+
whole session. Translate before any call that needs the other form.
|
|
17
|
+
|
|
18
|
+
## Conventions
|
|
19
|
+
|
|
20
|
+
- **Color:** 6-digit hex, with or without `#`. Keep a consistent palette per repo.
|
|
21
|
+
- **Names are unique** per repo. Rename with `update_label` (by id); never recreate
|
|
22
|
+
to rename.
|
|
23
|
+
- **Scoped/exclusive labels** use `scope/name` (e.g. `priority/low`, `priority/high`).
|
|
24
|
+
Within a scope, labels are mutually exclusive — adding `priority/high` removes
|
|
25
|
+
`priority/low`. Use this intentionally for single-value dimensions (priority,
|
|
26
|
+
type, status); use plain labels for multi-value dimensions (topic, team).
|
|
27
|
+
|
|
28
|
+
## Safe operations
|
|
29
|
+
|
|
30
|
+
- **Add one label without disturbing others** → `add_issue_labels(["name"])`
|
|
31
|
+
(additive, by name).
|
|
32
|
+
- **Remove one label** → `remove_issue_label(id)` (by id; get it from the issue's
|
|
33
|
+
`labels`).
|
|
34
|
+
- **Set an exact known set** → `replace_issue_labels(["a","b"])` — but read the
|
|
35
|
+
current labels first and confirm, since it removes everything not listed.
|
|
36
|
+
- **Bulk cleanup** → `delete_label(id)` removes the label from EVERY issue; only
|
|
37
|
+
after user confirmation.
|
|
38
|
+
|
|
39
|
+
## Anti-patterns
|
|
40
|
+
|
|
41
|
+
- Passing a label **name** to `remove_issue_label` (needs id) — hits the wrong id
|
|
42
|
+
or 404s.
|
|
43
|
+
- Passing a label **id** to `add_issue_labels` (needs name) — 404s.
|
|
44
|
+
- Using `update_issue({ labels })` to "add" a label — it REPLACES the whole set.
|
|
45
|
+
Use `add_issue_labels` instead.
|
|
46
|
+
- Deleting a label to "remove it from one issue" — that removes it from all issues.
|
|
47
|
+
Use `remove_issue_label` for one issue.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Tool cookbook — task → tool recipes
|
|
2
|
+
|
|
3
|
+
Quick recipes for common goals. Always resolve owner/repo first (explicit args,
|
|
4
|
+
`GITEA_DEFAULT_OWNER`/`REPO`, or `resolve_repo`).
|
|
5
|
+
|
|
6
|
+
## Discover where to work
|
|
7
|
+
- One local repo → `resolve_repo({})` once, reuse `{owner, repo}`.
|
|
8
|
+
- Across all repos → `list_my_repos({ page: 1, limit: 20 })`, page as needed.
|
|
9
|
+
|
|
10
|
+
## Read / report
|
|
11
|
+
- One issue's full picture → `get_issue` then `list_comments` (mind: list_comments
|
|
12
|
+
is one default page; long threads may be truncated).
|
|
13
|
+
- All open issues in a repo → `list_issues({ state: "open", page: 1, limit: 50 })`,
|
|
14
|
+
page until a page returns < 50.
|
|
15
|
+
- Issues across repos by keyword / duplicate check → `search_issues({ query, type:
|
|
16
|
+
"issues" })`.
|
|
17
|
+
- Milestone progress → `list_milestones({ state: "all" })` (default omits closed!).
|
|
18
|
+
|
|
19
|
+
## Create
|
|
20
|
+
- New issue with labels → `list_labels` (to get ids) → `create_issue({ title, body,
|
|
21
|
+
labels: [ids] })`. Or create then `add_issue_labels([names])`.
|
|
22
|
+
|
|
23
|
+
## Edit (non-destructive)
|
|
24
|
+
- Change title/body/assignee → `update_issue` (PATCH; only given fields change).
|
|
25
|
+
- Add ONE label → `add_issue_labels(["name"])` (additive, by name).
|
|
26
|
+
- Remove ONE label → `remove_issue_label(id)` (by id).
|
|
27
|
+
|
|
28
|
+
## Destructive (confirm first)
|
|
29
|
+
- Close an issue → `update_issue({ state: "closed" })` (preferred over delete).
|
|
30
|
+
- Delete an issue → `delete_issue` (irreversible).
|
|
31
|
+
- Replace all labels → `replace_issue_labels(["a","b"])` (overwrites whole set).
|
|
32
|
+
- Clear all labels → `clear_issue_labels`.
|
|
33
|
+
- Delete a label → `delete_label(id)` (removes from EVERY issue).
|
|
34
|
+
- Delete a milestone → prefer `update_milestone({ state: "closed" })`; `delete_milestone`
|
|
35
|
+
detaches its issues (they keep existing, milestone becomes null).
|
|
36
|
+
|
|
37
|
+
## Pagination pattern (all list tools)
|
|
38
|
+
```
|
|
39
|
+
page = 1
|
|
40
|
+
loop:
|
|
41
|
+
res = list_X({ ..., page, limit })
|
|
42
|
+
process(res)
|
|
43
|
+
if res.length < limit: break
|
|
44
|
+
page += 1
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Error triage
|
|
48
|
+
- 401/403 → token scope/expiry. Ask user; don't loop.
|
|
49
|
+
- 404 → wrong owner/repo or no permission.
|
|
50
|
+
- 409 → conflict (e.g. duplicate label name).
|
|
51
|
+
- 422 → validation (bad color, malformed date).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gitea-create-issue
|
|
3
|
+
description: Invoke to CREATE / FILE / OPEN a new Gitea issue. The flow checks for an existing duplicate first, then creates. Do NOT invoke to edit/close (gitea-update-issue), delete (no skill — destructive), read/find (gitea-find-issues), or attach labels (gitea-label-issue).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# gitea-create-issue
|
|
7
|
+
|
|
8
|
+
Open one new issue after ruling out a duplicate. Tools: `search_issues`, `create_issue`.
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
- Resolve `owner`+`repo`: pass explicitly, else `GITEA_DEFAULT_OWNER`/`GITEA_DEFAULT_REPO`, else `resolve_repo` (gitea-resolve-repo). Never guess — wrong values create the issue in the wrong repo.
|
|
12
|
+
|
|
13
|
+
## Flow
|
|
14
|
+
1. DUPLICATE CHECK (always first): `search_issues({ query: "<title keywords>", type: "issues" })`. If a match exists, comment on it (gitea-summarize-issue, then `create_comment`) instead of creating a duplicate. Do NOT skip this — creation does not de-duplicate.
|
|
15
|
+
2. CREATE: `create_issue({ title, body?, assignees? })`.
|
|
16
|
+
|
|
17
|
+
## create_issue
|
|
18
|
+
- RULES: `title` required; `body` is Markdown. Use `assignees` (array); do NOT also set the deprecated single `assignee`.
|
|
19
|
+
- Do NOT pass `labels` or `milestone` here: `labels` expect IDs (error-prone) and milestone needs an id. Create WITHOUT them, then attach labels by name via `add_issue_labels` (gitea-label-issue) and set the milestone via `update_issue` (gitea-update-issue).
|
|
20
|
+
- CHECK FIRST: confirm no duplicate (step 1) and that `owner`/`repo` are correct before writing.
|
|
21
|
+
- CHECK AFTER: the returned object's `number` is the new issue index.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gitea-find-issues
|
|
3
|
+
description: Invoke to DISCOVER or READ Gitea issues — listing one repo's issues, cross-repo keyword search, reading a single issue, or triage. Do NOT invoke to create/edit/close/delete (gitea-create-issue / gitea-update-issue), to manage labels (gitea-label-issue), or to read the comment discussion (gitea-summarize-issue).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# gitea-find-issues
|
|
7
|
+
|
|
8
|
+
Read-only issue discovery. Tools: `list_issues`, `search_issues`, `get_issue`.
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
- Resolve `owner`+`repo` for `list_issues`/`get_issue`: pass explicitly, else `GITEA_DEFAULT_OWNER`/`GITEA_DEFAULT_REPO`, else `resolve_repo` (gitea-resolve-repo). Never guess — wrong values 404 or silently target the wrong repo.
|
|
12
|
+
- Paginate 1-based, `limit` ≤ 100. A page is final ONLY when it returns fewer than `limit` items. Always set `limit` (default page size is server-controlled).
|
|
13
|
+
|
|
14
|
+
## Choose the tool
|
|
15
|
+
- ONE repo's issues, filtered by state/labels → `list_issues`.
|
|
16
|
+
- ACROSS repos by keyword, or duplicate check → `search_issues` (global; no owner/repo).
|
|
17
|
+
- ONE issue's full detail → `get_issue`.
|
|
18
|
+
|
|
19
|
+
## list_issues
|
|
20
|
+
- RULES: `labels` = comma-separated NAMES, AND-matched; a mistyped or non-existent name returns EMPTY with no error. Results include pull requests (no `type` filter here); identify a PR by a non-null `pull_request` field in the JSON.
|
|
21
|
+
- CHECK FIRST: confirm label names via `list_labels` (gitea-manage-labels) before filtering.
|
|
22
|
+
- CHECK AFTER: if `length === limit`, fetch the next page before treating the list as complete.
|
|
23
|
+
|
|
24
|
+
## search_issues
|
|
25
|
+
- RULES: GLOBAL — no owner/repo; each result carries its own `repository`. Returns issues AND PRs by default; set `type: "issues"` to exclude PRs (`type: "pulls"` for PRs only). `labels` = names. `query` matches title + body.
|
|
26
|
+
- CHECK FIRST: set `type` deliberately.
|
|
27
|
+
- CHECK AFTER: page fully if completeness matters.
|
|
28
|
+
|
|
29
|
+
## get_issue
|
|
30
|
+
- RULES: pass `index` = the issue `number` (URL #42 → 42), never the internal `id`.
|
|
31
|
+
- NOTE: the `comments` field is a COUNT only — to read the discussion use `list_comments` (gitea-summarize-issue).
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gitea-label-issue
|
|
3
|
+
description: Invoke to ATTACH labels to ONE Gitea issue — add, replace, remove one, or clear all. Covers the label name-vs-id pitfall. Do NOT invoke to create/edit/delete the repo's label definitions (gitea-manage-labels) or to create/edit the issue (gitea-create-issue / gitea-update-issue).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# gitea-label-issue
|
|
7
|
+
|
|
8
|
+
Manage the labels ON one issue. Tools: `list_labels`, `add_issue_labels`, `replace_issue_labels`, `remove_issue_label`, `clear_issue_labels`.
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
- Resolve `owner`+`repo`: pass explicitly, else `GITEA_DEFAULT_OWNER`/`GITEA_DEFAULT_REPO`, else `resolve_repo` (gitea-resolve-repo).
|
|
12
|
+
|
|
13
|
+
## CRITICAL — name vs id (the endpoints are inconsistent)
|
|
14
|
+
- BY NAME (string[]): `add_issue_labels`, `replace_issue_labels`.
|
|
15
|
+
- BY ID (number): `remove_issue_label` (param `id`).
|
|
16
|
+
Resolve names→ids via `list_labels` when you need an id.
|
|
17
|
+
|
|
18
|
+
## Choose the tool
|
|
19
|
+
- ADD labels (keep existing) → `add_issue_labels({ index, labels: [names] })`.
|
|
20
|
+
- SET the exact label set (overwrites all) → `replace_issue_labels({ index, labels: [names] })`.
|
|
21
|
+
- REMOVE ONE label → `remove_issue_label({ index, id })` (id, not name).
|
|
22
|
+
- REMOVE ALL → `clear_issue_labels({ index })`.
|
|
23
|
+
|
|
24
|
+
## Rules
|
|
25
|
+
- `index` = issue `number` (URL #N → N).
|
|
26
|
+
- Adding a non-existent NAME → 404. Confirm names via `list_labels` first.
|
|
27
|
+
- Scoped/exclusive labels (`scope/name`) are mutually exclusive within a scope — adding one may replace another in the same scope.
|
|
28
|
+
- CHECK FIRST: for `replace`, `get_issue` (gitea-find-issues) to see current labels so you don't drop one unintentionally; for `remove`, `list_labels` to resolve the id.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gitea-manage-labels
|
|
3
|
+
description: Invoke to CREATE or EDIT a Gitea label in the repo's taxonomy (the set of available label definitions). Do NOT invoke to attach labels to an issue (gitea-label-issue) or to delete a label (destructive — no skill).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# gitea-manage-labels
|
|
7
|
+
|
|
8
|
+
Create or edit the repo's label definitions. Tools: `list_labels`, `create_label`, `update_label`.
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
- Resolve `owner`+`repo`: pass explicitly, else `GITEA_DEFAULT_OWNER`/`GITEA_DEFAULT_REPO`, else `resolve_repo` (gitea-resolve-repo).
|
|
12
|
+
|
|
13
|
+
## list_labels
|
|
14
|
+
- Enumerate available labels (name, id, color, description). Use to resolve names→ids and to check name uniqueness before create. Paginate 1-based, `limit` ≤ 100.
|
|
15
|
+
|
|
16
|
+
## create_label
|
|
17
|
+
- RULES: `name` required and UNIQUE per repo (duplicate → conflict). `color` = 6-digit hex, with or without leading `#` (e.g. `#ff0000` or `ff0000`). `description` optional.
|
|
18
|
+
- CHECK FIRST: `list_labels` to avoid a name collision.
|
|
19
|
+
|
|
20
|
+
## update_label
|
|
21
|
+
- RULES: identifies the label by `id` (number). PATCH — only `name` / `color` / `description` you pass change; omit = unchanged. `color` stays 6-digit hex.
|
|
22
|
+
- NOTE: renaming or recoloring a label updates it on EVERY issue that currently has it.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gitea-plan-milestones
|
|
3
|
+
description: Invoke to CREATE, EDIT, or CLOSE a Gitea milestone, or to list/inspect milestones for planning. Do NOT invoke to delete a milestone (destructive — no skill) or to set an issue's milestone (that is gitea-update-issue).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# gitea-plan-milestones
|
|
7
|
+
|
|
8
|
+
Create / edit / close milestones. Tools: `list_milestones`, `get_milestone`, `create_milestone`, `update_milestone`.
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
- Resolve `owner`+`repo`: pass explicitly, else `GITEA_DEFAULT_OWNER`/`GITEA_DEFAULT_REPO`, else `resolve_repo` (gitea-resolve-repo).
|
|
12
|
+
|
|
13
|
+
## list_milestones — DEFAULT-OPEN TRAP
|
|
14
|
+
- Default returns ONLY open milestones. Pass `state: "all"` or `state: "closed"` to see the rest, or you will silently miss closed/completed milestones. Paginate 1-based, `limit` ≤ 100.
|
|
15
|
+
|
|
16
|
+
## create_milestone
|
|
17
|
+
- RULES: `title` required; `description` optional; `due_on` = ISO 8601 (e.g. `2025-12-31T23:59:59Z`). Returns the new milestone including its `id`.
|
|
18
|
+
|
|
19
|
+
## update_milestone
|
|
20
|
+
- RULES: identifies by `id` (number). PATCH — only `title` / `description` / `due_on` / `state` you pass change; omit = unchanged. State is `open` | `closed`.
|
|
21
|
+
- NOTE: CLOSING a milestone does NOT close its issues — they stay open. Close issues separately (gitea-update-issue) before or after.
|
|
22
|
+
|
|
23
|
+
## get_milestone
|
|
24
|
+
- Read one milestone by `id`: includes `open_issues` / `closed_issues` counts for progress (progress = closed / (open + closed)).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gitea-resolve-repo
|
|
3
|
+
description: Invoke to RESOLVE which owner/repo the other gitea tools should target (auto-detect from a git remote) or to LIST repositories the token can access. Run FIRST when the target repository is unknown. Do NOT invoke for issue/comment/label/milestone work once owner/repo are known.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# gitea-resolve-repo
|
|
7
|
+
|
|
8
|
+
Discover the target repository. Tools: `resolve_repo`, `list_my_repos`.
|
|
9
|
+
|
|
10
|
+
## resolve_repo
|
|
11
|
+
- Reads the `origin` remote of the git repo at `path` (default: current directory) and parses owner/repo from SSH (`git@gitea.example:owner/repo.git`) or HTTPS (`https://gitea.example/owner/repo.git`) URLs.
|
|
12
|
+
- Throws if there is no `origin` remote or the URL is unparseable. Do NOT guess owner/repo from context — call this, or ask the user.
|
|
13
|
+
|
|
14
|
+
## list_my_repos
|
|
15
|
+
- Lists repositories the token can access. GLOBAL. Returns large objects — paginate (`limit` ≤ 100) and read only the fields you need (name, full_name, owner.login).
|
|
16
|
+
|
|
17
|
+
## Resolution order (every repo-scoped tool)
|
|
18
|
+
explicit `owner`/`repo` args → `GITEA_DEFAULT_OWNER`/`GITEA_DEFAULT_REPO` → `resolve_repo`. If none resolve, the tool throws `owner and repo are required`. Wrong values 404 or silently target the wrong repo — never guess.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gitea-summarize-issue
|
|
3
|
+
description: Invoke to READ and SUMMARIZE an issue's discussion — the issue body plus its comment thread. Do NOT invoke to create/edit an issue (gitea-create-issue / gitea-update-issue), post or edit a comment (no skill — single tool), or manage labels/milestones.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# gitea-summarize-issue
|
|
7
|
+
|
|
8
|
+
Read an issue and its discussion, then synthesize. Tools: `get_issue`, `list_comments`.
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
- Resolve `owner`+`repo`: pass explicitly, else `GITEA_DEFAULT_OWNER`/`GITEA_DEFAULT_REPO`, else `resolve_repo` (gitea-resolve-repo).
|
|
12
|
+
|
|
13
|
+
## Flow
|
|
14
|
+
1. `get_issue({ index })` — `index` = issue `number` (URL #N → N), never the internal `id`. The `comments` field is only a COUNT.
|
|
15
|
+
2. `list_comments({ index })` — returns the comment thread, oldest-first.
|
|
16
|
+
|
|
17
|
+
## list_comments — TRUNCATION TRAP
|
|
18
|
+
- This tool passes NO page/limit and returns at most the server's default page size. For long threads the list is SILENTLY TRUNCATED. If the `comments` count (from `get_issue`) exceeds the number returned, warn that part of the thread is missing and do NOT claim a complete summary.
|
|
19
|
+
|
|
20
|
+
## Synthesis
|
|
21
|
+
- Report the issue state (open/closed), the body's ask, then the thread's consensus / decision / open questions. Attribute by author. Flag unresolved disagreement explicitly — do not paper over it.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gitea-update-issue
|
|
3
|
+
description: Invoke to EDIT fields, CLOSE, REOPEN, or CLEAR assignee/milestone on ONE existing Gitea issue. Do NOT invoke to create (gitea-create-issue), delete (destructive — no skill), find/read (gitea-find-issues), or change a single label (gitea-label-issue).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# gitea-update-issue
|
|
7
|
+
|
|
8
|
+
Edit one issue's fields or change its state. Tools: `get_issue`, `update_issue`.
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
- Resolve `owner`+`repo`: pass explicitly, else `GITEA_DEFAULT_OWNER`/`GITEA_DEFAULT_REPO`, else `resolve_repo` (gitea-resolve-repo).
|
|
12
|
+
- There is NO optimistic locking — always read current state first.
|
|
13
|
+
|
|
14
|
+
## Flow
|
|
15
|
+
1. READ CURRENT: `get_issue({ index })` — `index` = issue `number` (URL #N → N), never the internal `id`.
|
|
16
|
+
2. APPLY: `update_issue({ index, ...changedFields })`.
|
|
17
|
+
|
|
18
|
+
## update_issue
|
|
19
|
+
- RULES: PATCH — only fields you pass change; omit = unchanged. To CLEAR a field pass its EMPTY form, do NOT omit it: `milestone: 0` clears the milestone, `assignees: []` clears assignees. Use `assignees` (array), not the deprecated `assignee`. State values are `open` | `closed`.
|
|
20
|
+
- NOT FOR single-label changes: `labels` here are IDs and REPLACE the entire set — to add/remove one label use `add_issue_labels` / `remove_issue_label` (gitea-label-issue).
|
|
21
|
+
- CHECK FIRST: `get_issue` for current values if state may have changed since your last read; state the intended change to the user before writing.
|
package/dist/cli.js
CHANGED
|
@@ -1,15 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { runServer } from "./server.js";
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
const argv = process.argv.slice(2);
|
|
4
|
+
if (argv[0] === "skills") {
|
|
5
|
+
// `gitea-mcp skills ...` manages the bundled opencode skill. It needs no Gitea
|
|
6
|
+
// credentials, so it is dispatched before the env-var guard below.
|
|
7
|
+
const { runSkillsCommand } = await import("./skills.js");
|
|
8
|
+
runSkillsCommand(argv.slice(1)).catch((err) => {
|
|
9
|
+
console.error("Fatal error:", err);
|
|
10
|
+
process.exit(1);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
const baseUrl = process.env.GITEA_BASE_URL;
|
|
15
|
+
const token = process.env.GITEA_TOKEN;
|
|
16
|
+
const defaultOwner = process.env.GITEA_DEFAULT_OWNER;
|
|
17
|
+
const defaultRepo = process.env.GITEA_DEFAULT_REPO;
|
|
18
|
+
if (!baseUrl || !token) {
|
|
19
|
+
console.error("GITEA_BASE_URL and GITEA_TOKEN environment variables are required");
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
runServer(baseUrl, token, defaultOwner, defaultRepo).catch((err) => {
|
|
23
|
+
console.error("Fatal error:", err);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
});
|
|
10
26
|
}
|
|
11
|
-
runServer(baseUrl, token, defaultOwner, defaultRepo).catch((err) => {
|
|
12
|
-
console.error("Fatal error:", err);
|
|
13
|
-
process.exit(1);
|
|
14
|
-
});
|
|
15
27
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;IACzB,+EAA+E;IAC/E,mEAAmE;IACnE,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACzD,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QAC5C,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;KAAM,CAAC;IACN,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IACtC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IACrD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IAEnD,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACnF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACjE,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { z } from "zod";
|
|
3
4
|
import { GiteaClient } from "./gitea-client.js";
|
|
4
5
|
import { ListIssuesSchema, GetIssueSchema, CreateIssueSchema, UpdateIssueSchema, DeleteIssueSchema, SearchIssuesSchema, ListCommentsSchema, CreateCommentSchema, UpdateCommentSchema, DeleteCommentSchema, ListLabelsSchema, CreateLabelSchema, UpdateLabelSchema, DeleteLabelSchema, AddIssueLabelsSchema, RemoveIssueLabelSchema, ReplaceIssueLabelsSchema, ClearIssueLabelsSchema, ListMilestonesSchema, GetMilestoneSchema, CreateMilestoneSchema, UpdateMilestoneSchema, DeleteMilestoneSchema, ResolveRepoSchema, ListMyReposSchema, } from "./tools.js";
|
|
5
6
|
import { readFile } from "node:fs/promises";
|
|
6
|
-
import { join } from "node:path";
|
|
7
|
+
import { dirname, join } from "node:path";
|
|
7
8
|
import { createRequire } from "node:module";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
8
10
|
const require = createRequire(import.meta.url);
|
|
9
11
|
const pkg = require("../package.json");
|
|
10
12
|
function parseGitRemoteUrl(remoteUrl) {
|
|
@@ -20,13 +22,25 @@ function parseGitRemoteUrl(remoteUrl) {
|
|
|
20
22
|
}
|
|
21
23
|
export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
22
24
|
const client = new GiteaClient({ baseUrl, token });
|
|
25
|
+
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
26
|
+
let instructions;
|
|
27
|
+
try {
|
|
28
|
+
instructions = await readFile(join(moduleDir, "assets", "instructions.md"), "utf-8");
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Guidance assets may be absent during a partial build or `make dev` that did
|
|
32
|
+
// not run copy-assets; the server still works, just without the instructions hint.
|
|
33
|
+
}
|
|
23
34
|
const server = new McpServer({
|
|
24
35
|
name: "gitea-mcp",
|
|
25
36
|
version: pkg.version,
|
|
26
37
|
}, {
|
|
27
38
|
capabilities: {
|
|
28
39
|
tools: {},
|
|
40
|
+
prompts: {},
|
|
41
|
+
resources: {},
|
|
29
42
|
},
|
|
43
|
+
instructions,
|
|
30
44
|
});
|
|
31
45
|
function resolve(input) {
|
|
32
46
|
const owner = input.owner || defaultOwner;
|
|
@@ -38,7 +52,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
38
52
|
}
|
|
39
53
|
// ── Issue CRUD ──
|
|
40
54
|
server.registerTool("list_issues", {
|
|
41
|
-
description: "List issues in a Gitea
|
|
55
|
+
description: "List issues in one Gitea repository. Paginated: page is 1-based, limit <= 100; keep paging until a page returns fewer than `limit`. Filters: state (default open), labels (comma-separated NAMES). RISK: Gitea may include pull requests here; to list only issues use search_issues with type='issues'. Example: list_issues({ state: 'open', page: 1, limit: 50 })",
|
|
42
56
|
inputSchema: ListIssuesSchema.shape,
|
|
43
57
|
}, async (input) => {
|
|
44
58
|
const { owner, repo } = resolve(input);
|
|
@@ -48,7 +62,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
48
62
|
};
|
|
49
63
|
});
|
|
50
64
|
server.registerTool("get_issue", {
|
|
51
|
-
description: "
|
|
65
|
+
description: "Fetch one issue by its `index` — the number shown in the issue URL (e.g. #42), NOT the internal `id`. Use to read the full body, labels, assignee, or milestone of a single issue.",
|
|
52
66
|
inputSchema: GetIssueSchema.shape,
|
|
53
67
|
}, async (input) => {
|
|
54
68
|
const { owner, repo } = resolve(input);
|
|
@@ -58,7 +72,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
58
72
|
};
|
|
59
73
|
});
|
|
60
74
|
server.registerTool("create_issue", {
|
|
61
|
-
description: "Create
|
|
75
|
+
description: "Create an issue. `title` is required. `labels` takes label IDs (numbers) — call list_labels first to map names to IDs, or add labels by name after creation via add_issue_labels. `assignees` is an array of usernames. Returns the created issue including its `number`.",
|
|
62
76
|
inputSchema: CreateIssueSchema.shape,
|
|
63
77
|
}, async (input) => {
|
|
64
78
|
const { owner, repo } = resolve(input);
|
|
@@ -68,7 +82,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
68
82
|
};
|
|
69
83
|
});
|
|
70
84
|
server.registerTool("update_issue", {
|
|
71
|
-
description: "Update
|
|
85
|
+
description: "Update one issue by `index` (PATCH: only provided fields change). RISK: passing `labels` REPLACES the entire label set (give the full desired ID list) — to change a single label use add_issue_labels/remove_issue_label instead. `state` is 'open' or 'closed'; set milestone by ID.",
|
|
72
86
|
inputSchema: UpdateIssueSchema.shape,
|
|
73
87
|
}, async (input) => {
|
|
74
88
|
const { owner, repo } = resolve(input);
|
|
@@ -78,7 +92,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
78
92
|
};
|
|
79
93
|
});
|
|
80
94
|
server.registerTool("delete_issue", {
|
|
81
|
-
description: "
|
|
95
|
+
description: "PERMANENTLY delete an issue by `index`. IRREVERSIBLE (no recycle bin) and may fail if the instance disallows deletion. Confirm the index with the user first; prefer update_issue({ state: 'closed' }) to close instead of delete.",
|
|
82
96
|
inputSchema: DeleteIssueSchema.shape,
|
|
83
97
|
}, async (input) => {
|
|
84
98
|
const { owner, repo } = resolve(input);
|
|
@@ -88,7 +102,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
88
102
|
};
|
|
89
103
|
});
|
|
90
104
|
server.registerTool("search_issues", {
|
|
91
|
-
description: "Search issues across
|
|
105
|
+
description: "Search issues (and pull requests) across ALL repositories the token can see, by keyword/type/state/labels. Use for 'find issues about X' or duplicate detection across repos; set type='issues' to exclude pull requests. For listing one repo's issues use list_issues instead.",
|
|
92
106
|
inputSchema: SearchIssuesSchema.shape,
|
|
93
107
|
}, async (input) => {
|
|
94
108
|
const issues = await client.searchIssues(input);
|
|
@@ -98,7 +112,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
98
112
|
});
|
|
99
113
|
// ── Comments ──
|
|
100
114
|
server.registerTool("list_comments", {
|
|
101
|
-
description: "List comments on a Gitea
|
|
115
|
+
description: "List comments on one issue by its `index`. RISK: returns only the server's DEFAULT first page (this tool exposes no pagination), so long threads may be TRUNCATED — do not assume a short list means few comments. Gitea returns oldest-first. Each comment has an `id` (used to update/delete it), `body` (Markdown), `user`, and timestamps.",
|
|
102
116
|
inputSchema: ListCommentsSchema.shape,
|
|
103
117
|
}, async (input) => {
|
|
104
118
|
const { owner, repo } = resolve(input);
|
|
@@ -108,7 +122,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
108
122
|
};
|
|
109
123
|
});
|
|
110
124
|
server.registerTool("create_comment", {
|
|
111
|
-
description: "
|
|
125
|
+
description: "Add a comment to an issue by its `index`. `body` is required and supports Markdown. Returns the comment including its `id` — retain it to later update_comment/delete_comment that exact comment.",
|
|
112
126
|
inputSchema: CreateCommentSchema.shape,
|
|
113
127
|
}, async (input) => {
|
|
114
128
|
const { owner, repo } = resolve(input);
|
|
@@ -118,7 +132,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
118
132
|
};
|
|
119
133
|
});
|
|
120
134
|
server.registerTool("update_comment", {
|
|
121
|
-
description: "
|
|
135
|
+
description: "Edit a comment by its `id` (NOT the issue `index` — get the id from list_comments). `body` is the full replacement Markdown. Only the comment author or a repo admin may edit (403 otherwise).",
|
|
122
136
|
inputSchema: UpdateCommentSchema.shape,
|
|
123
137
|
}, async (input) => {
|
|
124
138
|
const { owner, repo } = resolve(input);
|
|
@@ -128,7 +142,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
128
142
|
};
|
|
129
143
|
});
|
|
130
144
|
server.registerTool("delete_comment", {
|
|
131
|
-
description: "Delete a comment from a
|
|
145
|
+
description: "Delete a comment by its `id` (NOT the issue `index` — get the id from list_comments). IRREVERSIBLE. Confirm with the user first; only the author or a repo admin may delete (403 otherwise).",
|
|
132
146
|
inputSchema: DeleteCommentSchema.shape,
|
|
133
147
|
}, async (input) => {
|
|
134
148
|
const { owner, repo } = resolve(input);
|
|
@@ -139,7 +153,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
139
153
|
});
|
|
140
154
|
// ── Labels ──
|
|
141
155
|
server.registerTool("list_labels", {
|
|
142
|
-
description: "List labels in a
|
|
156
|
+
description: "List labels in a repo. Paginated (page 1-based, limit <= 100); page until a page returns fewer than `limit`. Each label has `id` (number), `name`, `color` (hex), `description`. ALWAYS call this before any label mutation — label endpoints mix names and ids (add/replace use NAMES, remove/update/delete use IDS).",
|
|
143
157
|
inputSchema: ListLabelsSchema.shape,
|
|
144
158
|
}, async (input) => {
|
|
145
159
|
const { owner, repo } = resolve(input);
|
|
@@ -149,7 +163,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
149
163
|
};
|
|
150
164
|
});
|
|
151
165
|
server.registerTool("create_label", {
|
|
152
|
-
description: "Create a
|
|
166
|
+
description: "Create a label. `name` required and MUST be unique in the repo (a duplicate -> conflict error). `color` is 6-digit hex, with or without a leading '#' (e.g. '#ff0000' or 'ff0000'). `description` optional. Returns the label with its `id`.",
|
|
153
167
|
inputSchema: CreateLabelSchema.shape,
|
|
154
168
|
}, async (input) => {
|
|
155
169
|
const { owner, repo } = resolve(input);
|
|
@@ -159,7 +173,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
159
173
|
};
|
|
160
174
|
});
|
|
161
175
|
server.registerTool("update_label", {
|
|
162
|
-
description: "Update
|
|
176
|
+
description: "Update a label by `id` (number — NOT the name). Provide any of name/color/description (PATCH semantics). `color` is 6-digit hex. Get the id from list_labels.",
|
|
163
177
|
inputSchema: UpdateLabelSchema.shape,
|
|
164
178
|
}, async (input) => {
|
|
165
179
|
const { owner, repo } = resolve(input);
|
|
@@ -169,7 +183,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
169
183
|
};
|
|
170
184
|
});
|
|
171
185
|
server.registerTool("delete_label", {
|
|
172
|
-
description: "
|
|
186
|
+
description: "Permanently delete a label by `id` (number — NOT the name). IRREVERSIBLE and also removes it from EVERY issue that currently has it. Get the id from list_labels and confirm with the user before deleting.",
|
|
173
187
|
inputSchema: DeleteLabelSchema.shape,
|
|
174
188
|
}, async (input) => {
|
|
175
189
|
const { owner, repo } = resolve(input);
|
|
@@ -179,7 +193,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
179
193
|
};
|
|
180
194
|
});
|
|
181
195
|
server.registerTool("add_issue_labels", {
|
|
182
|
-
description: "Add labels to a
|
|
196
|
+
description: "Add labels to an issue by its `index`. `labels` is an array of label NAMES (strings) — NOT ids. Get valid names from list_labels; a name that does not exist errors (404). ADDITIVE: existing labels are kept.",
|
|
183
197
|
inputSchema: AddIssueLabelsSchema.shape,
|
|
184
198
|
}, async (input) => {
|
|
185
199
|
const { owner, repo } = resolve(input);
|
|
@@ -189,7 +203,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
189
203
|
};
|
|
190
204
|
});
|
|
191
205
|
server.registerTool("remove_issue_label", {
|
|
192
|
-
description: "Remove
|
|
206
|
+
description: "Remove ONE label from an issue. Takes the label `id` (number) — NOT the name. Get the id from list_labels (issue labels carry their id). Errors if the label is not currently on the issue.",
|
|
193
207
|
inputSchema: RemoveIssueLabelSchema.shape,
|
|
194
208
|
}, async (input) => {
|
|
195
209
|
const { owner, repo } = resolve(input);
|
|
@@ -199,7 +213,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
199
213
|
};
|
|
200
214
|
});
|
|
201
215
|
server.registerTool("replace_issue_labels", {
|
|
202
|
-
description: "
|
|
216
|
+
description: "REPLACE the issue's ENTIRE label set. `labels` is an array of label NAMES. Every existing label is removed and ONLY the listed ones remain. Read current labels first if any must survive; confirm with the user before replacing.",
|
|
203
217
|
inputSchema: ReplaceIssueLabelsSchema.shape,
|
|
204
218
|
}, async (input) => {
|
|
205
219
|
const { owner, repo } = resolve(input);
|
|
@@ -209,7 +223,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
209
223
|
};
|
|
210
224
|
});
|
|
211
225
|
server.registerTool("clear_issue_labels", {
|
|
212
|
-
description: "Remove
|
|
226
|
+
description: "Remove ALL labels from an issue by its `index`. Destructive for that issue's labels. Confirm with the user first; if a known subset must remain, use replace_issue_labels with that subset instead.",
|
|
213
227
|
inputSchema: ClearIssueLabelsSchema.shape,
|
|
214
228
|
}, async (input) => {
|
|
215
229
|
const { owner, repo } = resolve(input);
|
|
@@ -220,7 +234,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
220
234
|
});
|
|
221
235
|
// ── Milestones ──
|
|
222
236
|
server.registerTool("list_milestones", {
|
|
223
|
-
description: "List milestones in a Gitea
|
|
237
|
+
description: "List milestones in a repo. Paginated (page 1-based, limit <= 100). RISK: Gitea's DEFAULT returns only OPEN milestones — pass state='all' or 'closed' if you need closed/completed ones. Each milestone has `id`, `title`, `state`, `open_issues`, `closed_issues`, `due_on`.",
|
|
224
238
|
inputSchema: ListMilestonesSchema.shape,
|
|
225
239
|
}, async (input) => {
|
|
226
240
|
const { owner, repo } = resolve(input);
|
|
@@ -230,7 +244,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
230
244
|
};
|
|
231
245
|
});
|
|
232
246
|
server.registerTool("get_milestone", {
|
|
233
|
-
description: "
|
|
247
|
+
description: "Fetch one milestone by `id` (the internal id from list_milestones, NOT the title). Returns progress counts (open_issues / closed_issues), description, state, and due_on.",
|
|
234
248
|
inputSchema: GetMilestoneSchema.shape,
|
|
235
249
|
}, async (input) => {
|
|
236
250
|
const { owner, repo } = resolve(input);
|
|
@@ -240,7 +254,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
240
254
|
};
|
|
241
255
|
});
|
|
242
256
|
server.registerTool("create_milestone", {
|
|
243
|
-
description: "Create a
|
|
257
|
+
description: "Create a milestone. `title` required. `description` optional. `due_on` optional ISO 8601 (e.g. '2025-12-31T23:59:59Z'). New milestones start in state 'open'. Returns the milestone with its `id`.",
|
|
244
258
|
inputSchema: CreateMilestoneSchema.shape,
|
|
245
259
|
}, async (input) => {
|
|
246
260
|
const { owner, repo } = resolve(input);
|
|
@@ -250,7 +264,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
250
264
|
};
|
|
251
265
|
});
|
|
252
266
|
server.registerTool("update_milestone", {
|
|
253
|
-
description: "Update
|
|
267
|
+
description: "Update a milestone by `id` (PATCH: only provided fields change). Provide any of title/description/due_on/state. `state` is 'open' or 'closed'. NOTE: closing a milestone does NOT close its open issues (they stay open, merely ungrouped) — close the issues separately if required.",
|
|
254
268
|
inputSchema: UpdateMilestoneSchema.shape,
|
|
255
269
|
}, async (input) => {
|
|
256
270
|
const { owner, repo } = resolve(input);
|
|
@@ -260,7 +274,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
260
274
|
};
|
|
261
275
|
});
|
|
262
276
|
server.registerTool("delete_milestone", {
|
|
263
|
-
description: "
|
|
277
|
+
description: "Permanently delete a milestone by `id`. IRREVERSIBLE. Issues assigned to it are NOT deleted — they keep existing but lose the milestone assignment (milestone becomes null). Confirm with the user first; prefer update_milestone({ state: 'closed' }) to preserve history.",
|
|
264
278
|
inputSchema: DeleteMilestoneSchema.shape,
|
|
265
279
|
}, async (input) => {
|
|
266
280
|
const { owner, repo } = resolve(input);
|
|
@@ -271,7 +285,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
271
285
|
});
|
|
272
286
|
// ── Helpers ──
|
|
273
287
|
server.registerTool("resolve_repo", {
|
|
274
|
-
description: "Detect owner
|
|
288
|
+
description: "Detect owner/repo from a git repository's `origin` remote URL (SSH or HTTPS). `path` defaults to the current directory. Call ONCE at the start of a session to establish owner/repo for later calls instead of guessing. Errors if there is no `origin` remote or the URL cannot be parsed.",
|
|
275
289
|
inputSchema: ResolveRepoSchema.shape,
|
|
276
290
|
}, async (input) => {
|
|
277
291
|
const dir = input.path || process.cwd();
|
|
@@ -294,7 +308,7 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
294
308
|
};
|
|
295
309
|
});
|
|
296
310
|
server.registerTool("list_my_repos", {
|
|
297
|
-
description: "List
|
|
311
|
+
description: "List repositories the authenticated token's user can access (across ALL owners/orgs). Paginated (page 1-based, limit <= 100). Each repo object is large — keep `limit` modest. Use to DISCOVER owner/repo values or find where to work, not to list one repo's issues.",
|
|
298
312
|
inputSchema: ListMyReposSchema.shape,
|
|
299
313
|
}, async (input) => {
|
|
300
314
|
const repos = await client.listMyRepos(input.page, input.limit);
|
|
@@ -302,6 +316,137 @@ export async function createServer(baseUrl, token, defaultOwner, defaultRepo) {
|
|
|
302
316
|
content: [{ type: "text", text: JSON.stringify(repos, null, 2) }],
|
|
303
317
|
};
|
|
304
318
|
});
|
|
319
|
+
// ── Resources (on-demand reference docs for clients that surface them) ──
|
|
320
|
+
const registerDocResource = (name, file, description) => {
|
|
321
|
+
const uri = `gitea-mcp://guide/${name}`;
|
|
322
|
+
server.registerResource(name, uri, { mimeType: "text/markdown", description }, async () => {
|
|
323
|
+
let text;
|
|
324
|
+
try {
|
|
325
|
+
text = await readFile(join(moduleDir, "assets", "resources", file), "utf-8");
|
|
326
|
+
}
|
|
327
|
+
catch {
|
|
328
|
+
text = `# ${name}\n\nThis reference is unavailable in the current build.`;
|
|
329
|
+
}
|
|
330
|
+
return {
|
|
331
|
+
contents: [{ uri, mimeType: "text/markdown", text }],
|
|
332
|
+
};
|
|
333
|
+
});
|
|
334
|
+
};
|
|
335
|
+
registerDocResource("field-reference", "field-reference.md", "Gitea object field reference (Issue, Label, Milestone, Comment, Repo, User)");
|
|
336
|
+
registerDocResource("label-guide", "label-guide.md", "Label management guide: name-vs-id matrix, conventions, safe/unsafe operations");
|
|
337
|
+
registerDocResource("tool-cookbook", "tool-cookbook.md", "Task-to-tool recipes: discover, read, create, edit, destructive ops, pagination, errors");
|
|
338
|
+
// ── Prompts (multi-tool workflow triggers; the model runs the tools) ──
|
|
339
|
+
server.registerPrompt("triage_issues", {
|
|
340
|
+
title: "Triage issues",
|
|
341
|
+
description: "List open issues in a repo, read context on ambiguous ones, and propose priority labels + next actions. Returns an instruction the model executes via the tools.",
|
|
342
|
+
argsSchema: {
|
|
343
|
+
owner: z.string().optional().describe("Repository owner (defaults to GITEA_DEFAULT_OWNER)"),
|
|
344
|
+
repo: z.string().optional().describe("Repository name (defaults to GITEA_DEFAULT_REPO)"),
|
|
345
|
+
state: z
|
|
346
|
+
.enum(["open", "closed", "all"])
|
|
347
|
+
.optional()
|
|
348
|
+
.describe("Which issues to triage (default open)"),
|
|
349
|
+
},
|
|
350
|
+
}, async ({ owner, repo, state }) => {
|
|
351
|
+
const target = `${owner ?? "<GITEA_DEFAULT_OWNER>"}/${repo ?? "<GITEA_DEFAULT_REPO>"}`;
|
|
352
|
+
const st = state ?? "open";
|
|
353
|
+
const text = [
|
|
354
|
+
`Triage ${st} issues in the Gitea repository ${target}.`,
|
|
355
|
+
"",
|
|
356
|
+
"Steps:",
|
|
357
|
+
`1. Call list_issues({ state: "${st}", page: 1, limit: 50 }). Page forward while a page returns exactly 50.`,
|
|
358
|
+
" NOTE: list_issues may include pull requests — use search_issues({ type: 'issues' }) if you must exclude PRs.",
|
|
359
|
+
"2. For stale, ambiguous, or high-activity issues, call get_issue + list_comments to read context.",
|
|
360
|
+
"3. Propose for each issue: a priority/severity label, an assignee if obvious, and a one-line next action.",
|
|
361
|
+
"4. Apply labels with add_issue_labels (label NAMES) — confirm with the user first if the change is large.",
|
|
362
|
+
"5. Summarize: total triaged, how many need a human response, how many look stale.",
|
|
363
|
+
"",
|
|
364
|
+
"Do NOT delete issues. To resolve, use update_issue({ state: 'closed' }) after confirmation.",
|
|
365
|
+
].join("\n");
|
|
366
|
+
return {
|
|
367
|
+
description: `Triage ${st} issues in ${target}`,
|
|
368
|
+
messages: [{ role: "user", content: { type: "text", text } }],
|
|
369
|
+
};
|
|
370
|
+
});
|
|
371
|
+
server.registerPrompt("summarize_issue", {
|
|
372
|
+
title: "Summarize an issue",
|
|
373
|
+
description: "Read one issue plus its comment thread and produce a concise status: decisions, open questions, and a recommended next action.",
|
|
374
|
+
argsSchema: {
|
|
375
|
+
owner: z.string().optional().describe("Repository owner (defaults to GITEA_DEFAULT_OWNER)"),
|
|
376
|
+
repo: z.string().optional().describe("Repository name (defaults to GITEA_DEFAULT_REPO)"),
|
|
377
|
+
index: z.number().int().min(1).describe("Issue number (the # shown in the URL)"),
|
|
378
|
+
},
|
|
379
|
+
}, async ({ owner, repo, index }) => {
|
|
380
|
+
const target = `${owner ?? "<GITEA_DEFAULT_OWNER>"}/${repo ?? "<GITEA_DEFAULT_REPO>"}#${index}`;
|
|
381
|
+
const text = [
|
|
382
|
+
`Summarize Gitea issue ${target}.`,
|
|
383
|
+
"",
|
|
384
|
+
"Steps:",
|
|
385
|
+
"1. get_issue to read the title, body, labels, assignee(s), milestone, and state.",
|
|
386
|
+
"2. list_comments to read the discussion (oldest-first).",
|
|
387
|
+
" CAVEAT: list_comments returns only the server's default page and has no pagination here — if the count looks capped, say so.",
|
|
388
|
+
"3. Produce a summary with: a 2-3 sentence status, the key DECISIONS made, unresolved QUESTIONS/blockers, and one recommended NEXT ACTION.",
|
|
389
|
+
"4. Attribute statements to their author (user.login); never invent quotes.",
|
|
390
|
+
"5. Distinguish the reporter from maintainers/assignees.",
|
|
391
|
+
"",
|
|
392
|
+
"Do not edit or delete anything. This is read-only analysis.",
|
|
393
|
+
].join("\n");
|
|
394
|
+
return {
|
|
395
|
+
description: `Summarize issue ${target}`,
|
|
396
|
+
messages: [{ role: "user", content: { type: "text", text } }],
|
|
397
|
+
};
|
|
398
|
+
});
|
|
399
|
+
server.registerPrompt("audit_labels", {
|
|
400
|
+
title: "Audit label taxonomy",
|
|
401
|
+
description: "List every label in a repo and report duplicates, inconsistent colors, missing descriptions, and a proposed cleanup. Read-only analysis; applies nothing.",
|
|
402
|
+
argsSchema: {
|
|
403
|
+
owner: z.string().optional().describe("Repository owner (defaults to GITEA_DEFAULT_OWNER)"),
|
|
404
|
+
repo: z.string().optional().describe("Repository name (defaults to GITEA_DEFAULT_REPO)"),
|
|
405
|
+
},
|
|
406
|
+
}, async ({ owner, repo }) => {
|
|
407
|
+
const target = `${owner ?? "<GITEA_DEFAULT_OWNER>"}/${repo ?? "<GITEA_DEFAULT_REPO>"}`;
|
|
408
|
+
const text = [
|
|
409
|
+
`Audit the label taxonomy of Gitea repository ${target}.`,
|
|
410
|
+
"",
|
|
411
|
+
"Steps:",
|
|
412
|
+
"1. list_labels with page 1, limit 100; page forward while a page returns exactly 100 so the audit is complete.",
|
|
413
|
+
"2. Report: duplicate or near-duplicate NAMES (case/spelling), inconsistent or clashing COLORS, labels missing a description, and any obvious scope/name conventions (e.g. 'scope/name').",
|
|
414
|
+
"3. Propose a concrete cleanup per problem: rename via update_label (by id), recolor, or delete_label (by id).",
|
|
415
|
+
"4. DO NOT apply any change. delete_label removes the label from EVERY issue — only propose it; the user decides.",
|
|
416
|
+
"",
|
|
417
|
+
"Keep the name-vs-id matrix in mind: add/replace use NAMES, remove/update/delete use IDS.",
|
|
418
|
+
].join("\n");
|
|
419
|
+
return {
|
|
420
|
+
description: `Audit labels in ${target}`,
|
|
421
|
+
messages: [{ role: "user", content: { type: "text", text } }],
|
|
422
|
+
};
|
|
423
|
+
});
|
|
424
|
+
server.registerPrompt("milestone_report", {
|
|
425
|
+
title: "Milestone progress report",
|
|
426
|
+
description: "List all milestones in a repo, compute completion % for each, and flag overdue milestones that still have open issues. Read-only.",
|
|
427
|
+
argsSchema: {
|
|
428
|
+
owner: z.string().optional().describe("Repository owner (defaults to GITEA_DEFAULT_OWNER)"),
|
|
429
|
+
repo: z.string().optional().describe("Repository name (defaults to GITEA_DEFAULT_REPO)"),
|
|
430
|
+
},
|
|
431
|
+
}, async ({ owner, repo }) => {
|
|
432
|
+
const target = `${owner ?? "<GITEA_DEFAULT_OWNER>"}/${repo ?? "<GITEA_DEFAULT_REPO>"}`;
|
|
433
|
+
const text = [
|
|
434
|
+
`Produce a milestone progress report for Gitea repository ${target}.`,
|
|
435
|
+
"",
|
|
436
|
+
"Steps:",
|
|
437
|
+
"1. list_milestones with state='all' (the default returns ONLY open milestones — you would miss completed ones otherwise). Page through if needed.",
|
|
438
|
+
"2. For each milestone compute completion = closed_issues / (open_issues + closed_issues).",
|
|
439
|
+
"3. Flag any milestone whose due_on is in the past AND open_issues > 0 as AT RISK.",
|
|
440
|
+
"4. Summarize as a table: title, state, open/closed counts, % complete, due_on, and an AT RISK marker.",
|
|
441
|
+
"5. Recommend where to focus effort next.",
|
|
442
|
+
"",
|
|
443
|
+
"Do not edit or delete anything. Read-only analysis.",
|
|
444
|
+
].join("\n");
|
|
445
|
+
return {
|
|
446
|
+
description: `Milestone report for ${target}`,
|
|
447
|
+
messages: [{ role: "user", content: { type: "text", text } }],
|
|
448
|
+
};
|
|
449
|
+
});
|
|
305
450
|
return server;
|
|
306
451
|
}
|
|
307
452
|
export async function runServer(baseUrl, token, defaultOwner, defaultRepo) {
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/skills.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface InstallOptions {
|
|
2
|
+
project: boolean;
|
|
3
|
+
dir?: string;
|
|
4
|
+
}
|
|
5
|
+
/** Absolute path to the directory of bundled skills shipped inside dist/. */
|
|
6
|
+
export declare function bundledSkillsDir(): string;
|
|
7
|
+
/**
|
|
8
|
+
* Skills root to install into. Each bundled skill (a subdirectory containing a
|
|
9
|
+
* SKILL.md) is copied to `<root>/<skill-name>/`. Precedence: explicit --dir >
|
|
10
|
+
* --project (./.opencode/skills) > global opencode skills dir.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveInstallDir(opts: InstallOptions): string;
|
|
13
|
+
/** Parse `gitea-mcp skills <command> [flags]`. Throws on unknown flags or missing --dir value. */
|
|
14
|
+
export declare function parseInstallArgs(argv: string[]): {
|
|
15
|
+
command: string | undefined;
|
|
16
|
+
opts: InstallOptions;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Implements `gitea-mcp skills install`: copies every bundled opencode skill
|
|
20
|
+
* (each subdirectory of dist/assets/skills containing a SKILL.md) into the
|
|
21
|
+
* opencode skills directory so opencode loads them on next start. Does NOT need
|
|
22
|
+
* GITEA_BASE_URL / GITEA_TOKEN.
|
|
23
|
+
*/
|
|
24
|
+
export declare function runSkillsCommand(argv: string[]): Promise<void>;
|
package/dist/skills.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { readdir, mkdir, copyFile, access } from "node:fs/promises";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
const BUNDLED_SKILLS_REL = ["assets", "skills"];
|
|
6
|
+
const SKILL_FILENAME = "SKILL.md";
|
|
7
|
+
const USAGE = `Usage: gitea-mcp skills install [--project] [--dir <path>]
|
|
8
|
+
--project install into ./.opencode/skills/ (this project) instead of global
|
|
9
|
+
--dir <path> install into this exact directory (treated as the skills root)`;
|
|
10
|
+
/** Absolute path to the directory of bundled skills shipped inside dist/. */
|
|
11
|
+
export function bundledSkillsDir() {
|
|
12
|
+
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
return join(moduleDir, ...BUNDLED_SKILLS_REL);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Skills root to install into. Each bundled skill (a subdirectory containing a
|
|
17
|
+
* SKILL.md) is copied to `<root>/<skill-name>/`. Precedence: explicit --dir >
|
|
18
|
+
* --project (./.opencode/skills) > global opencode skills dir.
|
|
19
|
+
*/
|
|
20
|
+
export function resolveInstallDir(opts) {
|
|
21
|
+
if (opts.dir)
|
|
22
|
+
return opts.dir;
|
|
23
|
+
if (opts.project)
|
|
24
|
+
return join(process.cwd(), ".opencode", "skills");
|
|
25
|
+
const base = process.env.OPENCODE_CONFIG_DIR ?? join(homedir(), ".config", "opencode");
|
|
26
|
+
return join(base, "skills");
|
|
27
|
+
}
|
|
28
|
+
/** Parse `gitea-mcp skills <command> [flags]`. Throws on unknown flags or missing --dir value. */
|
|
29
|
+
export function parseInstallArgs(argv) {
|
|
30
|
+
const opts = { project: false };
|
|
31
|
+
let command;
|
|
32
|
+
for (let i = 0; i < argv.length; i++) {
|
|
33
|
+
const a = argv[i];
|
|
34
|
+
if (a === "--project") {
|
|
35
|
+
opts.project = true;
|
|
36
|
+
}
|
|
37
|
+
else if (a === "--dir") {
|
|
38
|
+
const val = argv[++i];
|
|
39
|
+
if (!val)
|
|
40
|
+
throw new Error("--dir requires a path argument");
|
|
41
|
+
opts.dir = val;
|
|
42
|
+
}
|
|
43
|
+
else if (a.startsWith("--dir=")) {
|
|
44
|
+
opts.dir = a.slice("--dir=".length);
|
|
45
|
+
}
|
|
46
|
+
else if (command === undefined && !a.startsWith("-")) {
|
|
47
|
+
command = a;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
throw new Error(`Unknown argument: ${a}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return { command, opts };
|
|
54
|
+
}
|
|
55
|
+
/** Recursively copy a directory tree (no experimental fs.cp dependency). */
|
|
56
|
+
async function copyTree(src, dest) {
|
|
57
|
+
await mkdir(dest, { recursive: true });
|
|
58
|
+
const entries = await readdir(src, { withFileTypes: true });
|
|
59
|
+
for (const entry of entries) {
|
|
60
|
+
const from = join(src, entry.name);
|
|
61
|
+
const to = join(dest, entry.name);
|
|
62
|
+
if (entry.isDirectory()) {
|
|
63
|
+
await copyTree(from, to);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
await copyFile(from, to);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Implements `gitea-mcp skills install`: copies every bundled opencode skill
|
|
72
|
+
* (each subdirectory of dist/assets/skills containing a SKILL.md) into the
|
|
73
|
+
* opencode skills directory so opencode loads them on next start. Does NOT need
|
|
74
|
+
* GITEA_BASE_URL / GITEA_TOKEN.
|
|
75
|
+
*/
|
|
76
|
+
export async function runSkillsCommand(argv) {
|
|
77
|
+
const { command, opts } = parseInstallArgs(argv);
|
|
78
|
+
if (command !== "install") {
|
|
79
|
+
const reason = command ? `Unknown skills subcommand: ${command}` : "Missing skills subcommand";
|
|
80
|
+
throw new Error(`${reason}\n${USAGE}`);
|
|
81
|
+
}
|
|
82
|
+
const srcDir = bundledSkillsDir();
|
|
83
|
+
let entries;
|
|
84
|
+
try {
|
|
85
|
+
entries = await readdir(srcDir, { withFileTypes: true });
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
throw new Error(`Bundled skills not found at ${srcDir}. The package may be corrupted or was installed without its assets.`);
|
|
89
|
+
}
|
|
90
|
+
const destRoot = resolveInstallDir(opts);
|
|
91
|
+
const installed = [];
|
|
92
|
+
for (const entry of entries) {
|
|
93
|
+
if (!entry.isDirectory())
|
|
94
|
+
continue;
|
|
95
|
+
const srcSkill = join(srcDir, entry.name);
|
|
96
|
+
try {
|
|
97
|
+
await access(join(srcSkill, SKILL_FILENAME));
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
continue; // not a skill directory — skip
|
|
101
|
+
}
|
|
102
|
+
await copyTree(srcSkill, join(destRoot, entry.name));
|
|
103
|
+
installed.push(entry.name);
|
|
104
|
+
}
|
|
105
|
+
if (installed.length === 0) {
|
|
106
|
+
throw new Error(`No skills found to install under ${srcDir}.`);
|
|
107
|
+
}
|
|
108
|
+
process.stdout.write(`Installed ${installed.length} gitea-mcp skill(s) -> ${destRoot}\n`);
|
|
109
|
+
for (const name of installed)
|
|
110
|
+
process.stdout.write(` - ${name}\n`);
|
|
111
|
+
process.stdout.write("Restart opencode for the skills to take effect.\n");
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amonstack/gitea-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "MCP server for managing Gitea issues via API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -11,13 +11,15 @@
|
|
|
11
11
|
"dist"
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
|
-
"build": "tsc",
|
|
14
|
+
"build": "tsc -p tsconfig.build.json && npm run build:assets",
|
|
15
|
+
"build:assets": "node scripts/copy-assets.mjs",
|
|
15
16
|
"dev": "tsx src/cli.ts",
|
|
16
17
|
"start": "node dist/cli.js",
|
|
17
|
-
"lint": "tsc
|
|
18
|
+
"lint": "tsc -p tsconfig.json",
|
|
18
19
|
"test": "vitest run",
|
|
19
20
|
"test:watch": "vitest",
|
|
20
|
-
"test:integration": "vitest run --config vitest.integration.config.ts"
|
|
21
|
+
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
22
|
+
"smoke": "node scripts/smoke.mjs"
|
|
21
23
|
},
|
|
22
24
|
"publishConfig": {
|
|
23
25
|
"access": "public"
|