mcpField
F
Forgejo / Codeberg / Gitea

Forgejo / Codeberg / Gitea

ローカル
codeberg.orgバージョン管理11 日前に更新

Forgejo / Codeberg / Gitea について

Claude CodeやClaude DesktopなどのMCPクライアントから、REST API経由でForgejo、Codeberg、GiteaにアクセスするRust製MCPサーバーです。既定では読み取り専用で、別の書き込みトークンと時間制限付きの書き込みモードを使うと、保護された更新操作を利用できます。

主な機能

  1. 01ユーザー、リポジトリ、課題、プルリクエストの読み取り
  2. 02組織、通知、コメント、レビューの検索
  3. 03Actionsワークフロー実行の確認
  4. 04時間制限付きの保護された書き込み
  5. 05REST APIによるForgejoとGiteaへの接続

活用シーン

  1. 01リポジトリ、課題、プルリクエストの検索
  2. 02Actions CIワークフローの実行状況確認
  3. 03書き込みモード有効化後の課題やプルリクエスト作成

MCP 対応

stdioを使用するツール専用のMCPサーバーで、MCPクライアントから呼び出せます。Forgejo、Codeberg、Giteaの各インスタンスに接続し、リソースやプロンプトは提供しません。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

インストール方法は未掲載です

このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。

リポジトリ
パッケージ
cargoforgejo-mcp-rs0.26.0

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

forgejo-mcp-rs

CI

Forgejo、Codeberg、 Gitea 向けの Model Context Protocol サーバーです。MCP クライアント(Claude Code、Claude Desktop など)から、Forgejo/Gitea REST API を介して、フォージ(認証済みユーザー、リポジトリ、イシュー、プルリクエスト)を読み取れます。

ステータス:デフォルトでは読み取り専用で、オプトイン方式の保護された書き込みに対応しています(v0.2 以降)。 フォージ全体の読み取りツール(ユーザー、リポジトリ、イシュー、プルリクエスト、検索、組織、通知、コメント、レビュー、Actions(CI)の実行)に加え、保護された書き込み(create_repo、edit_repo、create_branch、delete_branch、create_issue、edit_issue、comment_on_issue、create_pull_request、create_pull_request_review、merge_pull_request、create_or_update_file、delete_file、delete_repo、migrate_repo、プッシュミラーの管理、dispatch_workflow、cancel_workflow_run、rerun_workflow)を利用できます。これらの書き込みは、別の書き込みトークンと、意図的に有効化する時間制限付きの書き込みモードによって制御されます。設計の全容については、SPECIFICATION.md を参照してください。

Forgejo REST API と直接通信するため、社内製の小規模なクライアント(src/forgejo/client.rs。src/mcp_core/ のトランスポートを使用)を実装しています。これは、ドキュメント化された API に対する独立した実装であり、他のサーバーの移植版ではありません。信頼境界内にサードパーティ製のフォージ SDK はないため、トークンを扱うツールのコードを最初から最後まで読んで監査できます。

サーバーは MCP プロトコルバージョン 2026-07-28(v0.16 以降)で通信し、2024-11-05 へのダウングレードをネゴシエートするため、古いクライアントも変更なしで引き続き動作します。stdio で動作し、ツールのみを公開します。リソース、プロンプト、サンプリング、ルートはありません。

ビルド

cargo build --release   # target/release/forgejo-mcp-rs
cargo install --path .  # install to ~/.cargo/bin

日常的に開発・使用している macOS と、ビルドおよび実行できる Linux で動作します(Glama は Debian 上でビルドして検査しています)。Windows は未テストです。

Woodpecker CI

Woodpecker CI 向けの関連サーバーは、v0.13.0 から v0.17.0 まで、2 つ目の woodpecker-mcp バイナリとしてこのクレートに同梱されていました。現在は独立したリポジトリとクレートに移っています。 woodpecker-mcp。

Woodpecker は独自のシステムです。Forgejo と同様に Gitea、GitHub、GitLab、Bitbucket も操作でき、このサーバーが Forgejo API を呼び出すこともありません。そのため、ここに同梱していたことで、Forgejo を使っていないユーザーには存在が知られませんでした。移行による変更はありません。このクレートの woodpecker-mcp バイナリを使用していた場合は、新しいクレートからインストールし、MCP クライアントの接続先を新しいパスに変更してください。

設定

サーバーは環境変数で設定します。

