nats mcp tool kinds - noetl/worker GitHub Wiki
The
natstool kind is a supported user-facing integration. It is one of several ways a playbook reaches an external data or messaging service the user brings themselves — alongsidepostgres,duckdb,http, and the object-store kinds. The endpoint comes from the step's ownurlor from a keychain credential alias: the user's broker, not the platform's.Do not confuse it with the internal bus. NoETL's own command bus, event bus, and KV store run on EHDB and no longer speak NATS (noetl/ai-meta#212). That removal deleted the internal NATS client, listener, and KV buckets — it did not touch this tool, which lives in the separate
noetl-toolscrate with its ownasync-natsdependency. EHDB is internal transient infrastructure and is never exposed as a user store.Verified end to end on worker v5.91.2 (the post-removal build) against a user-provided broker:
kv_put→kv_get→kv_keysround-trips business data intact. Regression guard:tests/user_nats_tool_dispatch.rs. An earlier revision of this page called the kind "dead" — that was wrong, and noetl/ai-meta#219 (which proposed removing it) is closed as won't remove.
Added in noetl-tools 2.15.0 (nats) and 2.16.0 (mcp) — both are dispatched through the worker's existing dynamic ToolRegistry with no per-variant match arms in the worker code itself.
Bridges playbook steps to NATS JetStream, Key-Value store, and Object Store operations.
tool:
kind: nats
auth: my_nats_credential # credential alias → { url, user?, password?, token? }
operation: kv_get # kv_get | kv_put | kv_delete | kv_keys | kv_purge |
# object_get | object_put | object_delete | object_list |
# object_info | js_publish | js_get_msg | js_stream_info
bucket: my_bucket
key: my_keyThe credential alias is resolved via ctx.get_secret(alias) (keychain lookup) and must contain at minimum a url field. Inline url / user / password / token fields are also accepted directly in the config for simpler cases.
No subscriptions or pull operations — those would hold a worker slot while waiting for an external event, which violates the execution model (agents/rules/execution-model.md). Use JetStream push-to-subject patterns from a playbook-level callback step instead.
{
"status": "success",
"operation": "kv_get",
"bucket": "my_bucket",
"key": "my_key",
"value": "stored-value"
}Set up via NOETL_KEYCHAIN_ENV_VARS (see worker credentials):
NOETL_KEYCHAIN_ENV_VARS=MY_NATS_CRED
MY_NATS_CRED='{"url":"nats://host:4222","user":"alice","password":"s3cret"}'Playbook step:
tool:
kind: nats
auth: MY_NATS_CRED
operation: kv_put
bucket: session-cache
key: "{{ execution_id }}"
value: "{{ payload | tojson }}"Bridges playbook steps to MCP (Model Context Protocol) servers over JSON-RPC 2.0 + HTTP with optional SSE response parsing.
tool:
kind: mcp
endpoint: "http://localhost:8080/mcp" # direct endpoint, OR
server: kubernetes # key for NOETL_MCP_<SERVER>_ENDPOINT env var
method: tools/call # tools/call | tools/list | health | <other>
tool: get_pods # required for tools/call
arguments: # required for tools/call
namespace: default
timeout: 30 # seconds (default 60)-
config.endpoint(orconfig.url/config.server_url/config.base_url) -
NOETL_MCP_<SERVER>_ENDPOINTenv var keyed byconfig.serverslug -
NOETL_MCP_URLfallback env var
{
"status": "ok",
"server": "kubernetes",
"endpoint": "http://localhost:8080/mcp",
"method": "tools/call",
"tool": "get_pods",
"arguments": { "namespace": "default" },
"text": "...",
"result": { ... }
}On error: { "status": "error", "error": "<message>" }.
Each tool invocation POSTs an initialize request to get an Mcp-Session-Id header. Subsequent calls within the same invocation reuse that session id. Servers that omit the header are treated as stateless (no error).
Both tool kinds follow the same worker dispatch path as all other kinds:
NATS pull → CommandExecutor::execute
→ ToolRegistry::execute_from_config(&ToolConfig { kind: "nats" | "mcp", ... })
→ NatsTool::execute | McpTool::execute
→ call.done event (inline / durable / shm fallback chain)
The tool_kind is the only discriminator. CommandExecutor carries no per-kind match arms — adding a new kind to noetl-tools and bumping the dep is the entire wiring.
noetl_worker_dispatch_duration_seconds{tool_kind="nats"} and {tool_kind="mcp"} appear in /metrics after the first dispatch of each kind. The histogram label is dynamic, so no metrics code changes are needed when new tool kinds land.
-
noetl/tools wiki — implementation reference for
NatsToolandMcpTool. -
worker-credentials —
NOETL_KEYCHAIN_ENV_VARSallow-list for NATS auth credentials. - noetl-executor adoption — how the worker drives the tool registry.
- noetl/ai-meta#40 — tracking issue for this bump.