Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 33 additions & 29 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,49 @@
## [0.4.0] — unreleased

**Breaking.** The node is now organised around DataGrout operations instead of
raw tool calls, and talks to DataGrout's JSON-RPC API rather than MCP. Existing
raw tool calls, and calls DataGrout's REST API rather than MCP. Existing
workflows using the old *DataGrout MCP* node need to be repointed at the new
**DataGrout** node.

### Added
- **DataGrout Trigger** — starts a workflow when DataGrout pushes an event, over
one multiplexed WebSocket. Subscribes once to the server's event stream and
filters by event (`run.completed`, `task.completed`, `task.failed`,
`tool_call.failed`), emits one item per event,
filters connection lifecycle frames so a reconnect does not fire the workflow,
holds the connection open with a keepalive, and reopens a dropped one with a
backing-off delay. Requires Node 22+.
- **Answer → Ask** — a question in plain language returns a verified answer, a
caveat when DataGrout could not verify it, and a certificate URL.
- **Answer → Ask** — a question in plain language returns an answer, whether
DataGrout's verifier accepted it, a certificate showing what ran, and a skill
id to run the same work again.
- **Data → Transform** — server-side compute over inline data or a reference,
returning one item per record.
returning one item per row, or the whole response with **Split Rows Into
Items** off.
- **Memory → Remember / Recall** — facts that persist across executions, and
recall that includes what can be inferred from them.
- **Skill → Run** — re-run previously verified work.
- **API Token authentication** alongside OAuth2, selectable on the node.
- The transport a node needs is switched on automatically the first time a
workflow uses it — JSON-RPC on the node's first call, WebSocket when the
trigger starts — so nothing needs configuring in the DataGrout dashboard.
Both are logged, so a change to your server's settings is never silent.
Testing a credential only reads, and changes nothing.
recall that includes what can be inferred from them. Memory Name defaults to
`default`, the memory DataGrout uses when none is named.
- **Skill → Run** — re-run previously verified work, by a saved skill's id or the
Skill ID an Ask returned.
- **DataGrout Trigger** — starts a workflow when DataGrout pushes an event, over
one multiplexed WebSocket. Subscribes once to the server's event stream,
filters by event (`run.completed`, `task.completed`, `task.failed`,
`tool_call.failed`), emits one item per event, filters connection lifecycle
frames so a reconnect does not fire the workflow, holds the connection open
with a keepalive, and reopens a dropped one with a backing-off delay. It
switches on the WebSocket transport when it starts, and logs that it did.
Requires Node 22+.
- **API Token authentication** alongside OAuth2, selectable on the node. With
OAuth2 there is still nothing to fill in: DataGrout resolves the server from
the connected account.

### Changed
- Tool names are gone from the interface. Operations are named for what they do.
- A loop-guard intervention now fails the node instead of arriving as the answer.
DataGrout answers an identical call repeated with nothing changing in between
with an explanation rather than a result, and two of those replies are not
marked as errors — so a downstream node expecting rows used to receive
`{loop_detected: true, …}` as its data. The message says what happened and how
to proceed.
- A tool-level failure reported inside a success response now fails the node,
instead of returning an empty answer marked verified.
- Tool names and tool result handling are gone from the node. Each operation is
one REST call whose response has named fields, and slow work is followed by
polling the task the API returns.
- An answer DataGrout could not verify is returned as `verified: false`, with
what the plan found beside it, instead of failing the node — so a workflow can
branch on it.
- Errors carry DataGrout's own message: a repeated identical request the loop
guard declined, a skill that is unknown or has expired, a connected system
failing.
- Testing the API Token credential only reads, and costs nothing.

### Removed
- The **DataGrout MCP** node and its `List Tools` / `Execute Tool` operations.
- The **DataGrout MCP** node: its `List Tools` / `Execute Tool` operations and
the **Tools to Allow** filter.

## [0.3.1] - 2026-08-17

Expand Down
48 changes: 31 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ Two nodes:
| **DataGrout** | Ask questions, compute over data, store and recall facts, re-run verified work. Also works on an AI Agent's Tool connector. |
| **DataGrout Trigger** | Start a workflow when a DataGrout run or background task finishes or fails. |

The DataGrout node calls DataGrout's [REST API](https://library.datagrout.ai/rest-api).
No runtime dependencies.

## What you get that a plain HTTP call does not