変数必須デフォルト説明
FORGEJO_TOKEN_READ_ONLYはい—読み取りトークン(または FORGEJO_TOKEN)です。読み取り専用スコープで十分です。
FORGEJO_TOKEN_WRITEいいえ—書き込み/削除スコープのトークンです。指定すると書き込みツールが有効になります。読み取り専用サーバーとして使用する場合は省略してください。
FORGEJO_WRITE_MINUTESいいえ10書き込みモードのデフォルト有効時間(分、最大 60 分)です。
FORGEJO_MIRROR_TOKENいいえ—add_push_mirror がリモートのパスワードとして送信する認証情報です(例:GitHub PAT)。会話には含まれず、ツール引数として渡されることもありません。use_ssh=true のミラーのみを使用する場合は省略してください。
FORGEJO_MIGRATE_TOKENいいえ—migrate_repo が読み取り元のソースインスタンスに送信する認証情報です。これもツール引数として渡されません。FORGEJO_MIRROR_TOKEN とは意図的に分けています。後者はプッシュ先のターゲットへの認証に使われるため、変数を共用すると、発行先ではないホストに認証情報を送信してしまいます。公開リポジトリのみを移行する場合は省略してください。
FORGEJO_UPLOAD_ROOTいいえ—upload_release_asset がファイルを読み取るディレクトリです。未設定の場合、アップロードは無効です。リリースアセットを参照してください。
FORGEJO_UPLOAD_MAX_MBいいえ1001 つのアセットのアップロード上限(MiB)です。送信のため、ファイル全体をメモリに読み込みます。
FORGEJO_URLいいえhttps://codeberg.orgインスタンスのベース URL です。
FORGEJO_FLAVORいいえautoインスタンスのバージョンから検出する forgejo、gitea、または auto です。これを参照するのは Actions(CI)ツールのみです。Forgejo と Giteaを参照してください。

Codeberg → Settings → Applications(または使用するインスタンスの同等のページ)でトークンを作成してください。読み取りツールには、読み取りスコープ(read:repository、read:issue、read:user)があれば十分です。書き込みトークンには write:repository が必要です(削除、およびリポジトリ管理者向けのプッシュミラーエンドポイントを含みます)。

読み取りトークンは必須です。書き込みトークンだけではサーバーは起動せず、読み取りトークンは FORGEJO_TOKEN_WRITE とは別のトークンでなければなりません。書き込みトークンを読み取りにも再利用して済ませることはできません。

Forgejo 15 以降のトークンスコープ。 Forgejo 15.0 では、多くのリポジトリ API の認可が強化され、細粒度のリポジトリスコープ付きアクセストークンに対応しました。従来の広範なトークンには影響しませんが、リポジトリスコープ付きトークンを作成する場合は、上記のスコープを実際に付与する必要があります。特にプッシュミラーツールにはリポジトリ管理者スコープが必要です。これがないと 403 が返されます。アクセスする予定のすべてのリポジトリをトークンのスコープに含めてください。

Forgejo と Gitea

Forgejo は Gitea のフォークとして始まり、REST API の仕様も今なおほぼ同じです。このサーバーが呼び出す約 25 個のエンドポイントのうち、異なるのは Actions(CI)関連のみです。 イシュー、プルリクエスト、差分、PR ファイル、ブランチ、ファイルの内容、検索、組織、通知、プッシュミラー、移行は、両者でパス、メソッド、レスポンス形式が同一のため、特別な処理は不要で、実際に行っていません。

フレーバーはインスタンスの GET /version から遅延検出で一度だけ判定されます。これを参照するのは Actions ツールのみです。インスタンスでの検出結果が誤っている場合は、FORGEJO_FLAVOR を forgejo または gitea に設定して固定してください。

検出方法が奇妙に見えるのは意図的です。Forgejo は自身のバージョン文字列に Gitea の名前を含めます (Codeberg は API 互換性を示すために 16.0.0-dev-785-465b60ef+gitea-1.22.0 を返します)が、Gitea は自身の名前を含めません(29.0.0+dev-160-g55186ca39b)。そのため、gitea- マーカーがあれば Forgejo、なければ Gitea です。メジャーバージョンは判断材料になりません。Gitea は 1.x 系を離れており、v0.21.0 より前は、そのため gitea.com が Forgejo と判定されていました。

2 つのフォージで異なる点と、それに対するサーバーの処理は次のとおりです。

ForgejoGitea処理
git ref による実行の絞り込みref、完全修飾形式branch、ベア名変換します。refs/heads/main はどちらでも使用できます
ワークフローによる実行の絞り込みworkflow_id クエリパラメーター独立した …/actions/workflows/{file}/runs パス変換します
実行結果status のみstatus(フェーズ)と conclusion正規化します。conclusion を status に反映し、元の値もそのまま保持します
実行のフィールド名commit_sha、prettyref、index_in_repo、title、created、trigger_eventhead_sha、head_branch、run_number、display_title、created_at、event1 つの形式に正規化します
ワークフローファイルと ref別々:workflow_id と prettyrefci.yml@refs/heads/main のように path に結合分割します。ref は短縮し(main、v0.16.0)、プルリクエストの ref はそのまま保持します
不明なワークフローフィルター空のリスト404 workflow "x.yml" not foundそのまま表示します。ツールの説明にどちらの挙動かを記載しています
workflow_dispatch の応答作成された実行(return_run_info)204 No ContentForgejo の実行はそのまま返します。Gitea ではツールが確認応答を返し、呼び出し元に list_workflow_runs で実行を検索するよう案内します
ワークフローディレクトリ.forgejo/workflows、.github/workflows.gitea/workflows、.github/workflowsdispatch_workflow ツールの説明に記載しています
実行のジョブタイムスタンプやステップのない配列タイムスタンプとステップを含む { jobs, total_count }実行と同様にラップを解除して正規化します。Forgejo が省略する情報は省略したままです
ブランチによるプルリクエストの絞り込みbase、head(Forgejo 16 以降)base_branch のみ変換します。Gitea ではリストをたどって head を適用します。Forge が未対応のフィルターを無視するため、すべての応答を両方の条件で確認します
キャンセルと再実行の応答204 No Content実行(200/201)、ジョブの再実行ではジョブ応答に実行が含まれていればそれを使用し、含まれていなければ再取得します。list_workflow_runs と同じ形式で報告します
単一ジョブの再実行…/actions/jobs/{job_id}/rerun…/actions/runs/{run}/jobs/{job_id}/rerun変換します。どちらでも run_id が必要です
完了済み実行のキャンセル204、変更なし未検証。仕様には 409 Conflict と記載エラーはそのまま表示します。成功時は返された実行の status で処理結果を示します

