Skip to main content
Glama
space.py7.38 kB
import json from typing import Optional, Dict, Any, List from mcp.server.fastmcp import FastMCP from httpx import AsyncClient from utils.api import ( build_management_url, get_management_headers, _handle_response, APIError, ) def register_space(mcp: FastMCP, client: AsyncClient) -> None: @mcp.tool() async def fetch_spaces() -> Any: """ Retrieve all accessible spaces. """ try: url = "https://mapi.storyblok.com/v1/spaces/" resp = await client.get(url, headers=get_management_headers()) return _handle_response(resp, url) except APIError as e: return {"isError": True, "content": [{"type": "text", "text": str(e)}]} @mcp.tool() async def get_space(space_id: str) -> Any: """ Fetch a specific space by ID. """ try: url = f"https://mapi.storyblok.com/v1/spaces/{space_id}" resp = await client.get(url, headers=get_management_headers()) return _handle_response(resp, url) except APIError as e: return {"isError": True, "content": [{"type": "text", "text": str(e)}]} @mcp.tool() async def create_space( name: str, domain: Optional[str] = None, story_published_hook: Optional[str] = None, environments: Optional[List[Dict[str, str]]] = None ) -> Any: """ Creates a new Storyblok space via the Management API. """ try: payload: Dict[str, Any] = { "space": {"name": name} } if domain: payload["space"]["domain"] = domain if story_published_hook: payload["space"]["story_published_hook"] = story_published_hook if environments: payload["space"]["environments"] = environments url = "https://mapi.storyblok.com/v1/spaces/" resp = await client.post(url, json=payload, headers=get_management_headers()) return _handle_response(resp, url) except APIError as e: return {"isError": True, "content": [{"type": "text", "text": str(e)}]} @mcp.tool() async def update_space( space_id: int, name: Optional[str] = None, domain: Optional[str] = None, uniq_domain: Optional[str] = None, owner_id: Optional[int] = None, story_published_hook: Optional[str] = None, environments: Optional[List[Dict[str, str]]] = None, parent_id: Optional[int] = None, searchblok_id: Optional[int] = None, duplicatable: Optional[bool] = None, billing_address: Optional[Dict[str, Any]] = None, routes: Optional[List[str]] = None, default_root: Optional[str] = None, has_pending_tasks: Optional[bool] = None, ai_translation_disabled: Optional[bool] = None, options: Optional[Dict[str, Any]] = None ) -> Any: """ Updates an existing Storyblok space via the Management API. """ try: payload = {"space": {}} if name: payload["space"]["name"] = name if domain: payload["space"]["domain"] = domain if uniq_domain: payload["space"]["uniq_domain"] = uniq_domain if owner_id: payload["space"]["owner_id"] = owner_id if story_published_hook: payload["space"]["story_published_hook"] = story_published_hook if environments: payload["space"]["environments"] = environments if parent_id: payload["space"]["parent_id"] = parent_id if searchblok_id: payload["space"]["searchblok_id"] = searchblok_id if duplicatable is not None: payload["space"]["duplicatable"] = duplicatable if billing_address: payload["space"]["billing_address"] = billing_address if routes: payload["space"]["routes"] = routes if default_root: payload["space"]["default_root"] = default_root if has_pending_tasks is not None: payload["space"]["has_pending_tasks"] = has_pending_tasks if ai_translation_disabled is not None: payload["space"]["ai_translation_disabled"] = ai_translation_disabled if options: payload["space"]["options"] = options url = f"https://mapi.storyblok.com/v1/spaces/{space_id}" resp = await client.put(url, json=payload, headers=get_management_headers()) return _handle_response(resp, url) except APIError as e: return {"isError": True, "content": [{"type": "text", "text": str(e)}]} @mcp.tool() async def duplicate_space( original_space_id: int, new_space_name: str, domain: Optional[str] = None, story_published_hook: Optional[str] = None, environments: Optional[List[Dict[str, str]]] = None, searchblok_id: Optional[int] = None, has_pending_tasks: Optional[bool] = None ) -> Any: """ Duplicates an existing Storyblok space via the Management API. """ try: payload = { "dup_id": original_space_id, "space": { "name": new_space_name, "domain": domain, "story_published_hook": story_published_hook, "environments": environments, "searchblok_id": searchblok_id, "has_pending_tasks": has_pending_tasks } } url = "https://mapi.storyblok.com/v1/spaces/" resp = await client.post(url, json=payload, headers=get_management_headers()) return _handle_response(resp, url) except APIError as e: return {"isError": True, "content": [{"type": "text", "text": str(e)}]} @mcp.tool() async def backup_space( space_id: int ) -> Any: """ Triggers a backup task for a Storyblok space using Management API. """ try: url = f"https://mapi.storyblok.com/v1/spaces/{space_id}/backups" resp = await client.post(url, json={}, headers=get_management_headers()) return _handle_response(resp, url) except APIError as e: return {"isError": True, "content": [{"type": "text", "text": str(e)}]} @mcp.tool() async def delete_space( space_id: int ) -> Any: """ Permanently deletes a Storyblok space using the Management API. """ try: url = f"https://mapi.storyblok.com/v1/spaces/{space_id}" resp = await client.delete(url, headers=get_management_headers()) if resp.status_code == 204: return {"isError": False, "content": [{"type": "text", "text": f"Space deleted successfully."}]} else: return {"isError": True, "content": [{"type": "text", "text": f"Failed to delter space. Status code: {resp.status_code}"}]} except APIError as e: return {"isError": True, "content": [{"type": "text", "text": str(e)}]}

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Kiran1689/storyblok-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server