{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# MCP Mastery: Scoping, Catalogs, and Errors\r\n",
    "\r\n",
    "*Module 7*\r\n",
    "\r\n",
    "This module shifts from basic connectivity to strategic integration of Model Context Protocol (MCP) servers into production agentic workflows and team development environments. The focus is Task 2.4 and Task 2.1: scope MCP servers correctly, reduce exploratory discovery calls with Resources, engineer tool descriptions for reliable selection, and propagate structured errors the coordinator can recover from.\r\n",
    "\r\n",
    "**Lab notebook:** [Module7_Complete.ipynb](lab_files/Module7_Complete.ipynb)\r\n",
    "\r\n",
    "## 1. Administrative Scoping & Credential Security\r\n",
    "\r\n",
    "Orchestrators must manage tool availability at both personal and project levels while protecting sensitive credentials.\r\n",
    "\r\n",
    "- **Project-scoped servers (`.mcp.json`):** use for standardized team tooling shared through version control. Commit the server definition, not secrets.\r\n",
    "- **User-scoped servers (`~/.claude.json`):** use only for personal, local, or experimental servers that should not be shared with the team.\r\n",
    "- **Secure credential management:** never hardcode secrets. Use environment variable expansion such as `${GITHUB_TOKEN}` or `${DB_PASSWORD}`.\r\n",
    "- **Community vs. custom servers:** prefer existing community MCP servers for standard integrations like Jira or Slack. Reserve custom servers for proprietary, team-specific logic.\r\n",
    "\r\n",
    "*.mcp.json*\r\n",
    "```json\r\n",
    "{\r\n",
    "  \"mcpServers\": {\r\n",
    "    \"crm-db\": {\r\n",
    "      \"command\": \"node\",\r\n",
    "      \"args\": [\"./mcp-servers/mock-db-server.js\"],\r\n",
    "      \"env\": {\r\n",
    "        \"DB_HOST\": \"${DB_HOST}\",\r\n",
    "        \"DB_USER\": \"${DB_USER}\",\r\n",
    "        \"DB_PASSWORD\": \"${DB_PASSWORD}\"\r\n",
    "      }\r\n",
    "    }\r\n",
    "  }\r\n",
    "}\r\n",
    "```\r\n",
    "\r\n",
    "> **Tip.** Architect Tip for the Exam If the whole team should use the same integration, start with project-level `.mcp.json`. If the server is personal, experimental, or tied to private credentials, keep it in `~/.claude.json`.\r\n",
    "\r\n",
    "## 2. Reducing the Discovery Tax with MCP Resources\r\n",
    "\r\n",
    "Agents should plan tool sequences using navigable catalogs rather than burning tokens on exploratory trial-and-error calls.\r\n",
    "\r\n",
    "### 2a. The Discovery Tax\r\n",
    "\r\n",
    "Without a catalog, an agent asked to \"find recent enterprise leads in fintech with open opportunities\" may call `SHOW TABLES`, then inspect columns, then try a join, then recover from a schema mistake. Those calls do not answer the user; they only discover the system.\r\n",
    "\r\n",
    "### 2b. Resources as Content Catalogs\r\n",
    "\r\n",
    "Expose database schemas, API hierarchies, and documentation trees as MCP Resources. The model reads the catalog as a navigable map, then writes a precise query or tool call in its first execution step.\r\n",
    "\r\n",
    "*MCP Resource: db://crm/schema*\r\n",
    "```json\r\n",
    "{\r\n",
    "  \"uri\": \"db://crm/schema\",\r\n",
    "  \"name\": \"CRM database schema\",\r\n",
    "  \"description\": \"Use before CRM queries. Lists tables, join keys, allowed filters, and column definitions.\",\r\n",
    "  \"mimeType\": \"application/json\",\r\n",
    "  \"contents\": [{\r\n",
    "    \"mimeType\": \"application/json\",\r\n",
    "    \"text\": \"{\\\"tables\\\":{\\\"leads\\\":{\\\"columns\\\":{\\\"id\\\":\\\"uuid\\\",\\\"company\\\":\\\"text\\\",\\\"industry\\\":\\\"text\\\",\\\"account_id\\\":\\\"uuid\\\"}},\\\"opportunities\\\":{\\\"columns\\\":{\\\"id\\\":\\\"uuid\\\",\\\"account_id\\\":\\\"uuid\\\",\\\"stage\\\":\\\"text\\\",\\\"amount\\\":\\\"numeric\\\"}}},\\\"joins\\\":[\\\"leads.account_id = opportunities.account_id\\\"]}\"\r\n",
    "  }]\r\n",
    "}\r\n",
    "```\r\n",
    "\r\n",
    "With that Resource in context, the agent can plan: read `db://crm/schema`, identify `leads.account_id = opportunities.account_id`, then call the CRM query tool once with the correct join.\r\n",
    "\r\n",
    "## 3. Selection Reliability: MCP vs. Built-in Tools\r\n",
    "\r\n",
    "Descriptions are the primary mechanism for tool selection. If an agent incorrectly prefers a built-in tool such as `Grep` over a specialized MCP tool, the first fix is not to remove `Grep`; it is to improve the MCP tool description.\r\n",
    "\r\n",
    "### 3a. Description Discipline\r\n",
    "\r\n",
    "A strong description states the tool's unique capability, expected input format, output shape, and boundaries.\r\n",
    "\r\n",
    "*SemanticSearch description*\r\n",
    "```json\r\n",
    "{\r\n",
    "  \"name\": \"SemanticSearch\",\r\n",
    "  \"description\": \"Searches indexed product docs by concept, synonym, or meaning when the user does not know the exact wording. Input should be a natural-language concept query such as 'refund abuse risk' or 'enterprise SSO setup'. Returns ranked passages with document IDs and relevance scores. Do NOT use for exact string, filename, or symbol matches; use Grep for literal text.\"\r\n",
    "}\r\n",
    "```\r\n",
    "\r\n",
    "### 3b. Disambiguation\r\n",
    "\r\n",
    "Use `SemanticSearch` for concept-based questions like \"where do we describe account takeover risk?\" Use `Grep` for exact strings like `\"Invalid Token\"`, function names, exported symbols, filenames, and stack trace fragments.\r\n",
    "\r\n",
    "## 4. Structured Error Propagation\r\n",
    "\r\n",
    "Tools must return metadata that enables an agent or coordinator to make intelligent recovery decisions.\r\n",
    "\r\n",
    "- **`isError`:** set `true` when the tool failed. Do not use it for valid empty results.\r\n",
    "- **`errorCategory`:** standardize on four categories: `TRANSIENT`, `VALIDATION`, `PERMISSION`, and `BUSINESS`.\r\n",
    "- **`BUSINESS` errors:** policy violations, such as a refund denied by policy. They are never retryable; the agent should explain the policy to the user rather than retry.\r\n",
    "- **`isRetryable`:** set `true` only when retrying could plausibly succeed.\r\n",
    "- **Recovery vs. failure:** distinguish an access failure from a valid empty result. An access failure may require a pivot or user-facing explanation; an empty result is a successful query with no matches.\r\n",
    "\r\n",
    "*permission denied tool response*\r\n",
    "```json\r\n",
    "{\r\n",
    "  \"isError\": true,\r\n",
    "  \"errorCategory\": \"PERMISSION\",\r\n",
    "  \"isRetryable\": false,\r\n",
    "  \"message\": \"Database user lacks SELECT permission on opportunities. Ask an admin for crm.opportunities:read.\"\r\n",
    "}\r\n",
    "```\r\n",
    "\r\n",
    "*business policy violation*\r\n",
    "```json\r\n",
    "{\r\n",
    "  \"isError\": true,\r\n",
    "  \"errorCategory\": \"BUSINESS\",\r\n",
    "  \"isRetryable\": false,\r\n",
    "  \"message\": \"Refund denied by policy: purchases older than 90 days are not refundable. Explain the policy to the customer instead of retrying.\"\r\n",
    "}\r\n",
    "```\r\n",
    "\r\n",
    "*valid empty result*\r\n",
    "```json\r\n",
    "{\r\n",
    "  \"isError\": false,\r\n",
    "  \"rows\": [],\r\n",
    "  \"message\": \"Query succeeded; no matching leads found.\"\r\n",
    "}\r\n",
    "```\r\n",
    "\r\n",
    "## Lab Exercise: Designing a High-Reliability MCP Integration\r\n",
    "\r\n",
    "**Lab notebook:** [Module7_Self_Driven_Lab.ipynb](lab_files/Module7_Self_Driven_Lab.ipynb)\r\n",
    "\r\n",
    "**Objective:** master MCP configuration, description engineering, Resources, and structured error handling.\r\n",
    "\r\n",
    "1. **Secure configuration:** create a project-level `.mcp.json` file that connects to a mock database server using `${DB_PASSWORD}` for environment variable substitution.\r\n",
    "2. **Catalog implementation:** define an MCP Resource at `db://crm/schema` that lists available tables and column definitions. Verify that the agent uses this Resource to plan a complex join before calling tools.\r\n",
    "3. **Description engineering:** given built-in `Grep` and custom `SemanticSearch`, rewrite the `SemanticSearch` description so the agent chooses it for concept-based queries but continues using `Grep` for exact string matches.\r\n",
    "4. **Error handling:** implement a \"Permission Denied\" response with `isError: true`, `errorCategory: \"PERMISSION\"`, and `isRetryable: false`. Verify the agent informs the user instead of attempting a redundant retry.\r\n",
    "5. **Split an overlapping tool:** take a generic `analyze_document` tool and split it into `extract_data_points`, `summarize_content`, and `verify_claim_against_source`. Write boundary descriptions that make each tool unambiguous, then test that an ambiguous request routes to the correct tool.\r\n",
    "\r\n",
    "> **Tip.** Architect Tip for the Exam MCP reliability is not just connectivity. The architecture is reliable when server scope is intentional, secrets are externalized, Resources reduce exploratory calls, descriptions make tool choice obvious, and error metadata tells the agent whether to retry, pivot, or inform the user.\r\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}