We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/sooperset/mcp-atlassian'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
"""Module for Confluence space operations."""
import logging
from typing import cast
import requests
from .client import ConfluenceClient
logger = logging.getLogger("mcp-atlassian")
class SpacesMixin(ConfluenceClient):
"""Mixin for Confluence space operations."""
def get_spaces(self, start: int = 0, limit: int = 10) -> dict[str, object]:
"""
Get all available spaces.
Args:
start: The starting index for pagination
limit: Maximum number of spaces to return
Returns:
Dictionary containing space information with results and metadata
"""
spaces = self.confluence.get_all_spaces(start=start, limit=limit)
# Cast the return value to the expected type
return cast(dict[str, object], spaces)
def get_user_contributed_spaces(self, limit: int = 250) -> dict:
"""
Get spaces the current user has contributed to.
Args:
limit: Maximum number of results to return
Returns:
Dictionary of space keys to space information
"""
try:
# Use CQL to find content the user has contributed to
cql = "contributor = currentUser() order by lastmodified DESC"
results = self.confluence.cql(cql=cql, limit=limit)
# Extract and deduplicate spaces
spaces = {}
for result in results.get("results", []):
space_key = None
space_name = None
# Try to extract space from container
if "resultGlobalContainer" in result:
container = result.get("resultGlobalContainer", {})
space_name = container.get("title")
display_url = container.get("displayUrl", "")
if display_url and "/spaces/" in display_url:
space_key = display_url.split("/spaces/")[1].split("/")[0]
# Try to extract from content expandable
if (
not space_key
and "content" in result
and "_expandable" in result["content"]
):
expandable = result["content"].get("_expandable", {})
space_path = expandable.get("space", "")
if space_path and space_path.startswith("/rest/api/space/"):
space_key = space_path.split("/rest/api/space/")[1]
# Try to extract from URL
if not space_key and "url" in result:
url = result.get("url", "")
if url and url.startswith("/spaces/"):
space_key = url.split("/spaces/")[1].split("/")[0]
# Only add if we found a space key and it's not already in our results
if space_key and space_key not in spaces:
# Add some defaults if we couldn't extract all fields
space_name = space_name or f"Space {space_key}"
spaces[space_key] = {"key": space_key, "name": space_name}
return spaces
except KeyError as e:
logger.error(f"Missing key in Confluence spaces data: {str(e)}")
return {}
except ValueError as e:
logger.error(f"Invalid value in Confluence spaces: {str(e)}")
return {}
except TypeError as e:
logger.error(f"Type error when processing Confluence spaces: {str(e)}")
return {}
except requests.RequestException as e:
logger.error(f"Network error when fetching spaces: {str(e)}")
return {}
except Exception as e: # noqa: BLE001 - Intentional fallback with logging
logger.error(f"Unexpected error fetching Confluence spaces: {str(e)}")
logger.debug("Full exception details for Confluence spaces:", exc_info=True)
return {}