rakam-systems-agent 0.1.1rc7__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.
@@ -0,0 +1,375 @@
1
+ # Agent MCP Server
2
+
3
+ This module provides an MCP (Model Context Protocol) server for AI agent components, enabling flexible registration and communication between agent tools and utilities through a standardized message-based interface.
4
+
5
+ ## Overview
6
+
7
+ The Agent MCP Server creates a message-based component registry that allows AI agents to dynamically register, discover, and invoke tools. This provides:
8
+
9
+ - **Flexible component registration**: Add any BaseComponent implementation
10
+ - **Unified communication**: All components communicate through the same interface
11
+ - **Dynamic tool discovery**: Agents can query available tools at runtime
12
+ - **Async support**: Efficient concurrent operations
13
+ - **Decoupled architecture**: Tools don't need to know about each other
14
+
15
+ ## Usage
16
+
17
+ ### Basic Setup
18
+
19
+ ```python
20
+ from rakam_system_agent.server import run_agent_mcp
21
+ from rakam_systems_core.ai_core.base import BaseComponent
22
+
23
+ # Create some components
24
+ class SearchTool(BaseComponent):
25
+ def run(self, query: str, max_results: int = 10):
26
+ # Your search implementation
27
+ return f"Found {max_results} results for: {query}"
28
+
29
+ class CalculatorTool(BaseComponent):
30
+ def run(self, operation: str, a: float, b: float):
31
+ if operation == "add":
32
+ return a + b
33
+ elif operation == "multiply":
34
+ return a * b
35
+ return None
36
+
37
+ # Initialize components
38
+ search = SearchTool(name="search")
39
+ calculator = CalculatorTool(name="calculator")
40
+
41
+ # Create MCP server with components
42
+ mcp_server = run_agent_mcp([search, calculator])
43
+
44
+ # List available components
45
+ print(mcp_server.list_components())
46
+ # Output: ['calculator', 'search']
47
+ ```
48
+
49
+ ### Using with Synchronous Messages
50
+
51
+ ```python
52
+ # Invoke search tool
53
+ result = mcp_server.send_message(
54
+ sender="agent",
55
+ receiver="search",
56
+ message={
57
+ 'arguments': {
58
+ 'query': 'machine learning',
59
+ 'max_results': 5
60
+ }
61
+ }
62
+ )
63
+ print(result)
64
+ # Output: "Found 5 results for: machine learning"
65
+
66
+ # Invoke calculator tool
67
+ result = mcp_server.send_message(
68
+ sender="agent",
69
+ receiver="calculator",
70
+ message={
71
+ 'arguments': {
72
+ 'operation': 'add',
73
+ 'a': 10,
74
+ 'b': 5
75
+ }
76
+ }
77
+ )
78
+ print(result) # Output: 15
79
+ ```
80
+
81
+ ### Using with Async Messages
82
+
83
+ ```python
84
+ import asyncio
85
+
86
+ async def main():
87
+ # Async tool invocation
88
+ result = await mcp_server.asend_message(
89
+ sender="agent",
90
+ receiver="search",
91
+ message={
92
+ 'arguments': {
93
+ 'query': 'deep learning',
94
+ 'max_results': 3
95
+ }
96
+ }
97
+ )
98
+ print(result)
99
+
100
+ asyncio.run(main())
101
+ ```
102
+
103
+ ### Concurrent Operations
104
+
105
+ ```python
106
+ import asyncio
107
+
108
+ async def concurrent_operations():
109
+ # Execute multiple tool invocations concurrently
110
+ results = await asyncio.gather(
111
+ mcp_server.asend_message(
112
+ sender="agent",
113
+ receiver="search",
114
+ message={'arguments': {'query': 'AI', 'max_results': 5}}
115
+ ),
116
+ mcp_server.asend_message(
117
+ sender="agent",
118
+ receiver="calculator",
119
+ message={'arguments': {'operation': 'multiply', 'a': 7, 'b': 6}}
120
+ ),
121
+ mcp_server.asend_message(
122
+ sender="agent",
123
+ receiver="calculator",
124
+ message={'arguments': {'operation': 'add', 'a': 100, 'b': 200}}
125
+ )
126
+ )
127
+ return results
128
+
129
+ results = asyncio.run(concurrent_operations())
130
+ print(results)
131
+ # Output: ["Found 5 results for: AI", 42, 300]
132
+ ```
133
+
134
+ ### Integration with Tool Registry
135
+
136
+ ```python
137
+ from rakam_systems_core.ai_core.interfaces import ToolRegistry, ToolInvoker
138
+
139
+ # Create registry and invoker
140
+ registry = ToolRegistry()
141
+ invoker = ToolInvoker(registry)
142
+
143
+ # Register MCP server
144
+ invoker.register_mcp_server("agent_mcp", mcp_server)
145
+
146
+ # Register tools
147
+ registry.register_mcp_tool(
148
+ name="web_search",
149
+ mcp_server="agent_mcp",
150
+ mcp_tool_name="search",
151
+ description="Search the web for information",
152
+ category="search"
153
+ )
154
+
155
+ registry.register_mcp_tool(
156
+ name="calculate",
157
+ mcp_server="agent_mcp",
158
+ mcp_tool_name="calculator",
159
+ description="Perform mathematical calculations",
160
+ category="math"
161
+ )
162
+
163
+ # Use through invoker
164
+ result = await invoker.ainvoke("web_search", query="Python", max_results=10)
165
+ result = await invoker.ainvoke("calculate", operation="add", a=5, b=3)
166
+ ```
167
+
168
+ ### Custom Component with Message Handler
169
+
170
+ ```python
171
+ from rakam_systems_core.ai_core.base import BaseComponent
172
+ from typing import Dict, Any
173
+
174
+ class CustomTool(BaseComponent):
175
+ """Component with custom message handling."""
176
+
177
+ def handle_message(self, sender: str, message: Dict[str, Any]):
178
+ """Custom message handler for advanced logic."""
179
+ action = message.get('action', 'default')
180
+ args = message.get('arguments', {})
181
+
182
+ if action == 'process':
183
+ return self.process(**args)
184
+ elif action == 'analyze':
185
+ return self.analyze(**args)
186
+ else:
187
+ return self.run(**args)
188
+
189
+ def run(self, data: str):
190
+ return f"Default processing: {data}"
191
+
192
+ def process(self, data: str, method: str = "standard"):
193
+ return f"Processing {data} with {method} method"
194
+
195
+ def analyze(self, data: str):
196
+ return f"Analyzing: {data}"
197
+
198
+ # Register and use
199
+ custom = CustomTool(name="custom_tool")
200
+ mcp_server = run_agent_mcp([custom])
201
+
202
+ # Different actions
203
+ result1 = mcp_server.send_message(
204
+ sender="agent",
205
+ receiver="custom_tool",
206
+ message={'action': 'process', 'arguments': {'data': 'test', 'method': 'advanced'}}
207
+ )
208
+
209
+ result2 = mcp_server.send_message(
210
+ sender="agent",
211
+ receiver="custom_tool",
212
+ message={'action': 'analyze', 'arguments': {'data': 'test'}}
213
+ )
214
+ ```
215
+
216
+ ## Function Reference
217
+
218
+ ### run_agent_mcp()
219
+
220
+ Creates and configures an MCP server with agent components.
221
+
222
+ ```python
223
+ def run_agent_mcp(
224
+ components: Iterable[BaseComponent],
225
+ name: str = "agent_mcp",
226
+ enable_logging: bool = False
227
+ ) -> MCPServer
228
+ ```
229
+
230
+ **Parameters:**
231
+
232
+ - `components` (Iterable[BaseComponent]): Components to register with the server
233
+ - `name` (str, optional): Name for the MCP server (default: "agent_mcp")
234
+ - `enable_logging` (bool, optional): Enable detailed MCP logging (default: False)
235
+
236
+ **Returns:**
237
+
238
+ - `MCPServer`: Configured MCP server instance with registered components
239
+
240
+ **Example:**
241
+
242
+ ```python
243
+ from rakam_system_agent.server import run_agent_mcp
244
+
245
+ tools = [tool1, tool2, tool3]
246
+ server = run_agent_mcp(tools, name="my_agent_server", enable_logging=True)
247
+ ```
248
+
249
+ ## Component Requirements
250
+
251
+ Components registered with the agent MCP server must:
252
+
253
+ 1. **Inherit from BaseComponent**
254
+
255
+ ```python
256
+ from rakam_systems_core.ai_core.base import BaseComponent
257
+
258
+ class MyTool(BaseComponent):
259
+ pass
260
+ ```
261
+
262
+ 2. **Have a unique name**
263
+
264
+ ```python
265
+ tool = MyTool(name="unique_tool_name")
266
+ ```
267
+
268
+ 3. **Implement either:**
269
+ - `run(*args, **kwargs)` method for standard invocation
270
+ - `handle_message(sender, message)` method for custom message handling
271
+
272
+ 4. **Support async (optional)**
273
+ ```python
274
+ class AsyncTool(BaseComponent):
275
+ async def run(self, data: str):
276
+ # Async operation
277
+ await asyncio.sleep(1)
278
+ return f"Processed: {data}"
279
+ ```
280
+
281
+ ## Architecture
282
+
283
+ ```
284
+ ┌─────────────────────────────────────────┐
285
+ │ AI Agent / Client │
286
+ └──────────────┬──────────────────────────┘
287
+
288
+ │ send_message / asend_message
289
+
290
+ ┌─────────────────────────────────────────┐
291
+ │ MCPServer │
292
+ │ (Message Router & Component Registry) │
293
+ └──────────────┬──────────────────────────┘
294
+
295
+ ┌─────────┼─────────┬─────────┐
296
+ ▼ ▼ ▼ ▼
297
+ ┌─────────┐ ┌──────┐ ┌──────┐ ┌──────┐
298
+ │ Search │ │Calc │ │ DB │ │ ... │
299
+ │ Tool │ │Tool │ │Tool │ │ │
300
+ └─────────┘ └──────┘ └──────┘ └──────┘
301
+ (BaseComponent implementations)
302
+ ```
303
+
304
+ ## Benefits
305
+
306
+ 1. **Decoupled Architecture**: Components don't need direct dependencies
307
+ 2. **Standardized Interface**: All tools work the same way through MCP
308
+ 3. **Dynamic Registration**: Add/remove tools at runtime
309
+ 4. **Tool Discovery**: Query available tools dynamically
310
+ 5. **Async Support**: Efficient concurrent operations
311
+ 6. **Flexible Integration**: Works with various agent architectures
312
+ 7. **Easy Testing**: Mock individual components easily
313
+
314
+ ## Advanced Usage
315
+
316
+ ### Adding Components at Runtime
317
+
318
+ ```python
319
+ # Create server with initial components
320
+ server = run_agent_mcp([tool1, tool2])
321
+
322
+ # Add more components later
323
+ new_tool = NewTool(name="new_tool")
324
+ server.register_component(new_tool)
325
+
326
+ # Verify registration
327
+ assert server.has_component("new_tool")
328
+ ```
329
+
330
+ ### Removing Components
331
+
332
+ ```python
333
+ # Remove a component
334
+ server.unregister_component("old_tool")
335
+
336
+ # Check if removed
337
+ assert not server.has_component("old_tool")
338
+ ```
339
+
340
+ ### Server Statistics
341
+
342
+ ```python
343
+ # Get server stats
344
+ stats = server.get_stats()
345
+ print(f"Server: {stats['name']}")
346
+ print(f"Components: {stats['component_count']}")
347
+ print(f"Available: {stats['components']}")
348
+ ```
349
+
350
+ ## Examples
351
+
352
+ See comprehensive examples in:
353
+
354
+ - `/app/rakam_systems/rakam_systems/examples/ai_agents_examples/` - Agent examples
355
+ - `/docs/MCP_QUICKSTART.md` - Quick start guide
356
+ - `/docs/MCP_ARCHITECTURE_DIAGRAM.md` - Architecture overview
357
+
358
+ ## Related Documentation
359
+
360
+ - [MCP Server API](/app/rakam_systems/rakam_systems/ai_core/mcp/README.md)
361
+ - [MCP Quickstart](/docs/MCP_QUICKSTART.md)
362
+ - [Vector Store MCP Server](/app/rakam_systems/rakam_systems/ai_vectorstore/server/README.md)
363
+ - [BaseComponent API](/app/rakam_systems/rakam_systems/ai_core/base.py)
364
+
365
+ ## Comparison with Vector Store MCP Server
366
+
367
+ | Feature | Agent MCP | Vector Store MCP |
368
+ | ------------------ | --------------------------- | --------------------------------- |
369
+ | **Purpose** | General agent components | Vector store operations |
370
+ | **Components** | User-provided | Pre-built (search, storage, info) |
371
+ | **Registration** | Dynamic, flexible | Automatic with vector store |
372
+ | **Use Case** | Custom tools, utilities | Document search, RAG systems |
373
+ | **Initialization** | `run_agent_mcp(components)` | `run_vector_mcp(vector_store)` |
374
+
375
+ Both servers use the same underlying `MCPServer` and can be used together in a single system.
@@ -0,0 +1,12 @@
1
+ """
2
+ Agent MCP Server Module
3
+
4
+ This module provides MCP (Model Context Protocol) server functionality for AI agent components.
5
+ """
6
+
7
+ from .mcp_server_agent import run_agent_mcp
8
+
9
+ __all__ = [
10
+ "run_agent_mcp",
11
+ ]
12
+
@@ -0,0 +1,127 @@
1
+ """
2
+ Agent MCP Server
3
+
4
+ This module provides an MCP (Model Context Protocol) server for AI agent components.
5
+ It creates a unified interface for registering and managing agent-related tools and
6
+ components that can communicate through a standardized message-based protocol.
7
+
8
+ Features:
9
+ - Dynamic component registration
10
+ - Message-based communication between components
11
+ - Support for any BaseComponent implementation
12
+ - Async/await support for concurrent operations
13
+ - Easy integration with AI agents and tool systems
14
+
15
+ Example:
16
+ >>> from rakam_system_agent.server.mcp_server_agent import run_agent_mcp
17
+ >>> from rakam_systems_core.ai_core.base import BaseComponent
18
+ >>>
19
+ >>> # Create some agent components
20
+ >>> class SearchTool(BaseComponent):
21
+ ... def run(self, query: str):
22
+ ... return f"Searching for: {query}"
23
+ >>>
24
+ >>> search_tool = SearchTool(name="search")
25
+ >>>
26
+ >>> # Create MCP server with components
27
+ >>> mcp_server = run_agent_mcp([search_tool])
28
+ >>>
29
+ >>> # Use the server to route messages
30
+ >>> result = mcp_server.send_message(
31
+ ... sender="agent",
32
+ ... receiver="search",
33
+ ... message={'arguments': {'query': 'test'}}
34
+ ... )
35
+ """
36
+
37
+ from __future__ import annotations
38
+ from typing import Iterable, Optional
39
+
40
+ from rakam_systems_core.ai_utils import logging
41
+
42
+ from rakam_systems_core.ai_core.mcp.mcp_server import MCPServer
43
+ from rakam_systems_core.ai_core.base import BaseComponent
44
+
45
+ logger = logging.getLogger(__name__)
46
+
47
+
48
+ def run_agent_mcp(
49
+ components: Iterable[BaseComponent],
50
+ name: str = "agent_mcp",
51
+ enable_logging: bool = False
52
+ ) -> MCPServer:
53
+ """
54
+ Create and configure an MCP server with agent components.
55
+
56
+ This function creates a fully configured MCP server and registers all provided
57
+ components, making them available for message-based communication. Components
58
+ can be tools, utilities, or any BaseComponent implementation.
59
+
60
+ Args:
61
+ components: Iterable of BaseComponent instances to register
62
+ name: Name for the MCP server (default: "agent_mcp")
63
+ enable_logging: Whether to enable detailed MCP logging (default: False)
64
+
65
+ Returns:
66
+ MCPServer instance with registered components
67
+
68
+ Example:
69
+ >>> from rakam_system_agent.server import run_agent_mcp
70
+ >>> from rakam_systems_core.ai_core.base import BaseComponent
71
+ >>>
72
+ >>> # Create components
73
+ >>> class CalculatorTool(BaseComponent):
74
+ ... def run(self, operation: str, a: float, b: float):
75
+ ... if operation == "add":
76
+ ... return a + b
77
+ ... elif operation == "multiply":
78
+ ... return a * b
79
+ >>>
80
+ >>> calculator = CalculatorTool(name="calculator")
81
+ >>>
82
+ >>> # Create MCP server
83
+ >>> mcp_server = run_agent_mcp([calculator])
84
+ >>>
85
+ >>> # List registered components
86
+ >>> print(mcp_server.list_components())
87
+ >>> # Output: ['calculator']
88
+ >>>
89
+ >>> # Use the server
90
+ >>> result = mcp_server.send_message(
91
+ ... sender="agent",
92
+ ... receiver="calculator",
93
+ ... message={'arguments': {'operation': 'add', 'a': 5, 'b': 3}}
94
+ ... )
95
+ >>> print(result) # Output: 8
96
+
97
+ Example with async:
98
+ >>> result = await mcp_server.asend_message(
99
+ ... sender="agent",
100
+ ... receiver="calculator",
101
+ ... message={'arguments': {'operation': 'multiply', 'a': 5, 'b': 3}}
102
+ ... )
103
+ >>> print(result) # Output: 15
104
+
105
+ Note:
106
+ - All components must be BaseComponent instances with a unique name
107
+ - Components should implement the run() method or handle_message() method
108
+ - The server supports both sync (send_message) and async (asend_message) operations
109
+ """
110
+ logger.info(f"Creating agent MCP server: {name}")
111
+
112
+ # Create MCP server
113
+ server = MCPServer(name=name, enable_logging=enable_logging)
114
+ server.setup()
115
+
116
+ # Register all components
117
+ component_count = 0
118
+ for component in components:
119
+ server.register_component(component)
120
+ component_count += 1
121
+
122
+ logger.info(
123
+ f"Agent MCP server '{name}' ready with {component_count} component(s): "
124
+ f"{server.list_components()}"
125
+ )
126
+
127
+ return server