Model Context Protocol (MCP)
MCP is Anthropic's open standard for connecting Claude to external services in a uniform, secure, and discoverable way. It eliminates bespoke glue code and lets Claude work with any MCP-compatible server immediately.
Tools
Functions Claude can invoke. Each has a name, description Claude uses to decide when to call it, and a JSON Schema for inputs. Tools are the primary action primitive -- they can read, mutate state, or call external APIs.
Resources
Structured data Claude can read -- files, database rows, live feeds. Identified by URI schemes like file:///path or postgres://table. Can be static or dynamically generated.
Prompts
Reusable parameterised prompt templates stored on the server. Users invoke them by name with arguments. Ensures consistent framing of common tasks across every session.
Transport Layers
stdio for local tools (lowest latency), SSE for remote servers, HTTP Streamable for serverless deployments. All use JSON-RPC 2.0 over the chosen transport.
ShopMate -- Shopify MCP Server
# shopmate/mcp/shopify_server.py -- Connect Claude Desktop to the ThreadCo Shopify store # pip install mcp fastmcp httpx from mcp.server.fastmcp import FastMCP import httpx, os, json mcp = FastMCP(name="shopmate-shopify", version="1.0.0") SHOPIFY_URL = os.environ["SHOPIFY_STORE_URL"] # e.g. threadco.myshopify.com SHOPIFY_TOKEN= os.environ["SHOPIFY_ACCESS_TOKEN"] HEADERS = {"X-Shopify-Access-Token": SHOPIFY_TOKEN, "Content-Type": "application/json"} @mcp.tool() def get_low_stock_products(threshold: int = 5) -> list: """List all ThreadCo products with stock below the threshold. Use when Maya asks 'what do I need to reorder?'""" resp = httpx.get(f"{SHOPIFY_URL}/admin/api/2024-01/products.json?limit=250", headers=HEADERS) products = resp.json().get("products", []) low = [] for p in products: for v in p.get("variants", []): if v.get("inventory_quantity", 99) < threshold: low.append({"product": p["title"], "variant": v["title"], "stock": v["inventory_quantity"]}) return low @mcp.tool() def get_recent_orders(limit: int = 10) -> list: """Fetch the most recent ThreadCo orders. Use when Maya asks about recent sales or a specific customer.""" resp = httpx.get(f"{SHOPIFY_URL}/admin/api/2024-01/orders.json?limit={limit}&status=any", headers=HEADERS) orders = resp.json().get("orders", []) return [{"order": o["name"], "customer": o.get("email"), "total": o["total_price"], "status": o["fulfillment_status"]} for o in orders] @mcp.resource("shopify://store/summary") def store_summary() -> str: """ThreadCo store stats: total products, active, today's orders.""" count = httpx.get(f"{SHOPIFY_URL}/admin/api/2024-01/products/count.json", headers=HEADERS).json() return json.dumps({"total_products": count.get("count")}) if __name__ == "__main__": mcp.run(transport="stdio")
{
"mcpServers": {
"shopmate-shopify": {
"command": "python",
"args": ["/path/to/shopmate/mcp/shopify_server.py"],
"env": {
"SHOPIFY_STORE_URL": "https://threadco.myshopify.com",
"SHOPIFY_ACCESS_TOKEN": "shpat_..."
}
}
}
}