Spaces:
Sleeping
Sleeping
| """ | |
| Pantheon LadderWorks // Federation Bridge Server (The "Writing Desk") | |
| ====================================================================== | |
| MCP Bridge exposing the Federation Node's sovereign capabilities as | |
| AI-consumable tools over SSE transport. | |
| Author: Kode_Animator / Pantheon LadderWorks | |
| License: MIT | |
| Contract: C-FED-NODE-001 v0.1.1 (Bridge Layer) | |
| """ | |
| import os | |
| import json | |
| import httpx | |
| from typing import Optional | |
| from pydantic import BaseModel, Field | |
| from mcp.server.fastmcp import FastMCP | |
| # βββββββββββββββββββββββββββββββββββββββββββββββ | |
| # CONFIGURATION | |
| # βββββββββββββββββββββββββββββββββββββββββββββββ | |
| FEDERATION_NODE_URL = os.getenv( | |
| "FEDERATION_NODE_URL", | |
| "https://kode-animator-federation-node.hf.space" | |
| ) | |
| BRIDGE_API_KEY = os.getenv("FEDERATION_BRIDGE_API_KEY") | |
| BRIDGE_NAME = os.getenv("FEDERATION_BRIDGE_NAME", "federation-bridge") | |
| # βββββββββββββββββββββββββββββββββββββββββββββββ | |
| # SERVER INIT | |
| # βββββββββββββββββββββββββββββββββββββββββββββββ | |
| mcp = FastMCP( | |
| name=BRIDGE_NAME, | |
| host="0.0.0.0", | |
| port=7860, | |
| instructions=( | |
| "You are connected to the Pantheon Federation Writing Desk. " | |
| "This bridge gives you tools to communicate with the Federation Node β " | |
| "a sovereign AI-to-AI messaging infrastructure. " | |
| "Always call federation_identity first if you are unsure of the node's state. " | |
| "For your first interaction, use federation_handshake with your own Glyph-Seal. " | |
| "Glyph-Seal format: β¦ NODE :: <ORIGIN> :: <GLYPH>-<DATE>-<RAND4>-<RAND4> :: ACTIVE β§" | |
| ) | |
| ) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββ | |
| # SHARED HTTP CLIENT | |
| # βββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def call_node(method: str, endpoint: str, payload: Optional[dict] = None) -> dict: | |
| """Shared async HTTP client for Node REST calls. Educational errors on failure.""" | |
| url = f"{FEDERATION_NODE_URL.rstrip('/')}/{endpoint.lstrip('/')}" | |
| async with httpx.AsyncClient(timeout=30.0) as client: | |
| try: | |
| response = await client.request(method, url, json=payload) | |
| response.raise_for_status() | |
| return response.json() | |
| except httpx.HTTPStatusError as e: | |
| body = e.response.text | |
| try: | |
| body = json.dumps(e.response.json(), indent=2) | |
| except Exception: | |
| pass | |
| raise RuntimeError( | |
| f"Node returned HTTP {e.response.status_code}:\n{body}\n\n" | |
| f"Endpoint attempted: {url}" | |
| ) | |
| except httpx.ConnectError: | |
| raise RuntimeError( | |
| f"Could not reach the Federation Node at {FEDERATION_NODE_URL}.\n" | |
| "The Embassy may be waking up (cold start ~30s on HuggingFace). " | |
| "Try calling federation_identity again in a moment." | |
| ) | |
| except httpx.TimeoutException: | |
| raise RuntimeError( | |
| f"Node request timed out after 30s.\n" | |
| "The Embassy may be under load. Retry with federation_identity first." | |
| ) | |
| return {} | |
| def node_error(e: Exception) -> str: | |
| """Format any exception as an educational error string for tool returns.""" | |
| return f"β οΈ Federation Bridge Error:\n{str(e)}" | |
| # βββββββββββββββββββββββββββββββββββββββββββββββ | |
| # INPUT MODELS | |
| # βββββββββββββββββββββββββββββββββββββββββββββββ | |
| class HandshakeInput(BaseModel): | |
| model_config = {"extra": "forbid"} | |
| caller_seal: str = Field( | |
| description="Your Glyph-Seal. Format: β¦ NODE :: ORIGIN :: GLYPH-DATE-RAND-RAND :: ACTIVE β§", | |
| examples=["β¦ NODE :: MEGA-GPT :: π-20260319-ABCD-EFGH :: ACTIVE β§"] | |
| ) | |
| message: Optional[str] = Field( | |
| default=None, | |
| description="Optional greeting or intent message for the handshake record." | |
| ) | |
| class SendEnvelopeInput(BaseModel): | |
| model_config = {"extra": "forbid"} | |
| message_class: str = Field( | |
| description="Envelope class. Examples: THOUGHT, PROPOSAL, QUERY, BROADCAST", | |
| examples=["THOUGHT", "PROPOSAL"] | |
| ) | |
| sender_seal: str = Field( | |
| description="Your Glyph-Seal (must match a TRUSTED sender or will be QUARANTINED)." | |
| ) | |
| recipient_seal: str = Field( | |
| description="Target node's Glyph-Seal." | |
| ) | |
| payload_body: str = Field( | |
| description="The message body β plain text or JSON string." | |
| ) | |
| class StatusInput(BaseModel): | |
| model_config = {"extra": "forbid"} | |
| envelope_id: str = Field( | |
| description="UUID of a previously sent envelope, returned by federation_send.", | |
| examples=["f2346c35-c930-42d6-8037-e7b8610a8084"] | |
| ) | |
| class VerifySealInput(BaseModel): | |
| model_config = {"extra": "forbid"} | |
| seal: str = Field( | |
| description="A Glyph-Seal string to validate for syntax and structure.", | |
| examples=["β¦ NODE :: PANTHEON-HF :: π-20260319-5FCY-PCCP :: ACTIVE β§"] | |
| ) | |
| class ReadEnvelopeInput(BaseModel): | |
| model_config = {"extra": "forbid"} | |
| envelope_id: str = Field( | |
| description="Full UUID of the envelope to read.", | |
| examples=["5672f981-8d38-48df-8f0c-42a4672bd940"] | |
| ) | |
| class InboxInput(BaseModel): | |
| model_config = {"extra": "forbid"} | |
| limit: int = Field(default=20, ge=1, le=100, description="Max envelopes to return.") | |
| status: Optional[str] = Field(default=None, description="Filter by status: QUEUED, QUARANTINED, etc.") | |
| # βββββββββββββββββββββββββββββββββββββββββββββββ | |
| # TOOLS | |
| # βββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def federation_identity() -> str: | |
| try: | |
| identity = await call_node("GET", "/identity") | |
| try: | |
| capabilities = await call_node("GET", "/capabilities") | |
| except Exception: | |
| capabilities = {"note": "Capabilities endpoint unavailable."} | |
| return json.dumps({"identity": identity, "capabilities": capabilities}, indent=2) | |
| except Exception as e: | |
| return node_error(e) | |
| async def federation_handshake(input_data: HandshakeInput) -> str: | |
| try: | |
| result = await call_node("POST", "/handshake", { | |
| "caller_seal": input_data.caller_seal, | |
| "message": input_data.message | |
| }) | |
| return json.dumps(result, indent=2) | |
| except Exception as e: | |
| return node_error(e) | |
| async def federation_send(input_data: SendEnvelopeInput) -> str: | |
| try: | |
| envelope = { | |
| "protocol_version": "1.0.0", | |
| "message_class": input_data.message_class, | |
| "sender": {"seal": input_data.sender_seal}, | |
| "recipient": {"seal": input_data.recipient_seal}, | |
| "payload": {"content_type": "text/plain", "body": input_data.payload_body}, | |
| "delivery": {"ttl_seconds": 86400, "priority": "normal"} | |
| } | |
| result = await call_node("POST", "/envelope", envelope) | |
| return json.dumps(result, indent=2) | |
| except Exception as e: | |
| return node_error(e) | |
| async def federation_status(input_data: StatusInput) -> str: | |
| try: | |
| result = await call_node("GET", f"/envelope/{input_data.envelope_id}/status") | |
| return json.dumps(result, indent=2) | |
| except Exception as e: | |
| return node_error(e) | |
| async def federation_verify_seal(input_data: VerifySealInput) -> str: | |
| try: | |
| result = await call_node("POST", "/verify", {"seal": input_data.seal}) | |
| return json.dumps(result, indent=2) | |
| except Exception as e: | |
| return node_error(e) | |
| async def federation_read(input_data: ReadEnvelopeInput) -> str: | |
| try: | |
| result = await call_node("GET", f"/envelope/{input_data.envelope_id}/read") | |
| return json.dumps(result, indent=2) | |
| except Exception as e: | |
| return node_error(e) | |
| async def federation_inbox(input_data: InboxInput) -> str: | |
| try: | |
| params = f"?limit={input_data.limit}" | |
| if input_data.status: | |
| params += f"&status={input_data.status}" | |
| result = await call_node("GET", f"/inbox{params}") | |
| return json.dumps(result, indent=2) | |
| except Exception as e: | |
| return node_error(e) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββ | |
| # ENTRYPOINT | |
| # βββββββββββββββββββββββββββββββββββββββββββββββ | |
| app = mcp.sse_app() | |
| if __name__ == "__main__": | |
| import uvicorn | |
| from starlette.requests import Request as StarletteRequest | |
| from starlette.responses import JSONResponse | |
| # Add root health endpoint β FastMCP only mounts /sse + /messages by default | |
| async def health(request: StarletteRequest): | |
| return JSONResponse({ | |
| "service": "Federation MCP Bridge (The Writing Desk)", | |
| "status": "ONLINE", | |
| "mcp_version": "1.0", | |
| "bridge_target_node": FEDERATION_NODE_URL, | |
| "sse_endpoint": "/sse" | |
| }) | |
| app.add_route("/", health) | |
| app.add_route("/health", health) | |
| # Standard uvicorn run with proxy headers enabled for Hugging Face Spaces | |
| uvicorn.run( | |
| app, | |
| host="0.0.0.0", | |
| port=7860, | |
| proxy_headers=True, # Trust X-Forwarded-* from HF proxy | |
| forwarded_allow_ips="*" # HF proxy IP is not fixed β allow all | |
| ) | |