feat: add 13 read tools (PR files/commits, comments, branches, releases, milestones, org/status/languages/topics)
test / test (push) Successful in 1m13s
lint / lint (push) Successful in 1m14s
docker / docker-publish (pull_request) Has been skipped
docker / test (pull_request) Successful in 22s
docker / lint (pull_request) Successful in 29s
lint / lint (pull_request) Successful in 31s
test / test (pull_request) Successful in 21s
docker / docker-test (pull_request) Successful in 23s

Expands the read surface so the MCP can inspect more of Gitea:

- list_pull_request_files, list_pull_request_commits, list_issue_comments
- list_branches, get_branch
- get_release, get_latest_release, list_milestones
- get_commit_status
- list_org_repositories, list_organizations
- get_repo_languages, list_repo_topics

Each: arg schema (extra=forbid; GitRef on branch/sha fields), Gitea client
method with url-encoded path segments, bounded handler, MCP registration
(read-only), server wiring, docs, and parametrized success tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-14 20:43:03 +02:00
parent 7837ff43ad
commit b62ed098bf
7 changed files with 934 additions and 0 deletions
+81
View File
@@ -6,14 +6,27 @@ from aegis_gitea_mcp.config import reset_settings
from aegis_gitea_mcp.gitea_client import GiteaError
from aegis_gitea_mcp.tools.read_tools import (
compare_refs_tool,
get_branch_tool,
get_commit_diff_tool,
get_commit_status_tool,
get_issue_tool,
get_latest_release_tool,
get_pull_request_tool,
get_release_tool,
get_repo_languages_tool,
list_branches_tool,
list_commits_tool,
list_issue_comments_tool,
list_issues_tool,
list_labels_tool,
list_milestones_tool,
list_org_repositories_tool,
list_organizations_tool,
list_pull_request_commits_tool,
list_pull_request_files_tool,
list_pull_requests_tool,
list_releases_tool,
list_repo_topics_tool,
list_tags_tool,
search_code_tool,
)
@@ -88,6 +101,45 @@ class StubGitea:
async def list_releases(self, owner, repo, *, page, limit):
return [{"id": 1, "tag_name": "v1.0.0", "name": "release"}]
async def list_pull_request_files(self, owner, repo, index, *, page, limit):
return [{"filename": "a.py", "status": "modified", "additions": 1, "deletions": 0}]
async def list_pull_request_commits(self, owner, repo, index, *, page, limit):
return [{"sha": "abc", "commit": {"message": "m"}, "author": {"login": "alice"}}]
async def list_issue_comments(self, owner, repo, index, *, page, limit):
return [{"id": 1, "body": "hi", "user": {"login": "alice"}}]
async def list_branches(self, owner, repo, *, page, limit):
return [{"name": "main", "protected": True, "commit": {"id": "abc"}}]
async def get_branch(self, owner, repo, branch):
return {"name": branch, "protected": False, "commit": {"id": "abc"}}
async def get_release(self, owner, repo, release_id):
return {"id": release_id, "tag_name": "v1", "name": "rel"}
async def get_latest_release(self, owner, repo):
return {"id": 1, "tag_name": "v1", "name": "rel"}
async def list_milestones(self, owner, repo, *, state, page, limit):
return [{"id": 1, "title": "M", "state": state}]
async def get_commit_status(self, owner, repo, sha):
return {"state": "success", "statuses": [{"context": "ci", "status": "success"}]}
async def list_org_repositories(self, org, *, page, limit):
return [{"name": "r", "owner": {"login": org}, "full_name": f"{org}/r"}]
async def list_organizations(self, *, page, limit):
return [{"id": 1, "username": "acme", "description": "d"}]
async def get_repo_languages(self, owner, repo):
return {"Python": 100, "HTML": 5}
async def list_repo_topics(self, owner, repo):
return ["python", "mcp"]
async def create_issue(self, owner, repo, *, title, body, labels=None, assignees=None):
return {"number": 1, "title": title, "state": "open"}
@@ -169,6 +221,35 @@ class ErrorGitea(StubGitea):
(list_labels_tool, {"owner": "acme", "repo": "app"}, "labels"),
(list_tags_tool, {"owner": "acme", "repo": "app"}, "tags"),
(list_releases_tool, {"owner": "acme", "repo": "app"}, "releases"),
(
list_pull_request_files_tool,
{"owner": "acme", "repo": "app", "pull_number": 1},
"files",
),
(
list_pull_request_commits_tool,
{"owner": "acme", "repo": "app", "pull_number": 1},
"commits",
),
(
list_issue_comments_tool,
{"owner": "acme", "repo": "app", "issue_number": 1},
"comments",
),
(list_branches_tool, {"owner": "acme", "repo": "app"}, "branches"),
(get_branch_tool, {"owner": "acme", "repo": "app", "branch": "main"}, "name"),
(get_release_tool, {"owner": "acme", "repo": "app", "release_id": 1}, "tag_name"),
(get_latest_release_tool, {"owner": "acme", "repo": "app"}, "tag_name"),
(list_milestones_tool, {"owner": "acme", "repo": "app"}, "milestones"),
(
get_commit_status_tool,
{"owner": "acme", "repo": "app", "sha": "abc1234"},
"state",
),
(list_org_repositories_tool, {"org": "acme"}, "repositories"),
(list_organizations_tool, {}, "organizations"),
(get_repo_languages_tool, {"owner": "acme", "repo": "app"}, "languages"),
(list_repo_topics_tool, {"owner": "acme", "repo": "app"}, "topics"),
],
)
async def test_extended_read_tools_success(tool, args, expected_key):