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
1 change: 1 addition & 0 deletions scripts/validate-skills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const expectedSkillNames = [
"build-workflow",
"deploy-workflow",
"knowledge-base",
"run-tool",
"run-workflow",
"table",
] as const;
Expand Down
4 changes: 4 additions & 0 deletions skills/build-workflow/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ description: Create or modify Sim workflows through the sim CLI. Use when transl
Build the smallest valid graph that satisfies the request, using the Sim CLI as the source of truth
for available resources and accepted shapes.

A request that is one action against one connected service needs no graph at all — call the tool
directly with `sim tools execute` (see the `run-tool` skill). Build a workflow when the task needs
more than one call, branching, or a schedule.

## Establish context

- Use the profile the user named. If none was named, inspect configured profiles and current context;
Expand Down
67 changes: 67 additions & 0 deletions skills/run-tool/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
name: run-tool
description: Call one Sim integration tool directly through the sim CLI, using credentials Sim already holds. Use for a single action against a connected service — send a message, create an issue, scrape a page; not for multi-step logic or anything scheduled, which belongs in a workflow.
---

# Run a Sim Integration Tool

Sim holds the credentials. Read what the tool declares, bind auth from that declaration, and run it.
Never put a live credential in the command.

## Preflight

- `tools execute` requires a personal API-key profile; a workspace API key is refused.
- Find the tool with `sim --output json tools list --search <term>`, then read it with
`sim --output json tools get <toolId>`. Never guess a tool id or a parameter name.
- An unversioned name resolves to the newest version visible in the workspace, and the response
echoes the id that answered. Use that id in the call.

## Bind auth from the declaration, not from habit

`tools get` labels every parameter with a `visibility`, and the label says where its value comes
from:

- `user-or-llm` — you supply it in `--input`.
- `user-only` — you supply it, but pass a reference instead of the secret: `{{VAR_NAME}}` as the
whole value, resolved server-side. List the available names with
`sim --output json secrets list`; values are never returned. Any other value is sent verbatim.
One exception: a parameter named `credential` or `oauthCredential` is the credential selector,
not a secret — see below. It is refused in `--input`.
- `hidden` — Sim fills it. Never put it in `--input`; it is refused.

Then bind the credential by the tool's own shape:

- The tool declares `oauth.required`, **or** declares a required `credential` or `oauthCredential`
parameter (Snowflake and others do the latter, with no `oauth` block) — find the credential with
`sim --output json credentials list --provider-id <provider>` and pass `--credential-id`. It is
the one place a credential is named; Sim places it where the tool expects it. Omitting it fails
naming `credentialId`; putting it in `--input` under any spelling is refused.
- `hostedApiKey` is `always`, or `conditional` and this call matches — omit the key entirely; Sim
supplies its own and bills the workspace.
- Otherwise the tool takes its own `user-only` key parameter; pass a `{{VAR_NAME}}` reference.

`--input` accepts exactly what `tools get` publishes as yours to send. An undeclared key, a
`hidden` one, or a credential under any name is a `400` that names the offending field — read
it rather than guessing at a spelling.

## Run and read the outcome

```bash
sim --output json tools execute <toolId> --credential-id <id> --input '{"...": "..."}'
```

`--input` also accepts `@path` or `@-`, which is how a payload too large or too awkward to quote
reaches the command.

A tool that ran and refused exits non-zero with `status: "failed"` and the reason in `error.message`:
the call reached the service and the service declined. Report that reason. A `403` carrying
`error.details.code` `INTEGRATION_NOT_ALLOWED` is a workspace policy decision, not a fixable
argument — say so and stop.

## Invariants

- Never print a resolved secret, an OAuth token, or a profile credential. You hold a credential id
and a variable name; that is all the call needs.
- Do not retry a failed write blind. A tool call is not idempotent, and a retry can duplicate the
message, issue, or record the first attempt created.
- Build a workflow instead when the task needs more than one call, branching, or a schedule.
Loading