robot_lab 0.0.1 → 0.0.4
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 +90 -0
- data/README.md +203 -46
- data/Rakefile +70 -1
- data/docs/api/core/index.md +12 -0
- data/docs/api/core/robot.md +478 -130
- data/docs/api/core/tool.md +205 -209
- data/docs/api/history/active-record-adapter.md +174 -94
- data/docs/api/history/config.md +186 -93
- data/docs/api/history/index.md +57 -61
- data/docs/api/history/thread-manager.md +123 -73
- 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/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 +361 -112
- 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 +312 -48
- 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 +275 -162
- 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 +417 -212
- data/docs/guides/creating-networks.md +94 -24
- data/docs/guides/mcp-integration.md +152 -113
- data/docs/guides/memory.md +220 -164
- data/docs/guides/streaming.md +80 -110
- data/docs/guides/using-tools.md +259 -212
- data/docs/index.md +50 -37
- data/examples/01_simple_robot.rb +6 -9
- data/examples/02_tools.rb +6 -9
- data/examples/03_network.rb +13 -14
- 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 +140 -0
- data/examples/09_chaining.rb +223 -0
- data/examples/10_memory.rb +331 -0
- data/examples/11_network_introspection.rb +230 -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 +57 -0
- data/examples/14_rusty_circuit/open_mic.rb +121 -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 +173 -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/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 +1 -1
- data/lib/robot_lab/adapters/openai.rb +2 -1
- 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 +2 -2
- data/lib/robot_lab/robot.rb +523 -249
- data/lib/robot_lab/robot_message.rb +44 -0
- data/lib/robot_lab/robot_result.rb +1 -0
- data/lib/robot_lab/robotic_model.rb +1 -1
- data/lib/robot_lab/streaming/context.rb +1 -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/version.rb +1 -1
- data/lib/robot_lab.rb +66 -55
- metadata +107 -116
- 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/configuration.rb +0 -143
data/docs/examples/mcp-server.md
CHANGED
|
@@ -1,238 +1,190 @@
|
|
|
1
1
|
# MCP Server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Connecting robots to Model Context Protocol servers for external tool access.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
This example demonstrates how to
|
|
7
|
+
This example demonstrates how to connect robots to external MCP servers. MCP servers expose tools that robots can discover and invoke automatically. RobotLab supports stdio, HTTP, WebSocket, and SSE transports.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Using MCP with a Robot
|
|
10
|
+
|
|
11
|
+
The primary pattern is to pass MCP server configurations via `mcp:` or `mcp_servers:` when building a robot:
|
|
10
12
|
|
|
11
13
|
```ruby
|
|
12
14
|
#!/usr/bin/env ruby
|
|
13
|
-
# examples/
|
|
15
|
+
# examples/mcp_client.rb
|
|
14
16
|
|
|
15
17
|
require "bundler/setup"
|
|
16
18
|
require "robot_lab"
|
|
17
|
-
require "json"
|
|
18
|
-
|
|
19
|
-
# Create an MCP server with database tools
|
|
20
|
-
server = RobotLab::MCP::Server.new(
|
|
21
|
-
name: "database_tools",
|
|
22
|
-
version: "1.0.0"
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
# Mock database
|
|
26
|
-
USERS = {
|
|
27
|
-
"1" => { id: "1", name: "Alice", email: "alice@example.com", plan: "pro" },
|
|
28
|
-
"2" => { id: "2", name: "Bob", email: "bob@example.com", plan: "free" }
|
|
29
|
-
}
|
|
30
19
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
20
|
+
# MCP server configuration (stdio transport)
|
|
21
|
+
github_server = {
|
|
22
|
+
name: "github",
|
|
23
|
+
transport: {
|
|
24
|
+
type: "stdio",
|
|
25
|
+
command: "github-mcp-server",
|
|
26
|
+
args: ["stdio"],
|
|
27
|
+
env: {
|
|
28
|
+
"GITHUB_PERSONAL_ACCESS_TOKEN" => ENV.fetch("GITHUB_PERSONAL_ACCESS_TOKEN", "")
|
|
29
|
+
}
|
|
30
|
+
}
|
|
35
31
|
}
|
|
36
32
|
|
|
37
|
-
#
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
33
|
+
# Create a robot with MCP server integration
|
|
34
|
+
# Tools are automatically discovered when the robot connects
|
|
35
|
+
robot = RobotLab.build(
|
|
36
|
+
name: "github_assistant",
|
|
37
|
+
system_prompt: <<~PROMPT,
|
|
38
|
+
You are a GitHub assistant with access to repository tools.
|
|
39
|
+
Help users search repos, manage issues, and explore code.
|
|
40
|
+
PROMPT
|
|
41
|
+
mcp: [github_server],
|
|
42
|
+
model: "claude-sonnet-4"
|
|
48
43
|
)
|
|
49
44
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
parameters: {
|
|
54
|
-
plan: { type: "string", enum: ["free", "pro"], description: "Filter by plan" }
|
|
55
|
-
},
|
|
56
|
-
handler: ->(plan: nil) {
|
|
57
|
-
users = USERS.values
|
|
58
|
-
users = users.select { |u| u[:plan] == plan } if plan
|
|
59
|
-
users
|
|
60
|
-
}
|
|
61
|
-
)
|
|
45
|
+
# The robot auto-discovers MCP tools on first run
|
|
46
|
+
puts "MCP Servers: #{robot.mcp_clients.keys.join(", ")}"
|
|
47
|
+
puts "MCP Tools: #{robot.mcp_tools.size} discovered"
|
|
62
48
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
parameters: {
|
|
67
|
-
user_id: { type: "string", required: true },
|
|
68
|
-
status: { type: "string", enum: ["pending", "shipped", "delivered"] }
|
|
69
|
-
},
|
|
70
|
-
handler: ->(user_id:, status: nil) {
|
|
71
|
-
orders = ORDERS.values.select { |o| o[:user_id] == user_id }
|
|
72
|
-
orders = orders.select { |o| o[:status] == status } if status
|
|
73
|
-
orders
|
|
74
|
-
}
|
|
75
|
-
)
|
|
49
|
+
# Run the robot -- it can use any discovered MCP tools
|
|
50
|
+
result = robot.run("What are the top 3 most starred Ruby web frameworks on GitHub?")
|
|
51
|
+
puts result.last_text_content
|
|
76
52
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
order = ORDERS[order_id]
|
|
86
|
-
return { error: "Order not found" } unless order
|
|
87
|
-
order[:status] = status
|
|
88
|
-
{ success: true, order: order }
|
|
89
|
-
}
|
|
90
|
-
)
|
|
53
|
+
# Show tool calls if any were made
|
|
54
|
+
if result.tool_calls.any?
|
|
55
|
+
puts "\nTool calls made:"
|
|
56
|
+
result.tool_calls.each do |tc|
|
|
57
|
+
tool_info = tc.respond_to?(:tool) ? tc.tool : tc
|
|
58
|
+
puts " #{tool_info[:name] || tool_info}"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
91
61
|
|
|
92
|
-
#
|
|
93
|
-
|
|
94
|
-
server.start(transport: :stdio)
|
|
62
|
+
# Always disconnect MCP clients when done
|
|
63
|
+
robot.disconnect
|
|
95
64
|
```
|
|
96
65
|
|
|
97
|
-
##
|
|
66
|
+
## Direct MCP Client Usage
|
|
98
67
|
|
|
99
|
-
|
|
100
|
-
#!/usr/bin/env ruby
|
|
101
|
-
# examples/mcp_client.rb
|
|
68
|
+
You can also use the MCP client directly without a robot:
|
|
102
69
|
|
|
103
|
-
|
|
70
|
+
```ruby
|
|
104
71
|
require "robot_lab"
|
|
105
72
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
73
|
+
# Create and connect MCP client
|
|
74
|
+
github_server = {
|
|
75
|
+
name: "github",
|
|
76
|
+
transport: {
|
|
77
|
+
type: "stdio",
|
|
78
|
+
command: "github-mcp-server",
|
|
79
|
+
args: ["stdio"],
|
|
80
|
+
env: { "GITHUB_PERSONAL_ACCESS_TOKEN" => ENV["GITHUB_PERSONAL_ACCESS_TOKEN"] }
|
|
81
|
+
}
|
|
82
|
+
}
|
|
114
83
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
Help users look up information and manage orders.
|
|
118
|
-
PROMPT
|
|
84
|
+
client = RobotLab::MCP::Client.new(github_server)
|
|
85
|
+
client.connect
|
|
119
86
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
args: ["examples/mcp_server.rb"]
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
]
|
|
130
|
-
end
|
|
87
|
+
if client.connected?
|
|
88
|
+
# List available tools
|
|
89
|
+
tools = client.list_tools
|
|
90
|
+
tools.each do |tool|
|
|
91
|
+
puts "#{tool[:name]}: #{tool[:description]}"
|
|
92
|
+
end
|
|
131
93
|
|
|
132
|
-
#
|
|
133
|
-
|
|
134
|
-
|
|
94
|
+
# Call a tool directly
|
|
95
|
+
result = client.call_tool("search_repositories", {
|
|
96
|
+
query: "language:ruby stars:>1000",
|
|
97
|
+
per_page: 5
|
|
98
|
+
})
|
|
135
99
|
|
|
136
|
-
|
|
100
|
+
puts JSON.pretty_generate(result)
|
|
137
101
|
|
|
138
|
-
|
|
139
|
-
case event.type
|
|
140
|
-
when :text_delta
|
|
141
|
-
print event.text
|
|
142
|
-
when :tool_call
|
|
143
|
-
puts "\n[MCP: #{event.name}]"
|
|
144
|
-
end
|
|
102
|
+
client.disconnect
|
|
145
103
|
end
|
|
146
|
-
|
|
147
|
-
puts
|
|
148
|
-
admin_bot.disconnect
|
|
149
104
|
```
|
|
150
105
|
|
|
151
|
-
##
|
|
106
|
+
## Multiple MCP Servers
|
|
107
|
+
|
|
108
|
+
A robot can connect to multiple MCP servers simultaneously:
|
|
152
109
|
|
|
153
110
|
```ruby
|
|
154
|
-
|
|
111
|
+
filesystem_server = {
|
|
112
|
+
name: "filesystem",
|
|
113
|
+
transport: {
|
|
114
|
+
type: "stdio",
|
|
115
|
+
command: "npx",
|
|
116
|
+
args: ["@modelcontextprotocol/server-filesystem", "/data"]
|
|
117
|
+
}
|
|
118
|
+
}
|
|
155
119
|
|
|
156
|
-
|
|
157
|
-
name "
|
|
120
|
+
github_server = {
|
|
121
|
+
name: "github",
|
|
122
|
+
transport: {
|
|
123
|
+
type: "stdio",
|
|
124
|
+
command: "github-mcp-server",
|
|
125
|
+
args: ["stdio"],
|
|
126
|
+
env: { "GITHUB_PERSONAL_ACCESS_TOKEN" => ENV["GITHUB_PERSONAL_ACCESS_TOKEN"] }
|
|
127
|
+
}
|
|
128
|
+
}
|
|
158
129
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
{
|
|
166
|
-
name: "filesystem",
|
|
167
|
-
transport: {
|
|
168
|
-
type: "stdio",
|
|
169
|
-
command: "npx",
|
|
170
|
-
args: ["@modelcontextprotocol/server-filesystem", "/data"]
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
]
|
|
130
|
+
robot = RobotLab.build(
|
|
131
|
+
name: "developer",
|
|
132
|
+
system_prompt: "You help with coding tasks using GitHub and the filesystem.",
|
|
133
|
+
mcp: [filesystem_server, github_server],
|
|
134
|
+
model: "claude-sonnet-4"
|
|
135
|
+
)
|
|
174
136
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
template "You analyze user data."
|
|
178
|
-
mcp :inherit # Uses network's MCP servers
|
|
179
|
-
}
|
|
137
|
+
result = robot.run("Search for Ruby repos with CI configs and list their workflow files")
|
|
138
|
+
puts result.last_text_content
|
|
180
139
|
|
|
181
|
-
|
|
182
|
-
name "file_manager"
|
|
183
|
-
template "You manage files."
|
|
184
|
-
mcp :inherit
|
|
185
|
-
tools %w[read_file list_directory] # Only these MCP tools
|
|
186
|
-
}
|
|
187
|
-
end
|
|
140
|
+
robot.disconnect
|
|
188
141
|
```
|
|
189
142
|
|
|
190
|
-
##
|
|
191
|
-
|
|
192
|
-
```ruby
|
|
193
|
-
#!/usr/bin/env ruby
|
|
194
|
-
# examples/http_mcp_server.rb
|
|
143
|
+
## MCP in Networks
|
|
195
144
|
|
|
196
|
-
|
|
197
|
-
require "sinatra"
|
|
145
|
+
Networks pass MCP configuration through the hierarchical resolution system. Use `mcp: :inherit` on robots to use the network-level MCP config, or specify per-task MCP servers:
|
|
198
146
|
|
|
199
|
-
|
|
147
|
+
```ruby
|
|
148
|
+
# Create robots
|
|
149
|
+
data_analyst = RobotLab.build(
|
|
150
|
+
name: "data_analyst",
|
|
151
|
+
system_prompt: "You analyze data.",
|
|
152
|
+
mcp: :inherit # Will use whatever MCP config is resolved at runtime
|
|
153
|
+
)
|
|
200
154
|
|
|
201
|
-
|
|
202
|
-
name: "
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
{
|
|
207
|
-
uptime: `uptime`.strip,
|
|
208
|
-
memory: `free -m 2>/dev/null || vm_stat`.strip,
|
|
209
|
-
time: Time.now.iso8601
|
|
210
|
-
}
|
|
211
|
-
}
|
|
155
|
+
file_manager = RobotLab.build(
|
|
156
|
+
name: "file_manager",
|
|
157
|
+
system_prompt: "You manage files.",
|
|
158
|
+
mcp: :inherit,
|
|
159
|
+
tools: :none # Only use inherited MCP tools, no local tools
|
|
212
160
|
)
|
|
213
161
|
|
|
214
|
-
#
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
162
|
+
# Create network with per-task MCP configuration
|
|
163
|
+
network = RobotLab.create_network(name: "support_with_mcp") do
|
|
164
|
+
task :analyst, data_analyst,
|
|
165
|
+
mcp: [github_server],
|
|
166
|
+
depends_on: :none
|
|
167
|
+
|
|
168
|
+
task :files, file_manager,
|
|
169
|
+
mcp: [filesystem_server],
|
|
170
|
+
tools: %w[read_file list_directory], # Whitelist only these MCP tools
|
|
171
|
+
depends_on: :optional
|
|
220
172
|
end
|
|
221
173
|
|
|
222
|
-
|
|
223
|
-
# Connect with HTTP transport
|
|
174
|
+
result = network.run(message: "Analyze the project structure")
|
|
224
175
|
```
|
|
225
176
|
|
|
226
|
-
##
|
|
177
|
+
## HTTP Transport
|
|
227
178
|
|
|
228
|
-
|
|
229
|
-
robot = RobotLab.build do
|
|
230
|
-
name "remote_assistant"
|
|
231
|
-
template "You have access to remote tools."
|
|
179
|
+
Connect to remote MCP servers over HTTP:
|
|
232
180
|
|
|
233
|
-
|
|
181
|
+
```ruby
|
|
182
|
+
robot = RobotLab.build(
|
|
183
|
+
name: "remote_assistant",
|
|
184
|
+
system_prompt: "You have access to remote tools.",
|
|
185
|
+
mcp: [
|
|
234
186
|
{
|
|
235
|
-
name: "
|
|
187
|
+
name: "remote_api",
|
|
236
188
|
transport: {
|
|
237
189
|
type: "http",
|
|
238
190
|
url: "https://mcp.example.com/mcp",
|
|
@@ -240,48 +192,100 @@ robot = RobotLab.build do
|
|
|
240
192
|
}
|
|
241
193
|
}
|
|
242
194
|
]
|
|
243
|
-
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
result = robot.run("Use the remote tools to check system status")
|
|
198
|
+
robot.disconnect
|
|
244
199
|
```
|
|
245
200
|
|
|
246
|
-
## WebSocket
|
|
201
|
+
## WebSocket Transport
|
|
202
|
+
|
|
203
|
+
For real-time bidirectional communication:
|
|
247
204
|
|
|
248
205
|
```ruby
|
|
249
|
-
|
|
250
|
-
|
|
206
|
+
robot = RobotLab.build(
|
|
207
|
+
name: "realtime_assistant",
|
|
208
|
+
system_prompt: "You monitor real-time events.",
|
|
209
|
+
mcp: [
|
|
210
|
+
{
|
|
211
|
+
name: "realtime",
|
|
212
|
+
transport: {
|
|
213
|
+
type: "websocket",
|
|
214
|
+
url: "ws://localhost:8765"
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
)
|
|
251
219
|
|
|
252
|
-
|
|
220
|
+
result = robot.run("Subscribe to the events channel")
|
|
221
|
+
robot.disconnect
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## SSE Transport
|
|
225
|
+
|
|
226
|
+
Server-Sent Events transport for streaming responses:
|
|
227
|
+
|
|
228
|
+
```ruby
|
|
229
|
+
robot = RobotLab.build(
|
|
230
|
+
name: "sse_assistant",
|
|
231
|
+
system_prompt: "You have access to streaming tools.",
|
|
232
|
+
mcp: [
|
|
233
|
+
{
|
|
234
|
+
name: "streaming_api",
|
|
235
|
+
transport: {
|
|
236
|
+
type: "sse",
|
|
237
|
+
url: "https://api.example.com/sse"
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
result = robot.run("Stream the latest metrics")
|
|
244
|
+
robot.disconnect
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Runtime MCP Overrides
|
|
253
248
|
|
|
254
|
-
|
|
249
|
+
Override MCP configuration at runtime via `robot.run`:
|
|
255
250
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
251
|
+
```ruby
|
|
252
|
+
robot = RobotLab.build(
|
|
253
|
+
name: "flexible_bot",
|
|
254
|
+
system_prompt: "You use available tools.",
|
|
255
|
+
mcp: [github_server]
|
|
261
256
|
)
|
|
262
257
|
|
|
263
|
-
#
|
|
264
|
-
|
|
258
|
+
# Use default MCP config
|
|
259
|
+
result = robot.run("Search for Ruby repos")
|
|
260
|
+
|
|
261
|
+
# Override MCP at runtime -- disable all MCP
|
|
262
|
+
result = robot.run("Just answer from your knowledge", mcp: :none)
|
|
263
|
+
|
|
264
|
+
robot.disconnect
|
|
265
265
|
```
|
|
266
266
|
|
|
267
267
|
## Running
|
|
268
268
|
|
|
269
269
|
```bash
|
|
270
|
-
#
|
|
271
|
-
ruby examples/mcp_server.rb
|
|
272
|
-
|
|
273
|
-
# Run client in another terminal
|
|
270
|
+
# Set API keys
|
|
274
271
|
export ANTHROPIC_API_KEY="your-key"
|
|
272
|
+
export GITHUB_PERSONAL_ACCESS_TOKEN="your-token"
|
|
273
|
+
|
|
274
|
+
# Install MCP server (example: GitHub)
|
|
275
|
+
brew install github-mcp-server
|
|
276
|
+
|
|
277
|
+
# Run client
|
|
275
278
|
ruby examples/mcp_client.rb
|
|
276
279
|
```
|
|
277
280
|
|
|
278
281
|
## Key Concepts
|
|
279
282
|
|
|
280
|
-
1. **
|
|
281
|
-
2. **
|
|
282
|
-
3. **Transport**:
|
|
283
|
-
4. **
|
|
284
|
-
5. **Tool Filtering**: Use `tools
|
|
283
|
+
1. **MCP Configuration**: Pass server configs via `mcp:` parameter on `RobotLab.build` or `Robot.new`
|
|
284
|
+
2. **Auto-Discovery**: Tools are automatically discovered when the robot connects to an MCP server
|
|
285
|
+
3. **Transport Types**: stdio, http, websocket, sse
|
|
286
|
+
4. **Hierarchical Config**: `runtime > robot > network > global`, using `:none`, `:inherit`, or explicit arrays
|
|
287
|
+
5. **Tool Filtering**: Use `tools:` whitelist to limit which MCP tools are available
|
|
288
|
+
6. **Cleanup**: Always call `robot.disconnect` when done to release MCP connections
|
|
285
289
|
|
|
286
290
|
## See Also
|
|
287
291
|
|