両方の表記を送るのではなく変換するのは意図的です。不明なクエリパラメーターは拒否されず、 無視されます。そのため、Forgejo の ref を Gitea に送ると、実行が絞り込まれないまま 返されます。フィルターが適用されたように見えても、実際には適用されません。

Gitea の path は名前に惑わされやすいため、個別に注意が必要です。これはファイルシステムの パスではありません。ワークフローファイル、@、完全修飾 ref を組み合わせたものです。 たとえば、ci.yml@refs/heads/main や test-pr.yml@refs/pull/1117/head です。また、ref を 取得できる唯一の信頼できる情報源でもあります。head_branch はブランチの実行では設定されますが、 タグやプルリクエストでは null になるためです。

フォージの種類にかかわらず、ほかに 2 点あります。Gitea では、パブリックリポジトリでも Actions API に トークンが必要です。get_workflow_run は list_workflow_runs と同じ正規化済み形式で応答します。

書き込みモード

サーバーはデフォルトで読み取り専用です。create_repo/edit_repo/delete_repo は、(a) FORGEJO_TOKEN_WRITE が設定されており、かつ(b)enable_write_mode を使って意図的に 書き込みモードに入っている場合にのみ動作します。書き込みモードは時間制限付きの権限昇格で、デフォルトは10分、最大60分です。書き込みのたびに期限が延長され、自動的に元に戻ります。write_status で状態を確認できます。また、delete_repo には、"owner/repo" と一致する confirm 引数も必要です。

enable_write_mode、disable_write_mode、write_status はすべて、適用対象の instance を報告します。また、権限昇格の通知文にもインスタンス名が含まれるため、単に「書き込みモードが有効です」ではなく、「https://gitea.com/ で書き込みモードが有効です」と表示されます。これは、たとえばCodebergとGiteaのように、複数のサーバーを同時に実行する場合に重要です。それぞれが独立した書き込みモードを持つため、対象を明示しない警告では、どのForgeが書き込み可能になったのか分かりません。write_status は意図的にインスタンスへ接続しないため、ほかの処理で検出されるまでは flavor が null になります。設計の詳細については、SPECIFICATION.mdを参照してください。

移行元のトークン(任意)

非公開の移行元に対してmigrate_repoを使う場合にのみ必要です。公開されている移行元には認証情報は必要ありません。ここは省略してください。

方向に注意してください。ここにあるほかの変数はすべて、あなたのインスタンス(FORGEJO_URL)に対する認証に使われます。FORGEJO_MIGRATE_TOKEN は、コピー元となる別のインスタンスに対する認証に使われます。

  1. トークンは、自分のインスタンスではなく、移行元インスタンスの「Settings → Applications」で作成します。
  2. 読み取りスコープのみを付与します。read:repository に加え、IssueとPRを移行する場合は read:issue も付与します。移行元から読み取るだけなので、書き込み権限は不要です。ForgejoとGiteaでは、非公開の移行元にもアクセスできるよう、リポジトリへのアクセス範囲を「公開リポジトリのみ」ではなく「すべてのリポジトリ」に設定してください。
  3. 移行先インスタンス用のサーバーで、ほかのトークンと同じ env ブロックに FORGEJO_MIGRATE_TOKEN として設定します。移行先がコピーを依頼し、移行先から移行元へトークンが提示されます。
  4. authenticate: true を指定して migrate_repo を呼び出します。これを指定しないと、トークンは送信されません。

このトークンを設定する前に、どこへ送られるかを確認してください。 読み取り/書き込みトークンは FORGEJO_URL に対する Authorization ヘッダーとして送られ、それ以外には送信されません。このトークンは異なり、リクエストボディに含まれます。その後、移行先インスタンスがあなたに代わって移行元ホストにトークンを提示します。移行先にはトークンが平文で見えます。これはサーバー側の移行APIに共通する仕様であり、このサーバー固有の選択ではありません。ただし、移行先の運用者を信頼する必要があります。移行元が対応している場合は、トークンのアクセス範囲を単一のリポジトリに限定し、移行完了後に取り消してください。

