|
6 | 6 |
|
7 | 7 | import asyncio |
8 | 8 | import os |
9 | | -from dotenv import load_dotenv |
10 | | -from rich import print as rprint |
11 | | -from rich.panel import Panel |
12 | | -from rich.console import Console |
| 9 | + |
13 | 10 | import azure.identity |
| 11 | +from dotenv import load_dotenv |
14 | 12 | from langchain.agents import create_agent |
15 | 13 | from langchain_core.messages import HumanMessage |
16 | 14 | from langchain_mcp_adapters.client import MultiServerMCPClient |
17 | 15 | from langchain_openai import ChatOpenAI |
18 | 16 | from pydantic import SecretStr |
| 17 | +from rich import print as rprint |
| 18 | +from rich.console import Console |
| 19 | +from rich.panel import Panel |
19 | 20 |
|
20 | 21 | load_dotenv(override=True) |
21 | 22 |
|
|
50 | 51 | async def main(): |
51 | 52 | """Create a safe research agent with filtered read-only tools""" |
52 | 53 | console.print("\n[bold white on blue] LangChain Tool Filtering Demo [/bold white on blue]\n") |
53 | | - |
54 | | - console.print(Panel.fit( |
55 | | - "[bold cyan]GitHub Research Agent (Read-Only)[/bold cyan]\n" |
56 | | - "Filtered to only safe search tools", |
57 | | - border_style="cyan" |
58 | | - )) |
59 | | - |
60 | | - mcp_client = MultiServerMCPClient({ |
61 | | - "github": { |
62 | | - "url": "https://api.githubcopilot.com/mcp/", |
63 | | - "transport": "streamable_http", |
64 | | - "headers": {"Authorization": f"Bearer {os.environ['GITHUB_TOKEN']}"}, |
| 54 | + |
| 55 | + console.print( |
| 56 | + Panel.fit( |
| 57 | + "[bold cyan]GitHub Research Agent (Read-Only)[/bold cyan]\nFiltered to only safe search tools", |
| 58 | + border_style="cyan", |
| 59 | + ) |
| 60 | + ) |
| 61 | + |
| 62 | + mcp_client = MultiServerMCPClient( |
| 63 | + { |
| 64 | + "github": { |
| 65 | + "url": "https://api.githubcopilot.com/mcp/", |
| 66 | + "transport": "streamable_http", |
| 67 | + "headers": {"Authorization": f"Bearer {os.environ['GITHUB_TOKEN']}"}, |
| 68 | + } |
65 | 69 | } |
66 | | - }) |
67 | | - |
| 70 | + ) |
| 71 | + |
68 | 72 | # Get all tools and show what we're filtering out |
69 | 73 | all_tools = await mcp_client.get_tools() |
70 | | - |
| 74 | + |
71 | 75 | console.print(f"[dim]Total tools available: {len(all_tools)}[/dim]\n") |
72 | | - |
| 76 | + |
73 | 77 | # Filter to ONLY read operations |
74 | | - safe_tool_names = ['search_repositories', 'search_code', 'search_issues'] |
| 78 | + safe_tool_names = ["search_repositories", "search_code", "search_issues"] |
75 | 79 | filtered_tools = [t for t in all_tools if t.name in safe_tool_names] |
76 | | - |
| 80 | + |
77 | 81 | console.print("[bold cyan]Filtered Tools (read-only):[/bold cyan]") |
78 | 82 | for tool in filtered_tools: |
79 | 83 | console.print(f" ✓ {tool.name}") |
80 | | - |
81 | | - # Show what was filtered out |
82 | | - blocked_tools = [t for t in all_tools if 'create' in t.name or 'update' in t.name or 'fork' in t.name] |
83 | | - if blocked_tools: |
84 | | - console.print(f"\n[dim]Blocked tools ({len(blocked_tools)}): " + ", ".join([t.name for t in blocked_tools[:5]]) + "...[/dim]") |
85 | | - |
86 | 84 | console.print() |
87 | | - |
| 85 | + |
88 | 86 | # Create agent with filtered tools |
89 | 87 | agent = create_agent( |
90 | 88 | model, |
91 | 89 | tools=filtered_tools, |
92 | | - prompt="You help users research GitHub repositories. Search and analyze information." |
| 90 | + prompt="You help users research GitHub repositories. Search and analyze information.", |
93 | 91 | ) |
94 | | - |
| 92 | + |
95 | 93 | query = "Find popular Python MCP server repositories" |
96 | 94 | rprint(f"[bold]Query:[/bold] {query}\n") |
97 | | - |
| 95 | + |
98 | 96 | try: |
99 | 97 | result = await agent.ainvoke({"messages": [HumanMessage(content=query)]}) |
100 | 98 | rprint(f"[bold green]Result:[/bold green]\n{result['messages'][-1].content}\n") |
101 | 99 | except Exception as e: |
102 | 100 | rprint(f"[bold red]Error:[/bold red] {str(e)}\n") |
103 | | - |
104 | 101 |
|
105 | 102 |
|
106 | 103 | if __name__ == "__main__": |
|
0 commit comments