diff --git a/docs/API.md b/docs/API.md deleted file mode 100644 index 8455150..0000000 --- a/docs/API.md +++ /dev/null @@ -1,857 +0,0 @@ - - -# 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)* | | | | diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md deleted file mode 100644 index 9975bce..0000000 --- a/docs/ARCHITECTURE.md +++ /dev/null @@ -1,140 +0,0 @@ - - -# 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 ` 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 ` 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 diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md deleted file mode 100644 index d878c36..0000000 --- a/docs/INSTALLATION.md +++ /dev/null @@ -1,166 +0,0 @@ - - -# 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..baseUrl` | string | Yes | Base URL of the Gitea instance (no trailing slash) | -| `connections..token` | string | Yes | Gitea API access token | -| `connections..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 diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 5d0c60b..0000000 --- a/docs/index.md +++ /dev/null @@ -1,20 +0,0 @@ - - -# 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 diff --git a/src/config.ts b/src/config.ts index f62f817..7ae522e 100644 --- a/src/config.ts +++ b/src/config.ts @@ -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 { const config_path = process.env.GITEA_API_MCP_CONFIG diff --git a/src/index.ts b/src/index.ts index fd5da2c..b89d536 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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( diff --git a/src/types.ts b/src/types.ts index e104d24..7502a58 100644 --- a/src/types.ts +++ b/src/types.ts @@ -20,9 +20,15 @@ export interface GiteaConnection { insecure?: boolean; } +export interface GitHubBackupConfig { + token: string; + org: string; +} + export interface GiteaConfig { connections: Record; defaultConnection: string; + github?: GitHubBackupConfig; } export interface ApiResponse {