MongoDB Action

Reads and writes a MongoDB collection from a flow. Seven operations — insert, find one, find all, update, find-and-update, delete, and a full aggregation pipeline — all driven by JSON templates, so the query and the document are built from the payload at run time. Or switch it to AI toolkit mode and let an agent use the collection through seven tools.

Overview

The MongoDB Action node is a post-delivery action that writes data to an external MongoDB database after a webhook processes a webhook event. It connects to your MongoDB instance using an encrypted connection URI and performs the configured operation. The node appears on the canvas with a green color.

Event received--▶Webhook delivery--▶MongoDB Action fires

Configuration

FieldTypeRequiredDescription
namestringYesFriendly label for the MongoDB action
connectionUristringYesMongoDB connection string. Encrypted at rest.
databasestringYesTarget database name
collectionstringYesTarget collection name
operationstringYesOne of the seven values in Operations
documentstringYesJSON template for the document to insert/replace. Supports {{payload.*}}, {{response.*}}.
filterstringConditionalJSON template for the filter query. Used by every operation except insertOne.
inputNodes{ nodeType, nodeId }[]YesUpstream nodes that feed this one
isActivebooleanNoEnable or disable without deleting. Default: true.
⚠The connectionUri is encrypted before being stored. It is never returned in API responses after creation. Make sure your MongoDB instance allows connections from HostWebhook servers.

Operations

The Operation dropdown decides what the node does and which template boxes appear under it. Five of the seven read; only two write blindly.

ValueIn the dropdownDoesTemplates it shows
insertOneInsert OneInserts a single documentdocument
findOneFind OneReturns the first matching documentquery
findAllFind AllReturns every match, capped at 1000query · include count
updateOneUpdate OneUpdates the first matching documentquery · update
findOneAndUpdateFind & UpdateUpdates and returns the document in one round tripquery · update
deleteOneDelete OneDeletes the first matching documentquery
aggregateAggregateRuns a pipeline — $match, $group, $sort…pipeline
⚠Older versions of this page offered replaceOne. It is not one of the seven and the API rejects it. If a node of yours is configured with it, switch to updateOne.

The update box is a builder rather than a raw box: it writes the operators ($set, $inc…) for you so a typo cannot turn an update into a replacement. Query and document boxes take JSON with templates inside, so { "orderId": "{{payload.id}}" } is the normal shape.

ℹfindAll returns at most 1000 documents. If you need more, narrow the query or move the work into aggregate, where $group can do the counting server-side instead of shipping rows to the flow.

AI toolkit mode

Once a credential is picked, the node asks for a Mode. Single operation is everything above: one operation, your templates, every run. AI toolkit turns the node into seven tools that an AI Node — or an MCP client, through one of your MCP servers — calls by name, choosing the tool and its arguments on each turn.

ToolDoesArgumentsKind
find_documentsDocuments matching a filter, sorted and projectedfilter? · projection? · sort? · limit?Reads
find_one_documentThe first document matching a filterfilter · projection?Reads
aggregate_documentsAn aggregation pipeline — counts, sums, groupings, $lookuppipelineReads
insert_documentInserts one document and returns its _iddocumentWrites
update_documentUpdates the first document matching a filterfilter · updateDestructive
update_and_return_documentThe same, returning the document after the updatefilter · updateDestructive
delete_documentDeletes the first document matching a filterfilterDestructive

Every tool works on the node's database and collection, and only there: the model cannot name another collection. That is why the collection has to be a fixed name in this mode — a {{payload.x}} template would let the model's own arguments choose it, so every call fails until you pick one from the list.

What is refused before the database is touched

  • Server-side JavaScript — $where, $function, $accumulator — anywhere in a filter, an update or a pipeline.
  • The $out and $merge stages in aggregate_documents: they write, and that tool only reads.
  • Updating or deleting with an empty filter. {} matches whichever document comes first.
  • An update without operators. { "status": "shipped" } would replace the whole document; the model has to send { "$set": { "status": "shipped" } }.

Results are sized for a model's context, not a flow: find_documents returns 20 documents unless the model asks for more, and never more than 100; a pipeline without a $limit gets one of 100.

Block these tool calls

In toolkit mode the page lists every tool with a switch. A blocked tool disappears from every AI Node and MCP server that uses this node — the AI Node's tool picker shows it greyed out, and an agent that already had it stops being offered it — and the node refuses the call if one arrives anyway. Use it for what no agent should ever do on this collection. Block the destructive tools blocks the ones that overwrite or delete in one click.

ℹBlocking is per node — per resource. The AI Node's Block destructive tool calls is per agent. They add up: a tool runs only when neither stops it.

Testing a tool

⚠Only a tool call picks the tool. In AI toolkit mode, only an AI Node, an MCP client or a voice agent chooses which tool the node runs. Run Test, a flow or a webhook run the operation saved on the node: an operation in their payload that names another tool is refused.
✦To try a tool, call it from an AI Node or from an MCP client. Its arguments look like this:
jsonA tool call
{ "operation": "find_documents", "filter": { "status": "paid" }, "limit": 5 }
⚠A node in toolkit mode is not part of the pipeline. If it still has connections from before you switched, events arriving through them are refused — the node only runs the tool it is asked for, never its Single operation config. The canvas panel lists those connections: delete them, or switch back to Single operation.

Create a MongoDB Action

