{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# Module 6 — MCP Integration\n\n> ⚠️ **Heads up: this module is currently broken.** The MCP Connector example does not run end-to-end as written. Read through for the concepts, but expect to adjust the code before it works against a live server. Fix in progress.\n\nThe **MCP Connector** (`mcp-client-2025-11-20` beta) wires an MCP server in as a tool source directly inside a `/v1/messages` request — no separate MCP client process required. Claude calls MCP tools just like any other tool.\n\n> **ZDR note:** the MCP Connector is **not ZDR-eligible** (server-side routing).\n\n### Free public MCP server for the lab\n\nWe hit Hugging Face's official MCP server at **`https://huggingface.co/mcp`**. It's public, supports anonymous access, and fits the prospecting narrative: Claude can check whether a target prospect has published models, datasets, or papers on the Hub as a signal of their AI maturity. An optional `HF_TOKEN` raises rate limits but isn't required."
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import anthropic\n",
    "from dotenv import load_dotenv\n",
    "\n",
    "load_dotenv()\n",
    "client = anthropic.Anthropic()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "## 1. Call the Hugging Face MCP server inline\n\nThe MCP Connector splits the request into two pieces:\n\n- **`mcp_servers`** — connection details for each remote server (URL, type, auth token).\n- **`tools`** with `type: \"mcp_toolset\"` — references a server by name and enables specific tools via `configs`. This is your deny-by-default safety boundary: only tools with `{\"enabled\": True}` are exposed to Claude.\n\nNote that `authorization_token` lives on the server entry, not on the toolset entry."
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": "import os\n\n# 1. Define the server connection details separately\n# The 'authorization_token' belongs here, not in the tools array\nhf_token = os.environ.get(\"HF_TOKEN\")\nmcp_servers = [\n    {\n        \"name\": \"huggingface\",\n        \"type\": \"url\",\n        \"url\": \"https://huggingface.co/mcp\",\n        \"authorization_token\": hf_token,\n    }\n]\n\n# 2. Define which tools from that server to enable\n# The type MUST be 'mcp_toolset'\ntools = [\n    {\n        \"type\": \"mcp_toolset\",\n        \"mcp_server_name\": \"huggingface\",   # must match the name in mcp_servers\n        \"configs\": {\n            \"hf_doc_search\": {\"enabled\": True},\n            \"hf_doc_fetch\":  {\"enabled\": True},\n        },\n    }\n]\n\nresponse = client.beta.messages.create(\n    model=\"claude-opus-4-7\",\n    max_tokens=4096,\n    mcp_servers=mcp_servers,   # pass the servers array here\n    tools=tools,               # pass the toolset array here\n    messages=[{\n        \"role\": \"user\",\n        \"content\": (\n            \"We're scoping Stripe as an AI consulting prospect. Use the Hugging Face \"\n            \"MCP tools to (1) find any Hugging Face documentation referencing Stripe \"\n            \"or fintech inference patterns, and (2) summarize what Stripe's public AI \"\n            \"footprint suggests about their inference maturity. Cite the docs you used.\"\n        ),\n    }],\n    betas=[\"mcp-client-2025-11-20\"],\n)\n\nprint(\"stop_reason:\", response.stop_reason)\nfor block in response.content:\n    if block.type == \"text\":\n        print(block.text)"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Secure credentials with env-var substitution\n",
    "\n",
    "Use `${VAR_NAME}` placeholders in `.mcp.json` so secrets stay out of source control. Values resolve from the runtime environment at startup. The cell below scaffolds the file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pathlib import Path\n",
    "\n",
    "mcp_config = '''{\n",
    "  \"mcpServers\": {\n",
    "    \"crm\": {\n",
    "      \"command\": \"node\",\n",
    "      \"args\": [\"./mcp-servers/crm-server.js\"],\n",
    "      \"env\": {\n",
    "        \"CRM_API_KEY\": \"${CRM_API_KEY}\",\n",
    "        \"CRM_BASE_URL\": \"${CRM_BASE_URL}\"\n",
    "      }\n",
    "    }\n",
    "  }\n",
    "}\n",
    "'''\n",
    "\n",
    "Path(\"module6_demo\").mkdir(exist_ok=True)\n",
    "Path(\"module6_demo/.mcp.json\").write_text(mcp_config, encoding=\"utf-8\")\n",
    "print(\"wrote module6_demo/.mcp.json — add it to .gitignore if it ever holds real values\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}