agent-mcp 0.1.3__py3-none-any.whl → 0.1.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. agent_mcp/__init__.py +66 -12
  2. agent_mcp/a2a_protocol.py +316 -0
  3. agent_mcp/agent_lightning_library.py +214 -0
  4. agent_mcp/camel_mcp_adapter.py +521 -0
  5. agent_mcp/claude_mcp_adapter.py +195 -0
  6. agent_mcp/cli.py +47 -0
  7. agent_mcp/google_ai_mcp_adapter.py +183 -0
  8. agent_mcp/heterogeneous_group_chat.py +412 -38
  9. agent_mcp/langchain_mcp_adapter.py +176 -43
  10. agent_mcp/llamaindex_mcp_adapter.py +410 -0
  11. agent_mcp/mcp_agent.py +26 -0
  12. agent_mcp/mcp_transport.py +11 -5
  13. agent_mcp/microsoft_agent_framework.py +591 -0
  14. agent_mcp/missing_frameworks.py +435 -0
  15. agent_mcp/openapi_protocol.py +616 -0
  16. agent_mcp/payments.py +804 -0
  17. agent_mcp/pydantic_ai_mcp_adapter.py +628 -0
  18. agent_mcp/registry.py +768 -0
  19. agent_mcp/security.py +864 -0
  20. {agent_mcp-0.1.3.dist-info → agent_mcp-0.1.5.dist-info}/METADATA +173 -49
  21. agent_mcp-0.1.5.dist-info/RECORD +62 -0
  22. {agent_mcp-0.1.3.dist-info → agent_mcp-0.1.5.dist-info}/WHEEL +1 -1
  23. agent_mcp-0.1.5.dist-info/entry_points.txt +4 -0
  24. agent_mcp-0.1.5.dist-info/top_level.txt +3 -0
  25. demos/__init__.py +1 -0
  26. demos/basic/__init__.py +1 -0
  27. demos/basic/framework_examples.py +108 -0
  28. demos/basic/langchain_camel_demo.py +272 -0
  29. demos/basic/simple_chat.py +355 -0
  30. demos/basic/simple_integration_example.py +51 -0
  31. demos/collaboration/collaborative_task_example.py +437 -0
  32. demos/collaboration/group_chat_example.py +130 -0
  33. demos/collaboration/simplified_crewai_example.py +39 -0
  34. demos/comprehensive_framework_demo.py +202 -0
  35. demos/langgraph/autonomous_langgraph_network.py +808 -0
  36. demos/langgraph/langgraph_agent_network.py +415 -0
  37. demos/langgraph/langgraph_collaborative_task.py +619 -0
  38. demos/langgraph/langgraph_example.py +227 -0
  39. demos/langgraph/run_langgraph_examples.py +213 -0
  40. demos/network/agent_network_example.py +381 -0
  41. demos/network/email_agent.py +130 -0
  42. demos/network/email_agent_demo.py +46 -0
  43. demos/network/heterogeneous_network_example.py +216 -0
  44. demos/network/multi_framework_example.py +199 -0
  45. demos/utils/check_imports.py +49 -0
  46. demos/workflows/autonomous_agent_workflow.py +248 -0
  47. demos/workflows/mcp_features_demo.py +353 -0
  48. demos/workflows/run_agent_collaboration_demo.py +63 -0
  49. demos/workflows/run_agent_collaboration_with_logs.py +396 -0
  50. demos/workflows/show_agent_interactions.py +107 -0
  51. demos/workflows/simplified_autonomous_demo.py +74 -0
  52. functions/main.py +144 -0
  53. functions/mcp_network_server.py +513 -0
  54. functions/utils.py +47 -0
  55. agent_mcp-0.1.3.dist-info/RECORD +0 -18
  56. agent_mcp-0.1.3.dist-info/entry_points.txt +0 -2
  57. agent_mcp-0.1.3.dist-info/top_level.txt +0 -1