mirror: true を指定すると、移行先は再取得を続けるために認証情報を保持する必要があるため、認証情報は一度使い切って破棄されるのではなく、そのインスタンスのデータベースに保存されます。継続的なプルミラーが必要な場合を除き、1回限りの移行をおすすめします。

Claude Codeに接続する
claude mcp add --scope user forgejo /path/to/target/release/forgejo-mcp-rs \
  --env FORGEJO_URL=https://codeberg.org \
  --env FORGEJO_TOKEN_READ_ONLY=your_read_token_here
# add --env FORGEJO_TOKEN_WRITE=… only if you want the (gated) write tools
# add --env FORGEJO_MIGRATE_TOKEN=… only to migrate from a *private* source instance
またはClaude Desktopに接続する
{
  "mcpServers": {
    "forgejo": {
      "command": "/path/to/target/release/forgejo-mcp-rs",
      "env": { "FORGEJO_URL": "https://codeberg.org", "FORGEJO_TOKEN_READ_ONLY": "your_read_token_here" }
    }
  }
}

FORGEJO_URL にGiteaインスタンスを指定すれば、同じように動作します。フレーバーは自動的に検出されます。

{
  "mcpServers": {
    "gitea": {
      "command": "/path/to/target/release/forgejo-mcp-rs",
      "env": { "FORGEJO_URL": "https://gitea.com", "FORGEJO_TOKEN_READ_ONLY": "your_read_token_here" }
    }
  }
}

ログは標準エラー出力(標準出力はMCPトランスポート用)に出力されます。たとえば RUST_LOG=forgejo_mcp_rs=debug のように、RUST_LOG で詳細度を調整できます。

ツール

対象ごとに分類しています。2列目は、書き込みモードが必要なツールを示します。

