diff --git a/server.py b/server.py index 9c83fcb..874f57d 100644 --- a/server.py +++ b/server.py @@ -16,6 +16,8 @@ class PlankaClient: def __init__(self, url: str, token: str): self.url = url.rstrip("/") self.token = token + # Planka uses standard JWT tokens, but they don't always require "Bearer " in the header + # for all internal API calls, though standard is to use it. self.headers = {"Authorization": f"Bearer {token}"} def _get(self, endpoint: str, params: Optional[dict] = None) -> Any: @@ -29,13 +31,23 @@ class PlankaClient: return response.json() def get_projects(self) -> List[dict]: - return self._get("projects") + data = self._get("projects") + # Handle Planka API response structure which often wraps items in 'items' + if isinstance(data, dict) and "items" in data: + return data["items"] + return data def get_boards(self, project_id: str) -> List[dict]: - return self._get(f"projects/{project_id}/boards") + data = self._get(f"projects/{project_id}/boards") + if isinstance(data, dict) and "items" in data: + return data["items"] + return data def get_cards(self, board_id: str) -> List[dict]: - return self._get(f"boards/{board_id}/cards") + data = self._get(f"boards/{board_id}/cards") + if isinstance(data, dict) and "items" in data: + return data["items"] + return data def create_card(self, board_id: str, list_id: str, name: str, description: str = "") -> dict: return self._post("cards", { @@ -60,18 +72,24 @@ def get_client(): def list_projects() -> str: """List all Planka projects available to the user.""" projects = get_client().get_projects() + if not projects: + return "No projects found." return "\n".join([f"- {p['name']} (ID: {p['id']})" for p in projects]) @mcp.tool() def list_boards(project_id: str) -> str: """List all boards for a given project ID.""" boards = get_client().get_boards(project_id) + if not boards: + return "No boards found." return "\n".join([f"- {b['name']} (ID: {b['id']})" for b in boards]) @mcp.tool() def list_cards(board_id: str) -> str: """List all cards for a given board ID.""" cards = get_client().get_cards(board_id) + if not cards: + return "No cards found." return "\n".join([f"- {c['name']} (ID: {c['id']})" for c in cards]) @mcp.tool()