robot_lab 0.0.1 → 0.0.6

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 (187) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/deploy-github-pages.yml +9 -9
  3. data/.irbrc +6 -0
  4. data/CHANGELOG.md +140 -0
  5. data/README.md +263 -48
  6. data/Rakefile +71 -1
  7. data/docs/api/core/index.md +53 -46
  8. data/docs/api/core/memory.md +200 -154
  9. data/docs/api/core/network.md +13 -3
  10. data/docs/api/core/robot.md +490 -130
  11. data/docs/api/core/state.md +55 -73
  12. data/docs/api/core/tool.md +205 -209
  13. data/docs/api/index.md +7 -28
  14. data/docs/api/mcp/client.md +119 -48
  15. data/docs/api/mcp/index.md +75 -60
  16. data/docs/api/mcp/server.md +120 -136
  17. data/docs/api/mcp/transports.md +172 -184
  18. data/docs/api/messages/index.md +35 -20
  19. data/docs/api/messages/text-message.md +67 -21
  20. data/docs/api/messages/tool-call-message.md +80 -41
  21. data/docs/api/messages/tool-result-message.md +119 -50
  22. data/docs/api/messages/user-message.md +48 -24
  23. data/docs/api/streaming/context.md +157 -74
  24. data/docs/api/streaming/events.md +114 -166
  25. data/docs/api/streaming/index.md +74 -72
  26. data/docs/architecture/core-concepts.md +360 -116
  27. data/docs/architecture/index.md +97 -59
  28. data/docs/architecture/message-flow.md +138 -129
  29. data/docs/architecture/network-orchestration.md +197 -50
  30. data/docs/architecture/robot-execution.md +199 -146
  31. data/docs/architecture/state-management.md +255 -187
  32. data/docs/concepts.md +311 -49
  33. data/docs/examples/basic-chat.md +89 -77
  34. data/docs/examples/index.md +222 -47
  35. data/docs/examples/mcp-server.md +207 -203
  36. data/docs/examples/multi-robot-network.md +129 -35
  37. data/docs/examples/rails-application.md +159 -160
  38. data/docs/examples/tool-usage.md +295 -204
  39. data/docs/getting-started/configuration.md +347 -154
  40. data/docs/getting-started/index.md +1 -1
  41. data/docs/getting-started/installation.md +22 -13
  42. data/docs/getting-started/quick-start.md +166 -121
  43. data/docs/guides/building-robots.md +418 -212
  44. data/docs/guides/creating-networks.md +143 -24
  45. data/docs/guides/index.md +0 -5
  46. data/docs/guides/mcp-integration.md +152 -113
  47. data/docs/guides/memory.md +220 -164
  48. data/docs/guides/rails-integration.md +244 -162
  49. data/docs/guides/streaming.md +137 -187
  50. data/docs/guides/using-tools.md +259 -212
  51. data/docs/index.md +46 -41
  52. data/examples/01_simple_robot.rb +6 -9
  53. data/examples/02_tools.rb +6 -9
  54. data/examples/03_network.rb +19 -17
  55. data/examples/04_mcp.rb +5 -8
  56. data/examples/05_streaming.rb +5 -8
  57. data/examples/06_prompt_templates.rb +42 -37
  58. data/examples/07_network_memory.rb +13 -14
  59. data/examples/08_llm_config.rb +169 -0
  60. data/examples/09_chaining.rb +262 -0
  61. data/examples/10_memory.rb +331 -0
  62. data/examples/11_network_introspection.rb +253 -0
  63. data/examples/12_message_bus.rb +74 -0
  64. data/examples/13_spawn.rb +90 -0
  65. data/examples/14_rusty_circuit/comic.rb +143 -0
  66. data/examples/14_rusty_circuit/display.rb +203 -0
  67. data/examples/14_rusty_circuit/heckler.rb +63 -0
  68. data/examples/14_rusty_circuit/open_mic.rb +123 -0
  69. data/examples/14_rusty_circuit/prompts/open_mic_comic.md +20 -0
  70. data/examples/14_rusty_circuit/prompts/open_mic_heckler.md +23 -0
  71. data/examples/14_rusty_circuit/prompts/open_mic_scout.md +20 -0
  72. data/examples/14_rusty_circuit/scout.rb +156 -0
  73. data/examples/14_rusty_circuit/scout_notes.md +89 -0
  74. data/examples/14_rusty_circuit/show.log +234 -0
  75. data/examples/15_memory_network_and_bus/editor_in_chief.rb +24 -0
  76. data/examples/15_memory_network_and_bus/editorial_pipeline.rb +206 -0
  77. data/examples/15_memory_network_and_bus/linux_writer.rb +80 -0
  78. data/examples/15_memory_network_and_bus/os_editor.rb +46 -0
  79. data/examples/15_memory_network_and_bus/os_writer.rb +46 -0
  80. data/examples/15_memory_network_and_bus/output/combined_article.md +13 -0
  81. data/examples/15_memory_network_and_bus/output/final_article.md +15 -0
  82. data/examples/15_memory_network_and_bus/output/linux_draft.md +5 -0
  83. data/examples/15_memory_network_and_bus/output/mac_draft.md +7 -0
  84. data/examples/15_memory_network_and_bus/output/memory.json +13 -0
  85. data/examples/15_memory_network_and_bus/output/revision_1.md +19 -0
  86. data/examples/15_memory_network_and_bus/output/revision_2.md +15 -0
  87. data/examples/15_memory_network_and_bus/output/windows_draft.md +7 -0
  88. data/examples/15_memory_network_and_bus/prompts/os_advocate.md +13 -0
  89. data/examples/15_memory_network_and_bus/prompts/os_chief.md +13 -0
  90. data/examples/15_memory_network_and_bus/prompts/os_editor.md +13 -0
  91. data/examples/16_writers_room/display.rb +158 -0
  92. data/examples/16_writers_room/output/.gitignore +2 -0
  93. data/examples/16_writers_room/output/opus_001.md +263 -0
  94. data/examples/16_writers_room/output/opus_001_notes.log +470 -0
  95. data/examples/16_writers_room/prompts/writer.md +37 -0
  96. data/examples/16_writers_room/room.rb +150 -0
  97. data/examples/16_writers_room/tools.rb +162 -0
  98. data/examples/16_writers_room/writer.rb +121 -0
  99. data/examples/16_writers_room/writers_room.rb +162 -0
  100. data/examples/README.md +197 -0
  101. data/examples/prompts/{assistant/system.txt.erb → assistant.md} +3 -0
  102. data/examples/prompts/{billing/system.txt.erb → billing.md} +3 -0
  103. data/examples/prompts/{classifier/system.txt.erb → classifier.md} +3 -0
  104. data/examples/prompts/comedian.md +6 -0
  105. data/examples/prompts/comedy_critic.md +10 -0
  106. data/examples/prompts/configurable.md +9 -0
  107. data/examples/prompts/dispatcher.md +12 -0
  108. data/examples/prompts/{entity_extractor/system.txt.erb → entity_extractor.md} +3 -0
  109. data/examples/prompts/{escalation/system.txt.erb → escalation.md} +7 -0
  110. data/examples/prompts/frontmatter_mcp_test.md +9 -0
  111. data/examples/prompts/frontmatter_named_test.md +5 -0
  112. data/examples/prompts/frontmatter_tools_test.md +6 -0
  113. data/examples/prompts/{general/system.txt.erb → general.md} +3 -0
  114. data/examples/prompts/{github_assistant/system.txt.erb → github_assistant.md} +8 -0
  115. data/examples/prompts/{helper/system.txt.erb → helper.md} +3 -0
  116. data/examples/prompts/{keyword_extractor/system.txt.erb → keyword_extractor.md} +3 -0
  117. data/examples/prompts/llm_config_demo.md +20 -0
  118. data/examples/prompts/{order_support/system.txt.erb → order_support.md} +8 -0
  119. data/examples/prompts/os_advocate.md +13 -0
  120. data/examples/prompts/os_chief.md +13 -0
  121. data/examples/prompts/os_editor.md +13 -0
  122. data/examples/prompts/{product_support/system.txt.erb → product_support.md} +7 -0
  123. data/examples/prompts/{sentiment_analyzer/system.txt.erb → sentiment_analyzer.md} +3 -0
  124. data/examples/prompts/{synthesizer/system.txt.erb → synthesizer.md} +3 -0
  125. data/examples/prompts/{technical/system.txt.erb → technical.md} +3 -0
  126. data/examples/prompts/{triage/system.txt.erb → triage.md} +6 -0
  127. data/lib/generators/robot_lab/templates/initializer.rb.tt +0 -13
  128. data/lib/robot_lab/ask_user.rb +75 -0
  129. data/lib/robot_lab/config/defaults.yml +121 -0
  130. data/lib/robot_lab/config.rb +183 -0
  131. data/lib/robot_lab/error.rb +6 -0
  132. data/lib/robot_lab/mcp/client.rb +1 -1
  133. data/lib/robot_lab/memory.rb +10 -34
  134. data/lib/robot_lab/network.rb +13 -20
  135. data/lib/robot_lab/robot/bus_messaging.rb +239 -0
  136. data/lib/robot_lab/robot/mcp_management.rb +88 -0
  137. data/lib/robot_lab/robot/template_rendering.rb +130 -0
  138. data/lib/robot_lab/robot.rb +240 -330
  139. data/lib/robot_lab/robot_message.rb +44 -0
  140. data/lib/robot_lab/robot_result.rb +1 -0
  141. data/lib/robot_lab/run_config.rb +184 -0
  142. data/lib/robot_lab/state_proxy.rb +2 -12
  143. data/lib/robot_lab/streaming/context.rb +1 -1
  144. data/lib/robot_lab/task.rb +8 -1
  145. data/lib/robot_lab/tool.rb +108 -172
  146. data/lib/robot_lab/tool_config.rb +1 -1
  147. data/lib/robot_lab/tool_manifest.rb +2 -18
  148. data/lib/robot_lab/utils.rb +39 -0
  149. data/lib/robot_lab/version.rb +1 -1
  150. data/lib/robot_lab.rb +89 -57
  151. data/mkdocs.yml +0 -11
  152. metadata +121 -135
  153. data/docs/api/adapters/anthropic.md +0 -121
  154. data/docs/api/adapters/gemini.md +0 -133
  155. data/docs/api/adapters/index.md +0 -104
  156. data/docs/api/adapters/openai.md +0 -134
  157. data/docs/api/history/active-record-adapter.md +0 -195
  158. data/docs/api/history/config.md +0 -191
  159. data/docs/api/history/index.md +0 -132
  160. data/docs/api/history/thread-manager.md +0 -144
  161. data/docs/guides/history.md +0 -359
  162. data/examples/prompts/assistant/user.txt.erb +0 -1
  163. data/examples/prompts/billing/user.txt.erb +0 -1
  164. data/examples/prompts/classifier/user.txt.erb +0 -1
  165. data/examples/prompts/entity_extractor/user.txt.erb +0 -3
  166. data/examples/prompts/escalation/user.txt.erb +0 -34
  167. data/examples/prompts/general/user.txt.erb +0 -1
  168. data/examples/prompts/github_assistant/user.txt.erb +0 -1
  169. data/examples/prompts/helper/user.txt.erb +0 -1
  170. data/examples/prompts/keyword_extractor/user.txt.erb +0 -3
  171. data/examples/prompts/order_support/user.txt.erb +0 -22
  172. data/examples/prompts/product_support/user.txt.erb +0 -32
  173. data/examples/prompts/sentiment_analyzer/user.txt.erb +0 -3
  174. data/examples/prompts/synthesizer/user.txt.erb +0 -15
  175. data/examples/prompts/technical/user.txt.erb +0 -1
  176. data/examples/prompts/triage/user.txt.erb +0 -17
  177. data/lib/robot_lab/adapters/anthropic.rb +0 -163
  178. data/lib/robot_lab/adapters/base.rb +0 -85
  179. data/lib/robot_lab/adapters/gemini.rb +0 -193
  180. data/lib/robot_lab/adapters/openai.rb +0 -159
  181. data/lib/robot_lab/adapters/registry.rb +0 -81
  182. data/lib/robot_lab/configuration.rb +0 -143
  183. data/lib/robot_lab/errors.rb +0 -70
  184. data/lib/robot_lab/history/active_record_adapter.rb +0 -146
  185. data/lib/robot_lab/history/config.rb +0 -115
  186. data/lib/robot_lab/history/thread_manager.rb +0 -93
  187. data/lib/robot_lab/robotic_model.rb +0 -324