アカウントとインスタンス
ツール備考
whoamiread認証済みユーザー(トークンを検証します)
versionreadこの MCP サーバーのバージョン、接続先インスタンスのバージョン、およびその flavor(forgejo または gitea)
list_orgsread所属している組織
list_notificationsread通知スレッドの簡易版(既読と未読の両方を含めるには all=true を指定)
list_keysreadアカウントの SSH キーと GPG キー(自分のキーを取得する場合は username を省略)。verified は署名を検証できるかどうかを示します。ただし、Gitea は SSH キーではこのフィールドを省略するため、値がない場合は未検証ではなく、未報告を意味します。GPG エントリには、そのキーが対象とするアドレスと、それぞれが有効化されているかどうかが含まれます
書き込みモードの切り替え
ツール備考
write_statusread書き込みモードの状態を報告します(トークンが設定されているか、有効か、残り何分か)
enable_write_mode / disable_write_mode時間制限付きの書き込みモードを開始/終了します
リポジトリ
ツール備考
list_my_reposread自分のリポジトリ(自動ページネーション、簡易版)
search_reposreadキーワードでリポジトリを検索します
get_reporead1 つのリポジトリの詳細(デフォルトブランチ、サイズ(KiB)、has_* の各機能切り替えを含む、簡易版)
create_repowriteリポジトリを作成します(デフォルトでは非公開)
edit_repowriteリポジトリの設定を編集します(公開範囲、説明、ウェブサイト、デフォルトブランチ、機能切り替え(issues、PR、wiki、releases、actions、packages、projects)、アーカイブ)。指定したフィールドのみが変更され、名前の変更はできません。機能がオフの場合、その機能に属するエンドポイント群は空の結果を返すのではなく、すべて 404 になります。そのため、リポジトリが明らかに存在するのにツールから見つからないと報告される場合は、has_releases / has_actions を設定してください
delete_repowriteリポジトリを削除します(confirm = "owner/repo" が必要)
migrate_repowrite別のインスタンスからリポジトリをコピーします。インスタンス間で issues / PR を引き継ぐ唯一のツールです。インポート完了後に応答し、失敗によって残された空のリポジトリがあればその名前を示します。ソースは変更されません。認証情報には FORGEJO_MIGRATE_TOKEN を使用します
ファイル
ツール備考
get_repo_treereadリポジトリの git ツリー(sha、recursive は任意)。エントリにはパス、タイプ、サイズ、sha が含まれます。ファイルが存在しないと結論付ける前に truncated を確認してください
get_file_contentsreadファイルを読み取る(テキストをデコード)か、ディレクトリを一覧表示します(owner/repo/path、ref は任意)。start_line / end_line を指定すると、ファイルの範囲内に収まる 1 始まりの両端を含む範囲を取得します。total_lines は常に報告されます
create_or_update_filewrite1 つのコミットとしてファイルを作成するか、内容を置き換えます(owner/repo/path/content。content は UTF-8 テキスト)。更新するには、get_file_contents から取得した現在の sha を渡します。古い値は拒否されます。message、branch、new_branch は任意です
delete_filewrite1 つのコミットとしてファイルを削除します(owner/repo/path/sha)。message、branch、new_branch は任意です
ブランチとコミット
ツール備考
list_branches読み取りowner/repo 内のブランチ(自動ページネーション、名前/コミット/保護状態に絞り込み)
list_branch_protections読み取りリポジトリの保護ルール:ブランチ名または glob に対して各ルールが適用する内容(require_signed_commits、直接プッシュ、承認、ステータスチェック)。許可リストは省略されます。リストが空の場合、保護されているものはありません
create_branch書き込みブランチを作成します(owner/repo/new_branch、任意の old_ref)
delete_branch書き込みブランチを削除します(owner/repo/branch)。Forge はデフォルトブランチと保護されたブランチの削除を拒否します
list_commits読み取りref 上のコミット(owner/repo、任意の sha と path。自動ページネーション)。sha、件名、作成者、日付、署名状態に絞り込みます。生のオブジェクトには base64 の signature/payload blob と、コミットごとの files/stats が含まれます
get_commit読み取り1 件のコミット(owner/repo/sha)。同じフィールドを返します。signature は verified、unverified、unsigned のいずれかです。1 つ目の場合は signer、2 つ目の場合は reason が含まれます
get_commit_statuses読み取りコミット/ブランチ/タグに対する個々のステータス:コンテキスト、ステータス、説明、target_url。get_combined_status はこれらを 1 つの判定にまとめます
get_combined_status読み取りref に対する集約済み CI 判定。1 つの状態と、チェックごとの最新結果を返します。「CI は成功したか」を確認するツールです。get_commit_statuses は遷移履歴を返します
Issue
ツール備考
list_issues / get_issue読み取りowner/repo 内の Issue(デフォルトではオープン)。Forge が Issue としても一覧表示するプルリクエストは除外されます。labels、milestones、author、assignee、mentioned、search、since/before で絞り込みます。不明なラベル名またはマイルストーン名は、Forge がすべてを一覧表示してしまうため拒否されます。sort(oldest、recentupdate、mostcomment、nearduedate、…)は Forgejo で利用できます。Gitea の Issue 一覧には並べ替え機能がないため、そこでの指定は拒否されます。state、作成者、ラベル、担当者、マイルストーン、コメント数、日付に絞り込みます。get_issue は本文も返します
list_issue_comments読み取りIssue/PR のコメント(絞り込み済み)
create_issue書き込みIssue を作成します(owner/repo/title、任意の body)
edit_issue書き込みIssue を直接編集します(owner/repo/index):state は open/closed、title、body、assignees、milestone、due_date、labels(名前)。渡された項目のみ変更されます。プルリクエストの番号にも使用できるため、state: closed を指定するとマージされずに PR がクローズされます
comment_on_issue書き込みIssue/PR にコメントします(owner/repo/index/body)
プルリクエスト
ツール備考
list_pull_requests / get_pull_request読み取りowner/repo のプルリクエスト(デフォルトではオープン状態)。base と head ブランチ(head は owner:branch の形式も可)で絞り込み、ブランチにすでにオープン状態のプルリクエストがあるかどうかを確認できます。また、author でも絞り込めます。どちらのフォージでも、oldest、recentupdate、recentclose、mostcomment などで sort できます。情報は簡潔にまとめられており、ブランチ、状態、head_sha、作成者、ラベル、日付が含まれます。get_pull_request では説明、レビュアー、マージの詳細も取得できます
list_pull_request_files読み取りPR で変更されたファイル(自動ページネーション対応)。ファイルごとの追加・削除数と名前変更の情報も含まれます。Forgejo ではここにハンクは含まれないため、内容を確認するには get_pull_request_diff を使用してください
get_pull_request_diff読み取りPR の統合差分です。file_path を指定すると、1 つのファイルに絞り込めます(名前変更の前後どちらのパスにも一致します)。指定しない場合は 64 KiB で切り詰められます。max_bytes で上限を引き上げられます
list_pull_request_reviews読み取りPR のレビューです。承認/変更要求/コメントの判定と概要本文(インラインコメントは件数)が含まれます
create_pull_request書き込みPR をオープンします(owner/repo/title/head/base、本文は任意)
create_pull_request_review書き込みPR をレビューします(owner/repo/index/verdict)。判定は approve、request_changes、comment のいずれかで、概要の body と任意の commit_id を指定できます
merge_pull_request書き込みPR をマージします(owner/repo/index)。マージ方法は style で指定します(merge/rebase/rebase-merge/squash/fast-forward-only)。タイトル/メッセージ、delete_branch、および head が更新されていた場合にマージを拒否する head_sha ガードも指定できます。現在の PR の状態を返します
アクション(CI)
ツール備考
list_workflow_runs読み取りowner/repo のアクション(CI)の実行履歴です。どちらのフォージでも同じ形式に簡潔化されています。新しい順で、デフォルトでは 1 ページあたり 30 件です。head_sha/ref/status/event/workflow_id で絞り込めます。各実行の status に結果が含まれます
get_workflow_run読み取りrun_id で指定したワークフロー実行 1 件を、list_workflow_runs と同じ形式で取得します
list_workflow_jobs読み取り1 件の実行に含まれるジョブです。どちらのフォージでも形式が統一されています。各ジョブの id は get_job_log に渡す値です。Forgejo 16+
get_job_log読み取りHTTP Range で取得した、1 件のジョブのログの一部です。デフォルトでは末尾の 32 KiB(max_bytes は最大 1 MiB)を取得し、行の途中で切れないようにし、色コードとタイムスタンプを取り除きます。次の範囲を取得するには earlier/later を指定します。Forgejo 16+
dispatch_workflow書き込みworkflow_dispatch でアクションワークフローを起動します(owner/repo/workflow ファイル名/ref、inputs は任意)。Forgejo では作成された実行を返し、Gitea では受け付けたことを示す応答を返します
cancel_workflow_run書き込み保留中または実行中の実行をキャンセルします(owner/repo/run_id)。現在の実行状態を返します。Forgejo 16+
rerun_workflow書き込み完了した実行を再実行します。または job_id を指定すると、1 件のジョブと、それに依存するジョブを再実行します。実行を返します。Forgejo 17+ — エンドポイントがないインスタンスでは、その旨とバージョンが報告され、再実行は行われません
リリース
ツール説明
list_releases読み取りリポジトリのリリースを新しい順に一覧表示します(自動ページネーション)。識別情報に加え、asset_count と asset_names に絞って返します
get_release読み取りGit の タグを指定してリリースを1件取得します。リリーススクリプトを冪等にするための検索機能です。返す内容は同じく絞り込まれた形式で、ノートと target_commitish が加わります
list_release_assets読み取りrelease_id を指定して、リリースに添付されたファイル(id、名前、サイズ、ダウンロード URL)を一覧表示します
create_release書き込みタグにリリースを作成します(tag_name。タグが存在しない場合、target_commitish によってタグを作成します)
edit_release書き込みrelease_id を指定してリリースを直接編集します。対象は body(ノート)、name、tag_name、draft、prerelease です。渡されたフィールドのみが送信されるため、省略したフィールドは変更されません
upload_release_asset書き込みローカルファイルをリリースに添付します。FORGEJO_UPLOAD_ROOT の配下に限定されており、この変数が未設定の場合は完全に無効になります
delete_release_asset書き込みattachment_id を指定してアセットを1件削除します。同名ファイルを置き換える際に必要です。削除しない場合、Forgejo では同名ファイルが併存します
プッシュミラー
ツール説明
list_push_mirrors書き込みリポジトリのプッシュミラーを一覧表示します(管理者スコープ。シークレットは返されません)
add_push_mirror書き込みリポジトリを外部のリモート(例:GitHub ミラー)に自動プッシュします。認証情報には FORGEJO_MIRROR_TOKEN または use_ssh=true を使用します
delete_push_mirror書き込みremote_name を指定してプッシュミラーを削除します
sync_push_mirrors書き込みプッシュミラーの同期を直ちに実行します
ページネーションと結果の絞り込み