- **A verified answer, or an admission.** Every answer carries whether DataGrout
could verify it and a certificate URL showing the steps that produced it. A
result that failed verification arrives as an error, not as a confident null.
- **A verified answer, or an admission.** Every answer says whether DataGrout's
verifier accepted it, with a certificate showing the steps that produced it.
An answer it could not verify arrives as `verified: false`, with `answer` empty
and what the plan found under `unverified_answer` — never as a confident
answer — so a workflow can branch on it instead of trusting it.
- **Memory that outlives the execution.** Facts stored in one run are still there
in the next, and in other workflows pointed at the same memory.
- **Compute that stays next to the data.** A large result never has to travel
Expand All @@ -36,7 +39,18 @@ No runtime dependencies.
| **Answer** | Ask | Ask in plain language. DataGrout plans, runs and verifies, and returns the answer plus a certificate URL. |
| **Data** | Transform | Describe the result you want; DataGrout computes it on its own servers and returns records, one item per row. |
| **Memory** | Recall / Remember | Store facts as workflows run, then ask what is known — including what can be inferred from it. |
| **Skill** | Run | Re-run work DataGrout has already verified. No planning, so it is fast and repeatable. |
| **Skill** | Run | Re-run work DataGrout has already verified — a saved skill (`skill_…`), or the Skill ID an Ask returned. No planning, so it is fast and repeatable. |

### What Ask returns

| Field | |
|---|---|
| `answer` | The answer, or empty when it could not be verified |
| `verified` | Whether DataGrout's verifier accepted it |
| `unverified_answer`, `caveat` | What the plan found, and why it could not be verified |
| `certificate` | `id` and `url` of the certificate showing exactly what ran |
| `skill_id` | Run this verified work again with **Skill → Run**. An id beginning `skill_` does not expire; when `skill_expires` is true it lasts an hour. |
| `usage` | Credits charged and remaining |

### Why Transform is worth using

Expand Down Expand Up @@ -115,18 +129,15 @@ Choose either on the node's **Authentication** field.
| Gateway Base URL | Leave as-is unless you self-host the gateway |

**DataGrout OAuth2 API** — for instances that prefer an OAuth flow. Create the
credential, click **Connect my account**, and there is nothing to fill in.
credential, click **Connect my account**, and there is nothing to fill in: the
token itself names the server it was granted.

Testing a credential only reads — it lists the tools your server exposes and
changes nothing.
Testing a credential only reads — it fetches the server's name, changes nothing
and costs nothing.

DataGrout enables transports per server, and a new server has only MCP switched
on. Rather than sending you to the dashboard, these nodes switch on the transport
they need the first time a workflow actually uses it: the DataGrout node enables
JSON-RPC on its first call, and the trigger enables WebSocket when it starts.
Both are idempotent, and both are written to the n8n log so a change to your
server's settings is never silent. Until then, a transport you have deliberately
left off stays off.
The trigger listens over DataGrout's WebSocket transport, which a new server has
switched off. It switches it on when the trigger starts, and writes that to the
n8n log, so a change to your server's settings is never silent.

## Using it with an AI Agent

Expand All @@ -137,9 +148,12 @@ question. Replace a field with a fixed value to pin it.
## Options

- **Wait for Result** — DataGrout moves slow work to the background; the node
waits this long for the finished result. Set 0 to return immediately.
- **Full Response** — return everything DataGrout sent rather than the tidied
answer.
waits this long for the finished result. Set 0 to return immediately with the
task to follow.

On Transform, **Split Rows Into Items** (on by default) outputs one item per row
of the result. Turn it off to get the whole response as one item, with its
certificate and reference.

On the trigger:

Expand Down
19 changes: 6 additions & 13 deletions credentials/DataGroutApi.credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,15 @@ export class DataGroutApi implements ICredentialType {
},
};

// A credential test answers "are these credentials valid?", so it reads and
// changes nothing. `tools.list` settles both halves of the credential: a bad
// token is rejected by the gateway's auth plug (401/403), and an unknown
// Server ID is a 404.
//
// A server that has not yet switched on the JSON-RPC transport answers HTTP
// 200 with a JSON-RPC error in the body, which n8n reads as a pass — rightly,
// because that is a server setting rather than a bad credential. The node
// switches the transport on when a workflow actually runs, not when someone
// clicks Test.
// A credential test answers "are these credentials valid?", so it reads,
// changes nothing and costs nothing. The server endpoint settles both halves
// of the credential: a bad token is rejected by the gateway's auth plug
// (401/403), and an unknown Server ID is a 404.
test: ICredentialTestRequest = {
request: {
baseURL: '={{$credentials.baseUrl}}',
url: '=/servers/{{$credentials.serverId}}/rpc',
method: 'POST',
body: { jsonrpc: '2.0', id: 1, method: 'tools.list', params: {} },
url: '=/api/v1/servers/{{$credentials.serverId}}',
method: 'GET',
},
};
}
Loading
Loading