@@ -1,49 +1,53 @@
1
1
  # MCP Client
2
2
 
3
- Connects to MCP servers and discovers tools.
3
+ Connects to MCP servers, discovers tools, and invokes them via the Model Context Protocol.
4
4
 
5
5
  ## Class: `RobotLab::MCP::Client`
6
6
 
7
7
  ```ruby
8
8
  client = RobotLab::MCP::Client.new(
9
9
  name: "filesystem",
10
- transport: { type: "stdio", command: "mcp-server-filesystem" }
10
+ transport: { type: "stdio", command: "mcp-server-filesystem", args: ["--root", "/data"] }
11
11
  )
12
12
 
13
13
  client.connect
14
14
  tools = client.list_tools
15
+ result = client.call_tool("readFile", { path: "/data/readme.txt" })
16
+ client.disconnect
15
17
  ```
16
18
 
17
19
  ## Constructor
18
20
 
19
21
  ```ruby
20
- Client.new(name:, transport:)
22
+ Client.new(server_or_config)
21
23
  ```
22
24
 
25
+ Accepts either a `Server` instance or a Hash configuration. When a Hash is provided, it is used to construct a `Server` internally.
26
+
23
27
  **Parameters:**
24
28
 
25
29
  | Name | Type | Description |
26
30
  |------|------|-------------|
