forge-mcp
MCP server for Forgejo. Lets Cursor and Claude work with issues, pull requests, repository context, and cross-repo search via the Forgejo/Gitea API.
Requirements
- uv on your
PATH
- Python 3.13+ (uv will install it)
- A Forgejo personal access token with the scopes you need (at least issue read/write; repository read for repo/branch/file tools)
Setup
uv sync
cp .env.example .env
Edit .env with your Forgejo URL, token, and default owner/repo.
Configuration
| Variable |
Required |
Description |
FORGEJO_URL |
yes |
Forgejo base URL, e.g. https://git.example.com |
FORGEJO_TOKEN |
yes |
Personal access token |
FORGEJO_OWNER |
no |
Default repository owner |
FORGEJO_REPO |
no |
Default repository name |
Tools
Issues
| Tool |
Purpose |
list_issues |
List issues in a repository (excludes pull requests) |
get_issue |
Get a single issue by number, including its body |
create_issue |
Create a new issue |
update_issue |
Update an issue's title, body, state, labels, or assignees |
search_issues |
Search issues in a repository |
list_issue_comments |
List comments on an issue |
add_issue_comment |
Add a comment to an issue |
edit_issue_comment |
Edit an issue comment |
delete_issue_comment |
Delete an issue comment |
list_issue_timeline |
List timeline comments and events for an issue |
list_issue_attachments |
List attachments on an issue |
add_issue_attachment |
Upload a local file as an issue attachment |
delete_issue_attachment |
Delete an issue attachment |
list_issue_reactions |
List reactions on an issue |
add_issue_reaction |
Add a reaction to an issue |
remove_issue_reaction |
Remove a reaction from an issue |
add_comment_reaction |
Add a reaction to an issue comment |
remove_comment_reaction |
Remove a reaction from an issue comment |
list_pinned_issues |
List pinned issues in a repository |
pin_issue |
Pin an issue |
unpin_issue |
Unpin an issue |
Labels and milestones
| Tool |
Purpose |
list_labels |
List labels available in a repository |
create_label |
Create a repository label |
update_label |
Update a repository label |
delete_label |
Delete a repository label |
add_issue_labels |
Add labels to an issue |
remove_issue_label |
Remove one label from an issue |
list_milestones |
List milestones available in a repository |
create_milestone |
Create a repository milestone |
update_milestone |
Update a repository milestone |
delete_milestone |
Delete a repository milestone |
Pull requests
| Tool |
Purpose |
list_pull_requests |
List pull requests in a repository |
get_pull_request |
Get a single pull request by number, including its body |
create_pull_request |
Create a new pull request |
update_pull_request |
Update a pull request's title, body, state, base, labels, or assignees |
merge_pull_request |
Merge a pull request |
list_pull_files |
List changed files in a pull request |
get_pull_diff |
Get the unified diff for a pull request (large diffs truncated) |
list_pull_commits |
List commits included in a pull request |
list_pull_reviews |
List reviews on a pull request |
create_pull_review |
Create a review on a pull request |
request_pull_reviewers |
Request reviewers on a pull request |
remove_pull_reviewers |
Remove requested reviewers from a pull request |
Repository context
| Tool |
Purpose |
get_repository |
Get repository metadata including default branch and visibility |
list_branches |
List branches in a repository |
get_file_contents |
Get file contents or list a directory |
list_assignees |
List users who can be assigned to issues in a repository |
list_collaborators |
List collaborators on a repository |
list_releases |
List releases for a repository |
get_latest_release |
Get the latest non-draft release for a repository |
Search
| Tool |
Purpose |
search_issues_global |
Search issues across repositories the authenticated user can access |
Resources
| URI template |
Purpose |
forgejo://{owner}/{repo}/issue/{index} |
Full issue JSON for a repository issue |
forgejo://{owner}/{repo}/issue/{index}/timeline |
Timeline comments and events for a repository issue |
Prompts
| Prompt |
Purpose |
triage_open_issues |
Steer triage of open issues using list/get/update tools |
draft_issue_reply |
Steer drafting a reply to an issue using read tools before commenting |
summarise_pull_request |
Steer summarising a pull request using PR read tools |
Cursor
Project MCP config lives at .cursor/mcp.json and loads secrets from .env via envFile.
- Copy
.env.example to .env and fill in real values
- Reload the Cursor window (or restart MCP servers)
- Use the
forgejo tools against live data
.env is gitignored; do not commit tokens.
Claude Desktop
{
"mcpServers": {
"forgejo": {
"command": "uv",
"args": [
"run",
"--directory",
"/absolute/path/to/forge-mcp",
"python",
"-m",
"forge_mcp"
],
"env": {
"FORGEJO_URL": "https://git.example.com",
"FORGEJO_TOKEN": "your-token",
"FORGEJO_OWNER": "myorg",
"FORGEJO_REPO": "myrepo"
}
}
}
}
uv must be available on the PATH used by Cursor/Claude.
Development
uv run pytest
uv run pytest -m live
uv run python -m forge_mcp
uv run pytest skips live tests. uv run pytest -m live hits your configured Forgejo instance (read-only checks).