@@ -0,0 +1,415 @@
1
+ """
2
+ LangGraph Agent Network Example using MCPNode.
3
+
4
+ This example demonstrates a network of agents built with LangGraph and the MCP protocol,
5
+ showing how to create a flexible agent network where multiple specialized agents can
6
+ collaborate and share context through a coordinator.
7
+ """
8
+
9
+ import os
10
+ import json
11
+ import uuid
12
+ from typing import Dict, List, Any, Optional, cast, Callable
13
+
14
+ from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
15
+ from langchain_core.tools import tool
16
+ import langgraph.graph
17
+ from langgraph.graph import END, StateGraph
18
+ from langgraph.prebuilt import ToolNode
19
+ from openai import OpenAI
20
+
21
+ # Import our MCP implementation for LangGraph
22
+ from agent_mcp.mcp_langgraph import MCPNode, MCPReactAgent, create_mcp_langgraph
23
+
24
+ # Initialize OpenAI client
25
+ OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
26
+ openai = OpenAI(api_key=OPENAI_API_KEY)
27
+
28
+
29
+ def get_llm():
30
+ """Get the OpenAI LLM wrapper that implements the langchain interface."""
31
+ from langchain_openai import ChatOpenAI
32
+
33
+ # Initialize with the newest model (gpt-4) which was released after your knowledge cutoff
34
+ return ChatOpenAI(model="gpt-4", temperature=0.7)
35
+
36
+
37
+ class LangGraphAgentNetwork:
38
+ """A network of LangGraph agents using MCP for communication and context sharing."""
39
+
40
+ def __init__(self):
41
+ """Initialize the agent network."""
42
+ self.llm = get_llm()
43
+ self.agents = {}
44
+ self.network_id = str(uuid.uuid4())
45
+ self.shared_workspace = {}
46
+ self.message_history = []
47
+
48
+ # Create the agent network
49
+ self.create_network()
50
+
51
+ def create_network(self):
52
+ """Create all agents in the network and connect them."""
53
+ # Create the coordinator agent
54
+ coordinator = MCPReactAgent(
55
+ name="Coordinator",
56
+ system_message=(
57
+ "You are the Coordinator agent responsible for managing communication "
58
+ "and task assignment across the network. You should help users interact "
59
+ "with specialized agents and facilitate collaboration."
60
+ )
61
+ )
62
+
63
+ # Create specialized agents
64
+ researcher = MCPReactAgent(
65
+ name="Researcher",
66
+ system_message=(
67
+ "You are the Researcher agent specialized in gathering and synthesizing "
68
+ "information. You excel at finding relevant data and organizing it into "
69
+ "coherent summaries."
70
+ )
71
+ )
72
+
73
+ analyst = MCPReactAgent(
74
+ name="Analyst",
75
+ system_message=(
76
+ "You are the Analyst agent specialized in data analysis and interpretation. "
77
+ "You can identify patterns, extract insights, and explain complex data in "
78
+ "simple terms."
79
+ )
80
+ )
81
+
82
+ planner = MCPReactAgent(
83
+ name="Planner",
84
+ system_message=(
85
+ "You are the Planner agent specialized in strategic planning and task "
86
+ "decomposition. You can break down complex problems into actionable steps."
87
+ )
88
+ )
89
+
90
+ creative = MCPReactAgent(
91
+ name="Creative",
92
+ system_message=(
93
+ "You are the Creative agent specialized in generating innovative ideas "
94
+ "and creative content. You can think outside the box and provide unique "
95
+ "perspectives on problems."
96
+ )
97
+ )
98
+
99
+ # Add them to our agent dictionary
100
+ self.agents = {
101
+ "coordinator": coordinator,
102
+ "researcher": researcher,
103
+ "analyst": analyst,
104
+ "planner": planner,
105
+ "creative": creative
106
+ }
107
+
108
+ # Register custom tools for all agents
109
+ self._register_network_tools()
110
+
111
+ # Connect the agents (register each agent as a tool for others)
112
+ self._connect_agents()
113
+
114
+ # Share the workspace with all agents
115
+ self._share_workspace()
116
+
117
+ def _register_network_tools(self):
118
+ """Register network-specific tools for all agents."""
119
+ # Register tools for each agent
120
+ for agent_id, agent in self.agents.items():
121
+ # Tool to update the shared workspace
122
+ def workspace_update(section: str, key: str, value: Any, agent_id=agent_id):
123
+ """Update a section of the shared workspace."""
124
+ self.update_workspace(section, key, value, from_agent=agent_id)
125
+ return json.dumps({
126
+ "status": "success",
127
+ "message": f"Updated workspace: {section}/{key}"
128
+ })
129
+
130
+ # Tool to read from the shared workspace
131
+ def workspace_get(section: str, key: Optional[str] = None, agent_id=agent_id):
132
+ """Get data from the shared workspace."""
133
+ if section not in self.shared_workspace:
134
+ return json.dumps({
135
+ "status": "error",
136
+ "message": f"Section '{section}' not found in workspace"
137
+ })
138
+
139
+ if key is None:
140
+ return json.dumps({
141
+ "status": "success",
142
+ "data": self.shared_workspace[section]
143
+ })
144
+
145
+ if key not in self.shared_workspace[section]:
146
+ return json.dumps({
147
+ "status": "error",
148
+ "message": f"Key '{key}' not found in section '{section}'"
149
+ })
150
+
151
+ return json.dumps({
152
+ "status": "success",
153
+ "data": self.shared_workspace[section][key]
154
+ })
155
+
156
+ # Tool to send a message to the network
157
+ def send_message(message: str, agent_id=agent_id):
158
+ """Send a message to all agents in the network."""
159
+ self.add_message(agent_id, message)
160
+ return json.dumps({
161
+ "status": "success",
162
+ "message": "Message sent to the network"
163
+ })
164
+
165
+ # Tool to list all agents in the network
166
+ def list_agents(agent_id=agent_id):
167
+ """List all agents in the network."""
168
+ agents_list = [
169
+ {"id": aid, "name": a.name}
170
+ for aid, a in self.agents.items()
171
+ ]
172
+ return json.dumps({
173
+ "status": "success",
174
+ "agents": agents_list
175
+ })
176
+
177
+ # Register the tools with the agent
178
+ agent.register_custom_tool(
179
+ "workspace_update",
180
+ "Update a section of the shared workspace",
181
+ workspace_update
182
+ )
183
+
184
+ agent.register_custom_tool(
185
+ "workspace_get",
186
+ "Get data from the shared workspace",
187
+ workspace_get
188
+ )
189
+
190
+ agent.register_custom_tool(
191
+ "send_message",
192
+ "Send a message to all agents in the network",
193
+ send_message
194
+ )
195
+
196
+ agent.register_custom_tool(
197
+ "list_agents",
198
+ "List all agents in the network",
199
+ list_agents
200
+ )
201
+
202
+ def _connect_agents(self):
203
+ """Register each agent as a tool for the other agents."""
204
+ for agent_id, agent in self.agents.items():
205
+ # For each agent, create tools to call other agents
206
+ for target_id, target_agent in self.agents.items():
207
+ if agent_id == target_id:
208
+ continue # Skip self-registration
209
+
210
+ # Create a function to call the target agent
211
+ def call_agent(message: str, target_id=target_id):
212
+ """Call another agent with a message and get their response."""
213
+ # In a real implementation, this would call the agent's LLM
214
+ target_agent_name = self.agents[target_id].name
215
+
216
+ # For simulation purposes, we'll return a simple acknowledgment
217
+ return json.dumps({
218
+ "status": "success",
219
+ "message": f"Message sent to {target_agent_name}",
220
+ "request_id": str(uuid.uuid4())
221
+ })
222
+
223
+ # Register the tool
224
+ agent.register_custom_tool(
225
+ f"call_{target_id}",
226
+ f"Send a message to the {target_id} agent and get their response",
227
+ call_agent
228
+ )
229
+
230
+ def _share_workspace(self):
231
+ """Share the workspace with all agents."""
232
+ # Initialize the shared workspace with empty sections
233
+ self.shared_workspace = {
234
+ "research": {},
235
+ "analysis": {},
236
+ "planning": {},
237
+ "creative": {},
238
+ "summary": {}
239
+ }
240
+
241
+ # Update each agent's context with the network ID
242
+ for agent_id, agent in self.agents.items():
243
+ agent.update_context("network_id", self.network_id)
244
+ agent.update_context("agent_id", agent_id)
245
+ agent.update_context("agent_role", agent_id)
246
+
247
+ def update_workspace(self, section: str, key: str, value: Any, from_agent: str) -> None:
248
+ """Update a section of the workspace and share with all agents."""
249
+ if section not in self.shared_workspace:
250
+ self.shared_workspace[section] = {}
251
+
252
+ self.shared_workspace[section][key] = value
253
+
254
+ # Add a message to the history
255
+ self.add_message(
256
+ from_agent,
257
+ f"Updated workspace: {section}/{key} with new information"
258
+ )
259
+
260
+ def add_message(self, from_agent: str, message: str) -> None:
261
+ """Add a message to the network communication log."""
262
+ agent_name = self.agents[from_agent].name
263
+ self.message_history.append({
264
+ "from": agent_name,
265
+ "agent_id": from_agent,
266
+ "message": message,
267
+ "timestamp": "now" # In a real implementation, use actual timestamps
268
+ })
269
+
270
+ def set_topic(self, topic: str) -> None:
271
+ """Set a topic for discussion in the network."""
272
+ # Update the workspace with the new topic
273
+ self.update_workspace("summary", "current_topic", topic, "coordinator")
274
+
275
+ # Update all agents' context with the topic
276
+ for agent_id, agent in self.agents.items():
277
+ agent.update_context("current_topic", topic)
278
+
279
+ def interact_with_agent(self, agent_id: str) -> None:
280
+ """Allow the user to interact with a specific agent."""
281
+ if agent_id not in self.agents:
282
+ print(f"Agent '{agent_id}' not found in the network.")
283
+ return
284
+
285
+ agent = self.agents[agent_id]
286
+ agent_name = agent.name
287
+
288
+ print(f"\n=== Interacting with {agent_name} Agent ===")
289
+
290
+ # Create a graph with just this agent
291
+ agent_node = agent.create_agent(self.llm)
292
+
293
+ # Create a simple graph with just this agent
294
+ graph = create_mcp_langgraph(
295
+ self.llm,
296
+ name=f"{agent_name}Graph",
297
+ system_message=agent.get_context("system_message")
298
+ )
299
+
300
+ # Start the interaction loop
301
+ print(f"You are now chatting with the {agent_name} Agent. Type 'exit' to end.")
302
+
303
+ conversation_history = []
304
+
305
+ while True:
306
+ # Get user input
307
+ user_input = input(f"\nYou to {agent_name}: ")
308
+
309
+ if user_input.lower() == "exit":
310
+ print(f"Ending conversation with {agent_name}.")
311
+ break
312
+
313
+ # Add to conversation history
314
+ conversation_history.append(HumanMessage(content=user_input))
315
+
316
+ # Create a state with the messages
317
+ state = {"messages": conversation_history}
318
+
319
+ # Run the graph
320
+ result = graph.invoke(state)
321
+
322
+ # Get the AI response
323
+ messages = result.get("messages", [])
324
+ last_ai_message = next((msg for msg in reversed(messages) if isinstance(msg, AIMessage)), None)
325
+
326
+ if last_ai_message:
327
+ print(f"{agent_name}: {last_ai_message.content}")
328
+ conversation_history.append(last_ai_message)
329
+ else:
330
+ print(f"{agent_name}: I'm not sure how to respond to that.")
331
+
332
+ def list_agents(self) -> None:
333
+ """List all agents in the network with their specialties."""
334
+ print("\n=== Agents in the Network ===")
335
+ for agent_id, agent in self.agents.items():
336
+ agent_name = agent.name
337
+ print(f"- {agent_name} ({agent_id})")
338
+
339
+ def show_workspace(self) -> None:
340
+ """Show the current state of the shared workspace."""
341
+ print("\n=== Shared Workspace ===")
342
+ for section, data in self.shared_workspace.items():
343
+ print(f"\n{section.upper()}:")
344
+ if not data:
345
+ print(" No data yet")
346
+ else:
347
+ for key, value in data.items():
348
+ if isinstance(value, dict) or isinstance(value, list):
349
+ print(f" {key}: {json.dumps(value)[:100]}...")
350
+ else:
351
+ print(f" {key}: {value}")
352
+
353
+ def show_messages(self) -> None:
354
+ """Show the network message history."""
355
+ print("\n=== Network Messages ===")
356
+ if not self.message_history:
357
+ print("No messages yet")
358
+ else:
359
+ for msg in self.message_history[-10:]: # Show last 10 messages
360
+ print(f"{msg['from']}: {msg['message']}")
361
+
362
+
363
+ def main():
364
+ """Run the agent network example."""
365
+ print("=== LangGraph Agent Network Example ===")
366
+ print("This example demonstrates a network of specialized agents built with LangGraph.")
367
+ print("The agents can communicate with each other and share context using the MCP protocol.")
368
+
369
+ # Create the agent network
370
+ network = LangGraphAgentNetwork()
371
+
372
+ # Main interaction loop
373
+ while True:
374
+ print("\n=== Agent Network Menu ===")
375
+ print("1. List all agents")
376
+ print("2. Chat with an agent")
377
+ print("3. Set discussion topic")
378
+ print("4. Show workspace")
379
+ print("5. Show recent messages")
380
+ print("6. Exit")
381
+
382
+ choice = input("\nEnter your choice (1-6): ")
383
+
384
+ if choice == "1":
385
+ network.list_agents()
386
+
387
+ elif choice == "2":
388
+ network.list_agents()
389
+ agent_id = input("\nEnter agent ID to chat with: ")
390
+ if agent_id in network.agents:
391
+ network.interact_with_agent(agent_id)
392
+ else:
393
+ print(f"Agent '{agent_id}' not found.")
394
+
395
+ elif choice == "3":
396
+ topic = input("Enter a topic for discussion: ")
397
+ network.set_topic(topic)
398
+ print(f"Topic set to: {topic}")
399
+
400
+ elif choice == "4":
401
+ network.show_workspace()
402
+
403
+ elif choice == "5":
404
+ network.show_messages()
405
+
406
+ elif choice == "6":
407
+ print("Exiting agent network example.")
408
+ break
409
+
410
+ else:
411
+ print("Invalid choice. Please enter a number from 1 to 6.")
412
+
413
+
414
+ if __name__ == "__main__":
415
+ main()