mirror of
https://github.com/anthropics/claude-cookbooks.git
synced 2025-10-06 01:00:28 +03:00
453 lines
17 KiB
Plaintext
453 lines
17 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"id": "7e7958dd",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import os\n",
|
||
"from typing import Any\n",
|
||
"\n",
|
||
"from dotenv import load_dotenv\n",
|
||
"from utils.agent_visualizer import print_activity\n",
|
||
"\n",
|
||
"from claude_code_sdk import ClaudeCodeOptions, ClaudeSDKClient"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "ea47572b",
|
||
"metadata": {},
|
||
"source": [
|
||
"# 02 - The Observability Agent"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "08cc95b6",
|
||
"metadata": {},
|
||
"source": "In the previous notebooks we have built a basic research agent and a Chief of Staff multi-agent framework. While the agents we have built are already powerful, they were still limited in what they could do: the web search agent is limited to searching the internet and our Chief of Staff agent was limited to interacting with its own filesystem.\n\nThis is a serious constraint: real-world agents often need to interact with other systems like databases, APIs, file systems, and other specialized services. [MCP (Model Context Protocol)](https://modelcontextprotocol.io/docs/getting-started/intro) is an open-source standard for AI-tool integrations that allows for an easy connection between our agents and these external systems. In this notebook, we will explore how to connect MCP servers to our agent.\n\n**Need more details on MCP?** For comprehensive setup instructions, configuration best practices, and troubleshooting tips, see the [Claude Code MCP documentation](https://docs.claude.com/en/docs/claude-code/mcp)."
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "95247d94",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Introduction to the MCP Server\n",
|
||
"### 1. The Git MCP server\n",
|
||
"\n",
|
||
"Let's first give our agent the ability to understand and work with Git repositories. By adding the [Git MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/git) to our agent, it gains access to 13 Git-specific tools that let it examine commit history, check file changes, create branches, and even make commits. This transforms our agent from a passive observer into an active participant in your development workflow. In this example, we'll configure the agent to explore a repository's history using only Git tools. This is pretty simple, but knowing this, it is not difficult to imagine agents that can automatically create pull requests, analyze code evolution patterns, or help manage complex Git workflows across multiple repositories."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "21de60c4",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# define our git MCP server (it was downloaded when you ran uv sync as it is defined in the pyproject.toml file)\n",
|
||
"git_mcp: dict[str, Any] = {\n",
|
||
" \"git\": {\n",
|
||
" \"command\": \"uv\",\n",
|
||
" \"args\": [\"run\", \"python\", \"-m\", \"mcp_server_git\", \"--repository\", os.getcwd()],\n",
|
||
" }\n",
|
||
"}"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"id": "23aa5a3d",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: mcp__git()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: Bash()\n",
|
||
"🤖 Using: Bash()\n",
|
||
"🤖 Using: Bash()\n",
|
||
"✓ Tool completed\n",
|
||
"✓ Tool completed\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"messages = []\n",
|
||
"async with (\n",
|
||
" ClaudeSDKClient(\n",
|
||
" options=ClaudeCodeOptions(\n",
|
||
" model=\"claude-sonnet-4-20250514\",\n",
|
||
" mcp_servers=git_mcp,\n",
|
||
" allowed_tools=[\n",
|
||
" \"mcp__git\"\n",
|
||
" ], # For MCP tools, in allowed tools we must add the mcp__serverName__toolName format or mcp__serverName to enable all\n",
|
||
" permission_mode=\"acceptEdits\", # auto-accept file edit permissions\n",
|
||
" )\n",
|
||
" ) as agent\n",
|
||
"):\n",
|
||
" await agent.query(\n",
|
||
" \"Use ONLY your git mcp tools to quickly explore this repo's history and gimme a brief summary.\"\n",
|
||
" )\n",
|
||
" async for msg in agent.receive_response():\n",
|
||
" print_activity(msg)\n",
|
||
" messages.append(msg)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "691e0812",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(f\"\\nResult:\\n{messages[-1].result}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "346a8754",
|
||
"metadata": {},
|
||
"source": [
|
||
"### 2. The GitHub MCP server"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "1361ba84",
|
||
"metadata": {},
|
||
"source": [
|
||
"Now let's level up from local Git operations to full GitHub platform integration. By switching to the [official GitHub MCP server](https://github.com/github/github-mcp-server/tree/main), our agent gains access to over 100 tools that interact with GitHub's entire ecosystem – from managing issues and pull requests to monitoring CI/CD workflows and analyzing code security alerts. This server can work with both public and private repositories, giving your agent the ability to automate complex GitHub workflows that would typically require multiple manual steps."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "7fdb4aa2",
|
||
"metadata": {},
|
||
"source": "#### Step 1: Set up your GitHub Token\n\nYou need a GitHub Personal Access Token. Get one [here](https://github.com/settings/personal-access-tokens/new) and put in the .env file as ```GITHUB_TOKEN=\"<token>\"```\n> Note: When getting your token, select \"Fine-grained\" token with the default options (i.e., public repos, no account permissions), that'll be the easiest way to get this demo working.\n\nAlso, for this example you will have to have [Docker](https://www.docker.com/products/docker-desktop/) running on your machine. Docker is required because the GitHub MCP server runs in a containerized environment for security and isolation.\n\n**Docker Quick Setup:**\n- Install Docker Desktop from [docker.com](https://www.docker.com/products/docker-desktop/)\n- Ensure Docker is running (you'll see the Docker icon in your system tray)\n- Verify with `docker --version` in your terminal\n- **Troubleshooting:** If Docker won't start, check that virtualization is enabled in your BIOS. For detailed setup instructions, see the [Docker documentation](https://docs.docker.com/get-docker/)\n\n#### Step 2: Define the mcp server and start the agent loop!"
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"id": "c1e65281",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# define our github mcp server\n",
|
||
"load_dotenv(override=True)\n",
|
||
"github_mcp: dict[str, Any] = {\n",
|
||
" \"github\": {\n",
|
||
" \"command\": \"docker\",\n",
|
||
" \"args\": [\n",
|
||
" \"run\",\n",
|
||
" \"-i\",\n",
|
||
" \"--rm\",\n",
|
||
" \"-e\",\n",
|
||
" \"GITHUB_PERSONAL_ACCESS_TOKEN\",\n",
|
||
" \"ghcr.io/github/github-mcp-server\",\n",
|
||
" ],\n",
|
||
" \"env\": {\"GITHUB_PERSONAL_ACCESS_TOKEN\": os.environ.get(\"GITHUB_TOKEN\")},\n",
|
||
" }\n",
|
||
"}"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"id": "e4c524c1",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: mcp__github__search_repositories()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: mcp__github__get_file_contents()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"# run our agent\n",
|
||
"messages = []\n",
|
||
"async with ClaudeSDKClient(\n",
|
||
" options=ClaudeCodeOptions(\n",
|
||
" model=\"claude-sonnet-4-20250514\",\n",
|
||
" mcp_servers=github_mcp,\n",
|
||
" allowed_tools=[\"mcp__github\"],\n",
|
||
" permission_mode=\"acceptEdits\", # auto-accept permissions\n",
|
||
" )\n",
|
||
") as agent:\n",
|
||
" await agent.query(\n",
|
||
" \"Use ONLY your GitHub MCP tools to search for the anthropics/claude-code-sdk-python repository and and give me a couple facts about it\"\n",
|
||
" )\n",
|
||
" async for msg in agent.receive_response():\n",
|
||
" print_activity(msg)\n",
|
||
" messages.append(msg)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "4e0ac04f",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(f\"\\nResult:\\n{messages[-1].result}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "2a788ed6",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Real use case: An observability agent\n",
|
||
"\n",
|
||
"Now, with such simple setup we can already have an agent acting as self-healing software system!"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"id": "c8edb208",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: TodoWrite()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: TodoWrite()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Using: mcp__github__list_workflows()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: mcp__github__list_workflow_runs()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: TodoWrite()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: mcp__github__get_workflow_run()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: TodoWrite()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Using: mcp__github__get_job_logs()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: mcp__github__list_workflow_jobs()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: WebFetch()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: mcp__github__get_job_logs()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: mcp__github__get_job_logs()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: TodoWrite()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Using: mcp__github__get_job_logs()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n",
|
||
"🤖 Using: TodoWrite()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Using: TodoWrite()\n",
|
||
"✓ Tool completed\n",
|
||
"🤖 Thinking...\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"load_dotenv(override=True)\n",
|
||
"\n",
|
||
"prompt = \"\"\"Monitor the GitHub Actions workflows for facebook/react.\n",
|
||
"Look at the last triggered CI pipeline. \n",
|
||
"1. Analyze the trigger for the pipeline\n",
|
||
"2. Identify whether the pipeline passed or not\n",
|
||
"3. If it failed, explain which test failed\n",
|
||
"4. Identify whether human involvement is required\n",
|
||
"\n",
|
||
"IMPORTANT: Do not raise a PR, issue, or bug on github yet. Just give me a summary of your findings and plan.\n",
|
||
"\n",
|
||
"Focus on the 'CI' workflow specifically. Use your Github MCP server tools!\"\"\"\n",
|
||
"\n",
|
||
"github_mcp: dict[str, Any] = {\n",
|
||
" \"github\": {\n",
|
||
" \"command\": \"docker\",\n",
|
||
" \"args\": [\n",
|
||
" \"run\",\n",
|
||
" \"-i\",\n",
|
||
" \"--rm\",\n",
|
||
" \"-e\",\n",
|
||
" \"GITHUB_PERSONAL_ACCESS_TOKEN\",\n",
|
||
" \"ghcr.io/github/github-mcp-server\",\n",
|
||
" ],\n",
|
||
" \"env\": {\"GITHUB_PERSONAL_ACCESS_TOKEN\": os.environ.get(\"GITHUB_TOKEN\")},\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"messages = []\n",
|
||
"async with ClaudeSDKClient(\n",
|
||
" options=ClaudeCodeOptions(\n",
|
||
" model=\"claude-sonnet-4-20250514\",\n",
|
||
" mcp_servers=github_mcp,\n",
|
||
" allowed_tools=[\"mcp__github\"],\n",
|
||
" permission_mode=\"acceptEdits\",\n",
|
||
" )\n",
|
||
") as agent:\n",
|
||
" await agent.query(prompt)\n",
|
||
" async for msg in agent.receive_response():\n",
|
||
" print_activity(msg)\n",
|
||
" messages.append(msg)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "49a39ed7",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(f\"\\nResult:\\n{messages[-1].result}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "80cd321f",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Observability Agent as Module\n",
|
||
"\n",
|
||
"The `observability_agent/agent.py` file contains the same minimal helper functions as the research agent or chief of staff agent, just enhanced for GitHub monitoring. \n",
|
||
"\n",
|
||
"As before, to use it as a module in your Python code:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "97074fe7",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from observability_agent.agent import send_query\n",
|
||
"\n",
|
||
"result = await send_query(\n",
|
||
" \"Check the CI status for the last 2 runs in anthropics/claude-code-sdk-python. Just do 3 tool calls, be efficient.\"\n",
|
||
")\n",
|
||
"print(f\"Monitoring result: {result}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "0c1578dc",
|
||
"metadata": {},
|
||
"source": [
|
||
"We can do multi-turn conversations with this agent as well:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "7914f8db",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Example 2: Multi-turn conversation for deeper monitoring\n",
|
||
"result1 = await send_query(\"What's the current CI status for facebook/react?\")\n",
|
||
"print(f\"Initial check: {result1[:250]}...\\n\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "8014a701",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Continue the conversation to dig deeper\n",
|
||
"result2 = await send_query(\n",
|
||
" \"Are there any flaky tests in the recent failures? You can only make one tool call.\",\n",
|
||
" continue_conversation=True,\n",
|
||
")\n",
|
||
"print(f\"Follow-up analysis: {result2[:250]}...\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "5a2f48f7",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Conclusion\n",
|
||
"\n",
|
||
"We've demonstrated how the Claude Code SDK enables seamless integration with external systems through the Model Context Protocol (MCP). Starting with local Git operations through the Git MCP server, we progressively expanded to full GitHub platform integration with access to over 100 GitHub-specific tools. This transformed our agent from a local assistant into a powerful observability system capable of monitoring workflows, analyzing CI/CD failures, and providing actionable insights for production systems.\n",
|
||
"\n",
|
||
"By connecting MCP servers to our agent, we created an autonomous observability system that monitors GitHub Actions workflows, distinguishes between real failures and security restrictions, and provides detailed analysis of test failures. The system demonstrates how agents can actively participate in your DevOps workflow, moving from passive monitoring to intelligent incident response.\n",
|
||
"\n",
|
||
"This concludes, for now, our journey through the Claude Code SDK tutorial series. We've progressed from simple research agents to sophisticated multi-agent orchestration, and finally to external system integration through MCP. Together, these patterns provide the foundation for building production-ready agentic systems that can handle real-world complexity while maintaining governance, compliance, and observability.\n",
|
||
"\n",
|
||
"### What You've Learned Across All Notebooks\n",
|
||
"\n",
|
||
"**From Notebook 00 (Research Agent)**\n",
|
||
"- Core SDK fundamentals with `query()` and `ClaudeSDKClient`\n",
|
||
"- Basic tool usage with WebSearch and Read\n",
|
||
"- Simple agent loops and conversation management\n",
|
||
"\n",
|
||
"**From Notebook 01 (Chief of Staff)**\n",
|
||
"- Advanced features: memory, output styles, planning mode\n",
|
||
"- Multi-agent coordination through subagents\n",
|
||
"- Governance through hooks and custom commands\n",
|
||
"- Enterprise-ready agent architectures\n",
|
||
"\n",
|
||
"**From Notebook 02 (Observability Agent)**\n",
|
||
"- External system integration via MCP servers\n",
|
||
"- Real-time monitoring and incident response\n",
|
||
"- Production workflow automation\n",
|
||
"- Scalable agent deployment patterns\n",
|
||
"\n",
|
||
"The complete implementations for all three agents are available in their respective directories (`research_agent/`, `chief_of_staff_agent/`, `observability_agent/`), ready to serve as inspiration for integrations into your production systems."
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python (cc-sdk-tutorial)",
|
||
"language": "python",
|
||
"name": "cc-sdk-tutorial"
|
||
},
|
||
"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.13"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 5
|
||
} |