読み取り用の一覧ツールでは、任意で state(open/closed/all)と page/limit を指定できます。ページネーションを指定せずに呼び出した場合、list_my_repos/list_issues/list_pull_requests は全件を自動でページネーションし、{ returned, total, truncated, items } の形式で返します。明示的に page または limit を渡すと、単一ページを取得し、代わりに { page, limit, returned, total, items } の形式で返します(件数を返さない search_repos では、total は null です)。結果は重要なフィールドに絞り込まれ、書き込みツールは対応する読み取りツールと同じ形式で応答します。書き込みツールには書き込みモードが必要です。

インスタンス間でリポジトリを移行する

migrate_repo は Forgejo の POST /repos/migrate をラップしたもので、移行先で呼び出します。clone_addr は移行元を指します。Git の参照だけを複製するプッシュミラーとは異なり、課題、PR、ラベル、マイルストーン、リリース、Wiki も移行できます。知っておくべき点は 3 つあります。

  • service を設定してください。 デフォルトは git で、参照のみをコピーするベアクローンです。API ベースのインポーターを有効にするには、移行元のフォージ(Forgejo または Codeberg が移行元の場合は gitea。forgejo という値はありません)を指定してください。このインポーターがメタデータ関連フラグに必要です。
  • コンテンツ関連のフラグはデフォルトでオフです。 issues、pull_requests、labels、milestones、releases、wiki、lfs はそれぞれオプトイン方式で、API 自体のデフォルトと同じです。
  • 呼び出し中に完了し、コピーとして作成されます。 インスタンスはインポートが完了すると応答します(Codeberg 上の小規模なリポジトリなら数秒です)。インポートに失敗すると、新しい名前で空のリポジトリが残り、再試行を妨げることがあります。エラーにはその名前が示されるので、まず削除する必要があります。移行元のリポジトリが変更されることはありません。廃止する場合は、別途、明示的に作業する必要があります。

