@superglue/cli 1.1.21 → 1.1.22

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.
Files changed (32) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +1 -7
  3. package/dist/cli.js +300 -77
  4. package/dist/skills/superglue/SKILL.md +312 -631
  5. package/dist/skills/superglue/references/file-handling.md +116 -90
  6. package/dist/skills/superglue/references/graphql.md +131 -0
  7. package/dist/skills/superglue/references/http.md +246 -0
  8. package/dist/skills/superglue/references/integration.md +4 -2
  9. package/dist/skills/superglue/references/mssql.md +207 -0
  10. package/dist/skills/superglue/references/postgres.md +154 -0
  11. package/dist/skills/superglue/references/redis.md +68 -118
  12. package/dist/skills/superglue/references/sftp-smb.md +156 -0
  13. package/dist/skills/superglue/references/superglue-info.md +91 -0
  14. package/package.json +1 -1
  15. package/skills/superglue/SKILL.md +312 -631
  16. package/skills/superglue/references/file-handling.md +116 -90
  17. package/skills/superglue/references/graphql.md +131 -0
  18. package/skills/superglue/references/http.md +246 -0
  19. package/skills/superglue/references/integration.md +4 -2
  20. package/skills/superglue/references/mssql.md +207 -0
  21. package/skills/superglue/references/postgres.md +154 -0
  22. package/skills/superglue/references/redis.md +68 -118
  23. package/skills/superglue/references/sftp-smb.md +156 -0
  24. package/skills/superglue/references/superglue-info.md +91 -0
  25. package/dist/skills/superglue/references/data-handling.md +0 -303
  26. package/dist/skills/superglue/references/databases.md +0 -253
  27. package/dist/skills/superglue/references/file-servers.md +0 -112
  28. package/dist/skills/superglue/references/http-apis.md +0 -248
  29. package/skills/superglue/references/data-handling.md +0 -303
  30. package/skills/superglue/references/databases.md +0 -253
  31. package/skills/superglue/references/file-servers.md +0 -112
  32. package/skills/superglue/references/http-apis.md +0 -248
@@ -1,43 +1,62 @@
1
1
  ---
2
2
  name: superglue
3
- description: "Build, test, deploy and integrate superglue tools via the sg CLI and superglue SDKs. IMPORTANT — you MUST invoke this skill and read the full reference BEFORE running ANY sg command or writing ANY superglue SDK/REST/webhook integration code. Before using the sg CLI, first check that it is installed (run sg --version; if not found, install with npm install -g @superglue/cli), then verify it is configured (check that sg init has been run or that SUPERGLUE_API_KEY and SUPERGLUE_API_ENDPOINT environment variables are set). If not, guide the user through setup first. After reading the SKILL.md file, also read the relevant references/ files for the specific topic (databases, file servers, transforms, integration/SDK)."
3
+ description: "Build, test, deploy and integrate superglue tools via the sg CLI and superglue SDKs. IMPORTANT — you MUST invoke this skill and read the full reference BEFORE running ANY sg command or writing ANY superglue SDK/REST/webhook integration code. Before using the sg CLI, first check that it is installed (run sg --version; if not found, install with npm install -g @superglue/cli), then verify it is configured (check that sg init has been run or that SUPERGLUE_API_KEY and SUPERGLUE_API_ENDPOINT environment variables are set). If not, guide the user through setup first. After reading SKILL.md, also read the relevant references/ files for the specific protocols and topics involved."
4
4
  ---
5
5
 
6
6
  # superglue CLI (`sg`) — Agent Reference
7
7
 
8
+ This file is the entry point for operating superglue via the `sg` CLI. It covers setup, tool building, tool editing, system management, running tools, and deployment via SDK/REST/webhooks.
9
+
10
+ For protocol-specific details (HTTP, databases, Redis, file servers, GraphQL), file handling, access rules, SDK integration, and general superglue information, read the corresponding file in `references/` (linked throughout and listed at the bottom).
11
+
12
+ ## Reference Files
13
+
14
+ Read these on demand — they are authoritative for their topic and kept in sync with the web agent's skill references.
15
+
16
+ | File | When to read |
17
+ | ------------------------------ | ---------------------------------------------------------------------------------------------------- |
18
+ | `references/superglue-info.md` | Company info, interfaces (SDK, REST API, MCP, Web), web UI layout, execution pipeline, internals |
19
+ | `references/integration.md` | Deploying tools — SDK (TS/Python) usage, REST API calls, webhook triggers, retry patterns |
20
+ | `references/http.md` | HTTP step configuration, auth patterns, file uploads, response handling, pagination, error detection |
21
+ | `references/graphql.md` | GraphQL step config, schema introspection, error recovery |
22
+ | `references/postgres.md` | PostgreSQL connection URLs, SSL/TLS handling, schema introspection, parameterized queries |
23
+ | `references/mssql.md` | MSSQL / Azure SQL connection URLs, schema introspection, parameterized queries |
24
+ | `references/redis.md` | Redis command syntax, connection URLs, key type handling |
25
+ | `references/sftp-smb.md` | SFTP, FTP, and SMB operations, file upload/download semantics, path handling |
26
+ | `references/file-handling.md` | File detection, parsing, `file::` reference syntax, lazy base64 access, transform-produced files |
27
+ | `references/access-rules.md` | RBAC roles, tool/system permissions, mutation detection, custom rules (enterprise only) |
28
+
8
29
  ## CRITICAL RULES — READ FIRST
9
30
 
10
31
  **Pre-requisites for using the CLI**
11
32
 
12
- 1. **Check CLI exists**: Run `sg --version`. If it fails with `command not found`, install it: `npm install -g @superglue/cli`
13
- 2. **Check superglue CLI config exists**: Run `sg system list`. If it fails with `fetch failed` or auth errors, the CLI needs configuration via `sg init` (see below).
33
+ 1. **Check CLI exists**: Run `sg --version`. If it fails with `command not found`, install: `npm install -g @superglue/cli`.
34
+ 2. **Keep CLI and SDK up to date**: Always use the latest versions. Run `sg update` to update the CLI. For the SDK, run `npm install @superglue/client@latest` (JS) or `pip install --upgrade superglue-client` (Python).
35
+ 3. **Verify configuration**: Run `sg system list`. If it fails with `fetch failed` or auth errors, the CLI needs configuration via `sg init` (see Setup below).
14
36
 
15
37
  **Calling systems and running tools**
16
38
 
17
- 1. ALWAYS make sure you pull the relevant system context using `sg system find` before calling system endpoints and running inline JSON tools or building new tools.
18
- 2. Use `sg system search-docs` to do a targeted keyword search of system docs if you're unsure about how a system works.
39
+ 1. ALWAYS pull the relevant system context using `sg system find` before calling system endpoints and before building tools.
40
+ 2. Use `sg system search-docs` for a targeted keyword search of system docs when unsure how a system works.
19
41
 
20
- **Authentication & Credentials:**
42
+ **Authentication & Credentials**
21
43
 
22
- - **Authentication must always be explicitly configured** — nothing is injected automatically in any protocol
23
- - For HTTP: include auth headers using `<<systemId_credentialKey>>` syntax (e.g., `"Authorization": "Bearer <<systemId_access_token>>"`)
24
- - For databases/Redis/file servers: embed credential placeholders in the connection URL (e.g., `postgres://<<sys_user>>:<<sys_pass>>@host/db`)
25
- - OAuth systems also require explicit headers — only token refresh is automatic
44
+ - Authentication must ALWAYS be explicitly configured — nothing is injected automatically in any protocol.
45
+ - HTTP: include auth headers using `<<systemId_credentialKey>>` (e.g. `"Authorization": "Bearer <<my_api_access_token>>"`).
46
+ - Databases/Redis/file servers: embed credential placeholders in the connection URL (e.g. `postgres://<<sys_user>>:<<sys_pass>>@host/db`).
47
+ - OAuth: token refresh is automatic, but the header must still be explicit.
26
48
 
27
- **Saving Tools:**
49
+ **Saving tools**
28
50
 
29
- - **Don't save a tool without explicit user confirmation** — always ask "Should I save this tool?" first
30
- - After `sg tool build` + `sg tool run`, present results to the user and wait for approval
31
- - Only run `sg tool save --draft <id>` after the user explicitly confirms
51
+ - Never save a tool without explicit user confirmation. Build + run, present results, then save with `sg tool save --draft <id>` only after the user approves.
32
52
 
33
- **Credentials in Non-Interactive Environments (AI Agents, CI):**
53
+ **Non-interactive environments (AI agents, CI)**
34
54
 
35
- - **Pass ALL credentials (including secrets) directly via `--credentials` JSON**
36
- - Ask the user to provide secret values, then pass them in `--credentials '{"api_key":"sk-xxx"}'`
55
+ - Pass ALL credentials (including secrets) directly via `--credentials '{"api_key":"sk-xxx"}'`. Ask the user for secret values, then include them in the JSON.
37
56
 
38
57
  ---
39
58
 
