actionmcp 0.100.0 → 0.100.1
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/README.md +109 -0
- data/app/jobs/action_mcp/tool_execution_job.rb +4 -2
- data/lib/action_mcp/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5df97e0bdac66054109edabe63756d639e74bb3068d70d4028bd990b2bee8442
|
|
4
|
+
data.tar.gz: db73f42cf5307f09e3b4484799057fc10ee4a5341efa58aef99ab25be82abc4c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0fa54e67f4f7c5e60ba16bd708557534e3b374e19e16d8456289e269e3649c4117407d5e6b4c2ce5c3645476084ab7444e81681a7a900953b4d25da50e534ddc
|
|
7
|
+
data.tar.gz: 1b783e0ddb8c502cf9438049b7f88c74a89e2bb8e48fdd795789741a7de77b12507412c4b66116b299f7a6b7c75b0279bddf787c6ca522e246e66bee139dd694
|
data/README.md
CHANGED
|
@@ -219,6 +219,111 @@ sum_tool = CalculateSumTool.new(a: 5, b: 10)
|
|
|
219
219
|
result = sum_tool.call
|
|
220
220
|
```
|
|
221
221
|
|
|
222
|
+
#### Structured output (output_schema)
|
|
223
|
+
|
|
224
|
+
Advertise a JSON Schema for your tool's structuredContent and return machine-validated results alongside any text output.
|
|
225
|
+
|
|
226
|
+
```ruby
|
|
227
|
+
class PriceQuoteTool < ApplicationMCPTool
|
|
228
|
+
tool_name "price_quote"
|
|
229
|
+
description "Return a structured price quote"
|
|
230
|
+
|
|
231
|
+
property :sku, type: "string", description: "SKU to price", required: true
|
|
232
|
+
|
|
233
|
+
output_schema do
|
|
234
|
+
string :sku, required: true, description: "SKU that was priced"
|
|
235
|
+
number :price_cents, required: true, description: "Total price in cents"
|
|
236
|
+
object :meta do
|
|
237
|
+
string :currency, required: true, enum: %w[USD EUR GBP]
|
|
238
|
+
boolean :cached, default: false
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def perform
|
|
243
|
+
price_cents = lookup_price_cents(sku) # Implement your lookup
|
|
244
|
+
|
|
245
|
+
render structured: { sku: sku,
|
|
246
|
+
price_cents: price_cents,
|
|
247
|
+
meta: { currency: "USD", cached: false } }
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
The schema is included in the tool definition, and the `structured` payload is emitted as `structuredContent` in the response while remaining compatible with text/audio/image renders.
|
|
253
|
+
|
|
254
|
+
#### Returning resource links from a tool
|
|
255
|
+
|
|
256
|
+
When you want to hand back a URI instead of embedding the payload, use the built-in `render_resource_link`, which produces the MCP `resource_link` content type.
|
|
257
|
+
|
|
258
|
+
```ruby
|
|
259
|
+
class ReportLinkTool < ApplicationMCPTool
|
|
260
|
+
tool_name "report_link"
|
|
261
|
+
description "Return a downloadable report link"
|
|
262
|
+
|
|
263
|
+
property :report_id, type: "string", required: true
|
|
264
|
+
|
|
265
|
+
def perform
|
|
266
|
+
render_resource_link(
|
|
267
|
+
uri: "reports://#{report_id}.json",
|
|
268
|
+
name: "Report #{report_id}",
|
|
269
|
+
description: "Downloadable JSON for report #{report_id}",
|
|
270
|
+
mime_type: "application/json"
|
|
271
|
+
)
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Clients can resolve the URI with a separate `resources/read` call, keeping tool responses lightweight while still discoverable.
|
|
277
|
+
|
|
278
|
+
#### Task-augmented tools (async execution with progress)
|
|
279
|
+
|
|
280
|
+
Use MCP Tasks when work might take seconds/minutes. Advertise task support with `task_required!` (or `task_optional!`) and let callers opt in by sending `_meta.task` on `tools/call`. While running as a task, you can emit progress updates with `report_progress!`.
|
|
281
|
+
|
|
282
|
+
```ruby
|
|
283
|
+
class BatchIndexTool < ApplicationMCPTool
|
|
284
|
+
tool_name "batch_index"
|
|
285
|
+
description "Index many items asynchronously with progress updates"
|
|
286
|
+
|
|
287
|
+
task_required! # advertise that this tool is intended to run as a task
|
|
288
|
+
property :items, type: "array_string", description: "Items to index", required: true
|
|
289
|
+
|
|
290
|
+
def perform
|
|
291
|
+
total = items.length
|
|
292
|
+
items.each_with_index do |item, idx|
|
|
293
|
+
index_item(item) # your indexing logic
|
|
294
|
+
|
|
295
|
+
percent = ((idx + 1) * 100.0 / total).round
|
|
296
|
+
report_progress!(percent: percent, message: "Indexed #{idx + 1}/#{total}")
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
render(text: "Indexed #{total} items")
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
private
|
|
303
|
+
|
|
304
|
+
def index_item(item)
|
|
305
|
+
# Implement your indexing logic here
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Call it as a task from a client by adding `_meta.task` (creates a Task record and runs the tool via `ToolExecutionJob`):
|
|
311
|
+
|
|
312
|
+
```json
|
|
313
|
+
{
|
|
314
|
+
"jsonrpc": "2.0",
|
|
315
|
+
"id": 1,
|
|
316
|
+
"method": "tools/call",
|
|
317
|
+
"params": {
|
|
318
|
+
"name": "batch_index",
|
|
319
|
+
"arguments": { "items": ["a", "b", "c"] },
|
|
320
|
+
"_meta": { "task": { "ttl": 120000, "pollInterval": 2000 } }
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Poll task status with `tasks/get` or fetch the result when finished with `tasks/result`. Use `tasks/cancel` to stop non-terminal tasks.
|
|
326
|
+
|
|
222
327
|
### ActionMCP::ResourceTemplate
|
|
223
328
|
|
|
224
329
|
`ActionMCP::ResourceTemplate` facilitates the creation of URI templates for dynamic resources that LLMs can access.
|
|
@@ -311,6 +416,10 @@ ActionMCP provides comprehensive documentation across multiple specialized guide
|
|
|
311
416
|
- Transport configuration and connection handling
|
|
312
417
|
- Tool, prompt, and resource collections
|
|
313
418
|
- Production deployment patterns
|
|
419
|
+
- **[🔐 GATEWAY.md](GATEWAY.md)** - Authentication gateway guide
|
|
420
|
+
- Implementing `ApplicationGateway`
|
|
421
|
+
- Identifier handling via `ActionMCP::Current`
|
|
422
|
+
- Auth patterns, error handling, and hardening tips
|
|
314
423
|
|
|
315
424
|
### Protocol & Technical Details
|
|
316
425
|
- **[🚀 The Hitchhiker's Guide to MCP](The_Hitchhikers_Guide_to_MCP.md)** - Protocol versions and migration
|
|
@@ -27,7 +27,7 @@ module ActionMCP
|
|
|
27
27
|
@session = step(:validate_session, @task)
|
|
28
28
|
return unless @session
|
|
29
29
|
|
|
30
|
-
@tool = step(:prepare_tool, @session, tool_name, arguments)
|
|
30
|
+
@tool = step(:prepare_tool, @session, tool_name, arguments, @task)
|
|
31
31
|
return unless @tool
|
|
32
32
|
|
|
33
33
|
step(:execute_tool) do
|
|
@@ -60,7 +60,7 @@ module ActionMCP
|
|
|
60
60
|
session
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
def prepare_tool(session, tool_name, arguments)
|
|
63
|
+
def prepare_tool(session, tool_name, arguments, task)
|
|
64
64
|
tool_class = session.registered_tools.find { |t| t.tool_name == tool_name }
|
|
65
65
|
unless tool_class
|
|
66
66
|
@task.update(status_message: "Tool '#{tool_name}' not found")
|
|
@@ -76,6 +76,8 @@ module ActionMCP
|
|
|
76
76
|
params: @task.request_params
|
|
77
77
|
}
|
|
78
78
|
})
|
|
79
|
+
# Enable report_progress! inside the tool during task-augmented runs
|
|
80
|
+
tool.instance_variable_set(:@_task, task)
|
|
79
81
|
|
|
80
82
|
tool
|
|
81
83
|
end
|
data/lib/action_mcp/version.rb
CHANGED