27
- | `name` | `String` | Server identifier |
28
- | `transport` | `Hash` | Transport configuration |
31
+ | `server_or_config` | `Server`, `Hash` | Server instance or configuration hash |
29
32
 
30
- ## Attributes
33
+ **Hash Configuration Keys:**
31
34
 
32
- ### name
35
+ | Key | Type | Required | Description |
36
+ |-----|------|----------|-------------|
37
+ | `name` | `String` | Yes | Server identifier |
38
+ | `transport` | `Hash` | Yes | Transport configuration (must include `type`) |
33
39
 
34
- ```ruby
35
- client.name # => String
36
- ```
40
+ **Raises:** `ArgumentError` if the config is neither a `Server` nor a `Hash`.
37
41
 
38
- Server identifier.
42
+ ## Attributes
39
43
 
40
- ### transport
44
+ ### server
41
45
 
42
46
  ```ruby
43
- client.transport # => Transport
47
+ client.server # => RobotLab::MCP::Server
44
48
  ```
45
49
 
46
- The underlying transport connection.
50
+ The MCP server configuration object.
47
51
 
48
52
  ### connected?
49
53
 
@@ -51,38 +55,42 @@ The underlying transport connection.
51
55
  client.connected? # => Boolean
52
56
  ```
53
57
 
54
- Whether the client is connected.
58
+ Whether the client is currently connected to the server.
55
59
 
56
60
  ## Methods
57
61
 
58
62
  ### connect
59
63
 
60
64
  ```ruby