1 回限りのコピーを作成する代わりに、結果を定期的に移行元から再取得する プル ミラーとして維持するには、mirror: true を渡します。

非公開の移行元の場合は authenticate: true を設定してください。サーバーは認証情報として FORGEJO_MIGRATE_TOKEN を送信します。gitea、github、gitlab、gogs、gitbucket の場合はトークンとして、git(auth_username。デフォルトは oauth2)、onedev、codebase(auth_username が必要)の場合はクローン用パスワードとして送信します。トークンサービスではユーザー名を指定できません。指定すると各インポーターがトークンを無視し、移行に失敗するためです。プッシュミラーと同様、トークンがツールの引数になることはないため、会話に含まれません。トークンの発行方法とスコープの設定方法、さらに他のトークンとは異なる保存先については、移行元トークンを参照してください。

リリースアセット

ビルド完了前に記述したリリースノートは、リリースを作り直すのではなく edit_release で修正してください。リリースを削除すると、そのアセットも一緒に削除されます。送信されるのは渡したフィールドのみなので、body を変更してもタイトルやドラフト状態はそのままです。

ビルドを公開するには、タグを get_release で検索し、404 が返された場合は create_release を呼び出し、その後、ファイルごとに upload_release_asset を呼び出すという 3 回の呼び出しが必要です。同名のアセットを先に削除すれば、安全に再実行できます。そうしないと Forgejo は置き換えずに両方を保持します。リリースに表示されるのはアセット名のみです。削除に使う attachment_id は list_release_assets で取得できます。

upload_release_asset はローカルディスクを読み取る唯一のツールで、読み取ったものはすべて、誰でもダウンロードできるファイルになります。そのため、信頼するのではなく、アクセス範囲を制限しています。

  • 設定されていない場合はオフです。 FORGEJO_UPLOAD_ROOT が未設定の場合、すべてのアップロードが拒否されます。作業ディレクトリへのフォールバックは意図的にありません。MCP サーバーのカレントディレクトリは、クライアントが起動した場所に左右されるため、公開可能なものを判断する基準にはなりません。
  • 指定したルート内に限定されます。 チェックの前にシンボリックリンクをたどってパスを解決するため、.. による移動でも、ツリー外を指すシンボリックリンクでも、範囲外にはアクセスできません。
  • サイズなどに上限があります。 通常ファイルのみで、サイズは FORGEJO_UPLOAD_MAX_MB(デフォルトは 100)以下です。
  • ファイル名のみ指定できます。 公開名のデフォルトはファイル自体の名前です。Forgejo がそのまま使用するため、パス区切り文字を含めることはできません。

$HOME ではなく、実際にリリースに使うツリーをルートに指定してください。

"env": {
  "FORGEJO_UPLOAD_ROOT": "/Users/you/Developer",
  "FORGEJO_UPLOAD_MAX_MB": "100"
}

Forgejo と Gitea の違い

サーバーは 1 つのバイナリから両方と通信し、GET /version に基づいて種類を判別します。呼び出す約 25 個のエンドポイントのうち、2 つの Forge が異なるのは Actions だけです。ただし、異なる部分は完全に食い違っているため、何を変換し、何を変換しないかの基準としてここに示します。

以下の内容はすべて、公開されている 2 つの仕様 codeberg.org/swagger.v1.json と gitea.com/swagger.v1.json を定義ごとに比較して確認しました。実データ と記した 3 点は、仕様からは判断できません。該当するフィールドの型が、どちらの仕様でも単なる文字列として定義されているためです。

ワークフローの実行は、Forge ごとに異なるオブジェクトです

Gitea は GitHub の用語を取り入れ、Forgejo は独自の用語を維持しています。定義名すら一致していません。Forgejo の ActionRun に対して、Gitea は ActionWorkflowRun です。読み取る価値のあるフィールドのうち、同じ名前なのは id、event、html_url だけです。

内容ForgejoGiteaこのサーバー
実行番号index_in_reporun_numberrun_number
タイトルtitledisplay_titletitle
結果statusconclusionstatus
フェーズ—statusstatus に統合
ワークフローファイルworkflow_idpath のファイル部分workflow
refprettyrefhead_branch、または path 内の refref
コミットcommit_shahead_shacommit_sha
実行をトリガーしたユーザーtrigger_usertrigger_actor、actor破棄(メールアドレスが含まれます)
時刻started、stopped、createdstarted_at、completed_at、created_atstarted、stopped、created

実データからのみ確認できることが 3 つあります。

  • 実データ — path はパスではありません。 Gitea は ci.yml@refs/heads/main を返します。ワークフローファイル、@、完全修飾 ref の順です。これをファイルパスとして読み取ると、head が「ワークフロー」として扱われます。これは、このサーバーが最初に実データを調査したときに返された結果です。
  • 実データ — タグおよびプルリクエストの実行では head_branch が null になるため、ref は path から取得する必要があります。
  • 実データ — 未設定の値は null ではなく "" です。 実行中の Gitea の実行では、conclusion: "" と completed_at: "" になります。これらを日付としてデコードするコンシューマーは空文字列で失敗するため、キューに入った実行が 1 つあるだけで一覧全体が失敗する可能性があります。

