shotops-mcp 0.6.1 → 0.8.0
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.
- package/LICENSE +97 -0
- package/README.md +200 -38
- package/THIRD_PARTY_NOTICES +157 -0
- package/dist/local.js +18641 -5124
- package/harness-dist/assets/index-BfJOyBU7.js +1 -0
- package/harness-dist/assets/three-addons-CvX38LO6.js +1 -0
- package/harness-dist/assets/three-webgl-DCw804Ic.js +6491 -0
- package/harness-dist/index.html +3 -1
- package/package.json +13 -6
- package/widget-dist/bundle.js +4 -4
- package/widget-dist/panels.js +3 -3
- package/harness-dist/assets/index-XdyOXKM2.js +0 -3802
- package/harness-dist/assets/pixel-optimized-DZsBrOgu.glb +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
ShotOps CLI and Local MCP License
|
|
2
|
+
Version 1.1 — 11 August 2026
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2026 Rasmus Gehrke. All rights reserved.
|
|
5
|
+
|
|
6
|
+
This license governs the `shotops-mcp` software package, including the bundled
|
|
7
|
+
ShotOps rendering engine (the "Software"). "You" means the individual or legal
|
|
8
|
+
entity exercising the rights granted below. The Software is licensed, not sold.
|
|
9
|
+
Third-party components and assets are excluded from the definition of Software
|
|
10
|
+
and are governed by their own licenses and notices.
|
|
11
|
+
|
|
12
|
+
GRANT
|
|
13
|
+
|
|
14
|
+
Subject to this license, you are granted a free, worldwide, royalty-free,
|
|
15
|
+
non-exclusive, non-transferable right to:
|
|
16
|
+
|
|
17
|
+
1. install and run the Software, without limit, in computing environments you
|
|
18
|
+
own, control, or are authorized to use, including via `npx` and in CI;
|
|
19
|
+
2. use the Software to render device mockups, screenshot strips, and store
|
|
20
|
+
bundles from content you are authorized to use; and
|
|
21
|
+
3. use, publish, and commercialize the output the Software produces from that
|
|
22
|
+
content, subject to any rights in your content, third-party components,
|
|
23
|
+
assets, device designs, and trademarks.
|
|
24
|
+
|
|
25
|
+
As between you and the copyright holder, the copyright holder claims no
|
|
26
|
+
ownership in your content or in output created from it. This license does not
|
|
27
|
+
grant rights in third-party content, assets, designs, or trademarks that may
|
|
28
|
+
appear in the output.
|
|
29
|
+
|
|
30
|
+
Use of ShotOps hosted services through the Software is additionally governed
|
|
31
|
+
by the ShotOps Terms of Service at https://shotops.dev/terms.
|
|
32
|
+
|
|
33
|
+
RESTRICTIONS
|
|
34
|
+
|
|
35
|
+
You may not:
|
|
36
|
+
|
|
37
|
+
1. redistribute, republish, sell, rent, sublicense, or otherwise provide the
|
|
38
|
+
Software or any part of it (including the bundled rendering engine) to a
|
|
39
|
+
third party;
|
|
40
|
+
2. modify the Software or create derivative works from it;
|
|
41
|
+
3. extract, copy, or reuse components of the Software — including the
|
|
42
|
+
rendering engine — in another product or service;
|
|
43
|
+
4. offer the Software's functionality to third parties as a service, or use
|
|
44
|
+
it to build a product or service that competes with ShotOps; or
|
|
45
|
+
5. reverse engineer, decompile, disassemble, or otherwise attempt to derive
|
|
46
|
+
the source code of the Software; or
|
|
47
|
+
6. remove or obscure copyright, license, or attribution notices.
|
|
48
|
+
|
|
49
|
+
These restrictions apply only to the extent permitted by law. Nothing in this
|
|
50
|
+
license limits a right that cannot lawfully be waived or restricted. In
|
|
51
|
+
particular, where Directive 2009/24/EC or equivalent national law applies, this
|
|
52
|
+
license does not restrict the lawful user's rights to make a necessary backup
|
|
53
|
+
copy, to observe, study, or test the functioning of the Software while
|
|
54
|
+
performing authorized acts, or to reproduce or translate code where that is
|
|
55
|
+
indispensable to achieve interoperability and all statutory conditions are met.
|
|
56
|
+
|
|
57
|
+
THIRD-PARTY COMPONENTS
|
|
58
|
+
|
|
59
|
+
The Software depends on and may bundle third-party components and assets.
|
|
60
|
+
Their copyright notices and license terms are identified in the files,
|
|
61
|
+
metadata, or THIRD_PARTY_NOTICES distributed with the package. Those terms,
|
|
62
|
+
not this license, govern the relevant third-party material. Nothing in this
|
|
63
|
+
license restricts rights granted under a third-party license.
|
|
64
|
+
|
|
65
|
+
TERMINATION
|
|
66
|
+
|
|
67
|
+
If you materially breach this license, your rights terminate if you do not cure
|
|
68
|
+
the breach within 14 days after receiving notice. Rights terminate immediately
|
|
69
|
+
for a breach that cannot be cured or that involves intentional unauthorized
|
|
70
|
+
redistribution or provision of the Software as a service. On termination, you
|
|
71
|
+
must stop using the Software and delete your copies. Provisions that by their
|
|
72
|
+
nature should survive termination, including ownership, restrictions,
|
|
73
|
+
warranty, and liability provisions, remain effective.
|
|
74
|
+
|
|
75
|
+
NO WARRANTY; LIABILITY
|
|
76
|
+
|
|
77
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
78
|
+
IMPLIED, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
|
|
79
|
+
NON-INFRINGEMENT. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE COPYRIGHT HOLDER
|
|
80
|
+
IS NOT LIABLE FOR INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE
|
|
81
|
+
DAMAGES, OR FOR LOSS OF DATA, REVENUE, OR PROFITS, ARISING FROM OR IN CONNECTION
|
|
82
|
+
WITH THE SOFTWARE OR ITS USE.
|
|
83
|
+
|
|
84
|
+
NOTHING IN THIS LICENSE EXCLUDES OR LIMITS MANDATORY STATUTORY RIGHTS OR
|
|
85
|
+
REMEDIES, INCLUDING CONSUMER RIGHTS RELATING TO CONFORMITY OF DIGITAL CONTENT,
|
|
86
|
+
OR LIABILITY THAT CANNOT LAWFULLY BE EXCLUDED OR LIMITED.
|
|
87
|
+
|
|
88
|
+
GOVERNING LAW
|
|
89
|
+
|
|
90
|
+
This license is governed by the law of Denmark, without regard to conflict-of-
|
|
91
|
+
laws rules. If you are a consumer, this choice does not deprive you of mandatory
|
|
92
|
+
protections provided by the law that would apply without this choice, and
|
|
93
|
+
jurisdiction is determined by mandatory consumer-jurisdiction rules. In all
|
|
94
|
+
other cases, disputes are subject to the exclusive jurisdiction of the courts
|
|
95
|
+
of Denmark.
|
|
96
|
+
|
|
97
|
+
Contact: support@shotops.dev
|
package/README.md
CHANGED
|
@@ -11,20 +11,43 @@ reusable **looks** and editable **projects**, so the next release matches the la
|
|
|
11
11
|
Built for agents (ChatGPT / Claude Code / Cursor / CI). It runs over the same `@engine` render
|
|
12
12
|
spine the Studio web app and the `mockup-mcp` CLI use, driving headless Chromium (Playwright).
|
|
13
13
|
|
|
14
|
-
Ships as **two
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
[
|
|
18
|
-
|
|
14
|
+
Ships as **two doors, one engine**: an `npx shotops-mcp` **local stdio server** that renders on
|
|
15
|
+
your own machine, no account needed to preview (see [Local](#local--npx-shotops-mcp) below), and a
|
|
16
|
+
**hosted** server on Vercel with an account, saved looks, and share links (see [Hosted](#hosted)
|
|
17
|
+
below, or the public [`/connect`](https://shotops.dev/connect) page in the studio app).
|
|
18
|
+
|
|
19
|
+
## Preview free, export store-ready with Pro
|
|
20
|
+
|
|
21
|
+
Composing and previewing a strip is free through either door — every device, caption and locale, no
|
|
22
|
+
watermark, and locally without an account at all. **Store-ready output needs an active trial or
|
|
23
|
+
Pro:** a full-resolution `render_strip`/`render_project`, and every `emit_bundle` form, including
|
|
24
|
+
one that only re-zips panels you already rendered. That holds wherever the render happens; local
|
|
25
|
+
compute being free is not the same as local output being free.
|
|
26
|
+
|
|
27
|
+
The two limits are independent and neither substitutes for the other:
|
|
28
|
+
|
|
29
|
+
- **Entitlement** is permission to create store-ready files. One server-owned decision answers it
|
|
30
|
+
for Studio, hosted and local alike, so no door can be talked into a different answer. Free and
|
|
31
|
+
anonymous callers are refused before a credit is reserved, a screenshot is read or a file is
|
|
32
|
+
written — a refused call costs nothing and leaves nothing behind.
|
|
33
|
+
- **Credits** price compute ShotOps supplies: 0.5 per hosted preview panel, 2 per hosted
|
|
34
|
+
full-resolution panel, plus AI. Rendering on your own machine spends none, on any plan. More
|
|
35
|
+
credits never unlock store-ready output on Free.
|
|
36
|
+
|
|
37
|
+
Free accounts get 40 credits a month and 2 synced projects. Every new account starts with a 7-day
|
|
38
|
+
Pro trial; after that Pro is €9/month or €90/year. Without any account, the hosted server allows 3
|
|
39
|
+
preview strips per rolling 30 days, at most 5 panels each. Call `account_status` to see exactly
|
|
40
|
+
where this connection stands — it spends no credits and none of that anonymous allowance.
|
|
19
41
|
|
|
20
42
|
## Zero-custody
|
|
21
43
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
44
|
+
The hosted server and every MCP tool **never touch a store-signing credential.** `emit_bundle`
|
|
45
|
+
hands you a zip; **you** upload it with **your own** `fastlane`, signed in as yourself. The
|
|
46
|
+
generated `Deliverfile` is screenshots-only and **never submits for review**.
|
|
47
|
+
|
|
48
|
+
The one explicit exception is the local `release setup` CLI below. It validates an existing `.p8`
|
|
49
|
+
on your machine directly with Fastlane and Apple, then stores only its path and public identifiers.
|
|
50
|
+
The key is never copied, printed, or sent to ShotOps, and no release tool is installed or upgraded.
|
|
28
51
|
|
|
29
52
|
## Tools
|
|
30
53
|
|
|
@@ -36,12 +59,15 @@ share links) — nothing that could reach a store on your behalf.
|
|
|
36
59
|
| `read_look` | Return a project's saved ShotOps look (styling only), with its latest version, the held version, the `versions` history, and the `layout` template it is composed on (derived from its values, never stored) | `project?` (default: your most recently edited project) |
|
|
37
60
|
| `read_project` | Return a project's FULL current state as an opaque `ProjectFile` — frame order, per-locale caption words, locale list, styling — plus the derived `layout` and a `screenshots.cells` report for every shot × target-family × locale. Each cell says whether pixels resolve, where they resolved from, and which axes inherited | `project?` (default: your most recently edited project) |
|
|
38
61
|
| `render_project` | Render a SAVED project. By default it renders the screenshots **the project already holds** — pass none at all, no upload needed — into **every supported device the project targets**. Pixels resolve independently for each device family + locale through the shared manifest; genuine fallback is reported in `shots[].inherited` and `note` | `project?`, `screenshots?` (**optional** — omit to use what the project holds; else a FLAT list matched by original `name`, with optional `variant: { family?, locale? }` per cell), `outputs?` (override the project's saved devices for this call), `locale?`, `preview?`, `output?` |
|
|
62
|
+
| `refine_project` | Run one bounded Agent turn against a saved project. A supported request commits once and returns the actual diff; ambiguity, missing input, unsupported intent, conflict, and failure return a typed no-write outcome | `project?`, `instruction`, `focus?` |
|
|
39
63
|
| `save_look` | Persist a composed look on a project (styling only — appends a new version) | `look`, `project?`, `sourceName?` |
|
|
40
64
|
| `hold_look` | Hold which saved version agents render by default (replaces pinning) — the version must exist (`read_look` `versions`) | `version`, `project?` |
|
|
41
65
|
| `release_look` | Clear the held version — agents Follow latest (render the newest saved look) | `project?` |
|
|
42
66
|
| `describe_look` | Five named design presets, two named layout templates, the user-intake script, and the full styling field catalog + defaults | *(none)* |
|
|
43
67
|
| `request_screenshot_upload` | Mint signed upload slots for real screenshots; every returned slot carries its semantic screenshot `variant` | `count` (1–10), `names?`, `family?`, `locale?` |
|
|
44
68
|
| `import_screenshot` | Get screenshots INTO ShotOps — several per call, each from one named source (`{ url }`, `{ file }`, or local-stdio `{ path }`), returning a render-ready ref per entry in input order | `screenshots` (1–10 source entries), `file?` (the ChatGPT top-level attachment), `name?`, `locale?` |
|
|
69
|
+
| `account_status` | What THIS connection may do, for free: signed-in account, plan, trial, remaining ShotOps credits, what a preview costs here, and whether store-ready output (full-resolution renders, any `emit_bundle`) is allowed — with a machine-readable `nextStep`. Spends no credits, uses none of the free anonymous preview allowance, uploads and writes nothing | *(none)* |
|
|
70
|
+
| `production_operation` | Reconnect to one durable paid Hosted render or rendering bundle, report persisted progress, request cooperative cancellation, or mint fresh result download grants without rerendering or charging again | `action` (`get`, `cancel`, or `result`), `operationId` |
|
|
45
71
|
| `delete_assets` | Permanently delete private uploaded screenshots, rendered panels, or generated bundles owned by the signed-in account | `refs` (1–50 ShotOps refs) |
|
|
46
72
|
|
|
47
73
|
- **`panelPresetId`** — App Store size: `r69` (default, 6.9″ iPhone 1290×2796), `r65`, `r55`.
|
|
@@ -50,7 +76,9 @@ share links) — nothing that could reach a store on your behalf.
|
|
|
50
76
|
accepted set is `RENDERABLE_PANEL_PRESET_IDS` in `shotops-mcp/src/panelCatalog.ts`, a subset of
|
|
51
77
|
the hand-kept `PANEL_PRESET_IDS` copy of `mockup-engine/appstore.ts`'s `PANEL_PRESETS` — when
|
|
52
78
|
Apple revises required sizes, add the preset in the engine first, then mirror it here.
|
|
53
|
-
- **`style`** — the structured styling input
|
|
79
|
+
- **`style`** — the structured styling input. On both the hosted MCP and the local
|
|
80
|
+
`npx shotops-mcp` stdio server, call `describe_look` for the authoritative complete field
|
|
81
|
+
catalog and defaults:
|
|
54
82
|
`{ layout?, shotLook?, background?, captions? }`. `shotLook` is **one device for every phone**;
|
|
55
83
|
`captions` is one entry PER PANEL in slot order — each entry is EITHER a single caption object OR
|
|
56
84
|
an **array of caption layers** stacked on that panel (headline + subline + …). Each layer's
|
|
@@ -93,10 +121,10 @@ share links) — nothing that could reach a store on your behalf.
|
|
|
93
121
|
background, `style.captions` supplies the words, in one render. (Alone, `style` styles every
|
|
94
122
|
phone identically. If you pass `style.shotLook`/`style.background` *alongside* a `look`, the look
|
|
95
123
|
wins and the result carries a note.) Also composes with `useSavedLook`/`version`.
|
|
96
|
-
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
124
|
+
- **Clipping** — set `look.shots[].look.clipToFrame: true` to clip one device's complete composite
|
|
125
|
+
(body, screen, shadow, and reflection) to its own panel; omit it or use `false` for overflow.
|
|
126
|
+
Pass top-level `clip: "panel"` to clip every device, or `clip: "strip"` to force continuous
|
|
127
|
+
overflow. Call `describe_look` for the complete Look contract on either MCP tier.
|
|
100
128
|
- **`version`** — render a specific saved look version (implies the saved look). Without it,
|
|
101
129
|
a project with a PINNED version renders the pin; otherwise the latest saved look.
|
|
102
130
|
- **`emit_bundle` output** — a zip (`README.md`, `fastlane/Deliverfile`,
|
|
@@ -256,7 +284,7 @@ screenshot unavailable; public privacy disclosures must accurately state this re
|
|
|
256
284
|
## Prerequisites
|
|
257
285
|
|
|
258
286
|
1. **A ShotOps API token.** Sign in at the Studio app → account menu → **API tokens** →
|
|
259
|
-
create one. It looks like `
|
|
287
|
+
create one. It looks like `shotops_9Zq3Xr7T…` and is
|
|
260
288
|
shown once — copy it then.
|
|
261
289
|
2. **Supabase service env** (already in the repo's `.env.local` for local dev): `SUPABASE_URL`
|
|
262
290
|
and `SUPABASE_SERVICE_ROLE_KEY`. The server loads `../.env.local` automatically.
|
|
@@ -294,7 +322,7 @@ tests without private fixture data or third-party hosting.
|
|
|
294
322
|
|
|
295
323
|
```bash
|
|
296
324
|
claude mcp add --transport http shotops http://localhost:8788/mcp \
|
|
297
|
-
--header "Authorization: Bearer
|
|
325
|
+
--header "Authorization: Bearer shotops_…"
|
|
298
326
|
```
|
|
299
327
|
|
|
300
328
|
Then ask the agent to, e.g., *"render these two screenshots into a 6.9″ App Store strip and
|
|
@@ -322,14 +350,14 @@ fastlane deliver # signs in as YOU, previews, uploads screenshots to a dr
|
|
|
322
350
|
The server also runs hosted, 24/7-reachable (scale-to-zero when idle), at:
|
|
323
351
|
|
|
324
352
|
```
|
|
325
|
-
https://shotops.dev/mcp
|
|
353
|
+
https://mcp.shotops.dev/mcp
|
|
326
354
|
```
|
|
327
355
|
|
|
328
356
|
Nothing to install — point any MCP client at that URL with your `Authorization: Bearer
|
|
329
357
|
shotops_…` header, same as local dev, just swap the base URL:
|
|
330
358
|
|
|
331
359
|
```bash
|
|
332
|
-
claude mcp add --transport http shotops https://shotops.dev/mcp \
|
|
360
|
+
claude mcp add --transport http shotops https://mcp.shotops.dev/mcp \
|
|
333
361
|
--header "Authorization: Bearer shotops_…"
|
|
334
362
|
```
|
|
335
363
|
|
|
@@ -351,7 +379,7 @@ since this repo is private.
|
|
|
351
379
|
- **Verify after any deploy** — a green `flyctl deploy` isn't proof the server answers MCP
|
|
352
380
|
calls:
|
|
353
381
|
```bash
|
|
354
|
-
node verify-mcp.mjs https://shotops.dev/mcp <a-real-shotops_-token>
|
|
382
|
+
node verify-mcp.mjs https://mcp.shotops.dev/mcp <a-real-shotops_-token>
|
|
355
383
|
```
|
|
356
384
|
Exercises `tools/list`, `read_look`, `emit_bundle` (asserts the zip unzips to
|
|
357
385
|
README/Deliverfile/screenshots), and asserts no-token / bad-token both get `401`.
|
|
@@ -382,12 +410,12 @@ since this repo is private.
|
|
|
382
410
|
can take 60-110s before the CPU fix, and network/Supabase round trips add more on `urls`
|
|
383
411
|
output.
|
|
384
412
|
|
|
385
|
-
## Local
|
|
413
|
+
## Local — `npx shotops-mcp`
|
|
386
414
|
|
|
387
415
|
The SAME server also runs as a **local stdio MCP**, entirely on your own machine — no URL, no
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
transport and a few account-shaped tools differ.
|
|
416
|
+
hosted cost, and no render-timeout ceiling (the hosted server's one real limit — see "Ops" above).
|
|
417
|
+
Previewing needs no account. It's the same `registerTools`/render engine as the hosted server; only
|
|
418
|
+
the transport and a few account-shaped tools differ.
|
|
391
419
|
|
|
392
420
|
```bash
|
|
393
421
|
claude mcp add shotops -- npx -y shotops-mcp
|
|
@@ -410,14 +438,19 @@ instead of `{ ref }`/`{ url }`:
|
|
|
410
438
|
(`{ "path": ... }` only works over this LOCAL server — the hosted server rejects it, since
|
|
411
439
|
reading an arbitrary server-side path there would be a local-file-inclusion hole.)
|
|
412
440
|
|
|
413
|
-
**`emit_bundle` reads local panels off disk too** —
|
|
414
|
-
produce `output: "urls"` refs.
|
|
415
|
-
(same local-only `{ path }` door as screenshots) to package a
|
|
441
|
+
**`emit_bundle` reads local panels off disk too** — an unsigned local server has no account, so it
|
|
442
|
+
can't produce `output: "urls"` refs. Once you are signed in on a trial or Pro, pass the on-disk PNGs
|
|
443
|
+
straight to `emit_bundle` (same local-only `{ path }` door as screenshots) to package a
|
|
444
|
+
`fastlane deliver` zip with no upload and no credits:
|
|
416
445
|
|
|
417
446
|
```json
|
|
418
447
|
{ "bundleId": "com.acme.app", "panels": [{ "path": "/abs/panel-01.png" }, { "path": "/abs/panel-02.png" }] }
|
|
419
448
|
```
|
|
420
449
|
|
|
450
|
+
`emit_bundle` and full-resolution renders are the store-ready half of the offer, so they need that
|
|
451
|
+
trial or Pro even here, where the compute is yours. Preview renders need neither an account nor
|
|
452
|
+
credits. `account_status` reports which side of the line this process is on.
|
|
453
|
+
|
|
421
454
|
**Saving without a token:** a new `save_project` made from local `{ path }` PNGs creates a private
|
|
422
455
|
**pending claim**. It uploads only that saved project's byte-free record and raw source PNGs,
|
|
423
456
|
returns `status: "pending_claim"` plus `claimId` and `openUrl`, and deliberately returns no
|
|
@@ -425,31 +458,160 @@ returns `status: "pending_claim"` plus `claimId` and `openUrl`, and deliberately
|
|
|
425
458
|
with its screenshots, and the link expires after 7 days. An existing `project` cannot be updated
|
|
426
459
|
without the token that owns it. Non-path inputs are refused rather than creating a blank claim.
|
|
427
460
|
|
|
428
|
-
Ordinary `render_strip` / `emit_bundle` calls still upload **nothing** and
|
|
461
|
+
Ordinary `render_strip` / `emit_bundle` calls still upload **nothing** — pixels and zips are written
|
|
462
|
+
straight to your disk, and no screenshot leaves the machine. Other
|
|
429
463
|
account reads/writes (`read_look`, `save_look`, `read_project`, `render_project`, share links)
|
|
430
464
|
still need a token or hosted connection. A token-backed local `render_project` reads the cloud
|
|
431
465
|
manifest through the Studio control plane, downloads only the resolved cells, and renders locally:
|
|
432
466
|
|
|
433
|
-
| | Local (
|
|
467
|
+
| | Local (`npx shotops-mcp`) | Hosted (`shotops_…` token) |
|
|
434
468
|
|---|---|---|
|
|
435
|
-
| Render compute | **your machine** ($0, no timeout) | our servers |
|
|
436
|
-
|
|
|
469
|
+
| Render compute | **your machine** ($0, no timeout, no credits on any plan) | our servers — spends your ShotOps credits: 0.5 per preview panel, 2 per full-resolution panel |
|
|
470
|
+
| Preview render | free, no account | free on an account; 3 per 30 days, ≤5 panels, without one |
|
|
471
|
+
| Full-resolution render, any `emit_bundle` | trial or Pro (costs no credits) | trial or Pro, and spends credits |
|
|
472
|
+
| Auth | none to preview; a token for account state and store-ready output | account + API token |
|
|
437
473
|
| Saved looks / editable projects / project read+re-render / share links | new project: pending claim; existing/account state: token (below); share links: hosted | ✅ |
|
|
438
474
|
| Screenshot input | local `{ path }` off disk | `request_screenshot_upload` → `{ ref }` |
|
|
439
475
|
|
|
440
476
|
### Optional: bridge a local render into your hosted account
|
|
441
477
|
|
|
442
|
-
|
|
443
|
-
`
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
478
|
+
Connect your account and `save_project` / `read_look` / `save_look` / `read_project` /
|
|
479
|
+
`render_project` start working too — **rendering still happens locally and spends no credits**, and
|
|
480
|
+
a trial or Pro account unlocks full-resolution output and `emit_bundle` on this machine. A
|
|
481
|
+
deliberate save also uploads its local source PNGs privately so the project reopens with
|
|
482
|
+
screenshots on another device; normal renders and exports never upload.
|
|
483
|
+
|
|
484
|
+
Sign in through your browser, once per machine:
|
|
485
|
+
|
|
486
|
+
```bash
|
|
487
|
+
npx shotops-mcp login # opens ShotOps in your browser, saves the token it gets back
|
|
488
|
+
npx shotops-mcp whoami # which account is connected, and its plan
|
|
489
|
+
npx shotops-mcp logout # revokes that token and removes it from this machine
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
The token lands in `~/.shotops/credentials.json`, readable only by you, and every later
|
|
493
|
+
`npx shotops-mcp` picks it up — nothing to paste into a client config. It is an ordinary
|
|
494
|
+
ShotOps API token: revoke it any time from Studio → account menu → **API tokens**.
|
|
495
|
+
|
|
496
|
+
For CI, or to point one client at a different account, pass the token explicitly instead:
|
|
447
497
|
|
|
448
498
|
```bash
|
|
449
499
|
SHOTOPS_TOKEN=shotops_… claude mcp add shotops -- npx -y shotops-mcp
|
|
450
500
|
# or: npx shotops-mcp --token shotops_…
|
|
451
501
|
```
|
|
452
502
|
|
|
503
|
+
`--token` wins over `SHOTOPS_TOKEN`, which wins over a saved browser login — so a token in the
|
|
504
|
+
environment is never quietly shadowed by whoever last signed in on that machine.
|
|
505
|
+
|
|
506
|
+
### Local Apple release setup
|
|
507
|
+
|
|
508
|
+
Before preparing an App Store release, validate the Apple tooling and API key already on this
|
|
509
|
+
machine:
|
|
510
|
+
|
|
511
|
+
```bash
|
|
512
|
+
npx shotops-mcp release setup
|
|
513
|
+
# non-interactive form:
|
|
514
|
+
npx shotops-mcp release setup \
|
|
515
|
+
--issuer-id "$APP_STORE_CONNECT_ISSUER_ID" \
|
|
516
|
+
--key-id "$APP_STORE_CONNECT_KEY_ID" \
|
|
517
|
+
--key-path /secure/AuthKey_ABC123DEFG.p8
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
The command requires an owner-only `.p8`, Fastlane, and Apple Transporter; parses the key through
|
|
521
|
+
Fastlane; and makes read-only App Store Connect app-list requests to prove the key's real access.
|
|
522
|
+
It does not install or upgrade anything. Only Issuer ID, Key ID, and the canonical key path are
|
|
523
|
+
saved in `~/.shotops/release.json` (or `$SHOTOPS_CONFIG_DIR/release.json`); a failed rerun leaves the
|
|
524
|
+
last valid setup untouched.
|
|
525
|
+
|
|
526
|
+
For CI, create secret inputs named `APP_STORE_CONNECT_ISSUER_ID`,
|
|
527
|
+
`APP_STORE_CONNECT_KEY_ID`, and `APP_STORE_CONNECT_PRIVATE_KEY`. The setup command names these
|
|
528
|
+
inputs but never prints their values.
|
|
529
|
+
|
|
530
|
+
### Prepare a deterministic desired release
|
|
531
|
+
|
|
532
|
+
Once signed in to ShotOps, assemble the saved owner project and repository into one local,
|
|
533
|
+
content-addressed workspace — before reading or changing App Store Connect:
|
|
534
|
+
|
|
535
|
+
```bash
|
|
536
|
+
npx shotops-mcp release prepare --project "My project"
|
|
537
|
+
|
|
538
|
+
# Optional signed build and an explicit partial scope:
|
|
539
|
+
npx shotops-mcp release prepare \
|
|
540
|
+
--project proj_123 \
|
|
541
|
+
--build build/MyApp.ipa \
|
|
542
|
+
--locales en-US,de-DE \
|
|
543
|
+
--outputs iphone-6-9
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
The command renders every authored locale and selected output by default with the same engine as
|
|
547
|
+
Studio and the MCP. `--locales` or `--outputs` deliberately narrows the run and records every
|
|
548
|
+
omission as a **partial** scope. It writes `desired-release.json` plus the rendered PNGs under
|
|
549
|
+
`~/.shotops/release-workspaces/<desired-id>/` (or `--output <directory>`), with user-only
|
|
550
|
+
permissions. Identical project, repository, scope, and build inputs produce the same manifest ID
|
|
551
|
+
and pixels.
|
|
552
|
+
|
|
553
|
+
Repository input conventions are explicit so no Ruby is ever evaluated:
|
|
554
|
+
|
|
555
|
+
- `fastlane/metadata/<locale>/*.txt` — supported localized Deliver metadata;
|
|
556
|
+
- `fastlane/metadata/*.txt` and `review_information/*.txt` — app and review metadata;
|
|
557
|
+
- `fastlane/metadata/app_store_rating_config.json` — Fastlane's current age-rating shape;
|
|
558
|
+
- `fastlane/metadata/submission_information.json` — export/content compliance fields;
|
|
559
|
+
- `fastlane/metadata/app_review_attachment_file.txt` — empty clears the attachment; otherwise it
|
|
560
|
+
names a repository-relative supported attachment;
|
|
561
|
+
- `fastlane/app-previews/<locale>/*` — `.mov`, `.mp4`, or `.m4v`, with the ASC device token in
|
|
562
|
+
each filename (for example `APP_IPHONE_67_01_demo.mp4`).
|
|
563
|
+
|
|
564
|
+
Missing files mean **unchanged**; an existing supported empty text file means **clear**. Unknown
|
|
565
|
+
files, fields, locales, outputs, unreadable artifacts, and Bundle ID disagreements fail closed.
|
|
566
|
+
Fastfile and Deliverfile are never executed. Optional `.ipa`/supported `.pkg` bytes are hashed and
|
|
567
|
+
referenced, never copied into ShotOps state. This step performs no ASC request, upload, version
|
|
568
|
+
creation, signing, submission, or release.
|
|
569
|
+
|
|
570
|
+
### Create the exact App Store Connect plan
|
|
571
|
+
|
|
572
|
+
Read the editable App Store version and bind it to the prepared workspace without changing Apple:
|
|
573
|
+
|
|
574
|
+
```bash
|
|
575
|
+
npx shotops-mcp release plan \
|
|
576
|
+
--workspace ~/.shotops/release-workspaces/<desired-id> \
|
|
577
|
+
--repo .
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
The command resolves the Bundle ID to one accessible app and one editable iOS version, then reads
|
|
581
|
+
the supported metadata, review, age-rating, compliance, build, screenshot, and App Preview
|
|
582
|
+
baseline. It writes a user-only `release-plan.json` containing every create, update, clear,
|
|
583
|
+
replacement, upload, attachment, and no-op, plus a portable `release-review.zip` containing that
|
|
584
|
+
exact canonical plan and its content-addressed screenshot bytes. The plan expires after 15 minutes
|
|
585
|
+
and hash-binds the project revision, desired bytes, normalized Fastlane inputs, Apple setup identity,
|
|
586
|
+
policy version, and the complete remote snapshot so later approval cannot drift onto different state.
|
|
587
|
+
|
|
588
|
+
`release-plan-envelope.json` is the separate redacted form safe for a later ShotOps coordination
|
|
589
|
+
step: it carries identifiers and value hashes, never metadata values, review credentials, local
|
|
590
|
+
paths, Apple credentials, or asset bytes. This command talks directly to Apple with GET requests
|
|
591
|
+
only; it never uploads, creates a version, commits, submits, or sends the private key to ShotOps.
|
|
592
|
+
|
|
593
|
+
### Review the exact plan locally
|
|
594
|
+
|
|
595
|
+
From the plan directory, open its read-only local browser review:
|
|
596
|
+
|
|
597
|
+
```bash
|
|
598
|
+
npx shotops-mcp release review
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
To review an artifact downloaded from owner-controlled CI, pass it directly:
|
|
602
|
+
|
|
603
|
+
```bash
|
|
604
|
+
npx shotops-mcp release review release-review.zip
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
The command verifies the unexpired exact plan hash, artifact manifest, and every embedded screenshot
|
|
608
|
+
before opening a nonce-protected URL on `127.0.0.1` with a random port. The page shows target app and
|
|
609
|
+
team fingerprint, Bundle ID, version, expiry, complete or partial scope, every before/after/clear,
|
|
610
|
+
build, review, rating, compliance, preview, screenshot order/replacement/omission, no-op, and the
|
|
611
|
+
operations excluded by the plan. Partial-scope and no-build warnings cannot be dismissed. It loads
|
|
612
|
+
no remote resource, sends nothing, and has no edit or approval action; expired, corrupt, edited, or
|
|
613
|
+
content-mismatched inputs fail before a server is started.
|
|
614
|
+
|
|
453
615
|
The saved project remembers the exact on-disk folder your screenshots came from (not just their
|
|
454
616
|
filenames), so re-opening it on the SAME machine can point right back at it. Share links aren't
|
|
455
617
|
bridged yet — they'd need a hosted rendering step, which would defeat local rendering's whole
|
|
@@ -480,7 +642,7 @@ shotops-mcp/
|
|
|
480
642
|
uploads.ts Phase 10 — upload slots, ref ownership check, output:'urls' storage
|
|
481
643
|
screenshotInput.ts Phase 10 — resolves screenshots[] (inline/ref/url/path) to base64
|
|
482
644
|
env.ts loads ../.env.local; MCP_PORT / STUDIO_ORIGIN / MCP_PUBLIC_URL
|
|
483
|
-
local.ts the LOCAL
|
|
645
|
+
local.ts the LOCAL npx entry point — stdio transport, no auth required to preview
|
|
484
646
|
localDeps.ts the local ToolDeps fork — static-serve renderer, no-op/bridged persistence
|
|
485
647
|
hostedBridge.ts local→hosted bridge (a real MCP client using your shotops_ token)
|
|
486
648
|
harness/ the browser render page Chromium loads (render.js exposes window.renderStrip)
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
Third-Party Notices for shotops-mcp
|
|
2
|
+
|
|
3
|
+
This file identifies third-party software, font files and 3D models bundled
|
|
4
|
+
directly in the shotops-mcp package. Dependencies installed as separate npm
|
|
5
|
+
packages carry their own license files.
|
|
6
|
+
|
|
7
|
+
-------------------------------------------------------------------------------
|
|
8
|
+
iPhone 17 Pro 3D model
|
|
9
|
+
-------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
"iPhone 17 Pro" by Ranguel (https://sketchfab.com/Ranguel)
|
|
12
|
+
Source: https://sketchfab.com/3d-models/iphone-17-pro-4541aa8a28324b33a2baaf81d263aaec
|
|
13
|
+
Licensed under Creative Commons Attribution 4.0 International (CC BY 4.0):
|
|
14
|
+
https://creativecommons.org/licenses/by/4.0/
|
|
15
|
+
|
|
16
|
+
The model file bundled here (dist/harness assets) is a converted and optimized
|
|
17
|
+
derivative of that work, produced with glTF-Transform. CC BY 4.0 permits both
|
|
18
|
+
commercial use and redistribution of the model, including in modified form,
|
|
19
|
+
provided the author is credited — which is what this notice is for. Keep it in
|
|
20
|
+
any redistribution of this package.
|
|
21
|
+
|
|
22
|
+
Apple and iPhone are trademarks of Apple Inc. Google and Pixel are trademarks
|
|
23
|
+
of Google LLC. Neither company sponsors or endorses ShotOps.
|
|
24
|
+
|
|
25
|
+
-------------------------------------------------------------------------------
|
|
26
|
+
Three.js
|
|
27
|
+
-------------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
Copyright (c) 2010-2024 three.js authors
|
|
30
|
+
|
|
31
|
+
The MIT License
|
|
32
|
+
|
|
33
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
34
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
35
|
+
in the Software without restriction, including without limitation the rights
|
|
36
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
37
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
38
|
+
furnished to do so, subject to the following conditions:
|
|
39
|
+
|
|
40
|
+
The above copyright notice and this permission notice shall be included in
|
|
41
|
+
all copies or substantial portions of the Software.
|
|
42
|
+
|
|
43
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
44
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
45
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
46
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
47
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
48
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
49
|
+
THE SOFTWARE.
|
|
50
|
+
|
|
51
|
+
-------------------------------------------------------------------------------
|
|
52
|
+
Bundled caption fonts
|
|
53
|
+
-------------------------------------------------------------------------------
|
|
54
|
+
|
|
55
|
+
The package includes unmodified, Latin-subset WOFF2 files from these font
|
|
56
|
+
families:
|
|
57
|
+
|
|
58
|
+
Inter
|
|
59
|
+
Copyright 2020 The Inter Project Authors (https://github.com/rsms/inter)
|
|
60
|
+
|
|
61
|
+
Manrope
|
|
62
|
+
Copyright 2018 The Manrope Project Authors (https://github.com/sharanda/manrope)
|
|
63
|
+
|
|
64
|
+
Poppins
|
|
65
|
+
Copyright 2020 The Poppins Project Authors (https://github.com/itfoundry/Poppins)
|
|
66
|
+
|
|
67
|
+
Fraunces
|
|
68
|
+
Copyright 2018 The Fraunces Project Authors (https://github.com/undercasetype/Fraunces)
|
|
69
|
+
|
|
70
|
+
Space Grotesk
|
|
71
|
+
Copyright 2020 The Space Grotesk Project Authors (https://github.com/floriankarsten/space-grotesk)
|
|
72
|
+
|
|
73
|
+
Each font is licensed under the SIL Open Font License, Version 1.1:
|
|
74
|
+
https://openfontlicense.org/open-font-license-official-text/
|
|
75
|
+
|
|
76
|
+
-----------------------------------------------------------
|
|
77
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
78
|
+
-----------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
PREAMBLE
|
|
81
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
82
|
+
development of collaborative font projects, to support the font creation
|
|
83
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
84
|
+
open framework in which fonts may be shared and improved in partnership
|
|
85
|
+
with others.
|
|
86
|
+
|
|
87
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
88
|
+
redistributed freely as long as they are not sold by themselves. The fonts,
|
|
89
|
+
including any derivative works, can be bundled, embedded, redistributed
|
|
90
|
+
and/or sold with any software provided that any reserved names are not used
|
|
91
|
+
by derivative works. The fonts and derivatives, however, cannot be released
|
|
92
|
+
under any other type of license. The requirement for fonts to remain under
|
|
93
|
+
this license does not apply to any document created using the fonts or their
|
|
94
|
+
derivatives.
|
|
95
|
+
|
|
96
|
+
DEFINITIONS
|
|
97
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
98
|
+
Holder(s) under this license and clearly marked as such. This may include
|
|
99
|
+
source files, build scripts and documentation.
|
|
100
|
+
|
|
101
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
102
|
+
copyright statement(s).
|
|
103
|
+
|
|
104
|
+
"Original Version" refers to the collection of Font Software components as
|
|
105
|
+
distributed by the Copyright Holder(s).
|
|
106
|
+
|
|
107
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
108
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
109
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
110
|
+
new environment.
|
|
111
|
+
|
|
112
|
+
"Author" refers to any designer, engineer, programmer, technical writer or
|
|
113
|
+
other person who contributed to the Font Software.
|
|
114
|
+
|
|
115
|
+
PERMISSION & CONDITIONS
|
|
116
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
117
|
+
of the Font Software, to use, study, copy, merge, embed, modify, redistribute,
|
|
118
|
+
and sell modified and unmodified copies of the Font Software, subject to the
|
|
119
|
+
following conditions:
|
|
120
|
+
|
|
121
|
+
1) Neither the Font Software nor any of its individual components, in
|
|
122
|
+
Original or Modified Versions, may be sold by itself.
|
|
123
|
+
|
|
124
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
125
|
+
redistributed and/or sold with any software, provided that each copy contains
|
|
126
|
+
the above copyright notice and this license. These can be included either as
|
|
127
|
+
stand-alone text files, human-readable headers or in the appropriate
|
|
128
|
+
machine-readable metadata fields within text or binary files as long as those
|
|
129
|
+
fields can be easily viewed by the user.
|
|
130
|
+
|
|
131
|
+
3) No Modified Version of the Font Software may use the Reserved Font Name(s)
|
|
132
|
+
unless explicit written permission is granted by the corresponding Copyright
|
|
133
|
+
Holder. This restriction only applies to the primary font name as presented
|
|
134
|
+
to the users.
|
|
135
|
+
|
|
136
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
137
|
+
Software shall not be used to promote, endorse or advertise any Modified
|
|
138
|
+
Version, except to acknowledge the contribution(s) of the Copyright Holder(s)
|
|
139
|
+
and the Author(s) or with their explicit written permission.
|
|
140
|
+
|
|
141
|
+
5) The Font Software, modified or unmodified, in part or in whole, must be
|
|
142
|
+
distributed entirely under this license, and must not be distributed under
|
|
143
|
+
any other license. The requirement for fonts to remain under this license
|
|
144
|
+
does not apply to any document created using the Font Software.
|
|
145
|
+
|
|
146
|
+
TERMINATION
|
|
147
|
+
This license becomes null and void if any of the above conditions are not met.
|
|
148
|
+
|
|
149
|
+
DISCLAIMER
|
|
150
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
151
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
|
|
152
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
|
|
153
|
+
TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR
|
|
154
|
+
ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL,
|
|
155
|
+
INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF
|
|
156
|
+
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE
|
|
157
|
+
THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|