61
- client.connect
65
+ client.connect # => self
62
66
  ```
63
67
 
64
- Establish connection to the MCP server.
68
+ Establish a connection to the MCP server. Creates the appropriate transport based on the server's transport type, then connects. If already connected, returns immediately.
69
+
70
+ Connection failures are logged as warnings and the client remains in a disconnected state (does not raise).
65
71
 
66
72
  ### disconnect
67
73
 
68
74
  ```ruby
69
- client.disconnect
75
+ client.disconnect # => self
70
76
  ```
71
77
 
72
- Close the connection.
78
+ Close the connection to the MCP server. Closes the underlying transport and resets connection state. If not connected, returns immediately.
73
79
 
74
80
  ### list_tools
75
81
 
76
82
  ```ruby
77
- client.list_tools # => Array<Tool>
83
+ client.list_tools # => Array<Hash>
78
84
  ```
79
85
 
80
- Discover available tools from the server.
86
+ Discover available tools from the server. Returns an array of tool definition hashes.
87
+
88
+ **Raises:** `MCPError` if not connected.
81
89
 
82
90
  ### call_tool
83
91
 
84
92
  ```ruby
85
- result = client.call_tool(name, params)
93
+ result = client.call_tool(name, arguments = {})
86
94
  ```
87
95
 
88
96
  Execute a tool on the server.
@@ -92,30 +100,81 @@ Execute a tool on the server.
92
100
  | Name | Type | Description |
93
101
  |------|------|-------------|
94
102
  | `name` | `String` | Tool name |
95
- | `params` | `Hash` | Tool parameters |
103
+ | `arguments` | `Hash` | Tool arguments (default: `{}`) |
104
+
105
+ **Returns:** Tool result content (from the `content` field of the response).
106
+
107
+ **Raises:** `MCPError` if not connected.
96
108
 
97
109
  ### list_resources
98
110
 
99
111
  ```ruby
