fix(forgejo-mcp): convert sync httpx.Client to async AsyncClient
All tool functions and API helpers were using synchronous httpx.Client, which blocked FastMCP's async event loop on every tool call — causing 60s timeouts from Claude even though the container appeared healthy. Converted get_client(), api_get(), api_post(), api_patch() and all 12 @mcp.tool() functions to async/await, matching the pattern used by the other working backends (truenas-mcp, homeassistant-mcp). Redeploy with: docker compose up -d --build forgejo-mcp
This commit is contained in:
parent
39fff1e44a
commit
5f22831106
1 changed files with 23 additions and 23 deletions
|
|
@ -37,31 +37,31 @@ mcp = FastMCP("forgejo-mcp")
|
|||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def get_client() -> httpx.Client:
|
||||
return httpx.Client(
|
||||
def get_client() -> httpx.AsyncClient:
|
||||
return httpx.AsyncClient(
|
||||
base_url=FORGEJO_URL.rstrip("/"),
|
||||
headers={"Authorization": f"token {FORGEJO_TOKEN}"},
|
||||
timeout=30.0,
|
||||
)
|
||||
|
||||
|
||||
def api_get(endpoint: str, params: dict | None = None) -> Any:
|
||||
with get_client() as client:
|
||||
r = client.get(f"/api/v1{endpoint}", params=params or {})
|
||||
async def api_get(endpoint: str, params: dict | None = None) -> Any:
|
||||
async with get_client() as client:
|
||||
r = await client.get(f"/api/v1{endpoint}", params=params or {})
|
||||
r.raise_for_status()
|
||||
return r.json() if r.status_code != 204 else {}
|
||||
|
||||
|
||||
def api_post(endpoint: str, body: dict | None = None) -> Any:
|
||||
with get_client() as client:
|
||||
r = client.post(f"/api/v1{endpoint}", json=body or {})
|
||||
async def api_post(endpoint: str, body: dict | None = None) -> Any:
|
||||
async with get_client() as client:
|
||||
r = await client.post(f"/api/v1{endpoint}", json=body or {})
|
||||
r.raise_for_status()
|
||||
return r.json() if r.status_code != 204 else {}
|
||||
|
||||
|
||||
def api_patch(endpoint: str, body: dict | None = None) -> Any:
|
||||
with get_client() as client:
|
||||
r = client.patch(f"/api/v1{endpoint}", json=body or {})
|
||||
async def api_patch(endpoint: str, body: dict | None = None) -> Any:
|
||||
async with get_client() as client:
|
||||
r = await client.patch(f"/api/v1{endpoint}", json=body or {})
|
||||
r.raise_for_status()
|
||||
return r.json() if r.status_code != 204 else {}
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ def api_patch(endpoint: str, body: dict | None = None) -> Any:
|
|||
|
||||
|
||||
@mcp.tool()
|
||||
def forgejo_list_repositories(owner: str, limit: int = 20, page: int = 1) -> str:
|
||||
async def forgejo_list_repositories(owner: str, limit: int = 20, page: int = 1) -> str:
|
||||
"""List repositories for a user or organization.
|
||||
|
||||
Args:
|
||||
|
|
@ -88,7 +88,7 @@ def forgejo_list_repositories(owner: str, limit: int = 20, page: int = 1) -> str
|
|||
|
||||
|
||||
@mcp.tool()
|
||||
def forgejo_get_repository(owner: str, repo: str) -> str:
|
||||
async def forgejo_get_repository(owner: str, repo: str) -> str:
|
||||
"""Get details about a specific repository.
|
||||
|
||||
Args:
|
||||
|
|
@ -109,7 +109,7 @@ def forgejo_get_repository(owner: str, repo: str) -> str:
|
|||
|
||||
|
||||
@mcp.tool()
|
||||
def forgejo_create_repository(
|
||||
async def forgejo_create_repository(
|
||||
name: str,
|
||||
description: str = "",
|
||||
private: bool = False,
|
||||
|
|
@ -133,7 +133,7 @@ def forgejo_create_repository(
|
|||
|
||||
|
||||
@mcp.tool()
|
||||
def forgejo_list_issues(
|
||||
async def forgejo_list_issues(
|
||||
owner: str,
|
||||
repo: str,
|
||||
state: str = "open",
|
||||
|
|
@ -157,7 +157,7 @@ def forgejo_list_issues(
|
|||
|
||||
|
||||
@mcp.tool()
|
||||
def forgejo_create_issue(
|
||||
async def forgejo_create_issue(
|
||||
owner: str,
|
||||
repo: str,
|
||||
title: str,
|
||||
|
|
@ -182,7 +182,7 @@ def forgejo_create_issue(
|
|||
|
||||
|
||||
@mcp.tool()
|
||||
def forgejo_update_issue(
|
||||
async def forgejo_update_issue(
|
||||
owner: str,
|
||||
repo: str,
|
||||
issue_number: int,
|
||||
|
|
@ -206,7 +206,7 @@ def forgejo_update_issue(
|
|||
|
||||
|
||||
@mcp.tool()
|
||||
def forgejo_list_pull_requests(
|
||||
async def forgejo_list_pull_requests(
|
||||
owner: str,
|
||||
repo: str,
|
||||
state: str = "open",
|
||||
|
|
@ -230,7 +230,7 @@ def forgejo_list_pull_requests(
|
|||
|
||||
|
||||
@mcp.tool()
|
||||
def forgejo_create_pull_request(
|
||||
async def forgejo_create_pull_request(
|
||||
owner: str,
|
||||
repo: str,
|
||||
title: str,
|
||||
|
|
@ -258,7 +258,7 @@ def forgejo_create_pull_request(
|
|||
|
||||
|
||||
@mcp.tool()
|
||||
def forgejo_list_branches(owner: str, repo: str, limit: int = 20, page: int = 1) -> str:
|
||||
async def forgejo_list_branches(owner: str, repo: str, limit: int = 20, page: int = 1) -> str:
|
||||
"""List branches in a repository.
|
||||
|
||||
Args:
|
||||
|
|
@ -275,7 +275,7 @@ def forgejo_list_branches(owner: str, repo: str, limit: int = 20, page: int = 1)
|
|||
|
||||
|
||||
@mcp.tool()
|
||||
def forgejo_get_file(owner: str, repo: str, path: str, ref: str = "main") -> str:
|
||||
async def forgejo_get_file(owner: str, repo: str, path: str, ref: str = "main") -> str:
|
||||
"""Get file contents from a repository.
|
||||
|
||||
Args:
|
||||
|
|
@ -293,7 +293,7 @@ def forgejo_get_file(owner: str, repo: str, path: str, ref: str = "main") -> str
|
|||
|
||||
|
||||
@mcp.tool()
|
||||
def forgejo_search_repositories(q: str, limit: int = 20, page: int = 1) -> str:
|
||||
async def forgejo_search_repositories(q: str, limit: int = 20, page: int = 1) -> str:
|
||||
"""Search for repositories across the Forgejo instance.
|
||||
|
||||
Args:
|
||||
|
|
@ -310,7 +310,7 @@ def forgejo_search_repositories(q: str, limit: int = 20, page: int = 1) -> str:
|
|||
|
||||
|
||||
@mcp.tool()
|
||||
def forgejo_get_user(username: str) -> str:
|
||||
async def forgejo_get_user(username: str) -> str:
|
||||
"""Get user profile information.
|
||||
|
||||
Args:
|
||||
|
|
|
|||
Loading…
Reference in a new issue