stpr 1.0.5 → 1.0.6

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 (3) hide show
  1. package/README.md +159 -0
  2. package/dist/cli.js +12 -23
  3. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,159 @@
1
+ # stpr — Stepper Skills CLI
2
+
3
+ Skill Sets are a Stepper feature that let you bundle integration actions into curated, authenticated toolkits — and expose them to AI agents, CLIs, and any MCP-compatible client.
4
+
5
+ `stpr` is a command-line interface for interacting with [Stepper](https://stepper.io) Skill Sets. Discover, inspect, and execute integration actions directly from your terminal. This is perfect for OpenClaw or agents that can interact with a CLI, or for developers who want to use skills in their own scripts.
6
+
7
+ If you prefer, you can directly use the Stepper MCP server at `https://mcp.stepper.io/skill-sets/mcp`instead of the CLI.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install -g stpr
13
+ ```
14
+
15
+ ## Authentication
16
+
17
+ The CLI supports three authentication methods:
18
+
19
+ ### OAuth Login (recommended)
20
+
21
+ ```bash
22
+ stpr login
23
+ ```
24
+
25
+ Opens your browser to authenticate and select a Skill Set. Credentials are saved to `~/.config/stepper-skillsets/config.json` and automatically refreshed when they expire.
26
+
27
+ ### Static Token
28
+
29
+ Generate a token from [Stepper](https://app.stepper.io/flow/skill-sets) and pass it directly:
30
+
31
+ ```bash
32
+ stpr --token sst_your_token_here list
33
+ ```
34
+
35
+ ### Environment Variable
36
+
37
+ ```bash
38
+ export STEPPER_SKILL_TOKEN=sst_your_token_here
39
+ stpr list
40
+ ```
41
+
42
+ ## Commands
43
+
44
+ ### Profile Management
45
+
46
+ ```bash
47
+ stpr login # Authenticate via OAuth (opens browser)
48
+ stpr logout [name] # Remove a saved profile, or all profiles if no name given
49
+ stpr profiles # List all saved profiles
50
+ stpr use <name> # Switch the active profile
51
+ stpr whoami # Show active profile and server info
52
+ ```
53
+
54
+ ### Discovering Skills
55
+
56
+ ```bash
57
+ stpr list # List all available skills, grouped by service
58
+ stpr list --verbose # Include full input schemas
59
+ stpr list <service> # List skills for a specific service
60
+ stpr <service> # Shorthand for listing a service's skills
61
+ ```
62
+
63
+ ### Inspecting Parameters
64
+
65
+ Many skills have dynamic parameters — fields that change based on the values of other fields. Calling a skill without `--call` returns its current parameter schema.
66
+
67
+ ```bash
68
+ # See what fields are needed for add_row, given a spreadsheet
69
+ stpr google-sheets add_row -i '{"spreadsheet_id": "abc123"}'
70
+ ```
71
+
72
+ Some parameters have dynamic dropdown options. Fetch them with `--options`:
73
+
74
+ ```bash
75
+ stpr google-sheets add_row --options worksheet_id \
76
+ -i '{"spreadsheet_id": "abc123"}' \
77
+ --search "Sheet" \
78
+ --cursor "next_page"
79
+ ```
80
+
81
+ ### Calling Skills
82
+
83
+ Use the `--call` flag to execute an action:
84
+
85
+ ```bash
86
+ stpr google-sheets create_sheet --call \
87
+ -i '{"name": "Q1 Report", "columns": "Name, Email, Phone"}'
88
+ ```
89
+
90
+ ### Polling Async Results
91
+
92
+ Component library tools run asynchronously. Poll for results with:
93
+
94
+ ```bash
95
+ stpr status <statusId>
96
+ ```
97
+
98
+ ## Input
99
+
100
+ Pass JSON input via the `-i` / `--input` flag or pipe it through stdin:
101
+
102
+ ```bash
103
+ # Flag
104
+ stpr slack send_message --call -i '{"channel": "#general", "text": "Hello!"}'
105
+
106
+ # Stdin
107
+ echo '{"channel": "#general", "text": "Hello!"}' | stpr slack send_message --call
108
+ ```
109
+
110
+ ## Options Reference
111
+
112
+ | Flag | Description |
113
+ | -------------------- | --------------------------------------------------------------- |
114
+ | `--token <token>` | Auth token (overrides saved profiles and `STEPPER_SKILL_TOKEN`) |
115
+ | `--base-url <url>` | Override MCP server URL (default: `https://mcp.stepper.io`) |
116
+ | `--skillset <name>` | Use a specific saved profile instead of the active one |
117
+ | `--call` | Execute the skill (default behavior is parameter inspection) |
118
+ | `--verbose` | Include full `inputSchema` when listing skills |
119
+ | `-i, --input <json>` | JSON input for calls, parameter fetches, or option queries |
120
+ | `--options <param>` | Fetch dynamic dropdown options for a parameter |
121
+ | `--search <query>` | Filter dropdown options by search term |
122
+ | `--cursor <cursor>` | Pagination cursor for dropdown options |
123
+ | `-h, --help` | Show help |
124
+ | `-v, --version` | Show version |
125
+
126
+ ## Environment Variables
127
+
128
+ | Variable | Description |
129
+ | --------------------- | ------------------------------------------------------------- |
130
+ | `STEPPER_SKILL_TOKEN` | Auth token (used when no `--token` flag and no saved profile) |
131
+ | `STEPPER_URL` | Override the MCP server base URL |
132
+
133
+ ## Examples
134
+
135
+ ```bash
136
+ # Authenticate
137
+ stpr login
138
+
139
+ # List everything available
140
+ stpr list
141
+
142
+ # Explore a service
143
+ stpr google-sheets
144
+
145
+ # Inspect dynamic parameters step by step
146
+ stpr google-sheets add_row -i '{}'
147
+ stpr google-sheets add_row -i '{"spreadsheet_id": "abc123"}'
148
+
149
+ # Fetch dropdown options
150
+ stpr google-sheets add_row --options worksheet_id -i '{"spreadsheet_id": "abc123"}'
151
+
152
+ # Execute
153
+ stpr google-sheets add_row --call -i '{"spreadsheet_id": "abc123", "worksheet_id": "Sheet1", "values": {"Name": "Alice"}}'
154
+
155
+ # Switch between skill sets
156
+ stpr profiles
157
+ stpr use "Production Tools"
158
+ stpr list
159
+ ```
package/dist/cli.js CHANGED
@@ -138,7 +138,6 @@ var OAUTH_CALLBACK_PORT = 3847;
138
138
  var CALLBACK_PATH = "/callback";
139
139
  var CONFIG_DIR = path.join(os.homedir(), ".config", "stepper-skillsets");
140
140
  var CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
141
- var LEGACY_CREDENTIALS_FILE = path.join(CONFIG_DIR, "credentials.json");
142
141
  function generatePKCE() {
143
142
  const codeVerifier = crypto.randomBytes(32).toString("base64url");
144
143
  const codeChallenge = crypto.createHash("sha256").update(codeVerifier).digest().toString("base64url");
@@ -158,29 +157,14 @@ function saveConfig(config) {
158
157
  mode: 384
159
158
  });
160
159
  }