100
- client.list_resources # => Array<Resource>
112
+ client.list_resources # => Array<Hash>
101
113
  ```
102
114
 
103
- List available resources (if supported).
115
+ List available resources from the server.
116
+
117
+ **Raises:** `MCPError` if not connected.
104
118
 
105
119
  ### read_resource
106
120
 
107
121
  ```ruby
108
- client.read_resource(uri) # => Resource
122
+ client.read_resource(uri) # => Object
109
123
  ```
110
124
 
111
125
  Read a resource by URI.
112
126
 
127
+ **Parameters:**
128
+
129
+ | Name | Type | Description |
130
+ |------|------|-------------|
131
+ | `uri` | `String` | Resource URI |
132
+
133
+ **Raises:** `MCPError` if not connected.
134
+
135
+ ### list_prompts
136
+
137
+ ```ruby
138
+ client.list_prompts # => Array<Hash>
139
+ ```
140
+
141
+ List available prompts from the server.
142
+
143
+ **Raises:** `MCPError` if not connected.
144
+
145
+ ### get_prompt
146
+
147
+ ```ruby
148
+ client.get_prompt(name, arguments = {}) # => Hash
149
+ ```
150
+
151
+ Get a prompt by name with optional arguments.
152
+
153
+ **Parameters:**
154
+
155
+ | Name | Type | Description |
156
+ |------|------|-------------|
157
+ | `name` | `String` | Prompt name |
158
+ | `arguments` | `Hash` | Prompt arguments (default: `{}`) |
159
+
160
+ **Raises:** `MCPError` if not connected.
161
+
162
+ ### to_h
163
+
164
+ ```ruby
165
+ client.to_h # => Hash
166
+ ```
167
+
168
+ Converts the client to a hash representation containing server config and connection status.
169
+
113
170
  ## Transport Configuration
114
171
 
172
+ The transport type is determined by the `type` key in the transport hash of the `Server` configuration.
173
+
115
174
  ### Stdio
116
175
 
117
176
  ```ruby