bashCreate MongoDB Action (insertOne)
curl -X POST /api/mongo-actions \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "workspaceId": "<your-workspace-id>",
    "name": "Log Orders to MongoDB",
    "connectionUri": "mongodb+srv://user:pass@cluster.mongodb.net",
    "database": "analytics",
    "collection": "webhook_events",
    "operation": "insertOne",
    "document": "{ "eventType": "{{payload.type}}", "orderId": "{{payload.order.id}}", "amount": {{payload.order.total}}, "deliveryStatus": {{response.status}}, "processedAt": "{{response.body.processedAt}}", "receivedAt": { "$date": "{{payload.timestamp}}" } }",
    "inputNodes": [{ "nodeType": "webhook", "nodeId": "6642f1a2c3b4d5e6f7890123" }],
    "isActive": true
  }'

Response

json201 Created
{
  "_id": "6644b2c3d4e5f6a7b8901234",
  "name": "Log Orders to MongoDB",
  "database": "analytics",
  "collection": "webhook_events",
  "operation": "insertOne",
  "document": "{ "eventType": "{{payload.type}}", ... }",
  "inputNodes": [{ "nodeType": "webhook", "nodeId": "6642f1a2c3b4d5e6f7890123" }],
  "isActive": true,
  "organizationId": "6640a1b2c3d4e5f6a7890001",
  "createdAt": "2025-05-15T09:00:00.000Z",
  "updatedAt": "2025-05-15T09:00:00.000Z"
}

Update a MongoDB Action

bashUpdate MongoDB Action
curl -X PATCH /api/mongo-actions/6644b2c3d4e5f6a7b8901234 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "operation": "updateOne",
    "filter": "{ "orderId": "{{payload.order.id}}" }",
    "document": "{ "$set": { "lastStatus": {{response.status}}, "updatedAt": "{{payload.timestamp}}" } }"
  }'

Response

json200 OK
{
  "_id": "6644b2c3d4e5f6a7b8901234",
  "name": "Log Orders to MongoDB",
  "database": "analytics",
  "collection": "webhook_events",
  "operation": "updateOne",
  "filter": "{ "orderId": "{{payload.order.id}}" }",
  "document": "{ "$set": { "lastStatus": {{response.status}}, ... } }",
  "inputNodes": [{ "nodeType": "webhook", "nodeId": "6642f1a2c3b4d5e6f7890123" }],
  "isActive": true,
  "organizationId": "6640a1b2c3d4e5f6a7890001",
  "createdAt": "2025-05-15T09:00:00.000Z",
  "updatedAt": "2025-05-15T10:30:00.000Z"
}

Canvas Integration

On the visual canvas, the MongoDB Action node uses the type mongo-action and is rendered with a green color scheme. Connect it to any webhook node to persist data after deliveries.

The node displays the action name, database/collection path, and the operation type. Edges from webhooks flow into the MongoDB action node.

✦Combine MongoDB Actions with triggerOn: always to create a complete log of every webhook delivery, including failures, for later analysis.

Payload Examples

insertOne — Full Event Log

jsonDocument template
{
  "eventType": "{{payload.type}}",
  "orderId": "{{payload.order.id}}",
  "customer": {
    "email": "{{payload.customer.email}}",
    "name": "{{payload.customer.name}}"
  },
  "amount": {{payload.order.total}},
  "deliveryStatus": {{response.status}},
  "responseBody": "{{response.body}}",
  "receivedAt": "{{payload.timestamp}}"
}

updateOne — Upsert Order Status

jsonFilter
{ "orderId": "{{payload.order.id}}" }
jsonDocument (update)
{
  "$set": {
    "lastDeliveryStatus": {{response.status}},
    "lastEventType": "{{payload.type}}",
    "updatedAt": "{{payload.timestamp}}"
  },
  "$inc": { "deliveryCount": 1 }
}

findOneAndUpdate — Update and read back

jsonQuery
{ "externalId": "{{payload.id}}" }
jsonUpdate
{
  "$set": {
    "type": "{{payload.type}}",
    "status": {{response.status}},
    "updatedAt": "{{payload.timestamp}}"
  }
}

The updated document comes back in the node's output, so the next node can read the new state without a second query.

findAll — Everything matching, with a count

jsonQuery
{ "customerId": "{{payload.customerId}}", "status": "open" }

Turn on include count to get the total alongside the documents. Remember the 1000-document ceiling.

aggregate — Group without shipping rows

jsonPipeline
[
  { "$match": { "customerId": "{{payload.customerId}}" } },
  { "$group": { "_id": "$status", "total": { "$sum": "$amount" } } },
  { "$sort": { "total": -1 } }
]

Use Cases

Webhook Event Archival

Store every incoming webhook event and its delivery result in a MongoDB collection for long-term archival and compliance. Use insertOne with triggerOn: always to capture both successes and failures.

Real-Time Analytics Pipeline

Insert delivery data into a collection that feeds a real-time analytics dashboard. Include response times, status codes, and payload metadata to track integration health.

Idempotent State Updates

Use updateOne with a filter on a unique payload field (like an order ID) to maintain current state in MongoDB. Each delivery updates the record instead of creating duplicates.

Data Synchronization

Use findOneAndUpdate to keep a MongoDB collection in sync with an external system: each webhook writes the new values and hands the resulting document to the next node, so the flow can react to what actually landed rather than to what it hoped to write.

ℹMongoDB Actions execute after the primary delivery completes. If the MongoDB write fails, it does not affect the delivery status of the webhook. Failures are logged and visible in the action's execution history.

API Reference

MethodWebhookDescription
GET/api/mongo-actionsList all MongoDB actions for your organization
POST/api/mongo-actionsCreate a new MongoDB action
GET/api/mongo-actions/:idGet a single MongoDB action by ID
PATCH/api/mongo-actions/:idUpdate a MongoDB action
DELETE/api/mongo-actions/:idDelete a MongoDB action