From fbb115923a47723296b583ab2f155376bb5b592c Mon Sep 17 00:00:00 2001 From: teahubxyz Date: Wed, 14 Oct 2026 18:18:02 -0700 Subject: [PATCH] mcp 2.0.1: tea_issues also takes labels as a comma-separated string Connectors that were open before 2.0 keep 1.0's tool list, where labels is one comma-separated string, until they refresh it. That form now works too. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01CYHXFvWMCs1GUmRmpySqQ6 --- mcp/tea_mcp/server.py | 7 +++++-- mcp/tests/test_server.py | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/mcp/tea_mcp/server.py b/mcp/tea_mcp/server.py index 2d41543..b11625e 100644 --- a/mcp/tea_mcp/server.py +++ b/mcp/tea_mcp/server.py @@ -43,7 +43,7 @@ GITEA_OAUTH_CLIENT_SECRET = required_env("GITEA_OAUTH_CLIENT_SECRET") JWT_SIGNING_KEY = required_env("JWT_SIGNING_KEY") ALLOWED_HOSTS = [h.strip() for h in os.getenv("ALLOWED_HOSTS", "mcp.teahub.xyz,localhost").split(",") if h.strip()] -VERSION = "2.0.0" +VERSION = "2.0.1" OAUTH_SCOPES = ["openid", "profile", "email"] CLAUDE_CIMD_CLIENT_ID = "https://claude.ai/oauth/mcp-oauth-client-metadata" CLAUDE_REDIRECT_URI = "https://claude.ai/api/mcp/auth_callback" @@ -294,8 +294,11 @@ async def tea_whoami() -> dict[str, Any]: @mcp.tool(description="List issues or pull requests of a repository, newest first. `labels` keeps only those " "carrying all of them.", annotations=READ) async def tea_issues(repo: Repo, state: Literal["open", "closed", "all"] = "open", - kind: Literal["issues", "pulls"] = "issues", labels: Labels | None = None, page: Page = 1, + kind: Literal["issues", "pulls"] = "issues", + labels: Labels | Annotated[str, Field(max_length=1000)] | None = None, page: Page = 1, limit: Limit = 20) -> dict[str, Any]: + if isinstance(labels, str): # the comma-separated form that clients holding 1.0's schema still send + labels = [name.strip() for name in labels.split(",") if name.strip()] params = {"state": state, "type": kind, **({"labels": ",".join(labels)} if labels else {})} rows, more = await listing(f"{repo_path(repo)}/issues", page, limit, params) return {"repo": repo, "page": page, "more": more, "issues": [issue_row(x) for x in rows]} diff --git a/mcp/tests/test_server.py b/mcp/tests/test_server.py index a547dc5..a0aec0a 100644 --- a/mcp/tests/test_server.py +++ b/mcp/tests/test_server.py @@ -222,6 +222,8 @@ class TeaMCP(unittest.IsolatedAsyncioTestCase): self.assertEqual(self.sent("GET", f"{R}/issues")[0][2], {"state": "open", "type": "issues", "page": "1", "limit": "20"}) await self.call("tea_issues", repo="o/r", kind="pulls", labels=["bug", "docs"]) self.assertEqual(self.sent("GET", f"{R}/issues")[-1][2]["labels"], "bug,docs") + await self.call("tea_issues", repo="o/r", labels="bug, docs") + self.assertEqual(self.sent("GET", f"{R}/issues")[-1][2]["labels"], "bug,docs") async def test_unknown_labels_are_refused(self): message = await self.refused("tea_issue_create", repo="o/r", title="x", labels=["bug", "nope"])