118
- client = Client.new(
177
+ client = RobotLab::MCP::Client.new(
119
178
  name: "local",
120
179
  transport: {
121
180
  type: "stdio",
@@ -128,10 +187,10 @@ client = Client.new(
128
187
  ### WebSocket
129
188
 
130
189
  ```ruby
131
- client = Client.new(
190
+ client = RobotLab::MCP::Client.new(
132
191
  name: "remote",
133
192
  transport: {
134
- type: "websocket",
193
+ type: "ws",
135
194
  url: "wss://mcp.example.com/ws"
136
195
  }
137
196
  )
@@ -140,7 +199,7 @@ client = Client.new(
140
199
  ### SSE
141
200
 
142
201
  ```ruby
143
- client = Client.new(
202
+ client = RobotLab::MCP::Client.new(
144
203
  name: "streaming",
145
204
  transport: {
146
205
  type: "sse",
@@ -149,14 +208,15 @@ client = Client.new(
149
208
  )
150
209
  ```
151
210
 
152
- ### HTTP
211
+ ### Streamable HTTP
153
212
 
154
213
  ```ruby
155
- client = Client.new(
214
+ client = RobotLab::MCP::Client.new(
156
215
  name: "http",
157
216
  transport: {
158
- type: "http",
159
- url: "https://mcp.example.com/mcp"
217
+ type: "streamable-http",
218
+ url: "https://mcp.example.com/mcp",
219
+ session_id: "optional-session-id"
160
220
  }
161
221
  )
162
222
  ```
@@ -166,7 +226,7 @@ client = Client.new(
166
226
  ### Basic Usage
167
227
 
168
228
  ```ruby
169
- client = Client.new(
229
+ client = RobotLab::MCP::Client.new(
170
230
  name: "github",
171
231
  transport: { type: "stdio", command: "mcp-server-github" }
172
232
  )
@@ -175,7 +235,7 @@ client.connect
175
235
 
176
236
  # List available tools
177
237
  tools = client.list_tools
178
- tools.each { |t| puts "#{t.name}: #{t.description}" }
238
+ tools.each { |t| puts "#{t[:name]}: #{t[:description]}" }
179
239
 
180
240
  # Call a tool
181
241
  result = client.call_tool("search_repositories", { query: "ruby mcp" })
@@ -184,19 +244,32 @@ puts result
184
244
  client.disconnect
185
245
  ```
186
246
 
187
- ### In Robot
247
+ ### From a Server Object
188
248
 
189
249
  ```ruby
190
- robot = RobotLab.build do
191
- name "assistant"
250
+ server = RobotLab::MCP::Server.new(
251
+ name: "neon",
252
+ transport: { type: "ws", url: "ws://localhost:8080" }
253
+ )
192
254
 
193
- mcp [
255
+ client = RobotLab::MCP::Client.new(server)
256
+ client.connect
257
+ ```
258
+
259
+ ### In a Robot
260
+
261
+ ```ruby
262
+ robot = Robot.new(
263
+ name: "assistant",
264
+ system_prompt: "You help with file operations.",
265
+ mcp: [
194
266
  { name: "fs", transport: { type: "stdio", command: "mcp-fs" } }
195
267
  ]
196
- end
268
+ )
197
269
 
198
- # MCP tools are automatically available
199
- robot.tools.each { |t| puts t.name }
270
+ # MCP tools are automatically discovered and available to the LLM
271
+ result = robot.run("Read the contents of /data/config.yml")
272
+ puts result.last_text_content
200
273
  ```
201
274
 
202
275
  ### Error Handling
@@ -205,10 +278,8 @@ robot.tools.each { |t| puts t.name }
205
278
  begin
206
279
  client.connect
207
280
  result = client.call_tool("unknown_tool", {})
208
- rescue RobotLab::MCP::ConnectionError => e
209
- puts "Failed to connect: #{e.message}"
210
- rescue RobotLab::MCP::ToolError => e
211
- puts "Tool error: #{e.message}"
281
+ rescue RobotLab::MCPError => e
282
+ puts "MCP error: #{e.message}"
212
283
  ensure
213
284
  client.disconnect
214
285
  end
@@ -217,5 +288,5 @@ end
217
288
  ## See Also
218
289
 
219
290
  - [MCP Overview](index.md)
291
+ - [Server Configuration](server.md)
220
292
  - [Transports](transports.md)
221
- - [MCP Server](server.md)
@@ -4,108 +4,123 @@ Integration with MCP servers for extended tool capabilities.
4
4
 
5
5
  ## Overview
6
6
 
7
- MCP allows robots to connect to external tool servers, extending their capabilities without modifying robot code.
7
+ MCP allows robots to connect to external tool servers, extending their capabilities without modifying robot code. RobotLab provides an MCP client that communicates with MCP-compliant servers over multiple transport types.
8
8
 
9
9
  ```ruby
10
- robot = RobotLab.build do
11
- name "developer"
12
- template "You help with coding tasks."
13
-
14
- mcp [
10
+ robot = Robot.new(
11
+ name: "developer",
12
+ system_prompt: "You help with coding tasks.",
13
+ mcp: [
15
14
  {
16
15
  name: "filesystem",
17
16
  transport: { type: "stdio", command: "npx @modelcontextprotocol/server-filesystem" }
18
17
  }
19
18
  ]
20
- end
19
+ )
21
20
  ```
22
21
 
23
22
  ## Components
24
23
 
25
24
  | Component | Description |
26
25
  |-----------|-------------|
27
- | [Client](client.md) | Connects to MCP servers |
28
- | [Server](server.md) | Exposes tools via MCP |
29
- | [Transports](transports.md) | Communication methods |
26
+ | [Client](client.md) | Connects to MCP servers, lists tools, calls tools |
27
+ | [Server](server.md) | Server configuration data structure |
28
+ | [Transports](transports.md) | Communication methods (stdio, WebSocket, SSE, HTTP) |
30
29
 
31
30
  ## Quick Start
32
31
 
33
- ### Using MCP Tools
32
+ ### Using MCP with a Robot
34
33
 
35
- ```ruby
36
- network = RobotLab.create_network do
37
- name "with_mcp"
34
+ Pass MCP server configurations via the `mcp:` parameter when creating a robot:
38
35
 
39
- mcp [
36
+ ```ruby
37
+ robot = Robot.new(
38
+ name: "assistant",
39
+ template: :assistant,
40
+ mcp: [
40
41
  { name: "github", transport: { type: "stdio", command: "mcp-server-github" } }
41
42
  ]
43
+ )
42
44
 
43
- add_robot RobotLab.build {
44
- name "assistant"
45
- template "You help with GitHub tasks."
46
- mcp :inherit # Use network's MCP servers
47
- }
48
- end
45
+ result = robot.run("List my open pull requests")
46
+ result.last_text_content
49
47
  ```
50
48
 
51
- ### Creating an MCP Server
49
+ ### MCP in Networks
50
+
51
+ Robots in a network can inherit MCP servers from the network or define their own:
52
52
 
53
53
  ```ruby
54
- server = RobotLab::MCP::Server.new(name: "my_tools")
54
+ network_mcp = [
55
+ { name: "github", transport: { type: "stdio", command: "mcp-server-github" } }
56
+ ]
57
+
58
+ robot = Robot.new(
59
+ name: "assistant",
60
+ template: :assistant,
61
+ mcp: :inherit # Use network's MCP servers
62
+ )
63
+ ```
64
+
65
+ ### Direct Client Usage
55
66
 
56
- server.add_tool(
57
- name: "get_user",
58
- description: "Get user by ID",
59
- parameters: { id: { type: "string", required: true } },
60
- handler: ->(id:) { User.find(id).to_h }
67
+ ```ruby
68
+ client = RobotLab::MCP::Client.new(
69
+ name: "filesystem",
70
+ transport: { type: "stdio", command: "mcp-server-filesystem", args: ["--root", "/data"] }
61
71
  )
62
72
 
63
- server.start(transport: :stdio)
73
+ client.connect
74
+ tools = client.list_tools
75
+ result = client.call_tool("readFile", { path: "/data/config.yml" })
76
+ client.disconnect
64
77
  ```
65
78
 
66
79
  ## Transport Types
67
80
 
68
- | Type | Use Case |
69
- |------|----------|
70
- | `stdio` | Local command execution |
71
- | `websocket` | Real-time bidirectional |
72
- | `sse` | Server-sent events |
73
- | `http` | HTTP request/response |
81
+ | Type | Config Key | Use Case |
82
+ |------|------------|----------|
83
+ | `stdio` | `"stdio"` | Local command/subprocess execution |
84
+ | `websocket` | `"ws"` or `"websocket"` | Real-time bidirectional communication |
85
+ | `sse` | `"sse"` | Server-sent events streaming |
86
+ | `streamable-http` | `"streamable-http"` or `"http"` | HTTP request/response with session support |
74
87
 
75
- ## Configuration Levels
88
+ ## MCP Parameter Values
76
89
 
77
- ### Network Level
90
+ The `mcp:` parameter on a Robot accepts three types of values:
78
91
 
79
- ```ruby
80
- network = RobotLab.create_network do
81
- mcp [
82
- { name: "server1", transport: { type: "stdio", command: "..." } }
83
- ]
84
- end
85
- ```
92
+ | Value | Meaning |
93
+ |-------|---------|
94
+ | `:none` | No MCP servers (explicitly disabled) |
95
+ | `:inherit` | Use the network's MCP servers |
96
+ | `Array<Hash>` | Explicit list of server configurations |
86
97
 
87
- ### Robot Level
98
+ Each server configuration hash requires:
88
99
 
89
- ```ruby
90
- robot = RobotLab.build do
91
- mcp :inherit # Use network's servers
92
- # or
93
- mcp :none # No MCP servers
94
- # or
95
- mcp [...] # Specific servers
96
- end
97
- ```
100
+ | Key | Type | Description |
101
+ |-----|------|-------------|
102
+ | `name` | `String` | Unique server identifier |
103
+ | `transport` | `Hash` | Transport configuration (must include `type`) |
104
+
105
+ ## Error Handling
106
+
107
+ MCP operations raise `RobotLab::MCPError` when:
98
108
 
99
- ### Tool Filtering
109
+ - Connection to a server fails
110
+ - A request is made without an active connection
111
+ - An unsupported transport type is specified
100
112
 
101
113
  ```ruby
102
- robot = RobotLab.build do
103
- mcp :inherit
104
- tools %w[read_file write_file] # Only allow these tools
114
+ begin
115
+ client.connect
116
+ client.call_tool("unknown_tool", {})
117
+ rescue RobotLab::MCPError => e
118
+ puts "MCP error: #{e.message}"
105
119
  end
106
120
  ```
107
121
 
108
122
  ## See Also
109
123
 
110
- - [MCP Integration Guide](../../guides/mcp-integration.md)
111
- - [Tool](../core/tool.md)
124
+ - [MCP Client](client.md)
125
+ - [MCP Server](server.md)
126
+ - [Transports](transports.md)