# Execute actions with Embedded MCP

Run MindCloud app actions through Embedded MCP with arguments, connection selection, idempotency, and pagination.

`execute-actions` runs published app actions on the end user's connections. A Run Workflows key or higher can call it.

Each `actions` entry needs a unique `ref`, `appRef`, and `actionRef`. Add `arguments` from the action schema. Use `connectionRef` when the user has several accounts for the app. For writes, set `idempotencyKey` so a retry does not run the same write twice.

```json
{
  "actions": [
    {
      "ref": "send",
      "appRef": "slack",
      "actionRef": "sendMessage",
      "arguments": {
        "channel": "C123",
        "text": "Deployment complete"
      },
      "connectionRef": "cred_public_1",
      "idempotencyKey": "message-123"
    }
  ]
}
```

```json
{
  "success": true,
  "data": {
    "results": [
      {
        "ok": true,
        "ts": "1727524800.000100"
      }
    ]
  },
  "meta": {
    "resultCount": 1,
    "connectionId": "cred_public_1",
    "page": {
      "nextCursor": null
    }
  }
}
```

The example output is shortened. The live response can include connection, page, and compaction metadata.

## More than one action

Send up to 20 entries. Results use each entry's `ref`; independent entries run in parallel. If one action needs another's output, make separate calls.

```json
{
  "actions": [
    {
      "ref": "a",
      "appRef": "slack",
      "actionRef": "listChannels"
    },
    {
      "ref": "b",
      "appRef": "hubspot",
      "actionRef": "listContacts"
    }
  ]
}
```

Before execution, the server resolves and validates every entry. One invalid entry stops the batch before any action runs. A provider failure after execution starts can still leave other entries completed.

Without `resultTransformCode`, a multi-action result uses `data.byRef`. For example:

```json
{
  "success": true,
  "data": {
    "byRef": {
      "a": {
        "results": [
          {
            "id": "channel_1"
          }
        ]
      },
      "b": {
        "results": [
          {
            "id": "contact_1"
          }
        ]
      }
    }
  }
}
```

Use `fields` to select output field paths. Each entry can use `query.filter`, `query.sort`, and `query.page` when its schema allows them. Page mode is `single` by default; `all` drains within server limits. Follow `meta.page.nextCursor` for another page.

This example requests one filtered page. The field names and operators must match the live action schema:

```json
{
  "actions": [
    {
      "ref": "contacts",
      "appRef": "hubspot",
      "actionRef": "listContacts",
      "query": {
        "filter": {
          "where": [
            {
              "field": "status",
              "operator": "eq",
              "value": "active"
            }
          ]
        },
        "sort": [
          {
            "field": "createdAt",
            "direction": "desc"
          }
        ],
        "page": {
          "mode": "single",
          "size": 25
        }
      }
    }
  ],
  "fields": [
    "id",
    "email"
  ]
}
```

For large results, read `meta.notice` and pass `meta.compaction.resultSet` to [`query-result-set`](/docs/embedded/embedded-mcp/tool-calls/query-result-set). Stored results last 30 minutes from the last query. `resultTransformCode` takes a JavaScript function expression and shapes returned rows; it does not change the provider action.

For one action, the function receives `{ data }` and returns an array. For several actions, it receives `{ refs, dataByRef, metaByRef }`. Use separate calls when later action arguments depend on earlier output.