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.
- checksums.yaml +4 -4
- data/.github/workflows/deploy-github-pages.yml +9 -9
- data/.irbrc +6 -0
- data/CHANGELOG.md +140 -0
- data/README.md +263 -48
- data/Rakefile +71 -1
- data/docs/api/core/index.md +53 -46
- data/docs/api/core/memory.md +200 -154
- data/docs/api/core/network.md +13 -3
- data/docs/api/core/robot.md +490 -130
- data/docs/api/core/state.md +55 -73
- data/docs/api/core/tool.md +205 -209
- data/docs/api/index.md +7 -28
- data/docs/api/mcp/client.md +119 -48
- data/docs/api/mcp/index.md +75 -60
- data/docs/api/mcp/server.md +120 -136
- data/docs/api/mcp/transports.md +172 -184
- data/docs/api/messages/index.md +35 -20
- data/docs/api/messages/text-message.md +67 -21
- data/docs/api/messages/tool-call-message.md +80 -41
- data/docs/api/messages/tool-result-message.md +119 -50
- data/docs/api/messages/user-message.md +48 -24
- data/docs/api/streaming/context.md +157 -74
- data/docs/api/streaming/events.md +114 -166
- data/docs/api/streaming/index.md +74 -72
- data/docs/architecture/core-concepts.md +360 -116
- data/docs/architecture/index.md +97 -59
- data/docs/architecture/message-flow.md +138 -129
- data/docs/architecture/network-orchestration.md +197 -50
- data/docs/architecture/robot-execution.md +199 -146
- data/docs/architecture/state-management.md +255 -187
- data/docs/concepts.md +311 -49
- data/docs/examples/basic-chat.md +89 -77
- data/docs/examples/index.md +222 -47
- data/docs/examples/mcp-server.md +207 -203
- data/docs/examples/multi-robot-network.md +129 -35
- data/docs/examples/rails-application.md +159 -160
- data/docs/examples/tool-usage.md +295 -204
- data/docs/getting-started/configuration.md +347 -154
- data/docs/getting-started/index.md +1 -1
- data/docs/getting-started/installation.md +22 -13
- data/docs/getting-started/quick-start.md +166 -121
- data/docs/guides/building-robots.md +418 -212
- data/docs/guides/creating-networks.md +143 -24
- data/docs/guides/index.md +0 -5
- data/docs/guides/mcp-integration.md +152 -113
- data/docs/guides/memory.md +220 -164
- data/docs/guides/rails-integration.md +244 -162
- data/docs/guides/streaming.md +137 -187
- data/docs/guides/using-tools.md +259 -212
- data/docs/index.md +46 -41
- data/examples/01_simple_robot.rb +6 -9
- data/examples/02_tools.rb +6 -9
- data/examples/03_network.rb +19 -17
- data/examples/04_mcp.rb +5 -8
- data/examples/05_streaming.rb +5 -8
- data/examples/06_prompt_templates.rb +42 -37
- data/examples/07_network_memory.rb +13 -14
- data/examples/08_llm_config.rb +169 -0
- data/examples/09_chaining.rb +262 -0
- data/examples/10_memory.rb +331 -0
- data/examples/11_network_introspection.rb +253 -0
- data/examples/12_message_bus.rb +74 -0
- data/examples/13_spawn.rb +90 -0
- data/examples/14_rusty_circuit/comic.rb +143 -0
- data/examples/14_rusty_circuit/display.rb +203 -0
- data/examples/14_rusty_circuit/heckler.rb +63 -0
- data/examples/14_rusty_circuit/open_mic.rb +123 -0
- data/examples/14_rusty_circuit/prompts/open_mic_comic.md +20 -0
- data/examples/14_rusty_circuit/prompts/open_mic_heckler.md +23 -0
- data/examples/14_rusty_circuit/prompts/open_mic_scout.md +20 -0
- data/examples/14_rusty_circuit/scout.rb +156 -0
- data/examples/14_rusty_circuit/scout_notes.md +89 -0
- data/examples/14_rusty_circuit/show.log +234 -0
- data/examples/15_memory_network_and_bus/editor_in_chief.rb +24 -0
- data/examples/15_memory_network_and_bus/editorial_pipeline.rb +206 -0
- data/examples/15_memory_network_and_bus/linux_writer.rb +80 -0
- data/examples/15_memory_network_and_bus/os_editor.rb +46 -0
- data/examples/15_memory_network_and_bus/os_writer.rb +46 -0
- data/examples/15_memory_network_and_bus/output/combined_article.md +13 -0
- data/examples/15_memory_network_and_bus/output/final_article.md +15 -0
- data/examples/15_memory_network_and_bus/output/linux_draft.md +5 -0
- data/examples/15_memory_network_and_bus/output/mac_draft.md +7 -0
- data/examples/15_memory_network_and_bus/output/memory.json +13 -0
- data/examples/15_memory_network_and_bus/output/revision_1.md +19 -0
- data/examples/15_memory_network_and_bus/output/revision_2.md +15 -0
- data/examples/15_memory_network_and_bus/output/windows_draft.md +7 -0
- data/examples/15_memory_network_and_bus/prompts/os_advocate.md +13 -0
- data/examples/15_memory_network_and_bus/prompts/os_chief.md +13 -0
- data/examples/15_memory_network_and_bus/prompts/os_editor.md +13 -0
- data/examples/16_writers_room/display.rb +158 -0
- data/examples/16_writers_room/output/.gitignore +2 -0
- data/examples/16_writers_room/output/opus_001.md +263 -0
- data/examples/16_writers_room/output/opus_001_notes.log +470 -0
- data/examples/16_writers_room/prompts/writer.md +37 -0
- data/examples/16_writers_room/room.rb +150 -0
- data/examples/16_writers_room/tools.rb +162 -0
- data/examples/16_writers_room/writer.rb +121 -0
- data/examples/16_writers_room/writers_room.rb +162 -0
- data/examples/README.md +197 -0
- data/examples/prompts/{assistant/system.txt.erb → assistant.md} +3 -0
- data/examples/prompts/{billing/system.txt.erb → billing.md} +3 -0
- data/examples/prompts/{classifier/system.txt.erb → classifier.md} +3 -0
- data/examples/prompts/comedian.md +6 -0
- data/examples/prompts/comedy_critic.md +10 -0
- data/examples/prompts/configurable.md +9 -0
- data/examples/prompts/dispatcher.md +12 -0
- data/examples/prompts/{entity_extractor/system.txt.erb → entity_extractor.md} +3 -0
- data/examples/prompts/{escalation/system.txt.erb → escalation.md} +7 -0
- data/examples/prompts/frontmatter_mcp_test.md +9 -0
- data/examples/prompts/frontmatter_named_test.md +5 -0
- data/examples/prompts/frontmatter_tools_test.md +6 -0
- data/examples/prompts/{general/system.txt.erb → general.md} +3 -0
- data/examples/prompts/{github_assistant/system.txt.erb → github_assistant.md} +8 -0
- data/examples/prompts/{helper/system.txt.erb → helper.md} +3 -0
- data/examples/prompts/{keyword_extractor/system.txt.erb → keyword_extractor.md} +3 -0
- data/examples/prompts/llm_config_demo.md +20 -0
- data/examples/prompts/{order_support/system.txt.erb → order_support.md} +8 -0
- data/examples/prompts/os_advocate.md +13 -0
- data/examples/prompts/os_chief.md +13 -0
- data/examples/prompts/os_editor.md +13 -0
- data/examples/prompts/{product_support/system.txt.erb → product_support.md} +7 -0
- data/examples/prompts/{sentiment_analyzer/system.txt.erb → sentiment_analyzer.md} +3 -0
- data/examples/prompts/{synthesizer/system.txt.erb → synthesizer.md} +3 -0
- data/examples/prompts/{technical/system.txt.erb → technical.md} +3 -0
- data/examples/prompts/{triage/system.txt.erb → triage.md} +6 -0
- data/lib/generators/robot_lab/templates/initializer.rb.tt +0 -13
- data/lib/robot_lab/ask_user.rb +75 -0
- data/lib/robot_lab/config/defaults.yml +121 -0
- data/lib/robot_lab/config.rb +183 -0
- data/lib/robot_lab/error.rb +6 -0
- data/lib/robot_lab/mcp/client.rb +1 -1
- data/lib/robot_lab/memory.rb +10 -34
- data/lib/robot_lab/network.rb +13 -20
- data/lib/robot_lab/robot/bus_messaging.rb +239 -0
- data/lib/robot_lab/robot/mcp_management.rb +88 -0
- data/lib/robot_lab/robot/template_rendering.rb +130 -0
- data/lib/robot_lab/robot.rb +240 -330
- data/lib/robot_lab/robot_message.rb +44 -0
- data/lib/robot_lab/robot_result.rb +1 -0
- data/lib/robot_lab/run_config.rb +184 -0
- data/lib/robot_lab/state_proxy.rb +2 -12
- data/lib/robot_lab/streaming/context.rb +1 -1
- data/lib/robot_lab/task.rb +8 -1
- data/lib/robot_lab/tool.rb +108 -172
- data/lib/robot_lab/tool_config.rb +1 -1
- data/lib/robot_lab/tool_manifest.rb +2 -18
- data/lib/robot_lab/utils.rb +39 -0
- data/lib/robot_lab/version.rb +1 -1
- data/lib/robot_lab.rb +89 -57
- data/mkdocs.yml +0 -11
- metadata +121 -135
- data/docs/api/adapters/anthropic.md +0 -121
- data/docs/api/adapters/gemini.md +0 -133
- data/docs/api/adapters/index.md +0 -104
- data/docs/api/adapters/openai.md +0 -134
- data/docs/api/history/active-record-adapter.md +0 -195
- data/docs/api/history/config.md +0 -191
- data/docs/api/history/index.md +0 -132
- data/docs/api/history/thread-manager.md +0 -144
- data/docs/guides/history.md +0 -359
- data/examples/prompts/assistant/user.txt.erb +0 -1
- data/examples/prompts/billing/user.txt.erb +0 -1
- data/examples/prompts/classifier/user.txt.erb +0 -1
- data/examples/prompts/entity_extractor/user.txt.erb +0 -3
- data/examples/prompts/escalation/user.txt.erb +0 -34
- data/examples/prompts/general/user.txt.erb +0 -1
- data/examples/prompts/github_assistant/user.txt.erb +0 -1
- data/examples/prompts/helper/user.txt.erb +0 -1
- data/examples/prompts/keyword_extractor/user.txt.erb +0 -3
- data/examples/prompts/order_support/user.txt.erb +0 -22
- data/examples/prompts/product_support/user.txt.erb +0 -32
- data/examples/prompts/sentiment_analyzer/user.txt.erb +0 -3
- data/examples/prompts/synthesizer/user.txt.erb +0 -15
- data/examples/prompts/technical/user.txt.erb +0 -1
- data/examples/prompts/triage/user.txt.erb +0 -17
- data/lib/robot_lab/adapters/anthropic.rb +0 -163
- data/lib/robot_lab/adapters/base.rb +0 -85
- data/lib/robot_lab/adapters/gemini.rb +0 -193
- data/lib/robot_lab/adapters/openai.rb +0 -159
- data/lib/robot_lab/adapters/registry.rb +0 -81
- data/lib/robot_lab/configuration.rb +0 -143
- data/lib/robot_lab/errors.rb +0 -70
- data/lib/robot_lab/history/active_record_adapter.rb +0 -146
- data/lib/robot_lab/history/config.rb +0 -115
- data/lib/robot_lab/history/thread_manager.rb +0 -93
- data/lib/robot_lab/robotic_model.rb +0 -324
data/docs/api/mcp/client.md
CHANGED
|
@@ -1,49 +1,53 @@
|
|
|
1
1
|
# MCP Client
|
|
2
2
|
|
|
3
|
-
Connects to MCP servers and
|
|
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(
|
|
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
|
-
| `
|
|
28
|
-
| `transport` | `Hash` | Transport configuration |
|
|
31
|
+
| `server_or_config` | `Server`, `Hash` | Server instance or configuration hash |
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
**Hash Configuration Keys:**
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
| Key | Type | Required | Description |
|
|
36
|
+
|-----|------|----------|-------------|
|
|
37
|
+
| `name` | `String` | Yes | Server identifier |
|
|
38
|
+
| `transport` | `Hash` | Yes | Transport configuration (must include `type`) |
|
|
33
39
|
|
|
34
|
-
|
|
35
|
-
client.name # => String
|
|
36
|
-
```
|
|
40
|
+
**Raises:** `ArgumentError` if the config is neither a `Server` nor a `Hash`.
|
|
37
41
|
|
|
38
|
-
|
|
42
|
+
## Attributes
|
|
39
43
|
|
|
40
|
-
###
|
|
44
|
+
### server
|
|
41
45
|
|
|
42
46
|
```ruby
|
|
43
|
-
client.
|
|
47
|
+
client.server # => RobotLab::MCP::Server
|
|
44
48
|
```
|
|
45
49
|
|
|
46
|
-
The
|
|
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<
|
|
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,
|
|
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
|
-
| `
|
|
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<
|
|
112
|
+
client.list_resources # => Array<Hash>
|
|
101
113
|
```
|
|
102
114
|
|
|
103
|
-
List available resources
|
|
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) # =>
|
|
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: "
|
|
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
|
|
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
|
-
###
|
|
247
|
+
### From a Server Object
|
|
188
248
|
|
|
189
249
|
```ruby
|
|
190
|
-
|
|
191
|
-
name "
|
|
250
|
+
server = RobotLab::MCP::Server.new(
|
|
251
|
+
name: "neon",
|
|
252
|
+
transport: { type: "ws", url: "ws://localhost:8080" }
|
|
253
|
+
)
|
|
192
254
|
|
|
193
|
-
|
|
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
|
-
|
|
268
|
+
)
|
|
197
269
|
|
|
198
|
-
# MCP tools are automatically available
|
|
199
|
-
robot.
|
|
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::
|
|
209
|
-
puts "
|
|
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)
|
data/docs/api/mcp/index.md
CHANGED
|
@@ -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 =
|
|
11
|
-
name "developer"
|
|
12
|
-
|
|
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
|
-
|
|
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) |
|
|
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
|
|
32
|
+
### Using MCP with a Robot
|
|
34
33
|
|
|
35
|
-
|
|
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
|
-
|
|
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
|
-
|
|
44
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
88
|
+
## MCP Parameter Values
|
|
76
89
|
|
|
77
|
-
|
|
90
|
+
The `mcp:` parameter on a Robot accepts three types of values:
|
|
78
91
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
98
|
+
Each server configuration hash requires:
|
|
88
99
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
|
111
|
-
- [
|
|
124
|
+
- [MCP Client](client.md)
|
|
125
|
+
- [MCP Server](server.md)
|
|
126
|
+
- [Transports](transports.md)
|