Gitea の status が示すのは queued/in_progress/completed だけです。実行が終わると、結果は別途 conclusion に入ります。このサーバーは conclusion を status に昇格させます。Forgejo ではすでに結果が status に入っているためです。また、元の値もそのまま保持するので、「これは成功したか」という問いは両方で 1 つにまとまります。

最後の列の出力フィールド名は、このサーバー独自のものであり、どちらの Forge のものでもありません。 これらをワイヤ形式として解釈しないでください。

リクエストにも違いがあります

未知のクエリパラメーターは拒否されず、無視 されるため、誤った名前を指定するとエラーではなく、フィルターなしの結果が返されます。

フィルターForgejoGitea
git refref、完全修飾branch、名前のみ
ワークフローファイルworkflow_id クエリ…/actions/workflows/{file}/runs パス
head_sha、status、event同じ同じ

フィルターなしの場合、一覧のパスは両方で同じです。dispatch_workflow にも違いがあります。return_run_info は Forgejo の拡張機能であり、Gitea はそのエンドポイントで未知の本文フィールドを拒否するため、これは Forgejo にのみ送信されます。そのため Gitea は実行情報ではなく、受け付けたことを示す応答を返します。

その他すべて

課題、プルリクエスト、差分、PR ファイル、ブランチ、コンテンツ、検索、組織、通知、プッシュミラー、移行は、パス、メソッド、レスポンスの形式がすべて同一です。各 Forge には相手にはないフィールドがありますが、相違点というより追加情報です。Forgejo にはユーザーの pronouns とリリースの archive_download_count があり、Gitea には課題の time_estimate とリポジトリの branch_count があります。

Actions 以外で唯一の例外はコンテンツのエンドポイントで、各 Forge に相手にはない最終コミットのフィールドがあります。

ForgejoGitea
最終変更日時last_commit_whenlast_author_date, last_committer_date
コミットメッセージ—last_commit_message

このサーバーはこれらのフィールドを読み取りませんが、ファイル一覧を表示するものは、どちらの Forge でも日付列が空欄にならないよう、両方の表記に対応する必要があります。

セキュリティ

トークンは環境変数からのみ読み取られます。ログに記録されることも、ディスクに書き込まれることもありません(クライアントはトークンをゼロ化バッファーに保持し、Authorization ヘッダーを機密情報として扱います)。デフォルトでは読み取り専用のため、別途書き込み用トークンと書き込みモードを用意しない限り、サーバーがアカウントを変更することはありません。ツールの出力は信頼できないリポジトリ由来のテキストであり、サーバーはこれを指示ではなくデータとして扱います。詳しくはSPECIFICATION.mdを参照してください。

2 つのリモート認証情報である FORGEJO_MIRROR_TOKEN と FORGEJO_MIGRATE_TOKEN も、プロセス内では同じ方法で扱われます(環境変数からのみ読み取り、ゼロ化し、ツールの引数にせず、返却もしません)。ただし、これらはヘッダー認証情報ではないため、ユーザーと自分のインスタンスの間に留まりません。それぞれがリクエスト本文で自分のインスタンスに送られ、サードパーティーのホストに中継されます。そのホストはトークンを平文で確認できます。これは Forgejo のミラー API と移行 API の仕組みであり、このサーバーが選択したものではありません。両方の権限を必要最小限にし、リモートの運用者に開示されたものとして扱ってください。

品質チェック

cargo fmt --all
cargo clippy --all-targets -- -D warnings
cargo test
cargo deny check          # cargo install cargo-deny

CI はCodeberg Forgejo Actionsでも同じチェックを実行します。追跡対象の.githooks/pre-pushフックを使えば、ローカルでも同じチェックを実行できます(git config core.hooksPath .githooks)。

履歴

各リリースでの変更はCHANGELOG.mdに、各設計の根拠はSPECIFICATION.mdに記載されています。

v0.5 までのリリースは、Cyborus によるforgejo-apiクレートを基盤としていました。現在、forgejo-mcp-rs は独自の小さなクライアントを通じて Forgejo REST API と通信し、サードパーティー製の Forge SDK は使用していません。

v0.13.0 から v0.17.0 まで、2 つ目のバイナリとして同梱されていた Woodpecker CI のコンパニオンサーバーは、v0.18.0 で独自のリポジトリに移動しました。 woodpecker-mcp。

ライセンス

MIT ライセンスです。詳細はLICENSE.mdを参照してください。

MCP レジストリ

MCP レジストリの所有権確認トークン(crates.io に表示されるこのクレートの README から読み取られます):

レジストリ所有権トークン:mcp-name: io.github.brechanbech/forgejo-mcp-rs

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。