chore: merge dev into main � MCP underscore convention + new features #1
-857
@@ -1,857 +0,0 @@
|
||||
<!-- Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
DEFGROUP: gitea-api-mcp.Documentation
|
||||
REPO: https://git.mokoconsulting.tech/MokoConsulting/gitea-api-mcp
|
||||
-->
|
||||
|
||||
# API Reference
|
||||
|
||||
Full parameter reference for all 61 tools in gitea-api-mcp.
|
||||
|
||||
All tools accept an optional `connection` parameter (string) to select a named connection from your config. If omitted, the default connection is used.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [User / Auth](#user--auth)
|
||||
- [Repositories](#repositories)
|
||||
- [File Contents](#file-contents)
|
||||
- [Branches](#branches)
|
||||
- [Commits](#commits)
|
||||
- [Issues](#issues)
|
||||
- [Labels](#labels)
|
||||
- [Milestones](#milestones)
|
||||
- [Pull Requests](#pull-requests)
|
||||
- [Releases](#releases)
|
||||
- [Tags](#tags)
|
||||
- [Actions](#actions)
|
||||
- [Organizations](#organizations)
|
||||
- [Users](#users)
|
||||
- [Webhooks](#webhooks)
|
||||
- [Wiki](#wiki)
|
||||
- [Notifications](#notifications)
|
||||
- [Generic](#generic)
|
||||
|
||||
---
|
||||
|
||||
## User / Auth
|
||||
|
||||
### gitea_me
|
||||
|
||||
Get the authenticated user info.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_user_orgs
|
||||
|
||||
List organizations the authenticated user belongs to.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_user_repos
|
||||
|
||||
List repositories owned by the authenticated user.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Repositories
|
||||
|
||||
### gitea_repo_get
|
||||
|
||||
Get repository details.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_repo_create
|
||||
|
||||
Create a new repository.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `name` | string | Yes | Repository name |
|
||||
| `org` | string | No | Organization (omit for personal) |
|
||||
| `description` | string | No | Description |
|
||||
| `private` | boolean | No | Private repository |
|
||||
| `auto_init` | boolean | No | Initialize with README |
|
||||
| `default_branch` | string | No | Default branch (default "main") |
|
||||
| `template` | boolean | No | Mark as template repository |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_repo_delete
|
||||
|
||||
Delete a repository.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_repo_edit
|
||||
|
||||
Edit repository settings.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `description` | string | No | New description |
|
||||
| `private` | boolean | No | Set private/public |
|
||||
| `has_issues` | boolean | No | Enable issues |
|
||||
| `has_wiki` | boolean | No | Enable wiki |
|
||||
| `has_pull_requests` | boolean | No | Enable PRs |
|
||||
| `default_branch` | string | No | Default branch |
|
||||
| `archived` | boolean | No | Archive/unarchive |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_repo_fork
|
||||
|
||||
Fork a repository.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `organization` | string | No | Fork to this org (omit for personal) |
|
||||
| `name` | string | No | Custom name for fork |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_repo_search
|
||||
|
||||
Search repositories.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `q` | string | Yes | Search query |
|
||||
| `topic` | boolean | No | Search in topics |
|
||||
| `sort` | string | No | Sort field: `alpha`, `created`, `updated`, `size`, `stars`, `forks` |
|
||||
| `order` | string | No | Sort order: `asc`, `desc` |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_org_repos
|
||||
|
||||
List repositories in an organization.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `org` | string | Yes | Organization name |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_list_connections
|
||||
|
||||
List configured Gitea connections.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| *(none)* | | | |
|
||||
|
||||
---
|
||||
|
||||
## File Contents
|
||||
|
||||
### gitea_file_get
|
||||
|
||||
Get file contents from a repository.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `filepath` | string | Yes | File path (e.g. "src/index.ts") |
|
||||
| `ref` | string | No | Branch/tag/commit (default: default branch) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_dir_get
|
||||
|
||||
Get directory contents (file listing) from a repository.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `dirpath` | string | No | Directory path (default: root) |
|
||||
| `ref` | string | No | Branch/tag/commit |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_file_create_or_update
|
||||
|
||||
Create or update a file in a repository.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `filepath` | string | Yes | File path |
|
||||
| `content` | string | Yes | File content (will be base64-encoded automatically) |
|
||||
| `message` | string | Yes | Commit message |
|
||||
| `branch` | string | No | Branch (default: default branch) |
|
||||
| `sha` | string | No | SHA of existing file (required for updates) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_file_delete
|
||||
|
||||
Delete a file from a repository.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `filepath` | string | Yes | File path to delete |
|
||||
| `sha` | string | Yes | SHA of file to delete |
|
||||
| `message` | string | Yes | Commit message |
|
||||
| `branch` | string | No | Branch |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_tree_get
|
||||
|
||||
Get the git tree for a repository (recursive file listing).
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `sha` | string | Yes | Tree SHA or branch name |
|
||||
| `recursive` | boolean | No | Recursive listing (default true) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Branches
|
||||
|
||||
### gitea_branches_list
|
||||
|
||||
List branches in a repository.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_branch_get
|
||||
|
||||
Get a specific branch.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `branch` | string | Yes | Branch name |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_branch_create
|
||||
|
||||
Create a new branch.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `new_branch_name` | string | Yes | Name for new branch |
|
||||
| `old_branch_name` | string | No | Source branch (default: default branch) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_branch_delete
|
||||
|
||||
Delete a branch.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `branch` | string | Yes | Branch name |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Commits
|
||||
|
||||
### gitea_commits_list
|
||||
|
||||
List commits in a repository.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `sha` | string | No | Branch or commit SHA |
|
||||
| `path` | string | No | Filter by file path |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_commit_get
|
||||
|
||||
Get a specific commit.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `sha` | string | Yes | Commit SHA |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Issues
|
||||
|
||||
### gitea_issues_list
|
||||
|
||||
List issues in a repository.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `state` | string | No | Issue state filter: `open`, `closed`, `all` |
|
||||
| `type` | string | No | Filter by type: `issues`, `pulls` |
|
||||
| `labels` | string | No | Comma-separated label names |
|
||||
| `milestones` | string | No | Comma-separated milestone names |
|
||||
| `q` | string | No | Search query |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_issue_get
|
||||
|
||||
Get a single issue by number.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `number` | number | Yes | Issue number |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_issue_create
|
||||
|
||||
Create a new issue.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `title` | string | Yes | Issue title |
|
||||
| `body` | string | No | Issue body (markdown) |
|
||||
| `labels` | number[] | No | Label IDs |
|
||||
| `milestone` | number | No | Milestone ID |
|
||||
| `assignees` | string[] | No | Usernames to assign |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_issue_update
|
||||
|
||||
Update an issue.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `number` | number | Yes | Issue number |
|
||||
| `title` | string | No | New title |
|
||||
| `body` | string | No | New body |
|
||||
| `state` | string | No | State: `open`, `closed` |
|
||||
| `assignees` | string[] | No | Assignees |
|
||||
| `milestone` | number | No | Milestone ID |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_issue_comments_list
|
||||
|
||||
List comments on an issue.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `number` | number | Yes | Issue number |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_issue_comment_create
|
||||
|
||||
Add a comment to an issue.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `number` | number | Yes | Issue number |
|
||||
| `body` | string | Yes | Comment body (markdown) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_issue_search
|
||||
|
||||
Search issues across all repositories.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `q` | string | Yes | Search query |
|
||||
| `state` | string | No | State filter: `open`, `closed`, `all` |
|
||||
| `labels` | string | No | Comma-separated label IDs |
|
||||
| `type` | string | No | Filter type: `issues`, `pulls` |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Labels
|
||||
|
||||
### gitea_labels_list
|
||||
|
||||
List labels in a repository.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_label_create
|
||||
|
||||
Create a label.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `name` | string | Yes | Label name |
|
||||
| `color` | string | Yes | Color hex (e.g. "#d73a4a") |
|
||||
| `description` | string | No | Label description |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Milestones
|
||||
|
||||
### gitea_milestones_list
|
||||
|
||||
List milestones in a repository.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `state` | string | No | State filter: `open`, `closed`, `all` |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_milestone_create
|
||||
|
||||
Create a milestone.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `title` | string | Yes | Milestone title |
|
||||
| `description` | string | No | Description |
|
||||
| `due_on` | string | No | Due date (ISO 8601) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Pull Requests
|
||||
|
||||
### gitea_pulls_list
|
||||
|
||||
List pull requests.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `state` | string | No | State filter: `open`, `closed`, `all` |
|
||||
| `sort` | string | No | Sort: `oldest`, `recentupdate`, `leastupdate`, `mostcomment`, `leastcomment`, `priority` |
|
||||
| `labels` | string | No | Comma-separated label IDs |
|
||||
| `milestone` | number | No | Milestone ID |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_pull_get
|
||||
|
||||
Get a single pull request.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `number` | number | Yes | PR number |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_pull_create
|
||||
|
||||
Create a pull request.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `title` | string | Yes | PR title |
|
||||
| `head` | string | Yes | Source branch |
|
||||
| `base` | string | Yes | Target branch |
|
||||
| `body` | string | No | PR description (markdown) |
|
||||
| `labels` | number[] | No | Label IDs |
|
||||
| `milestone` | number | No | Milestone ID |
|
||||
| `assignees` | string[] | No | Assignees |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_pull_merge
|
||||
|
||||
Merge a pull request.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `number` | number | Yes | PR number |
|
||||
| `merge_type` | string | No | Merge method: `merge`, `rebase`, `squash`, `rebase-merge` (default: merge) |
|
||||
| `title` | string | No | Custom merge commit title |
|
||||
| `message` | string | No | Custom merge commit message |
|
||||
| `delete_branch_after_merge` | boolean | No | Delete head branch after merge |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_pull_files
|
||||
|
||||
List files changed in a pull request.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `number` | number | Yes | PR number |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_pull_review_create
|
||||
|
||||
Create a pull request review.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `number` | number | Yes | PR number |
|
||||
| `event` | string | Yes | Review action: `APPROVED`, `REQUEST_CHANGES`, `COMMENT` |
|
||||
| `body` | string | No | Review comment |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Releases
|
||||
|
||||
### gitea_releases_list
|
||||
|
||||
List releases.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_release_get
|
||||
|
||||
Get a single release by ID.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `id` | number | Yes | Release ID |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_release_latest
|
||||
|
||||
Get the latest release.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_release_create
|
||||
|
||||
Create a new release.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `tag_name` | string | Yes | Tag name (e.g. "v1.0.0") |
|
||||
| `name` | string | No | Release title |
|
||||
| `body` | string | No | Release notes (markdown) |
|
||||
| `target_commitish` | string | No | Target branch/commit |
|
||||
| `draft` | boolean | No | Create as draft |
|
||||
| `prerelease` | boolean | No | Mark as prerelease |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_release_delete
|
||||
|
||||
Delete a release.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `id` | number | Yes | Release ID |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Tags
|
||||
|
||||
### gitea_tags_list
|
||||
|
||||
List tags.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_tag_create
|
||||
|
||||
Create a tag.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `tag_name` | string | Yes | Tag name |
|
||||
| `target` | string | No | Target branch/commit SHA |
|
||||
| `message` | string | No | Tag message (annotated tag) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_tag_delete
|
||||
|
||||
Delete a tag.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `tag` | string | Yes | Tag name |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Actions
|
||||
|
||||
### gitea_actions_runs_list
|
||||
|
||||
List workflow runs for a repository.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_actions_run_get
|
||||
|
||||
Get a specific workflow run.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `run_id` | number | Yes | Run ID |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Organizations
|
||||
|
||||
### gitea_org_get
|
||||
|
||||
Get organization details.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `org` | string | Yes | Organization name |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_org_teams_list
|
||||
|
||||
List teams in an organization.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `org` | string | Yes | Organization name |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_org_members_list
|
||||
|
||||
List members of an organization.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `org` | string | Yes | Organization name |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Users
|
||||
|
||||
### gitea_user_get
|
||||
|
||||
Get a user profile.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `username` | string | Yes | Username |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_users_search
|
||||
|
||||
Search users.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `q` | string | Yes | Search query |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Webhooks
|
||||
|
||||
### gitea_webhooks_list
|
||||
|
||||
List webhooks for a repository.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_webhook_create
|
||||
|
||||
Create a webhook.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `type` | string | Yes | Hook type: `gitea`, `slack`, `discord`, `dingtalk`, `telegram`, `msteams`, `feishu`, `matrix`, `wechatwork`, `packagist` |
|
||||
| `url` | string | Yes | Webhook URL |
|
||||
| `events` | string[] | No | Events to listen for (e.g. `["push", "pull_request"]`) |
|
||||
| `active` | boolean | No | Active status |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Wiki
|
||||
|
||||
### gitea_wiki_pages_list
|
||||
|
||||
List wiki pages.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_wiki_page_get
|
||||
|
||||
Get a wiki page.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `owner` | string | Yes | Repository owner (user or org) |
|
||||
| `repo` | string | Yes | Repository name |
|
||||
| `page_name` | string | Yes | Page name/slug |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Notifications
|
||||
|
||||
### gitea_notifications_list
|
||||
|
||||
List notifications for the authenticated user.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `status_types` | string | No | Comma-separated: `read`, `unread`, `pinned` |
|
||||
| `page` | number | No | Page number (1-based) |
|
||||
| `limit` | number | No | Items per page (max 50) |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_notifications_read
|
||||
|
||||
Mark all notifications as read.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
---
|
||||
|
||||
## Generic
|
||||
|
||||
### gitea_api_request
|
||||
|
||||
Make a raw API request to any Gitea v1 endpoint.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `method` | string | Yes | HTTP method: `GET`, `POST`, `PUT`, `PATCH`, `DELETE` |
|
||||
| `endpoint` | string | Yes | API endpoint path (e.g. "/repos/owner/repo") |
|
||||
| `body` | object | No | Request body |
|
||||
| `params` | object | No | Query parameters |
|
||||
| `connection` | string | No | Named connection from config |
|
||||
|
||||
### gitea_list_connections
|
||||
|
||||
List configured Gitea connections.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| *(none)* | | | |
|
||||
@@ -1,140 +0,0 @@
|
||||
<!-- Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
DEFGROUP: gitea-api-mcp.Documentation
|
||||
REPO: https://git.mokoconsulting.tech/MokoConsulting/gitea-api-mcp
|
||||
-->
|
||||
|
||||
# Architecture
|
||||
|
||||
## Component Overview
|
||||
|
||||
```
|
||||
src/
|
||||
index.ts -- MCP server entry point, tool registrations (61 tools)
|
||||
client.ts -- HTTP client for Gitea REST API v1
|
||||
config.ts -- Configuration loader (multi-connection support)
|
||||
types.ts -- TypeScript type definitions
|
||||
```
|
||||
|
||||
### index.ts -- Server Entry Point
|
||||
|
||||
The main module that:
|
||||
|
||||
- Creates the `McpServer` instance with stdio transport
|
||||
- Loads configuration on startup via `loadConfig()`
|
||||
- Registers all 61 tools organized by category
|
||||
- Provides shared parameter schemas (`OwnerRepo`, `PaginationParams`, `ConnectionParam`)
|
||||
- Routes tool calls through `clientFor(connection)` to resolve the target Gitea instance
|
||||
- Formats all API responses through `formatResponse()` for consistent MCP output
|
||||
|
||||
### client.ts -- HTTP Client
|
||||
|
||||
`GiteaClient` is a zero-dependency HTTP client built on `node:https` and `node:http`:
|
||||
|
||||
- Prepends `/api/v1` to all endpoint paths
|
||||
- Sets `Authorization: token <token>` header on every request (Gitea's native auth format)
|
||||
- Supports `GET`, `POST`, `PUT`, `PATCH`, `DELETE` methods
|
||||
- Handles query parameter construction via `URL.searchParams`
|
||||
- Parses JSON responses automatically
|
||||
- 30-second request timeout
|
||||
- Optional TLS certificate verification bypass (`insecure` flag)
|
||||
|
||||
### config.ts -- Configuration Loader
|
||||
|
||||
Loads the connection configuration from disk:
|
||||
|
||||
- Default path: `~/.gitea-api-mcp.json`
|
||||
- Override via `GITEA_API_MCP_CONFIG` environment variable
|
||||
- Validates that at least one connection exists
|
||||
- Sets `defaultConnection` to the first connection if not explicitly specified
|
||||
- `getConnection()` resolves a named connection or falls back to the default
|
||||
|
||||
### types.ts -- Type Definitions
|
||||
|
||||
Three core interfaces:
|
||||
|
||||
- `GiteaConnection` -- Single connection config (`baseUrl`, `token`, `insecure?`)
|
||||
- `GiteaConfig` -- Full config with named connections map and default
|
||||
- `ApiResponse` -- Standardized response wrapper (`status`, `data`)
|
||||
|
||||
## Design Decisions
|
||||
|
||||
### Token Authentication
|
||||
|
||||
Gitea uses `Authorization: token <access-token>` as its native authentication header format, unlike GitHub's `Bearer` token format. This server uses the native Gitea format directly, ensuring compatibility with all Gitea versions without requiring OAuth2 setup.
|
||||
|
||||
### Multi-Connection Architecture
|
||||
|
||||
Every tool accepts an optional `connection` parameter. This enables:
|
||||
|
||||
- Managing multiple Gitea instances from a single MCP server
|
||||
- Switching between production, staging, and development instances
|
||||
- Cross-instance operations within a single Claude Code session
|
||||
|
||||
The connection is resolved at call time, not at startup, so different tool calls can target different instances.
|
||||
|
||||
### node:https (Zero HTTP Dependencies)
|
||||
|
||||
The HTTP client uses Node.js built-in `node:https` and `node:http` modules instead of third-party libraries (e.g., axios, node-fetch). This decision:
|
||||
|
||||
- Eliminates supply-chain risk from HTTP client dependencies
|
||||
- Reduces `node_modules` size
|
||||
- Avoids compatibility issues across Node.js versions
|
||||
- Provides full control over TLS configuration (needed for `insecure` flag)
|
||||
|
||||
### Stdio Transport
|
||||
|
||||
The MCP server uses stdio transport (stdin/stdout) rather than HTTP/SSE. This means:
|
||||
|
||||
- No network ports are opened by the server
|
||||
- Tokens are never exposed through HTTP endpoints
|
||||
- The server runs as a child process of the MCP client
|
||||
- Communication is process-local, reducing attack surface
|
||||
|
||||
### Shared Parameter Objects
|
||||
|
||||
Common parameter patterns are defined as reusable objects:
|
||||
|
||||
- `OwnerRepo` -- `{ owner, repo }` for all repository-scoped operations
|
||||
- `PaginationParams` -- `{ page, limit }` for all list endpoints
|
||||
- `ConnectionParam` -- `{ connection }` for multi-connection routing
|
||||
|
||||
This ensures consistency across all 61 tools and simplifies adding new tools.
|
||||
|
||||
## Data Flow
|
||||
|
||||
```
|
||||
+-----------------+
|
||||
| Claude Code / |
|
||||
| MCP Client |
|
||||
+--------+--------+
|
||||
|
|
||||
stdio (JSON-RPC)
|
||||
|
|
||||
+--------v--------+
|
||||
| index.ts |
|
||||
| McpServer |
|
||||
| (tool router) |
|
||||
+--------+--------+
|
||||
|
|
||||
+-----------+-----------+
|
||||
| |
|
||||
+------v------+ +-------v-------+
|
||||
| config.ts | | client.ts |
|
||||
| loadConfig | | GiteaClient |
|
||||
| getConn | | (HTTP calls) |
|
||||
+------+------+ +-------+-------+
|
||||
| |
|
||||
+------v------+ HTTPS / HTTP
|
||||
| ~/.gitea- | |
|
||||
| api-mcp.json| +--------v--------+
|
||||
+-------------+ | Gitea Instance |
|
||||
| /api/v1/* |
|
||||
+-----------------+
|
||||
```
|
||||
|
||||
1. Claude Code sends a JSON-RPC tool call over stdio
|
||||
2. `McpServer` routes the call to the registered tool handler
|
||||
3. The handler calls `clientFor(connection)` which resolves the connection from config
|
||||
4. `GiteaClient` constructs the HTTP request and sends it to the Gitea API
|
||||
5. The JSON response is wrapped in `formatResponse()` and returned to the MCP client
|
||||
@@ -1,166 +0,0 @@
|
||||
<!-- Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
DEFGROUP: gitea-api-mcp.Documentation
|
||||
REPO: https://git.mokoconsulting.tech/MokoConsulting/gitea-api-mcp
|
||||
-->
|
||||
|
||||
# Installation Guide
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Node.js** >= 20.0.0 ([download](https://nodejs.org))
|
||||
- **npm** (included with Node.js)
|
||||
- A **Gitea instance** with API access enabled
|
||||
- A **Gitea access token** with appropriate scopes
|
||||
|
||||
## Install
|
||||
|
||||
### Clone and Build
|
||||
|
||||
```bash
|
||||
git clone https://git.mokoconsulting.tech/MokoConsulting/gitea-api-mcp.git
|
||||
cd gitea-api-mcp
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
The compiled output is placed in `dist/index.js`.
|
||||
|
||||
### Verify the Build
|
||||
|
||||
```bash
|
||||
node dist/index.js --help
|
||||
```
|
||||
|
||||
## Gitea Token Generation
|
||||
|
||||
1. Log in to your Gitea instance (e.g., `https://git.mokoconsulting.tech`)
|
||||
2. Navigate to **Settings** (click your avatar, top-right corner)
|
||||
3. Select **Applications** from the sidebar
|
||||
4. Under **Manage Access Tokens**, enter a descriptive token name (e.g., `mcp-server`)
|
||||
5. Select the required permission scopes:
|
||||
- `repo` -- for repository operations
|
||||
- `admin:org` -- for organization management
|
||||
- `notification` -- for notification tools
|
||||
- `user` -- for user profile operations
|
||||
- `issue` -- for issue and pull request tools
|
||||
- `package` -- if using package-related endpoints
|
||||
6. Click **Generate Token**
|
||||
7. **Copy the token immediately** -- it will not be displayed again
|
||||
|
||||
## Configuration
|
||||
|
||||
### Config File Format
|
||||
|
||||
Create `~/.gitea-api-mcp.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"defaultConnection": "moko",
|
||||
"connections": {
|
||||
"moko": {
|
||||
"baseUrl": "https://git.mokoconsulting.tech",
|
||||
"token": "your-gitea-access-token",
|
||||
"insecure": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Config Fields
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `defaultConnection` | string | No | Name of the default connection (defaults to the first one) |
|
||||
| `connections` | object | Yes | Map of named connections |
|
||||
| `connections.<name>.baseUrl` | string | Yes | Base URL of the Gitea instance (no trailing slash) |
|
||||
| `connections.<name>.token` | string | Yes | Gitea API access token |
|
||||
| `connections.<name>.insecure` | boolean | No | Skip TLS certificate verification (default: `false`) |
|
||||
|
||||
### Custom Config Path
|
||||
|
||||
Override the default config location with an environment variable:
|
||||
|
||||
```bash
|
||||
export GITEA_API_MCP_CONFIG=/path/to/custom-config.json
|
||||
```
|
||||
|
||||
### File Permissions
|
||||
|
||||
Secure your config file since it contains API tokens:
|
||||
|
||||
```bash
|
||||
chmod 600 ~/.gitea-api-mcp.json
|
||||
```
|
||||
|
||||
## Claude Code Registration
|
||||
|
||||
### Project-Level (`.mcp.json`)
|
||||
|
||||
Create or edit `.mcp.json` in your project root:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"gitea-moko": {
|
||||
"command": "node",
|
||||
"args": ["/absolute/path/to/gitea-api-mcp/dist/index.js"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Global-Level (`~/.claude/claude_desktop_config.json`)
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"gitea-moko": {
|
||||
"command": "node",
|
||||
"args": ["/absolute/path/to/gitea-api-mcp/dist/index.js"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After registering, restart Claude Code or run `/mcp` to verify the server is connected.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Failed to load config" Error
|
||||
|
||||
- Verify `~/.gitea-api-mcp.json` exists and is valid JSON
|
||||
- Check that at least one connection is defined in `connections`
|
||||
- If using `GITEA_API_MCP_CONFIG`, verify the path is correct and the file is readable
|
||||
|
||||
### "Connection not found" Error
|
||||
|
||||
- The `connection` parameter you passed does not match any key in `connections`
|
||||
- Run `gitea_list_connections` to see available connections
|
||||
- Check for typos in the connection name
|
||||
|
||||
### Authentication Failures (HTTP 401)
|
||||
|
||||
- Verify your token is correct and has not expired
|
||||
- Ensure the token has the required scopes for the operation
|
||||
- Check that the `baseUrl` points to the correct Gitea instance
|
||||
- Confirm the Gitea instance has API access enabled (admin setting)
|
||||
|
||||
### TLS / Certificate Errors
|
||||
|
||||
- For self-signed certificates, set `"insecure": true` in the connection config
|
||||
- Ensure the Gitea instance URL uses the correct protocol (`https://` vs `http://`)
|
||||
|
||||
### Timeout Errors
|
||||
|
||||
- The default request timeout is 30 seconds
|
||||
- Check network connectivity to the Gitea instance
|
||||
- Verify the Gitea instance is running and responsive
|
||||
- For large responses (e.g., recursive tree listings), consider pagination
|
||||
|
||||
### MCP Server Not Appearing in Claude Code
|
||||
|
||||
- Ensure the path in your MCP config is an absolute path to `dist/index.js`
|
||||
- Verify the build completed successfully (`npm run build`)
|
||||
- Check that Node.js >= 20.0.0 is in your PATH
|
||||
- Restart Claude Code after modifying MCP configuration
|
||||
@@ -1,20 +0,0 @@
|
||||
<!-- Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
DEFGROUP: gitea-api-mcp.Documentation
|
||||
REPO: https://git.mokoconsulting.tech/MokoConsulting/gitea-api-mcp
|
||||
-->
|
||||
|
||||
# gitea-api-mcp Documentation
|
||||
|
||||
## Contents
|
||||
|
||||
- [INSTALLATION.md](INSTALLATION.md) -- Prerequisites, installation, configuration, and troubleshooting
|
||||
- [ARCHITECTURE.md](ARCHITECTURE.md) -- Component overview, design decisions, and data flow
|
||||
- [API.md](API.md) -- Full parameter reference for all 61 tools
|
||||
|
||||
## Project-Level Documentation
|
||||
|
||||
- [README](../README.md) -- Project overview, quick start, and tool tables
|
||||
- [CHANGELOG](../CHANGELOG.md) -- Version history and release notes
|
||||
- [CONTRIBUTING](../CONTRIBUTING.md) -- Development guidelines and contribution process
|
||||
- [SECURITY](../SECURITY.md) -- Security policy and token storage best practices
|
||||
+1
-1
@@ -18,7 +18,7 @@ import { resolve } from 'node:path';
|
||||
import { homedir } from 'node:os';
|
||||
import type { GiteaConfig, GiteaConnection } from './types.js';
|
||||
|
||||
const CONFIG_FILENAME = '.gitea-api-mcp.json';
|
||||
const CONFIG_FILENAME = '.mcp_mokogitea.json';
|
||||
|
||||
export async function loadConfig(): Promise<GiteaConfig> {
|
||||
const config_path = process.env.GITEA_API_MCP_CONFIG
|
||||
|
||||
+212
@@ -1096,6 +1096,218 @@ server.tool(
|
||||
async ({ owner, repo, connection }) => formatResponse(await clientFor(connection).get(`/repos/${owner}/${repo}/push_mirrors`)),
|
||||
);
|
||||
|
||||
server.tool(
|
||||
'gitea_repo_mirror_create',
|
||||
'Create a push mirror to GitHub (backup). Sets up automatic push mirroring from Gitea to a GitHub repo.',
|
||||
{
|
||||
...OwnerRepo,
|
||||
github_owner: z.string().optional().describe('GitHub org or user (defaults to config github.org)'),
|
||||
github_repo: z.string().optional().describe('GitHub repo name (defaults to same as Gitea repo)'),
|
||||
github_token: z.string().optional().describe('GitHub token (defaults to config github.token)'),
|
||||
interval: z.string().optional().describe('Sync interval (e.g. "8h0m0s", default "8h0m0s")'),
|
||||
...ConnectionParam,
|
||||
},
|
||||
async ({ owner, repo, github_owner, github_repo, github_token, interval, connection }) => {
|
||||
const ghToken = github_token ?? config.github?.token;
|
||||
const ghOwner = github_owner ?? config.github?.org;
|
||||
if (!ghToken) return { content: [{ type: 'text' as const, text: 'Error: No GitHub token. Pass github_token or set github.token in config.' }] };
|
||||
if (!ghOwner) return { content: [{ type: 'text' as const, text: 'Error: No GitHub owner. Pass github_owner or set github.org in config.' }] };
|
||||
const ghRepo = github_repo ?? repo;
|
||||
return formatResponse(await clientFor(connection).post(`/repos/${owner}/${repo}/push_mirrors`, {
|
||||
remote_address: `https://github.com/${ghOwner}/${ghRepo}.git`,
|
||||
remote_username: ghOwner,
|
||||
remote_password: ghToken,
|
||||
interval: interval ?? '8h0m0s',
|
||||
sync_on_commit: true,
|
||||
}));
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
'gitea_repo_mirror_delete',
|
||||
'Delete a push mirror from a repository',
|
||||
{
|
||||
...OwnerRepo,
|
||||
mirror_name: z.string().describe('Push mirror remote name (from mirrors_list)'),
|
||||
...ConnectionParam,
|
||||
},
|
||||
async ({ owner, repo, mirror_name, connection }) => formatResponse(await clientFor(connection).delete(`/repos/${owner}/${repo}/push_mirrors/${mirror_name}`)),
|
||||
);
|
||||
|
||||
server.tool(
|
||||
'gitea_repo_mirror_setup_github_backup',
|
||||
'One-step GitHub backup mirror setup: creates the GitHub repo (if needed) and configures push mirror. Requires a GitHub token with repo+org scope.',
|
||||
{
|
||||
...OwnerRepo,
|
||||
github_org: z.string().optional().describe('GitHub org (defaults to config github.org)'),
|
||||
github_token: z.string().optional().describe('GitHub token (defaults to config github.token)'),
|
||||
private: z.boolean().optional().describe('Make GitHub repo private (default true)'),
|
||||
description: z.string().optional().describe('GitHub repo description'),
|
||||
interval: z.string().optional().describe('Mirror sync interval (default "8h0m0s")'),
|
||||
...ConnectionParam,
|
||||
},
|
||||
async ({ owner, repo, github_org, github_token, private: isPrivate, description, interval, connection }) => {
|
||||
const ghToken = github_token ?? config.github?.token;
|
||||
const ghOrg = github_org ?? config.github?.org;
|
||||
if (!ghToken) return { content: [{ type: 'text' as const, text: 'Error: No GitHub token. Pass github_token or set github.token in config.' }] };
|
||||
if (!ghOrg) return { content: [{ type: 'text' as const, text: 'Error: No GitHub org. Pass github_org or set github.org in config.' }] };
|
||||
const client = clientFor(connection);
|
||||
const results: string[] = [];
|
||||
|
||||
// 1. Try to create the GitHub repo via GitHub API
|
||||
const ghRes = await fetch(`https://api.github.com/orgs/${ghOrg}/repos`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${ghToken}`,
|
||||
'Accept': 'application/vnd.github+json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: repo,
|
||||
private: isPrivate ?? true,
|
||||
description: description ?? `Backup mirror of ${owner}/${repo} from MokoGitea`,
|
||||
auto_init: false,
|
||||
has_issues: false,
|
||||
has_wiki: false,
|
||||
has_projects: false,
|
||||
}),
|
||||
});
|
||||
const ghData = await ghRes.json();
|
||||
if (ghRes.status === 201) {
|
||||
results.push(`GitHub repo created: ${ghOrg}/${repo}`);
|
||||
} else if (ghRes.status === 422) {
|
||||
results.push(`GitHub repo already exists: ${ghOrg}/${repo}`);
|
||||
} else {
|
||||
return { content: [{ type: 'text' as const, text: `GitHub repo creation failed (${ghRes.status}): ${JSON.stringify(ghData)}` }] };
|
||||
}
|
||||
|
||||
// 2. Create push mirror on Gitea
|
||||
const mirrorRes = await client.post(`/repos/${owner}/${repo}/push_mirrors`, {
|
||||
remote_address: `https://github.com/${ghOrg}/${repo}.git`,
|
||||
remote_username: ghOrg,
|
||||
remote_password: ghToken,
|
||||
interval: interval ?? '8h0m0s',
|
||||
sync_on_commit: true,
|
||||
});
|
||||
|
||||
if (mirrorRes.status >= 400) {
|
||||
const err = mirrorRes.data as { message?: string };
|
||||
results.push(`Push mirror failed: ${err?.message ?? mirrorRes.status}`);
|
||||
} else {
|
||||
results.push(`Push mirror configured: sync every ${interval ?? '8h0m0s'}, sync on commit`);
|
||||
}
|
||||
|
||||
// 3. Trigger initial sync
|
||||
await client.post(`/repos/${owner}/${repo}/mirror-sync`, {});
|
||||
results.push('Initial sync triggered');
|
||||
|
||||
return { content: [{ type: 'text' as const, text: results.join('\n') }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
'gitea_repo_mirror_setup_github_backup_full',
|
||||
'Full GitHub backup: mirrors code repo + wiki repo to GitHub. Creates GitHub repo, sets up push mirrors for both code and wiki, triggers initial sync.',
|
||||
{
|
||||
...OwnerRepo,
|
||||
github_org: z.string().optional().describe('GitHub org (defaults to config github.org)'),
|
||||
github_token: z.string().optional().describe('GitHub token (defaults to config github.token)'),
|
||||
private: z.boolean().optional().describe('Make GitHub repo private (default true)'),
|
||||
description: z.string().optional().describe('GitHub repo description'),
|
||||
interval: z.string().optional().describe('Mirror sync interval (default "8h0m0s")'),
|
||||
...ConnectionParam,
|
||||
},
|
||||
async ({ owner, repo, github_org, github_token, private: isPrivate, description, interval, connection }) => {
|
||||
const ghToken = github_token ?? config.github?.token;
|
||||
const ghOrg = github_org ?? config.github?.org;
|
||||
if (!ghToken) return { content: [{ type: 'text' as const, text: 'Error: No GitHub token. Pass github_token or set github.token in config.' }] };
|
||||
if (!ghOrg) return { content: [{ type: 'text' as const, text: 'Error: No GitHub org. Pass github_org or set github.org in config.' }] };
|
||||
const client = clientFor(connection);
|
||||
const syncInterval = interval ?? '8h0m0s';
|
||||
const results: string[] = [];
|
||||
|
||||
// 1. Create GitHub repo (if needed)
|
||||
const ghRes = await fetch(`https://api.github.com/orgs/${ghOrg}/repos`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${ghToken}`,
|
||||
'Accept': 'application/vnd.github+json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: repo,
|
||||
private: isPrivate ?? true,
|
||||
description: description ?? `Backup mirror of ${owner}/${repo} from MokoGitea`,
|
||||
auto_init: false,
|
||||
has_issues: false,
|
||||
has_wiki: true,
|
||||
has_projects: false,
|
||||
}),
|
||||
});
|
||||
const ghData = await ghRes.json();
|
||||
if (ghRes.status === 201) {
|
||||
results.push(`GitHub repo created: ${ghOrg}/${repo}`);
|
||||
} else if (ghRes.status === 422) {
|
||||
results.push(`GitHub repo already exists: ${ghOrg}/${repo}`);
|
||||
} else {
|
||||
return { content: [{ type: 'text' as const, text: `GitHub repo creation failed (${ghRes.status}): ${JSON.stringify(ghData)}` }] };
|
||||
}
|
||||
|
||||
// 2. Enable wiki on GitHub repo (in case it was disabled)
|
||||
await fetch(`https://api.github.com/repos/${ghOrg}/${repo}`, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${ghToken}`,
|
||||
'Accept': 'application/vnd.github+json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ has_wiki: true }),
|
||||
});
|
||||
|
||||
// 3. Code push mirror
|
||||
const codeRes = await client.post(`/repos/${owner}/${repo}/push_mirrors`, {
|
||||
remote_address: `https://github.com/${ghOrg}/${repo}.git`,
|
||||
remote_username: ghOrg,
|
||||
remote_password: ghToken,
|
||||
interval: syncInterval,
|
||||
sync_on_commit: true,
|
||||
});
|
||||
if (codeRes.status >= 400) {
|
||||
const err = codeRes.data as { message?: string };
|
||||
results.push(`Code mirror: ${err?.message ?? `failed (${codeRes.status})`}`);
|
||||
} else {
|
||||
results.push(`Code mirror configured: sync every ${syncInterval}, sync on commit`);
|
||||
}
|
||||
|
||||
// 4. Wiki push mirror — Gitea wiki repos are at {repo}.wiki
|
||||
// Check if wiki exists first
|
||||
const wikiCheck = await client.get(`/repos/${owner}/${repo}/wiki/pages`);
|
||||
if (wikiCheck.status < 400) {
|
||||
const wikiRes = await client.post(`/repos/${owner}/${repo}/push_mirrors`, {
|
||||
remote_address: `https://github.com/${ghOrg}/${repo}.wiki.git`,
|
||||
remote_username: ghOrg,
|
||||
remote_password: ghToken,
|
||||
interval: syncInterval,
|
||||
sync_on_commit: true,
|
||||
});
|
||||
if (wikiRes.status >= 400) {
|
||||
const err = wikiRes.data as { message?: string };
|
||||
results.push(`Wiki mirror: ${err?.message ?? `failed (${wikiRes.status})`}`);
|
||||
} else {
|
||||
results.push(`Wiki mirror configured: ${ghOrg}/${repo}.wiki.git`);
|
||||
}
|
||||
} else {
|
||||
results.push('Wiki mirror skipped: no wiki pages found');
|
||||
}
|
||||
|
||||
// 5. Trigger initial sync
|
||||
await client.post(`/repos/${owner}/${repo}/mirror-sync`, {});
|
||||
results.push('Initial sync triggered');
|
||||
|
||||
return { content: [{ type: 'text' as const, text: results.join('\n') }] };
|
||||
},
|
||||
);
|
||||
|
||||
// ── Repo Statistics ─────────────────────────────────────────────────────
|
||||
|
||||
server.tool(
|
||||
|
||||
@@ -20,9 +20,15 @@ export interface GiteaConnection {
|
||||
insecure?: boolean;
|
||||
}
|
||||
|
||||
export interface GitHubBackupConfig {
|
||||
token: string;
|
||||
org: string;
|
||||
}
|
||||
|
||||
export interface GiteaConfig {
|
||||
connections: Record<string, GiteaConnection>;
|
||||
defaultConnection: string;
|
||||
github?: GitHubBackupConfig;
|
||||
}
|
||||
|
||||
export interface ApiResponse {
|
||||
|
||||
Reference in New Issue
Block a user