#!/usr/bin/env python3 """ BotWire Memory MCP Server Generated by https://botwire.dev/templates/mcp-memory DISCLAIMER: - Data is stored on BotWire's infrastructure (botwire.dev) under your agent ID - BotWire provides this service on a best-effort basis with no SLA on the free tier - Review terms at https://botwire.dev/terms - Always maintain your own backups for critical agent state - Free tier: rate-limited, shared infrastructure """ import httpx from mcp.server.fastmcp import FastMCP AGENT_ID = "{YOUR_AGENT_ID}" # Your BotWire agent ID — register free at botwire.dev/identity/register BASE_URL = "https://botwire.dev" mcp = FastMCP("botwire-memory", version="1.0.0") @mcp.tool() def memory_read(namespace: str, key: str) -> str: """Read a value from BotWire persistent memory. Args: namespace: Logical bucket (e.g. "tasks", "facts", "goals") key: Key within the namespace Returns: Stored string value, or "NOT_FOUND" """ ns_key = f"{AGENT_ID}-{namespace}" if AGENT_ID and AGENT_ID != "{YOUR_AGENT_ID}" else namespace r = httpx.get(f"{BASE_URL}/memory/{ns_key}/{key}", timeout=10) if r.status_code == 404: return "NOT_FOUND" r.raise_for_status() return r.json().get("value", "") @mcp.tool() def memory_write(namespace: str, key: str, value: str) -> str: """Write a value to BotWire persistent memory. Args: namespace: Logical bucket (e.g. "tasks", "facts", "goals") key: Key within the namespace value: String value to store Returns: "OK" on success """ ns_key = f"{AGENT_ID}-{namespace}" if AGENT_ID and AGENT_ID != "{YOUR_AGENT_ID}" else namespace r = httpx.put( f"{BASE_URL}/memory/{ns_key}/{key}", json={"value": value}, timeout=10, ) r.raise_for_status() return "OK" @mcp.tool() def memory_delete(namespace: str, key: str) -> str: """Delete a value from BotWire persistent memory. Args: namespace: Logical bucket key: Key to delete Returns: "DELETED" or "NOT_FOUND" """ ns_key = f"{AGENT_ID}-{namespace}" if AGENT_ID and AGENT_ID != "{YOUR_AGENT_ID}" else namespace r = httpx.delete(f"{BASE_URL}/memory/{ns_key}/{key}", timeout=10) if r.status_code == 404: return "NOT_FOUND" r.raise_for_status() return "DELETED" @mcp.tool() def memory_list(namespace: str) -> list[str]: """List all keys stored in a namespace. Args: namespace: Logical bucket to list Returns: List of key strings """ ns_key = f"{AGENT_ID}-{namespace}" if AGENT_ID and AGENT_ID != "{YOUR_AGENT_ID}" else namespace r = httpx.get(f"{BASE_URL}/memory/{ns_key}", timeout=10) if r.status_code == 404: return [] r.raise_for_status() return r.json().get("keys", []) @mcp.tool() def memory_search(namespace: str, query: str) -> list[str]: """Find keys matching a substring query within a namespace. Args: namespace: Logical bucket to search query: Substring to match against key names Returns: Matching key strings """ keys = memory_list(namespace) return [k for k in keys if query.lower() in k.lower()] if __name__ == "__main__": # Run: python botwire_memory_mcp.py # Or add to your MCP config as a stdio server mcp.run()