40
- ## Installation & Setup
59
+ ## Setup
41
60
 
42
61
  ### Installing the CLI
43
62
 
@@ -45,80 +64,53 @@ description: "Build, test, deploy and integrate superglue tools via the sg CLI a
45
64
  npm install -g @superglue/cli
46
65
  ```
47
66
 
48
- After installation, the `sg` command is available globally.
67
+ After installation the `sg` command is available globally.
49
68
 
50
- ### Initialization (REQUIRED before first use)
69
+ ### Initialization
51
70
 
52
- The CLI **will not work** until configured with an API key. The endpoint defaults to `https://api.superglue.cloud` if not specified.
71
+ The CLI will not work until configured with an API key. The endpoint defaults to `https://api.superglue.cloud`.
53
72
 
54
- **Option A: Interactive setup (recommended for humans)**
73
+ **Interactive (humans):**
55
74
 
56
75
  ```bash
57
76
  sg init
58
77
  ```
59
78
 
60
- This prompts for:
61
-
62
- 1. **API Key** (required) — get one at https://app.superglue.cloud/admin?view=api-keys
63
- 2. **API Endpoint** — defaults to `https://api.superglue.cloud`
64
- 3. **Web Endpoint** — for OAuth callbacks, auto-derived from API endpoint
65
- 4. **Output mode** — `stdout` (default) or `stdout+file`
66
- 5. **Config location** — project-local (`.superglue/config.json`) or global (`~/.superglue/config.json`)
67
-
68
- It verifies the connection before saving. On success it creates the config file, a `drafts/` directory, and updates `.gitignore` if using local config.
69
-
70
- **Option B: Non-interactive init (recommended for CI and AI agents)**
79
+ Prompts for: API key (required — get one at https://app.superglue.cloud/admin?view=api-keys), API endpoint, web endpoint (for OAuth callbacks), output mode (`stdout` or `stdout+file`), and config location (project-local `.superglue/config.json` vs global `~/.superglue/config.json`). Verifies the connection before saving.
71
80
 
72
- Pass the global `--api-key` flag to skip interactive prompts and save a config file:
81
+ **Non-interactive (CI, agents):**
73
82
 
74
83
  ```bash
75
84
  sg init --api-key "your-api-key" --global
76
85
  sg init --api-key "your-api-key" --endpoint "https://custom.endpoint.com" --global
77
86
  ```
78
87
 
79
- > **Note:** `--api-key` and `--endpoint` are global flags (not shown in `sg init --help`). They work on all subcommands including `init`.
88
+ `--api-key` and `--endpoint` are global flags and work on all subcommands.
80
89
 
81
- **Option C: Environment variables (no config file)**
82
-
83
- If you don't need a persistent config file, set these env vars instead:
90
+ **Environment variables (no config file):**
84
91
 
85
92
  ```bash
86
93
  export SUPERGLUE_API_KEY="your-api-key"
87
- export SUPERGLUE_API_ENDPOINT="https://api.superglue.cloud" # optional, this is the default
94
+ export SUPERGLUE_API_ENDPOINT="https://api.superglue.cloud" # optional, this is the default
88
95
  ```
89
96
 
90
- With these set, all `sg` commands work without a config file.
91
-
92
- **Option C: CLI flags (per-command override)**
93
-
94
- ```bash
95
- sg system list --api-key "your-key" --endpoint "https://api.superglue.cloud"
96
- ```
97
-
98
- ### Config Resolution Order
99
-
100
- CLI flags > environment variables > config file (local `.superglue/config.json` > global `~/.superglue/config.json`).
97
+ **Config resolution order:** CLI flags > environment variables > local `.superglue/config.json` > global `~/.superglue/config.json`.
101
98
 
102
- ### Verifying Setup
99
+ Verify with `sg system list` — should return a list (possibly empty) without errors.
103
100
 
104
- After configuring, verify the connection works:
101
+ ### Capability Presets
105
102
 
106
- ```bash
107
- sg system list # should return a list (possibly empty) without errors
108
- ```
109
-
110
- ---
103
+ Set during `sg init` or via `SUPERGLUE_CLI_PRESET` env var. Stored in `config.json` as `"preset"`.
111
104
 
112
- ## Quick Start
105
+ | Preset | Description |
106
+ | --------- | ------------------------------------------------------------------ |
107
+ | `runner` | Run saved tools by ID only. Read-only lookups. No building/editing |
108
+ | `builder` | Runner + build/edit/save tools, call systems. No system CRUD |
109
+ | `admin` | Full access (default) |
113
110
 
114
- ```bash
115
- sg system list
116
- sg tool build --config '{"id":"...","instruction":"...","steps":[...]}'
117
- sg tool run --draft <draftId>
118
- sg tool save --draft <draftId>
119
- ```
111
+ Blocked commands print a clear error showing the current preset and how to change it.
120
112
 
121
- ## Global Flags
113
+ ### Global Flags
122
114
 
123
115
  | Flag | Description |
124
116
  | ------------------ | ------------------------------------------- |
@@ -127,243 +119,144 @@ sg tool save --draft <draftId>
127
119
  | `--api-key <key>` | Override API key |
128
120
  | `--endpoint <url>` | Override API endpoint |
129
121
 
130
- ## Capability Presets
122
+ ---
131
123
 
132
- The CLI supports three capability presets that control which commands are available. Set during `sg init` or via `SUPERGLUE_CLI_PRESET` env var. Stored in `config.json` as `"preset"`.
124
+ ## Workflow
133
125
 
134
- | Preset | Description |
135
- | --------- | ------------------------------------------------------------------ |
136
- | `runner` | Run saved tools by ID only. Read-only lookups. No building/editing |
137
- | `builder` | Runner + build/edit/save tools, call systems. No system CRUD |
138
- | `admin` | Full access (default) |
126
+ ### Building a Tool
139
127
 
140
- ### Preset-to-Command Matrix
128
+ 1. **Load relevant protocol references** from `references/` based on the systems involved (http, postgres, graphql, etc.)
129
+ 2. Use `sg system find` for every involved system — note `storedCredentials` and the system URL
130
+ 3. Use `sg system search-docs` for each system — look up endpoints, auth patterns, pagination, response structure
131
+ 4. Use `sg system call` to test 1-2 primary endpoints — verify response structure and field names before building
132
+ 5. Call `sg tool build --config '{...}'` with the full tool config (see Reference → Tool Config Schema)
133
+ 6. Test with `sg tool run --draft <draftId>`. Use `--include-step-results` to inspect raw step data
134
+ 7. Iterate using `sg tool edit --draft <draftId> --patches '[...]'` (see Reference → Tool Editing)
135
+ 8. Present results to the user and ask for approval. Only then run `sg tool save --draft <draftId>`
141
136
 
142
- ```
143
- Command runner builder admin
144
- ─────────────────────────────────────────────────
145
- sg init x x x
146
- sg update x x x
147
- sg skill x x x
148
- sg tool build - x x
149
- sg tool run --tool x x x
150
- sg tool run --config/etc - x x
151
- sg tool edit - x x
152
- sg tool save - x x
153
- sg tool find / list x x x
154
- sg system create - - x
155
- sg system edit - - x
156
- sg system oauth - - x
157
- sg system call - x x
158
- sg system search-docs - x x
159
- sg system find / list x x x
160
- sg run list x x x
161
- sg run get x x x
162
- ```
137
+ ### Editing a Tool
163
138
 
164
- ### Setting the Preset
139
+ 1. Use `sg tool find --id <toolId>` or `sg tool find <query>` to locate the tool and inspect its current config
140
+ 2. Determine whether upstream steps use object or array selectors so you reference `.data` correctly in downstream code
141
+ 3. Plan the JSON Patch operations (RFC 6902)
142
+ 4. Apply with `sg tool edit --tool <toolId> --patches '[...]'` (or `--draft <draftId>` for drafts)
143
+ 5. Re-run to verify behavior
165
144
 
166
- ```bash
167
- # During init (interactive or non-interactive)
168
- sg init --preset runner --api-key "..." --global
145
+ ### Creating/Editing a System
146
+
147
+ 1. Search for an existing system first: `sg system find <query>`
148
+ 2. If creating: `sg system create --name "..." --url "..." --credentials '{...}'`. Prefer `--template <id>` when one exists — it auto-fills URL and OAuth config
149
+ 3. For OAuth: `sg system oauth --system-id <id> --scopes "..."` opens a browser flow. User approves → tokens saved automatically
150
+ 4. Verify connectivity with `sg system call`
151
+ 5. For updates: `sg system edit --id <id>` with the fields to change
169
152
 
170
- # Via environment variable (overrides config.json)
171
- export SUPERGLUE_CLI_PRESET=builder
153
+ ### Running a Tool (Ad-hoc)
172
154
 
173
- # Manually edit .superglue/config.json
174
- { "preset": "runner", "apiKey": "...", ... }
155
+ ```bash
156
+ sg tool run --tool <toolId> --payload '{"userId":"123"}'
157
+ sg tool run --draft <draftId> --payload-file payload.json
175
158
  ```
176
159
 
177
- Blocked commands print a clear error with the current preset name and how to change it.
160
+ Streams live execution logs to the terminal. Use `--include-step-results` for raw per-step responses and `--include-config` for the full config dump.
178
161
 
179
- ## Command Reference
162
+ ---
180
163
 
181
- ### `sg init`
164
+ ## Reference
182
165
 
183
- Interactive setup — API key, endpoint, output mode, capability preset. Creates `.superglue/`.
166
+ ### Tool Translation (web agent tool → CLI command)
184
167
 
185
- Non-interactive: `sg init --api-key "..." --preset runner --global`
168
+ Agents familiar with the web tool names can map them directly to CLI commands:
186
169
 
187
- ### Tool Commands
170
+ | Web agent tool | CLI command | Notes |
171
+ | ---------------------------- | --------------------------------------------- | ------------------------------------------------------------------ |
172
+ | `build_tool` | `sg tool build --config '{...}'` | CLI is not AI-powered — you provide the full JSON config |
173
+ | `edit_tool` | `sg tool edit --tool <id> --patches '[...]'` | JSON Patch (RFC 6902). Use `--draft <id>` for drafts |
174
+ | `run_tool` | `sg tool run --tool <id>` / `--draft <id>` | Add `--include-step-results` to inspect per-step data |
175
+ | `save_tool` | `sg tool save --draft <draftId>` | Persists a draft to the database |
176
+ | `inspect_tool` / `find_tool` | `sg tool find --id <id>` / `sg tool find <q>` | Full config with `--id`, compact search with a query string |
177
+ | `create_system` | `sg system create --name "..." --url "..."` | Use `--template <id>` when available |
178
+ | `edit_system` | `sg system edit --id <id> ...` | Supports `--env dev\|prod` |
179
+ | `find_system` | `sg system find <query>` / `--id <id>` | Returns `storedCredentials` and system URL |
180
+ | `call_system` | `sg system call --url "..." --system-id <id>` | Authenticated ad-hoc calls for testing / schema introspection |
181
+ | `search_documentation` | `sg system search-docs --system-id <id> -k` | Targeted keyword search over ingested system docs |
182
+ | `authenticate_oauth` | `sg system oauth --system-id <id> --scopes` | Opens browser flow. Supports `--grant-type client_credentials` too |
183
+ | `get_runs` | `sg run list` / `sg run get <runId>` | Filter `list` by `--tool`, `--status`, `--source`, `--limit` |
184
+ | (no direct equivalent) | `sg init`, `sg update`, `sg skill` | CLI-specific setup, updater, and this reference system |
188
185
 
189
- **`sg tool build`** — Register a tool config. Returns a `draftId`. Not AI-powered — you provide the full config.
186
+ Web-agent-only concepts with no CLI equivalent: `load_skill` (references are accessed via `sg skill <topic>` instead), `create_schedule`/`edit_schedule`/`find_schedule` (manage schedules via web app or REST API), `authenticate_oauth`'s dedicated MCP `authenticate` tool (CLI uses `sg system oauth`).
190
187
 
191
- ```bash
192
- sg tool build --config '{"id":"...","steps":[...]}' # inline JSON
193
- sg tool build --id my-tool --instruction "..." --steps steps.json --payload '{"key":"val"}'
194
- sg tool build --config tool.json # from file
195
- ```
188
+ ### Command Reference
196
189
 
197
- | `--config <file-or-json>` | Full JSON config (file path or inline JSON string) |
198
- | `--id <id>` | Tool ID (kebab-case) |
199
- | `--instruction <text>` | Human-readable description |
200
- | `--steps <file>` | JSON file with steps array |
201
- | `--payload <json>` | Sample payload |
202
- | `--file <key=path>` | Attach file reference |
190
+ **`sg init`** — Interactive or non-interactive setup. Creates `.superglue/` config. Flags: `--api-key`, `--endpoint`, `--preset`, `--global`.
203
191
 
204
- **`sg tool run`** — Execute a draft or saved tool. Streams live execution logs to the terminal.
192
+ **Tool commands:**
205
193
 
206
194
  ```bash
195
+ sg tool build --config '{"id":"...","steps":[...]}' # inline JSON
196
+ sg tool build --config tool.json # from file
197
+ sg tool build --id my-tool --instruction "..." --steps steps.json --payload '{...}'
207
198
  sg tool run --draft <draftId> --payload '{"userId":"123"}'
208
- sg tool run --tool my-tool --payload-file payload.json
209
- ```
210
-
211
- | `--draft <id>` / `--tool <id>` | Draft ID or saved tool ID |
212
- | `--payload <json>` / `--payload-file <path>` | Payload |
213
- | `--include-step-results` | Include raw step results |
214
- | `--include-config` | Include full tool config |
215
-
216
- **`sg tool edit`** — Apply JSON Patch (RFC 6902) operations.
217
-
218
- ```bash
199
+ sg tool run --tool my-tool --payload-file payload.json --include-step-results
219
200
  sg tool edit --draft <draftId> --patches '[{"op":"replace","path":"/steps/0/config/url","value":"..."}]'
220
201
  sg tool edit --tool my-tool --patches patches.json
221
- ```
222
-
223
- | `--patches <json-or-file>` | JSON Patch array (inline or file) |
224
-
225
- **`sg tool save`** — Persist draft to database. Deletes draft file on success.
226
-
227
- ```bash
228
202
  sg tool save --draft <draftId>
203
+ sg tool list
204
+ sg tool find "shopify orders" # keyword search (compact results)
205
+ sg tool find --id my-tool # exact lookup (full config)
229
206
  ```
230
207
 
231
- **`sg tool list` / `sg tool find`**
232
-
233
- ```bash
234
- sg tool list # all non-archived tools
235
- sg tool find "shopify orders" # search (compact results)
236
- sg tool find --id my-tool # exact ID lookup (full config)
237
- ```
238
-
239
- ### System Commands
240
-
241
- **`sg system create`**
242
-
243
- **Required flags:**
244
-
245
- - `--name <name>` — Human-readable display name
246
- - `--url <url>` — API base URL (auto-filled when using `--template`)
247
-
248
- **Optional:**
249
-
250
- - `--id <id>` — System ID (lowercase, underscores only, no hyphens). Derived from `--name` if omitted.
251
- - `--template <id>` — Pre-configured template (auto-fills name and url if not provided)
252
-
253
- **Example with credentials (non-interactive — use this in AI agent / CI contexts):**
254
-
255
- ```bash
256
- sg system create --name "My API" --url https://api.example.com \
257
- --credentials '{"api_key":"sk-xxx"}'
258
- ```
259
-
260
- **With template:**
208
+ **System commands:**
261
209
 
262
210
  ```bash
211
+ sg system create --name "My API" --url https://api.example.com --credentials '{"api_key":"sk-xxx"}'
263
212
  sg system create --name "Slack" --template slack
213
+ sg system edit --id my_api --credentials '{...}'
214
+ sg system list
215
+ sg system find slack
216
+ sg system find --id my_api --env dev
217
+ sg system call --url https://api.example.com/users --system-id my_api --method GET \
218
+ --headers '{"Authorization":"Bearer <<my_api_access_token>>"}'
219
+ sg system search-docs --system-id slack -k "send message channels"
220
+ sg system oauth --system-id gmail --scopes "https://www.googleapis.com/auth/gmail.readonly"
221
+ sg system oauth --system-id my_api --grant-type client_credentials --scopes "read write"
264
222
  ```
265
223
 
266
- **Full flag reference:**
267
-
268
- | Flag | Description |
269
- | ---------------------- | ---------------------------------------------------------------------- |
270
- | `--name <name>` | Human-readable name — **REQUIRED** |
271
- | `--id <id>` | System ID (lowercase, underscores only) — derived from name if omitted |
272
- | `--url <url>` | API base URL — **REQUIRED** (auto-filled by `--template`) |
273
- | `--template <id>` | Template ID (stripe, shopify, slack, etc.) |
274
- | `--credentials <json>` | Credentials JSON (all fields including secrets) |
275
- | `--docs-url <url>` | Documentation URL to scrape |
276
- | `--openapi-url <url>` | OpenAPI spec URL |
277
- | `--env <environment>` | Environment: `dev` or `prod` (default: prod) |
278
-
279
- **`sg system edit`** — Update system config or credentials. Supports `--env dev|prod`.
280
- **`sg system list` / `sg system find`** — List or search systems. `find` supports `--env dev|prod`.
281
-
282
- **`sg system call`** — **CRITICAL for tool building.** Make authenticated calls to APIs, databases, and file servers. Use this to:
283
-
284
- - Explore API endpoints and response structures
285
- - Verify field names and data shapes BEFORE building tools
286
-
287
- ```bash
288
-
289
- # POST request with auth and body
290
- sg system call --url https://api.example.com/users \
291
- --system-id my_api \
292
- --method POST \
293
- --headers '{"Authorization":"Bearer <<my_api_access_token>>"}' \
294
- --body '{"name":"test"}'
295
-
296
- # Database query (Postgres)
297
- sg system call --url "postgres://<<my_db_host>>:5432/mydb" \
298
- --system-id my_db \
299
- --body '{"query":"SELECT * FROM users LIMIT 5"}'
300
-
301
- # Redis command
302
- sg system call --url "redis://<<my_redis_host>>:6379/0" \
303
- --system-id my_redis \
304
- --body '{"command":"HGETALL","args":["user:123"]}'
305
-
306
- # File server (SFTP)
307
- sg system call --url "sftp://<<my_sftp_host>>:22/data" \
308
- --system-id my_sftp \
309
- --body '{"operation":"list","path":"/"}'
310
- ```
311
-
312
- | Flag | Description |
313
- | ------------------- | ------------------------------------------------------------------------------------------------- |
314
- | `--url <url>` | Full URL with protocol (http/https/postgres/postgresql/mssql/sqlserver/redis/rediss/sftp/ftp/smb) |
315
- | `--system-id <id>` | System ID for credential injection |
316
- | `--method <method>` | HTTP method (GET, POST, PUT, DELETE, PATCH) |
317
- | `--headers <json>` | HTTP headers JSON with credential placeholders |
318
- | `--body <string>` | Request body (JSON string) |
319
- | `--env <env>` | Environment: `dev` or `prod` |
320
- | `--file <key=path>` | File references (repeatable) |
321
-
322
- **`sg system search-docs`** — Search system documentation.
224
+ **Run commands:**
323
225
 
324
226
  ```bash
325
- sg system search-docs --system-id slack -k "send message channels"
227
+ sg run list --tool my-tool --status failed --limit 20
228
+ sg run get <runId> --fetch-results
326
229
  ```
327
230
 
328
- **`sg system oauth`** — Authenticate via OAuth.
231
+ **File attachments:**
329
232
 
330
233
  ```bash
331
- sg system oauth --system-id gmail --scopes "https://www.googleapis.com/auth/gmail.readonly"
332
- sg system oauth --system-id my_api --grant-type client_credentials --scopes "read write"
234
+ sg tool run --draft <id> --payload '{"data":"file::mysheet"}' --file mysheet=data.xlsx
333
235
  ```
334
236
 
335
- | `--system-id <id>` | Required |
336
- | `--scopes <scopes>` | Space-separated OAuth scopes (required) |
337
- | `--grant-type <type>` | `authorization_code` (default) or `client_credentials` |
338
-
339
- ### Run Commands
340
-
341
- **`sg run list`** — List execution runs. Filter by `--tool`, `--status`, `--source`, `--limit`.
342
- **`sg run get <runId>`** — Get run details. `--fetch-results` to include data.
343
-
344
- ---
237
+ Attach files with repeatable `--file key=path`. Reference in payloads with `file::<key>`. Auto-parsed to JSON where applicable. See `references/file-handling.md` for the full reference syntax including `.raw`, `.base64`, and `.extracted` suffixes.
345
238
 
346
- ## Tool Configuration — Full Schema
239
+ ### Tool Config Schema
347
240
 
348
241
  ```json
349
242
  {
350
243
  "id": "kebab-case-tool-name",
351
- "instruction": "Brief human-readable description of what this tool does",
244
+ "instruction": "Brief 1-2 sentence description of what this tool does and returns",
352
245
  "steps": [
353
246
  {
354
247
  "id": "unique-step-id",
355
248
  "config": {
249
+ "type": "request",
356
250
  "systemId": "example_system",
357
- "url": "https://api.example.com/endpoint?param=<<payload_field>>",
251
+ "url": "<<example_system_url>>/endpoint?param=<<payload_field>>",
358
252
  "method": "GET",
359
- "headers": {
360
- "Authorization": "Bearer <<example_system_access_token>>"
361
- },
253
+ "headers": { "Authorization": "Bearer <<example_system_access_token>>" },
362
254
  "queryParams": { "limit": "10" },
363
255
  "body": "{ \"key\": \"<<payload_field>>\" }"
364
256
  },
365
257
  "dataSelector": "(sourceData) => sourceData.previousStep.data.items",
366
- "failureBehavior": "fail"
258
+ "failureBehavior": "fail",
259
+ "modify": false
367
260
  }
368
261
  ],
369
262
  "outputTransform": "(sourceData) => sourceData.stepId.data",
@@ -372,91 +265,66 @@ sg system oauth --system-id my_api --grant-type client_credentials --scopes "rea
372
265
  }
373
266
  ```
374
267
 
375
- ### Step Config Fields (Request Steps)
268
+ **Request step fields** (HTTP, Postgres, MSSQL, Redis, FTP/SFTP, SMB) — see protocol-specific references for full details:
376
269
 
377
- | Field | Type | Description |
378
- | ------------- | ------ | -------------------------------------------- |
379
- | `type` | string | `"request"` (default, can be omitted) |
380
- | `systemId` | string | System whose credentials to use |
381
- | `url` | string | Full URL with `<<variable>>` placeholders |
382
- | `method` | string | HTTP method |
383
- | `headers` | object | HTTP headers with credential placeholders |
384
- | `queryParams` | object | URL query parameters |
385
- | `body` | string | Request body (JSON string with placeholders) |
386
- | `pagination` | object | Auto-pagination config (see below) |
270
+ | Field | Type | Description |
271
+ | ------------- | ------ | ------------------------------------------------------------------------ |
272
+ | `type` | string | `"request"` (default, can be omitted) |
273
+ | `systemId` | string | Optional. Links system credentials for `<<systemId_credKey>>` resolution |
274
+ | `url` | string | Full URL with `<<variable>>` placeholders. Required. |
275
+ | `method` | string | HTTP method (HTTP only) |
276
+ | `headers` | object | HTTP headers with credential placeholders (HTTP only) |
277
+ | `queryParams` | object | URL query parameters (HTTP only) |
278
+ | `body` | string | Request body / DB query / Redis command / file operation |
279
+ | `pagination` | object | Auto-pagination config (HTTP only, see `references/http.md`) |
387
280
 
388
- ### Step Config Fields (Transform Steps)
281
+ **Transform step fields:**
389
282
 
390
- | Field | Type | Description |
391
- | --------------- | ------ | ------------------------------------------------ |
392
- | `type` | string | `"transform"` — **REQUIRED** for transform steps |
393
- | `transformCode` | string | JS function: `(sourceData) => transformedData` |
283
+ | Field | Type | Description |
284
+ | --------------- | ------ | -------------------------------------------------- |
285
+ | `type` | string | `"transform"` — required for transform steps |
286
+ | `transformCode` | string | `(sourceData) => transformedData` — single-line JS |
394
287
 
395
- ### Step Behavior Fields
288
+ Transform steps do NOT have `systemId`, `url`, `method`, `headers`, `body`, `queryParams`, or `pagination`.
396
289
 
397
- | Field | Type | Description |
398
- | ----------------- | ------ | ------------------------------------------------ |
399
- | `dataSelector` | string | JS function controlling step input and loop mode |
400
- | `failureBehavior` | string | `fail` (default) or `continue` |
290
+ **Step behavior fields:**
401
291
 
402
- ---
292
+ | Field | Type | Description |
293
+ | ----------------- | ------- | ---------------------------------------------------- |
294
+ | `dataSelector` | string | JS function controlling step input and loop mode |
295
+ | `failureBehavior` | string | `fail` (default) or `continue` |
296
+ | `modify` | boolean | Set `true` only when the step writes/updates/deletes |
403
297
 
404
- ## Credential Placeholders
298
+ ### Expression Syntax (`<<>>`)
405
299
 
406
- System credentials are namespaced as `<<systemId_credentialKey>>` and resolved server-side at execution time. **You MUST explicitly reference them in headers.**
300
+ All step config fields (url, headers, body, queryParams) support `<<expression>>` placeholders.
407
301
 
408
- ### Auth Header Patterns
302
+ **Simple top-level keys** — only these work without arrow functions:
409
303
 
410
- ```json
411
- {"Authorization": "Bearer <<stripe_api_key>>"}
412
- {"Authorization": "Bearer <<gmail_access_token>>"}
413
- {"X-API-Key": "<<my_api_api_key>>"}
414
- {"Authorization": "Basic <<my_api_username>>:<<my_api_password>>"}
304
+ ```
305
+ <<userId>> payload inputs
306
+ <<currentItem>> whole current loop item
307
+ <<page>> <<offset>> <<cursor>> <<limit>> <<pageSize>> pagination variables
308
+ <<systemId_api_key>> system credentials (namespaced: systemId_credKey)
309
+ <<systemId_url>> system base URLs (namespaced: systemId_url)
310
+ <<sg_auth_email>> email of the authenticated user (NOT available in scheduled runs)
415
311
  ```
416
312
 
417
- Basic auth is auto-encoded: if the value after `Basic ` isn't already base64, the engine encodes it automatically.
418
-
419
- ### Credential Lifecycle
420
-
421
- - Non-sensitive creds (`client_id`, `auth_url`, etc.) are stored via `--credentials`
422
- - Sensitive creds (`api_key`, `client_secret`) — pass via `--credentials` JSON: `--credentials '{"client_secret":"..."}'`
423
- - OAuth tokens (`access_token`, `refresh_token`) are auto-refreshed before each step execution
424
-
425
- ---
426
-
427
- ## Variables and Data Flow
428
-
429
- ### Variable Syntax
430
-
431
- All step config fields support `<<variable>>` placeholders:
432
-
433
- | Syntax | Resolves to |
434
- | -------------------------- | --------------------------- |
435
- | `<<fieldName>>` | Payload field or credential |
436
- | `<<systemId_credKey>>` | System credential |
437
- | `<<sg_auth_email>>` | Email of authenticated user |
438
- | `<<(sourceData) => expr>>` | JavaScript expression |
439
-
440
- **CRITICAL**: Simple `<<varName>>` only works for **top-level keys**. No dots, no nesting.
441
-
442
- - VALID: `<<userId>>`, `<<currentItem>>`, `<<stripe_api_key>>`, `<<sg_auth_email>>`
443
- - INVALID: `<<currentItem.id>>`, `<<sourceData.userId>>` — these FAIL at runtime
444
-
445
- For nested access, use arrow functions: `<<(sourceData) => sourceData.currentItem.id>>`
446
-
447
- ### Context Variables
448
-
449
- Context variables provide information about the execution environment:
313
+ Simple `<<varName>>` only works for top-level keys. No dots, no nesting. `<<currentItem.id>>`, `<<sourceData.userId>>`, `<<user.name>>` all FAIL at runtime.
450
314
 
451
- - `<<sg_auth_email>>` — Email of the authenticated user who triggered the tool
315
+ **Arrow function expressions** — for everything else:
452
316
 
453
- **Use case**: Personalize tool outputs based on who runs the tool (e.g., user-specific permissions, account lookups, audit logging).
317
+ ```
318
+ <<(sourceData) => sourceData.currentItem.player_id>>
319
+ <<(sourceData) => sourceData.getUsers.data.map(u => u.id)>>
320
+ <<(sourceData) => JSON.stringify({ ids: sourceData.fetchUsers.data.map(u => u.id) })>>
321
+ ```
454
322
 
455
- **Important**: `sg_auth_email` is NOT available in scheduled executions. Tools using `<<sg_auth_email>>` will fail if run via scheduler.
323
+ Object/array return values are `JSON.stringify`'d automatically when spliced into strings.
456
324
 
457
325
  ### sourceData Object
458
326
 
459
- `sourceData` is the cumulative state available to all JS expressions (data selectors, transforms, variable expressions):
327
+ `sourceData` is the cumulative state available to every JS expression, data selector, and transform:
460
328
 
461
329
  ```javascript
462
330
  sourceData = {
@@ -465,45 +333,30 @@ sourceData = {
465
333
  date: "2024-01-15",
466
334
 
467
335
  // Previous step results, keyed by step ID
468
- // Object-selector step:
469
- getUsers: { currentItem: {}, data: { users: [...] }, success: true },
470
- // Array-selector (loop) step:
471
- fetchDetails: [
336
+ getUsers: { currentItem: {}, data: { users: [...] }, success: true }, // object selector
337
+ fetchDetails: [ // array selector
472
338
  { currentItem: "id1", data: { name: "Alice" }, success: true },
473
- { currentItem: "id2", data: { name: "Bob" }, success: true },
339
+ { currentItem: "id2", data: { name: "Bob" }, success: true }
474
340
  ],
475
341
 
476
342
  // Current loop item (only set inside a looping step's config)
477
343
  currentItem: { id: 1 },
478
344
 
479
345
  // Credentials (flattened, namespaced)
480
- systemId_access_token: "...",
481
- systemId_api_key: "..."
346
+ my_api_access_token: "...",
347
+ my_api_api_key: "..."
482
348
  }
483
349
  ```
484
350
 
485
- ### Step Result Envelope
486
-
487
- **Every** step result is wrapped in an envelope — you MUST account for this.
488
-
489
- **Object selector (or no selector)** — step runs once:
351
+ ### Step Result Envelopes
490
352
 
491
- ```javascript
492
- sourceData.stepId = { currentItem: <selectorOutput>, data: <apiResponse>, success: true }
493
- // Access the API response:
494
- sourceData.stepId.data
495
- sourceData.stepId.data.users
496
- ```
353
+ **Every** step result is wrapped in `{ currentItem, data, success }`. You MUST account for this when writing data selectors or transforms.
497
354
 
498
- **Array selector** — step loops, result is an array of envelopes:
355
+ - **Object selector (or none)** — access via `sourceData.stepId.data`
356
+ - **Array selector (loop)** — array of envelopes: `sourceData.stepId.map(i => i.data)`
357
+ - **Paginated step** — all pages merged into a single `.data` field: access via `sourceData.stepId.data`. Do NOT `.map()` over it — returns a single object if one result, array if multiple (unwrapped from single-element array).
499
358
 
500
- ```javascript
501
- sourceData.stepId = [
502
- { currentItem: <item1>, data: <response1>, success: true },
503
- { currentItem: <item2>, data: <response2>, success: true },
504
- ...
505
- ]
506
- ```
359
+ NEVER access step results without `.data`. `sourceData.stepId.results` hits the envelope, not the API response.
507
360
 
508
361
  ### Data Selectors
509
362
 
@@ -515,50 +368,29 @@ Control what a step receives as input and whether it loops:
515
368
  | Array | Step runs once per item (loop mode) |
516
369
  | `undefined`/`null` | Step receives full sourceData |
517
370
 
518
- In loop mode, `sourceData.currentItem` is set to the current array element.
371
+ In loop mode, `sourceData.currentItem` is set to the current array element. Empty arrays are valid — the step skips execution.
519
372
 
520
- Empty arrays are valid — the step simply skips execution.
373
+ ### Transform Steps vs outputTransform
521
374
 
522
- ### Two Step Types
375
+ | Need | Use |
376
+ | ------------------------------------------- | ---------------------------------------------------------------------- |
377
+ | Reshape data for a SUBSEQUENT request step | Transform step (`config.type: "transform"`) |
378
+ | Shape the final tool output | `outputTransform` (runs after all steps; slightly different signature) |
379
+ | Control input / looping for a step | `dataSelector` on the step |
380
+ | Inline data computation in URL/body/headers | `<<(sourceData) => ...>>` expressions |
523
381
 
524
- **Request step** (HTTP, PostgreSQL, MSSQL, Redis, FTP/SFTP/SMB) — makes an API call:
382
+ `outputTransform` must be a single-line JS string (no literal newlines or tabs).
525
383
 
526
- ```json
527
- {
528
- "id": "get-users",
529
- "config": {
530
- "type": "request",
531
- "systemId": "my_api",
532
- "url": "https://api.example.com/users",
533
- "method": "GET",
534
- "headers": { "Authorization": "Bearer <<my_api_access_token>>" }
535
- }
536
- }
537
- ```
384
+ **Complex request bodies** — when a body needs data from multiple steps or aggregation, use a preceding transform step:
538
385
 
539
- **Transform step** — pure JavaScript, no API call. Use when a subsequent request step needs reshaped data:
386
+ ```javascript
387
+ // Step: prepareBody (transform)
388
+ transformCode: "(sourceData) => { var items = sourceData.step1.data.results; return { data: items.filter(function(i) { return i.active; }), count: items.length }; }";
540
389
 
541
- ```json
542
- {
543
- "id": "format-data",
544
- "config": {
545
- "type": "transform",
546
- "transformCode": "(sourceData) => sourceData.getUsers.data.map(u => ({ id: u.id, name: u.fullName }))"
547
- }
548
- }
390
+ // Step: submitData (request)
391
+ body: "<<(sourceData) => JSON.stringify(sourceData.prepareBody.data)>>";
549
392
  ```
550
393
 
551
- Transform steps do NOT have: `systemId`, `url`, `method`, `headers`, `body`, `queryParams`, or `pagination`. The `transformCode` function receives `sourceData` (same object available everywhere) and its return value becomes `.data` in the step envelope.
552
-
553
- **When to use each:**
554
-
555
- | Need | Use |
556
- | ------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
557
- | Filter/reshape data for a SUBSEQUENT request step | Transform step (`config.type: "transform"`) |
558
- | Shape the final tool output | `outputTransform` (runs after all steps, has a slightly different schema than transform only steps) |
559
- | Select input / control looping for a step | `dataSelector` on the step |
560
- | Inline data computation in URL/body/headers | `<<(sourceData) => ...>>` expressions |
561
-
562
394
  ### Execution Pipeline
563
395
 
564
396
  For each step in order:
@@ -566,187 +398,77 @@ For each step in order:
566
398
  1. Build `sourceData`: `{ ...originalPayload, ...previousStepResults, ...credentials }`
567
399
  2. Run `dataSelector(sourceData)` → determines single vs loop execution
568
400
  3. For each item: merge `currentItem` into `sourceData`, resolve `<<>>` variables, execute step
569
- - **Request step**: makes the HTTP/DB/FTP call, raw response becomes `.data`
401
+ - **Request step**: makes the HTTP/DB/FTP/Redis call, raw response becomes `.data`
570
402
  - **Transform step**: runs `transformCode(sourceData)`, return value becomes `.data`
571
403
  4. Wrap result: `{ currentItem, data, success }` and store in `sourceData[stepId]`
572
404
  5. After all steps: run `outputTransform(sourceData)` to shape final output
573
405
 
574
- ---
406
+ All user-provided JS runs in an isolated Deno sandbox.
575
407
 
576
- ## HTTP API Patterns
408
+ ### Credentials and Systems
577
409
 
578
- ### Pagination
410
+ Credentials are namespaced as `<<systemId_credentialKey>>` and resolved server-side at execution time. You MUST explicitly reference them:
579
411
 
580
- ```json
581
- {
582
- "pagination": {
583
- "type": "offset|cursor|page",
584
- "pageSize": 100,
585
- "cursorPath": "$.nextPageToken",
586
- "stopCondition": "(response) => !response.hasMore"
587
- }
588
- }
412
+ ```
413
+ System id="stripe", storedCredentials: api_key → "sk_proj****"
414
+ → Available as: <<stripe_api_key>>
589
415
  ```
590
416
 
591
- | Type | How it works |
592
- | -------- | ------------------------------------------------------------ |
593
- | `offset` | Increments `offset` param by `pageSize` each page |
594
- | `cursor` | Extracts next cursor from `cursorPath`, sends as query param |
595
- | `page` | Increments `page` query param |
596
-
597
- All types stop when `stopCondition` returns true, response is empty, or max pages reached.
598
-
599
- ## Systems
600
-
601
- ### Credential Model
602
-
603
- - `credentials` — all credentials passed as JSON via `--credentials`
604
- - **Pass ALL credentials** (including secrets like api_key, client_secret) directly via `--credentials '{"api_key":"..."}'`. Ask the user to provide the secret values, then include them in the JSON.
605
- - OAuth tokens (`access_token`, `refresh_token`) are auto-refreshed before each step execution
417
+ **Auth header patterns:**
606
418
 
607
- ### Templates
419
+ ```json
420
+ {"Authorization": "Bearer <<stripe_api_key>>"}
421
+ {"Authorization": "Bearer <<gmail_access_token>>"}
422
+ {"X-API-Key": "<<my_api_api_key>>"}
423
+ {"Authorization": "Basic <<my_api_username>>:<<my_api_password>>"}
424
+ ```
608
425
 
609
- Templates auto-populate endpoints and OAuth config. Use `sg system find` to discover available templates.
426
+ Basic auth auto-encodes: if the value after `Basic ` isn't already base64, the engine encodes it.
610
427
 
611
- **Preconfigured OAuth** (no user client_id/secret needed): slack, salesforce, asana, notion, airtable, jira, confluence
428
+ **System URL variables** — use these instead of hardcoding base URLs. They switch automatically between dev/prod environments:
612
429
 
613
- ### OAuth Flow
430
+ ```json
431
+ { "url": "<<salesforce_url>>/services/data/v58.0/sobjects/Account" }
432
+ ```
614
433
 
615
- **IMPORTANT:** For OAuth systems, prefer `--template` when available because it auto-configures OAuth URLs and defaults. OAuth also works without a template if you provide required credentials (for example `client_id`, `auth_url`, and `token_url`) manually.
434
+ **Credential lifecycle:**
616
435
 
617
- If you don't know the template ID, the CLI auto-detects it from the URL — but using `--template` explicitly is more reliable.
436
+ - Pass ALL credentials (including secrets) via `--credentials '{"api_key":"...","client_secret":"..."}'` on create/edit
437
+ - OAuth tokens (`access_token`, `refresh_token`) auto-refresh before each step execution
438
+ - Non-sensitive fields (`client_id`, `auth_url`, `token_url`) are stored alongside secrets in the same `--credentials` JSON
618
439
 
619
- **Step 1: Create the system with template and credentials**
440
+ **System IDs:** lowercase letters, numbers, underscores only — no hyphens. Used for credential namespacing.
620
441
 
621
- ```bash
622
- # Best: explicit template (auto-fills URL and OAuth config)
623
- sg system create --name "Gmail" --template gmail \
624
- --credentials '{"client_id":"...","client_secret":"..."}'
442
+ **Templates:** auto-populate endpoints and OAuth config. `sg system find` lists available templates.
625
443
 
626
- # Also works: URL-based auto-detection (template inferred from googleapis.com)
627
- sg system create --name "Gmail" --url https://gmail.googleapis.com \
628
- --credentials '{"client_id":"...","client_secret":"..."}'
629
- ```
444
+ - **Preconfigured OAuth** (no user `client_id`/`client_secret` needed): slack, salesforce, asana, notion, airtable, jira, confluence
445
+ - **Common OAuth templates:** gmail, googleDrive, googleCalendar, googleSheets, slack, salesforce, github, jira, confluence, notion, airtable, hubspot, shopify, dropbox, zoom, microsoft
630
446
 
631
- **For custom OAuth systems without a template**, you must include `client_id`, `client_secret`, `auth_url`, and `token_url` in the credentials at create time — or add them later with `sg system edit` before running `sg system oauth`:
447
+ **Custom OAuth (no template):** must include `client_id`, `client_secret`, `auth_url`, `token_url` in credentials at create time — or add later with `sg system edit`:
632
448
 
633
449
  ```bash
634
450
  sg system create --name "My API" --url https://api.example.com \
635
451
  --credentials '{"client_id":"...","client_secret":"...","auth_url":"https://example.com/oauth/authorize","token_url":"https://example.com/oauth/token"}'
636
-
637
- # Or add credentials to an existing system:
638
- sg system edit --id my_api \
639
- --credentials '{"client_id":"...","client_secret":"...","auth_url":"https://...","token_url":"https://..."}'
640
452
  ```
641
453
 
642
- **Step 2: Authenticate via OAuth**
643
-
644
- ```bash
645
- sg system oauth --system-id gmail --scopes "https://www.googleapis.com/auth/gmail.readonly"
646
- ```
647
-
648
- **Step 3:** User authenticates in browser → tokens saved automatically
649
-
650
- **Common OAuth templates:** gmail, googleDrive, googleCalendar, googleSheets, slack, salesforce, github, jira, confluence, notion, airtable, hubspot, shopify, dropbox, zoom, microsoft
651
-
652
- ### System IDs
653
-
654
- - Lowercase letters, numbers, underscores only — **no hyphens**
655
- - Used for credential namespacing: `<<systemId_credKey>>`
656
-
657
- ---
658
-
659
- ## Tool Building Guide
660
-
661
- ### Build Recipe
662
-
663
- Before producing a tool config:
664
-
665
- 1. Load relevant skills: data-handling and protocol skill(s) for the involved systems
666
- 2. Use `sg system find` for every involved system — note `storedCredentials` and URL
667
- 3. Use `sg system search-docs` for each system — look up endpoints, auth patterns, pagination, response structure
668
- 4. Use `sg system call` to test 1-2 primary endpoints — verify response structure and field names before building
669
- 5. Only then call `sg tool build --config '...'` with the full tool config
670
-
671
- ### Planning Steps
672
-
673
- - Fetch prerequisites: available projects, entity types, categories, etc.
674
- - Each step = one API call, one DB query, one file operation, or a transform step (no compound ops)
675
- - Final aggregation/filtering/sorting should happen in the `outputTransform`, not in a step
676
- - Step instructions: 2-3 sentences describing the goal and expected data
677
- - `instruction`: Write a 1-2 sentence summary of the tool's purpose. Never leave empty.
678
-
679
- ### Step Result Envelopes
680
-
681
- Every step result is wrapped — you MUST account for this in dataSelectors and outputTransform.
682
-
683
- - **Object selector (or none)** — access via `sourceData.stepId.data`
684
- - **Array selector** — access via `sourceData.stepId.map(i => i.data)`
685
- - **Paginated step** — access via `sourceData.stepId.data` (pages are merged server-side into a single envelope — do NOT `.map()` over it)
454
+ **Dev/Prod environments:** `--env dev|prod` at creation (immutable afterward). Two systems with the same ID but different environments are automatically linked. Dev systems inherit documentation from their linked prod system. When creating a dev system, always ask for new credentials — never copy from prod.
686
455
 
687
- NEVER access step results without `.data` — `sourceData.stepId.results` will fail because you're hitting the envelope, not the API response.
456
+ **System-specific instructions:** systems may include `specificInstructions` from the user (visible in `sg system find` output). Follow them when present — they override general patterns.
688
457
 
689
- ### modify Flag
458
+ ### Tool Editing (JSON Patch)
690
459
 
691
- Set `modify: true` only when the step writes, updates, or deletes live data. Don't rely on HTTP method alone — a POST that only reads (e.g., GraphQL query) should be `modify: false`. Default is false.
692
-
693
- ### Validation Rules
694
-
695
- - Tool must have a valid `id` string
696
- - Tool must have a `steps` array
697
- - `systemId` is optional on request steps. Setting it makes that system's credentials available as `<<systemId_credKey>>` template variables, and enables `<<systemId_url>>` for the base URL. Omit for public APIs.
698
- - Every request step must have a non-empty `url`
699
- - Transform steps must have `transformCode`
700
-
701
- ### Key Pitfalls
702
-
703
- - NEVER guess API endpoints — always verify with `sg system search-docs` or `sg system call` first
704
- - NEVER put `systemId` on the step object — it belongs inside `step.config.systemId`
705
- - NEVER use `<<(sourceData) => sourceData.payload.X>>` — payload fields are at root level of sourceData
706
- - NEVER use `<<currentItem.id>>` — use arrow function syntax: `<<(sourceData) => sourceData.currentItem.id>>`
707
- - NEVER hardcode pagination params — use `<<page>>`, `<<offset>>`, `<<cursor>>`, `<<limit>>`
708
- - NEVER add an `outputSchema` unless the user explicitly requested a specific response structure
709
- - NEVER leave instructions empty
710
- - ALWAYS explicitly configure authentication in every step — credentials are never automatically included in any protocol
711
- - PREFER system URL variables (`<<systemId_url>>`) over hardcoded base URLs
712
- - Check `sg system find` output for `storedCredentials` to know the exact variable names available
713
- - `outputTransform` must be a single-line JS string (no literal newlines or tabs)
714
- - NEVER use regex literals with `/` or complex escapes in transforms — they corrupt during serialization. Use `new URL()`, `.split()`, or `new RegExp()` instead. See data-handling reference "Serialization Safety".
715
- - For complex request bodies, use a preceding transform step — don't put multi-statement logic inside `<<>>` expressions
716
- - When the body contains nested/stringified JSON (e.g. LLM APIs): have `<<>>` expressions return a string via `JSON.stringify(...)`, and use a single expression for the whole body rather than mixing `<<>>` expressions with static JSON
717
-
718
- ### Complex Body Construction
719
-
720
- When a request body needs data from multiple steps or requires aggregation, use a preceding transform step:
721
-
722
- ```javascript
723
- // Step: prepareBody (transform)
724
- transformCode: "(sourceData) => { var items = sourceData.step1.data.results; return { data: items.filter(function(i) { return i.active; }), count: items.length }; }";
725
-
726
- // Step: submitData (request)
727
- body: "<<(sourceData) => JSON.stringify(sourceData.prepareBody.data)>>";
728
- ```
729
-
730
- ---
731
-
732
- ## Tool Editing Guide
733
-
734
- Edit tools using RFC 6902 JSON Patch operations via `sg tool edit`.
735
-
736
- ### Patch Format
737
-
738
- Each operation:
460
+ `sg tool edit` applies RFC 6902 JSON Patch operations. Each operation:
739
461
 
740
462
  ```typescript
741
463
  {
742
464
  op: "add" | "remove" | "replace" | "move" | "copy" | "test",
743
- path: string, // JSON Pointer (e.g., "/steps/0/config/url")
744
- value?: any, // required for add, replace, test
745
- from?: string // required for move, copy
465
+ path: string, // JSON Pointer, e.g. "/steps/0/config/url"
466
+ value?: any, // required for add, replace, test
467
+ from?: string // required for move, copy
746
468
  }
747
469
  ```
748
470
 
749
- ### Key Paths
471
+ **Key paths:**
750
472
 
751
473
  - `/instruction` — tool description
752
474
  - `/steps/N` — step at index N
@@ -755,148 +477,107 @@ Each operation:
755
477
  - `/outputTransform` — final output shaping function
756
478
  - `/outputSchema` — optional JSON schema for output
757
479
 
758
- ### Operations
480
+ **Operations:**
759
481
 
760
- - **`replace`** — Change an existing value. **Path must exist** — if the field is `null` or absent, `replace` fails. Use `add` instead for optional fields.
761
- - **`add`** — Creates the field if missing, overwrites if it exists. **Prefer `add` over `replace`** when the field might be null or absent. Append to array with `/steps/-`.
762
- - **`remove`** — Delete field or array element.
763
- - **`move`** — Reorder or relocate.
482
+ - `replace` — Change an existing value. **Path must exist** — if the field is `null` or absent, `replace` fails. Prefer `add` when the field might be absent.
483
+ - `add` — Creates if missing, overwrites if present. Append to array with `/steps/-`.
484
+ - `remove` — Delete field or array element.
485
+ - `move` — Reorder or relocate.
764
486
 
765
- ### Validation Rules
487
+ **Validation:**
766
488
 
767
- - Never patch `id` — tool IDs and draft IDs are immutable when editing
768
- - `op` and `path` are required on every patch; `path` must start with `/`
769
- - Patches are applied **sequentially** — later patches see effects of earlier ones
770
- - After patches, same validation rules as building apply (valid id, steps array, URLs present)
489
+ - Never patch `id` — tool IDs and draft IDs are immutable
490
+ - `op` and `path` required; `path` must start with `/`
491
+ - Patches applied **sequentially** — later patches see effects of earlier ones
492
+ - After patches, same validation as building (valid id, steps array, URLs on request steps, transformCode on transform steps)
771
493
 
772
- ### Principles
494
+ **Downstream shape changes:** if you change a step's output shape, check if later dataSelectors and `outputTransform` need updating. When removing array elements, subsequent indices shift down.
773
495
 
774
- - **Check result wrapping** — before writing any dataSelector or outputTransform patch, determine whether the upstream step used an object or array selector, and access `.data` accordingly
775
- - **Don't forget downstream** — if you change a step's output shape, check if later dataSelectors and outputTransform need updating
776
- - **Index shifts** — when removing array elements, subsequent indices shift down. Account for this in multi-patch operations.
496
+ ### Draft Management
777
497
 
778
- ---
498
+ Drafts live in `.superglue/drafts/<draftId>.json`. Created by `sg tool build`, updated by `sg tool edit`, deleted by `sg tool save`. Ephemeral — not persisted across sessions.
779
499
 
780
- ## Systems Handling Guide
500
+ ### Deployment
781
501
 
782
- Systems are reusable building blocks that store configuration details and credentials.
502
+ After building and saving, tools can be invoked from code via REST API, SDK, or webhook. See `references/integration.md` for complete SDK (TypeScript/Python), REST API, and webhook examples including retry patterns.
783
503
 
784
- ### Credential Use in Tool Configurations
504
+ **IP whitelisting:** if a customer's system requires IP whitelisting (firewall rules, security groups, etc.), superglue's outbound IPs are `34.234.12.178` and `18.198.191.215`.
785
505
 
786
- For every `systemId` referenced in a tool, credentials are namespaced as `<<systemId_credentialKey>>` and must be explicitly placed in the step config. For HTTP: in headers. For databases/Redis/file servers: in the connection URL. Nothing is injected automatically.
787
-
788
- ```
789
- System id="stripe", storedCredentials: api_key → "sk_proj****"
790
- → Available as: <<stripe_api_key>>
791
- ```
792
-
793
- OAuth tokens (`access_token`, `refresh_token`) are auto-refreshed before each step execution. Access tokens must also be explicitly referenced in step headers.
794
-
795
- ### System URL Variables
796
-
797
- System URLs are available as `<<systemId_url>>` and should be used instead of hardcoding base URLs:
798
-
799
- ```
800
- System id="salesforce", url="https://mycompany.salesforce.com"
801
- → Available as: <<salesforce_url>>
802
-
803
- Step config: { "url": "<<salesforce_url>>/services/data/v58.0/sobjects/Account" }
804
- ```
805
-
806
- ### Dev/Prod Environments
807
-
808
- `environment` is `"dev"` or `"prod"` (or unset for legacy systems). Set at creation only — immutable afterward. Two systems with the same ID but different environments are automatically linked. Dev systems inherit documentation from their linked prod system. When creating a dev system, always ask for new credentials — never copy from prod.
809
-
810
- Tools reference systems by ID only. Execution mode determines which environment is used (dev mode falls back to prod if no dev system exists).
811
-
812
- ### System-Specific Instructions
813
-
814
- Systems may include `specificInstructions` from the user (visible in `sg system find` output). Follow them when present. These capture API constraints, rate limits, special endpoints, auth requirements, or usage patterns.
815
-
816
- ---
817
-
818
- ## Debugging Failed Tools
819
-
820
- ### Debug Workflow
821
-
822
- 1. Run with `--include-step-results` to see raw step responses
823
- 2. Check each step's `data` field — is the API returning what you expect?
824
- 3. Verify credential placeholders match `sg system find --id <systemId>` placeholder list
825
- 4. **Test API calls directly with `sg system call`** — isolate whether the issue is auth, endpoint, or transform
826
-
827
- ---
828
-
829
- ## Deploying Tools to Production
830
-
831
- After building and saving a tool, integrate it into your application:
832
-
833
- ### REST API (Any Language)
506
+ Quick reference:
834
507
 
835
508
  ```bash
836
- # Run a tool
509
+ # REST (sync)
837
510
  curl -X POST "https://api.superglue.cloud/v1/tools/{toolId}/run" \
838
511
  -H "Authorization: Bearer $SUPERGLUE_API_KEY" \
839
512
  -H "Content-Type: application/json" \
840
- -d '{"inputs": {"userId": "123"}}'
513
+ -d '{"inputs":{"userId":"123"}}'
841
514
 
842
515
  # Webhook trigger (async, fire-and-forget)
843
516
  curl -X POST "https://api.superglue.cloud/v1/hooks/{toolId}?token=$SUPERGLUE_API_KEY" \
844
517
  -H "Content-Type: application/json" \
845
- -d '{"userId": "123"}'
518
+ -d '{"userId":"123"}'
846
519
  ```
847
520
 
848
- ### TypeScript SDK
521
+ ---
849
522
 
850
- ```typescript
851
- import { configure, runTool } from "@superglue/client";
852
- configure({ apiKey: process.env.SUPERGLUE_API_KEY!, baseUrl: "https://api.superglue.cloud/v1" });
853
- const response = await runTool("my-tool-id", { inputs: { userId: "123" } });
854
- // response.data is a Run object: { runId, toolId, status, data, error, metadata }
855
- ```
523
+ ## Common Pitfalls
524
+
525
+ - **Guessing API endpoints** — always verify with `sg system search-docs` or `sg system call` first
526
+ - **`systemId` in the wrong place** — it belongs inside `step.config.systemId`, not on the step object
527
+ - **`<<(sourceData) => sourceData.payload.X>>`** — payload fields are at root level of `sourceData`, not under `.payload`
528
+ - **`<<currentItem.id>>`** — must use arrow function syntax: `<<(sourceData) => sourceData.currentItem.id>>`
529
+ - **Hardcoded pagination params** — use `<<page>>`, `<<offset>>`, `<<cursor>>`, `<<limit>>`
530
+ - **Missing auth headers** — credentials are never automatically included in any protocol, including for OAuth systems (only token refresh is automatic)
531
+ - **Hardcoded base URLs** — prefer system URL variables (`<<systemId_url>>`) for environment portability
532
+ - **Empty `instruction`** — never leave the tool-level `instruction` blank
533
+ - **Adding `outputSchema` unsolicited** — only add when the user explicitly requests a specific response structure
534
+ - **Multi-line `outputTransform`** — must be a single-line JS string (no literal newlines or tabs)
535
+ - **Regex literals in transforms** — `/.../ ` literals and complex escapes corrupt during serialization. Use `new RegExp()`, `.split()`, or `new URL()` instead
536
+ - **Complex bodies inline** — for bodies built from multiple steps, use a preceding transform step rather than stuffing multi-statement logic into `<<>>` expressions
537
+ - **Double-encoded JSON** — when the body contains nested/stringified JSON (e.g. LLM APIs), have `<<>>` expressions return a string via `JSON.stringify(...)`, and use a single expression for the whole body rather than mixing `<<>>` with static JSON
538
+ - **POST for read-only ops** — GraphQL queries via POST should have `modify: false`. Don't rely on HTTP method alone
539
+ - **Saving without approval** — always present `sg tool run` results and ask before `sg tool save`
540
+ - **`sg_auth_email` in scheduled runs** — not available in scheduler-triggered executions. Tools using `<<sg_auth_email>>` will fail
541
+
542
+ ---
856
543
 
857
- ### Python SDK
544
+ ## Error Recovery
858
545
 
859
- ```python
860
- import os
861
- from superglue_client import AuthenticatedClient
862
- from superglue_client.api.tools import run_tool
863
- from superglue_client.models.run_request import RunRequest
864
- from superglue_client.models.run_request_inputs import RunRequestInputs
546
+ For protocol-specific error recovery (HTTP, Postgres, MSSQL, Redis, GraphQL, SFTP/SMB), read the matching reference file in `references/`. General strategies below.
865
547
 
866
- client = AuthenticatedClient(base_url="https://api.superglue.cloud/v1", token=os.environ["SUPERGLUE_API_KEY"])
867
- with client as c:
868
- result = run_tool.sync("my-tool-id", client=c, body=RunRequest(inputs=RunRequestInputs.from_dict({"userId": "123"})))
869
- ```
548
+ ### Tool build fails validation
870
549
 
871
- ---
550
+ `sg tool build` returns a validation error. Read the message, fix the config, and re-run. Common causes: missing `id`, empty `steps`, missing `url` on request steps, missing `transformCode` on transform steps, `systemId` on the step object instead of `step.config.systemId`.
872
551
 
873
- ## Reference Files
552
+ ### Tool runs but a step fails
874
553
 
875
- For detailed documentation on specific topics, read these files in the `references/` directory:
554
+ 1. Re-run with `--include-step-results` to see raw per-step responses and `data` fields
555
+ 2. Use `sg system call` to test the failing endpoint directly — isolates step config vs system/auth issues
556
+ 3. Use `sg system find --id <systemId>` to verify `storedCredentials` keys match what the step references
557
+ 4. For HTTP: load `references/http.md` and follow the error recovery section (endpoint vs system isolation, credential scopes, rate limiting)
558
+ 5. For databases: load `references/postgres.md` or `references/mssql.md` — SSL/TLS and schema issues are common causes
559
+ 6. Use `sg system search-docs` and web search to verify the current API shape. APIs change across versions
876
560
 
877
- | File | When to read |
878
- | ----------------------------- | ------------------------------------------------------------------------------------------------ |
879
- | `references/integration.md` | **READ THIS** when deploying tools to production - SDK usage, REST API, webhooks, error handling |
880
- | `references/databases.md` | Building tools that query PostgreSQL or Microsoft SQL Server (Azure SQL) databases |
881
- | `references/redis.md` | Building tools that interact with Redis (commands, pipelines, data types) |
882
- | `references/file-servers.md` | Building tools that interact with FTP/SFTP/SMB file servers |
883
- | `references/data-handling.md` | Variables, selectors, result envelopes, transforms, JS sandbox constraints |
884
- | `references/file-handling.md` | File detection, parsing, producedFiles, file references, aliasing rules |
885
- | `references/http-apis.md` | HTTP step config — auth patterns, pagination, retries, error detection |
886
- | `references/access-rules.md` | RBAC roles, tool/system permissions, custom rules, mutation detection (enterprise only) |
561
+ ### Authentication failures
887
562
 
888
- **Important:** When the user asks about integrating superglue into their codebase, deploying tools, using the SDK, or calling tools from code, you MUST read `references/integration.md` for complete examples.
563
+ 1. Run `sg system find --id <systemId>` → check `storedCredentials` for masked but present values
564
+ 2. For OAuth: re-run `sg system oauth` if tokens are missing or expired
565
+ 3. For custom OAuth: verify `client_id`, `client_secret`, `auth_url`, `token_url` are all present. Confirm the redirect URI is registered on the provider's OAuth app
566
+ 4. Check scopes — 403 / empty responses often mean the token lacks required scopes
889
567
 
890
- ---
568
+ ### System creation fails
891
569
 
892
- ## Draft Management
570
+ 1. Check for an existing system with the same ID — use `sg system edit` to update instead
571
+ 2. Ensure `id` uses only lowercase letters, numbers, and underscores (no hyphens)
572
+ 3. For templated systems, verify the template ID is correct (`sg system find` lists available templates)
893
573
 
894
- Drafts live in `.superglue/drafts/<draftId>.json`. Created by `build`, updated by `edit`, deleted by `save`. Ephemeral — not persisted across sessions.
574
+ ### Data selector / transform returns wrong data
895
575
 
896
- ## File References
576
+ 1. Confirm whether the upstream step used an object selector (access `.data` directly) or an array selector (access via `.map(i => i.data)`)
577
+ 2. Re-run with `--include-step-results` to see the exact envelope shape
578
+ 3. Paginated steps merge into a single `.data` field — do not `.map()` over them
579
+ 4. Verify `sourceData.currentItem` is only referenced inside looping steps (set by the step's own `dataSelector`, not upstream)
897
580
 
898
- Attach files with `--file key=path`. Reference in payloads with `file::<key>`. Auto-parsed to JSON.
581
+ ### Persistent failures
899
582
 
900
- ```bash
901
- sg tool run --draft <id> --payload '{"data": "file::mysheet"}' --file mysheet=data.xlsx
902
- ```
583
+ After 3-5 unsuccessful iterations on the same step, stop and ask the user for clarification or additional context (credentials, docs, expected payload shape). Don't keep guessing — gather evidence first.