161
- function migrateLegacyCredentials() {
162
- try {
163
- const data = fs.readFileSync(LEGACY_CREDENTIALS_FILE, "utf-8");
164
- const creds = JSON.parse(data);
165
- const config = {
166
- active: "default",
167
- skillsets: { default: creds }
168
- };
169
- saveConfig(config);
170
- fs.unlinkSync(LEGACY_CREDENTIALS_FILE);
171
- } catch {
172
- }
173
- }
174
160
  function getConfigPathForDisplay() {
175
161
  return CONFIG_FILE;
176
162
  }
177
163
  function getActiveSkillset() {
178
- migrateLegacyCredentials();
179
164
  const config = loadConfig();
180
165
  return config.active;
181
166
  }
182
167
  function setActiveSkillset(name) {
183
- migrateLegacyCredentials();
184
168
  const config = loadConfig();
185
169
  if (!(name in config.skillsets)) {
186
170
  return false;
@@ -190,7 +174,6 @@ function setActiveSkillset(name) {
190
174
  return true;
191
175
  }
192
176
  function listSkillsets() {
193
- migrateLegacyCredentials();
194
177
  const config = loadConfig();
195
178
  return Object.entries(config.skillsets).map(([name, creds]) => ({
196
179
  name,
@@ -199,12 +182,10 @@ function listSkillsets() {
199
182
  }));
200
183
  }
201
184
  function getCredentials(name) {
202
- migrateLegacyCredentials();
203
185
  const config = loadConfig();
204
186
  return config.skillsets[name] ?? null;
205
187
  }
206
188
  function saveCredentials(name, creds) {
207
- migrateLegacyCredentials();
208
189
  const config = loadConfig();
209
190
  config.skillsets[name] = creds;
210
191
  if (!config.active || !(config.active in config.skillsets)) {
@@ -213,7 +194,6 @@ function saveCredentials(name, creds) {
213
194
  saveConfig(config);
214
195
  }
215
196
  function deleteSkillset(name) {
216
- migrateLegacyCredentials();
217
197
  const config = loadConfig();
218
198
  if (!(name in config.skillsets)) {
219
199
  return false;
@@ -226,7 +206,6 @@ function deleteSkillset(name) {
226
206
  return true;
227
207
  }
228
208
  function deleteAllSkillsets() {
229
- migrateLegacyCredentials();
230
209
  const config = loadConfig();
231
210
  const count = Object.keys(config.skillsets).length;
232
211
  config.skillsets = {};
@@ -320,6 +299,18 @@ async function runLoginFlow(baseUrl) {
320
299
  res.end("Not found");
321
300
  return;
322
301
  }
302
+ const requestHost = req.headers.host ?? `127.0.0.1:${OAUTH_CALLBACK_PORT}`;
303
+ const callbackUrl = new URL(req.url ?? "/", `http://${requestHost}`);
304
+ const receivedCallbackUrl = `${callbackUrl.origin}${callbackUrl.pathname}`;
305
+ if (receivedCallbackUrl !== redirectUri) {
306
+ res.writeHead(200, { "Content-Type": "text/html" });
307
+ res.end(
308
+ "<html><body><h1>Login failed</h1><p>Redirect URI mismatch</p><p>You can close this tab.</p></body></html>"
309
+ );
310
+ server.close();
311
+ reject(new Error("OAuth redirect URI mismatch"));
312
+ return;
313
+ }
323
314
  const code = url.searchParams.get("code");
324
315
  const returnedState = url.searchParams.get("state");
325
316
  const error = url.searchParams.get("error");
@@ -412,7 +403,6 @@ async function refreshAccessToken(baseUrl, clientId, refreshToken) {
412
403
  };
413
404
  }
414
405
  async function getValidToken(skillsetName, baseUrl) {
415
- migrateLegacyCredentials();
416
406
  const config = loadConfig();
417
407
  const name = skillsetName ?? config.active;
418
408
  if (!name || !(name in config.skillsets)) {
@@ -575,7 +565,6 @@ Options:
575
565
  -v, --version Show version
576
566
 
577
567
  Examples:
578
-
579
568
  Auth (optional, can use STEPPER_SKILL_TOKEN env var, or --token <token> from https://app.stepper.io/flow/skill-sets):
580
569
  stpr login
581
570
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stpr",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "CLI for Stepper skill sets",
5
5
  "type": "module",
6
6
  "files": [