@@ -44,12 +44,12 @@ async def main() -> None:
44
44
# Get MCP server configuration from environment variables
45
45
mcp_server_url = os .environ .get ("MCP_SERVER_URL" , "https://gitmcp.io/Azure/azure-rest-api-specs" )
46
46
mcp_server_label = os .environ .get ("MCP_SERVER_LABEL" , "github" )
47
-
47
+
48
48
project_client = AIProjectClient (
49
49
endpoint = os .environ ["PROJECT_ENDPOINT" ],
50
50
credential = DefaultAzureCredential (),
51
51
)
52
-
52
+
53
53
# Initialize agent MCP tool
54
54
mcp_tool = McpTool (
55
55
server_label = mcp_server_label ,
@@ -60,11 +60,11 @@ async def main() -> None:
60
60
search_api_code = "search_azure_rest_api_code"
61
61
mcp_tool .allow_tool (search_api_code )
62
62
print (f"Allowed tools: { mcp_tool .allowed_tools } " )
63
-
63
+
64
64
# Create agent with MCP tool and process agent run
65
65
async with project_client :
66
66
agents_client = project_client .agents
67
-
67
+
68
68
# Create a new agent.
69
69
# NOTE: To reuse existing agent, fetch it with get_agent(agent_id)
70
70
agent = await agents_client .create_agent (
@@ -73,39 +73,39 @@ async def main() -> None:
73
73
instructions = "You are a helpful agent that can use MCP tools to assist users. Use the available MCP tools to answer questions and perform tasks." ,
74
74
tools = mcp_tool .definitions ,
75
75
)
76
-
76
+
77
77
print (f"Created agent, ID: { agent .id } " )
78
78
print (f"MCP Server: { mcp_tool .server_label } at { mcp_tool .server_url } " )
79
-
79
+
80
80
# Create thread for communication
81
81
thread = await agents_client .threads .create ()
82
82
print (f"Created thread, ID: { thread .id } " )
83
-
83
+
84
84
# Create message to thread
85
85
message = await agents_client .messages .create (
86
86
thread_id = thread .id ,
87
87
role = "user" ,
88
88
content = "Please summarize the Azure REST API specifications Readme" ,
89
89
)
90
90
print (f"Created message, ID: { message .id } " )
91
-
91
+
92
92
# Create and process agent run in thread with MCP tools
93
93
mcp_tool .update_headers ("SuperSecret" , "123456" )
94
94
# mcp_tool.set_approval_mode("never") # Uncomment to disable approval requirement
95
95
run = await agents_client .runs .create (thread_id = thread .id , agent_id = agent .id , tool_resources = mcp_tool .resources )
96
96
print (f"Created run, ID: { run .id } " )
97
-
97
+
98
98
while run .status in ["queued" , "in_progress" , "requires_action" ]:
99
99
await asyncio .sleep (1 )
100
100
run = await agents_client .runs .get (thread_id = thread .id , run_id = run .id )
101
-
101
+
102
102
if run .status == "requires_action" and isinstance (run .required_action , SubmitToolApprovalAction ):
103
103
tool_calls = run .required_action .submit_tool_approval .tool_calls
104
104
if not tool_calls :
105
105
print ("No tool calls provided - cancelling run" )
106
106
await agents_client .runs .cancel (thread_id = thread .id , run_id = run .id )
107
107
break
108
-
108
+
109
109
tool_approvals = []
110
110
for tool_call in tool_calls :
111
111
if isinstance (tool_call , RequiredMcpToolCall ):
@@ -120,36 +120,36 @@ async def main() -> None:
120
120
)
121
121
except Exception as e :
122
122
print (f"Error approving tool_call { tool_call .id } : { e } " )
123
-
123
+
124
124
print (f"tool_approvals: { tool_approvals } " )
125
125
if tool_approvals :
126
126
await agents_client .runs .submit_tool_outputs (
127
127
thread_id = thread .id , run_id = run .id , tool_approvals = tool_approvals
128
128
)
129
-
129
+
130
130
print (f"Current run status: { run .status } " )
131
-
131
+
132
132
print (f"Run completed with status: { run .status } " )
133
133
if run .status == "failed" :
134
134
print (f"Run failed: { run .last_error } " )
135
-
135
+
136
136
# Display run steps and tool calls
137
137
run_steps = agents_client .run_steps .list (thread_id = thread .id , run_id = run .id )
138
-
138
+
139
139
# Loop through each step
140
140
async for step in run_steps :
141
141
print (f"Step { step ['id' ]} status: { step ['status' ]} " )
142
-
142
+
143
143
# Check if there are tool calls in the step details
144
144
step_details = step .get ("step_details" , {})
145
145
tool_calls = step_details .get ("tool_calls" , [])
146
-
146
+
147
147
if tool_calls :
148
148
print (" MCP Tool calls:" )
149
149
for call in tool_calls :
150
150
print (f" Tool Call ID: { call .get ('id' )} " )
151
151
print (f" Type: { call .get ('type' )} " )
152
-
152
+
153
153
if isinstance (step_details , RunStepActivityDetails ):
154
154
for activity in step_details .activities :
155
155
for function_name , function_definition in activity .tools .items ():
@@ -164,9 +164,9 @@ async def main() -> None:
164
164
print (f" Description: { func_argument .description } " )
165
165
else :
166
166
print ("This function has no parameters" )
167
-
167
+
168
168
print () # add an extra newline between steps
169
-
169
+
170
170
# Fetch and log all messages
171
171
messages = agents_client .messages .list (thread_id = thread .id , order = ListSortOrder .ASCENDING )
172
172
print ("\n Conversation:" )
@@ -176,22 +176,23 @@ async def main() -> None:
176
176
last_text = msg .text_messages [- 1 ]
177
177
print (f"{ msg .role .upper ()} : { last_text .text .value } " )
178
178
print ("-" * 50 )
179
-
179
+
180
180
# Example of dynamic tool management
181
181
print (f"\n Demonstrating dynamic tool management:" )
182
182
print (f"Current allowed tools: { mcp_tool .allowed_tools } " )
183
-
183
+
184
184
# Remove a tool
185
185
try :
186
186
mcp_tool .disallow_tool (search_api_code )
187
187
print (f"After removing { search_api_code } : { mcp_tool .allowed_tools } " )
188
188
except ValueError as e :
189
189
print (f"Error removing tool: { e } " )
190
-
190
+
191
191
# Clean-up and delete the agent once the run is finished.
192
192
# NOTE: Comment out this line if you plan to reuse the agent later.
193
193
await agents_client .delete_agent (agent .id )
194
194
print ("Deleted agent" )
195
195
196
+
196
197
if __name__ == "__main__" :
197
198
asyncio .run (main ())
0 commit comments