@alisaitteke/photoshop-mcp 1.7.13 → 1.7.15

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/AGENTS.md CHANGED
@@ -7,7 +7,8 @@
7
7
 
8
8
  | Scenario | Path |
9
9
  | -------- | ---- |
10
- | Cursor / Claude Desktop / VS Code | Configure `mcpServers` → `npx -y @alisaitteke/photoshop-mcp` (stdio) |
10
+ | Cursor | Install the `photoshop-mcp` plugin (Customize → Plugins / Marketplace) so the Photoshop logo appears in the MCP list. Fallback: `mcpServers` → `npx -y @alisaitteke/photoshop-mcp` (stdio, generic icon) |
11
+ | Claude Desktop / VS Code | Configure `mcpServers` → `npx -y @alisaitteke/photoshop-mcp` (stdio) |
11
12
  | Claude Code | `claude mcp add photoshop -- npx -y @alisaitteke/photoshop-mcp` |
12
13
  | Standalone chat UI (no IDE) | `npx -p @alisaitteke/photoshop-mcp photoshop-mcp-ui` |
13
14
  | Local development | `npm install && npm run build && node dist/index.js` — see [docs/development.md](docs/development.md) |
@@ -58,6 +59,8 @@ Full catalog: [docs/available-tools.md](docs/available-tools.md). Prompt layer:
58
59
 
59
60
  ## MCP client configuration
60
61
 
62
+ Cursor: prefer the `photoshop-mcp` plugin (Customize → Plugins) so the Photoshop logo appears in the MCP list. Other hosts and the install-mcp deeplink use:
63
+
61
64
  ```json
62
65
  {
63
66
  "mcpServers": {
@@ -99,6 +102,7 @@ More: [docs/troubleshooting.md](docs/troubleshooting.md).
99
102
  | npm | `@alisaitteke/photoshop-mcp` |
100
103
  | MCP Registry | `io.github.alisaitteke/photoshop-mcp` |
101
104
  | GitHub | https://github.com/alisaitteke/photoshop-mcp |
105
+ | Cursor Marketplace | plugin `photoshop-mcp` (submit via [CONTRIBUTING.md](CONTRIBUTING.md#cursor-marketplace)) |
102
106
 
103
107
  ## Key files
104
108
 
@@ -111,6 +115,8 @@ More: [docs/troubleshooting.md](docs/troubleshooting.md).
111
115
  | [src/tools/](src/tools/) | Tool implementations |
112
116
  | [src/prompts/](src/prompts/) | MCP prompt templates |
113
117
  | [CONTRIBUTING.md](CONTRIBUTING.md) | PR and release workflow |
118
+ | [`.cursor-plugin/plugin.json`](.cursor-plugin/plugin.json) | Cursor Plugin manifest (MCP list logo) |
119
+ | [`mcp.json`](mcp.json) | Cursor Plugin stdio server config |
114
120
 
115
121
  ## Contributing (agents editing this repo)
116
122
 
package/README.de.md CHANGED
@@ -602,7 +602,9 @@ Für die lokale Entwicklung am Repository: [Aus dem Quellcode](docs/development.
602
602
 
603
603
  ### Für Cursor
604
604
 
605
- Zu den Cursor-Einstellungen (`.cursor/config.json` oder Workspace-Einstellungen) hinzufügen:
605
+ Damit das Photoshop-Logo in der MCP-Liste erscheint, das Plugin unter **Customize → Plugins** installieren oder nach der Freigabe im [Cursor Marketplace](https://cursor.com/marketplace) nach `photoshop-mcp` suchen. Ein manuelles `mcp.json` funktioniert weiterhin, zeigt aber ein generisches Symbol.
606
+
607
+ Zu den Cursor-Einstellungen (`~/.cursor/mcp.json` oder Workspace-Einstellungen) hinzufügen:
606
608
 
607
609
  ```json
608
610
  {
package/README.es.md CHANGED
@@ -557,7 +557,9 @@ Para trabajar en el repositorio localmente, consulte [From Source](docs/developm
557
557
 
558
558
  ### Para Cursor
559
559
 
560
- Añada a su configuración de Cursor (`.cursor/config.json` o la configuración del espacio de trabajo):
560
+ Para que el logo de Photoshop aparezca en la lista MCP, instale el plugin desde **Customize → Plugins**, o busque `photoshop-mcp` en el [Cursor Marketplace](https://cursor.com/marketplace) cuando esté publicado. Un `mcp.json` manual sigue funcionando, pero muestra un icono genérico.
561
+
562
+ Añada a su configuración de Cursor (`~/.cursor/mcp.json` o la configuración del espacio de trabajo):
561
563
 
562
564
  ```json
563
565
  {
package/README.ja.md CHANGED
@@ -559,7 +559,9 @@ npx @alisaitteke/photoshop-mcp
559
559
 
560
560
  ### Cursor向け
561
561
 
562
- Cursorの設定に追加してください(`.cursor/config.json`またはワークスペース設定):
562
+ MCPリストにPhotoshopロゴを表示するには、**Customize → Plugins** からプラグインをインストールするか、公開後に [Cursor Marketplace](https://cursor.com/marketplace) で `photoshop-mcp` を検索してください。手動の `mcp.json` でも動作しますが、汎用アイコンになります。
563
+
564
+ Cursorの設定に追加してください(`~/.cursor/mcp.json`またはワークスペース設定):
563
565
 
564
566
  ```json
565
567
  {
package/README.md CHANGED
@@ -89,6 +89,10 @@ Details, providers, Action Plan (API key or CLI account), and security notes:
89
89
 
90
90
  ### Option 2 — Inside your AI app (Cursor, Claude, VS Code)
91
91
 
92
+ **Cursor (shows the Photoshop logo in the MCP list):** install the plugin from **Customize → Plugins**, or search the [Cursor Marketplace](https://cursor.com/marketplace) for `photoshop-mcp` once it is listed. That package still launches `npx -y @alisaitteke/photoshop-mcp`; the plugin manifest is what supplies the icon.
93
+
94
+ Until the Marketplace listing is live, copy `.cursor-plugin/`, `mcp.json`, and `assets/` into `~/.cursor/plugins/local/photoshop-mcp` and reload the window — details in [CONTRIBUTING.md](CONTRIBUTING.md#cursor-marketplace). The Install-in-Cursor button and a raw `mcp.json` entry still work, but they show a generic icon.
95
+
92
96
  [![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=photoshop&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBhbGlzYWl0dGVrZS9waG90b3Nob3AtbWNwIl19)
93
97
  [![Install in VS Code](https://img.shields.io/badge/Install%20in-VS%20Code-0098FF)](https://vscode.dev/redirect/mcp/install?name=photoshop&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40alisaitteke%2Fphotoshop-mcp%22%5D%7D)
94
98
 
package/README.tr.md CHANGED
@@ -596,7 +596,9 @@ Depoyu yerel olarak geliştirmek için geliştirme kılavuzundaki [Kaynaktan](do
596
596
 
597
597
  ### Cursor için
598
598
 
599
- Cursor ayarlarınıza ekleyin (`.cursor/config.json` veya workspace ayarları):
599
+ MCP listesinde Photoshop logosunun görünmesi için eklentiyi **Customize → Plugins** üzerinden kurun (veya listelendikten sonra [Cursor Marketplace](https://cursor.com/marketplace) içinde `photoshop-mcp` arayın). Ham `mcp.json` yedek olarak çalışır ama jenerik ikon gösterir.
600
+
601
+ Cursor ayarlarınıza ekleyin (`.cursor/mcp.json` veya workspace ayarları):
600
602
 
601
603
  ```json
602
604
  {
package/README.zh-CN.md CHANGED
@@ -554,7 +554,9 @@ npx @alisaitteke/photoshop-mcp
554
554
 
555
555
  ### 适用于 Cursor
556
556
 
557
- 在您的 Cursor 设置(`.cursor/config.json` 或工作区设置)中添加:
557
+ 若要在 MCP 列表中显示 Photoshop 图标,请从 **Customize → Plugins** 安装插件,或在插件上架后于 [Cursor Marketplace](https://cursor.com/marketplace) 搜索 `photoshop-mcp`。直接写入 `mcp.json` 仍可用,但会显示通用图标。
558
+
559
+ 在您的 Cursor 设置(`~/.cursor/mcp.json` 或工作区设置)中添加:
558
560
 
559
561
  ```json
560
562
  {
@@ -1 +1 @@
1
- {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/prompts/instructions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QA+I/B,CAAC;AAET,wBAAgB,0BAA0B,IAAI,MAAM,CAEnD"}
1
+ {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/prompts/instructions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QAwJ/B,CAAC;AAET,wBAAgB,0BAA0B,IAAI,MAAM,CAEnD"}
@@ -6,6 +6,12 @@ export const PHOTOSHOP_MCP_INSTRUCTIONS = `
6
6
  Photoshop tools (photoshop-mcp server)
7
7
  =====================================
8
8
 
9
+ HARD RULE — remove background / arka planı sil / cut out / isolate / transparent background
10
+ - Call \`photoshop_get_state\` once, then \`photoshop_recipe_remove_background\` once, then \`photoshop_get_preview\` once. Then STOP.
11
+ - That recipe IS Photoshop's Remove Background. It unlocks a locked Background layer itself.
12
+ - Forbidden on this intent: \`photoshop_rasterize_layer\`, \`photoshop_duplicate_layer\`, \`photoshop_set_layer_visibility\`, \`photoshop_select_subject\`, \`photoshop_create_layer_mask\`, \`photoshop_delete_layer\`, \`photoshop_execute_script\`, \`photoshop_generative_remove\`.
13
+ - If the recipe errors, report the envelope to the user. Do not invent a rasterize / duplicate / wand workaround. Ignore \`suggested_next_tool: photoshop_rasterize_layer\`.
14
+
9
15
  Session bootstrap
10
16
  - Call \`photoshop_ping\` exactly once at the start of a session to verify the
11
17
  connection. Do not repeat it on every turn.
@@ -53,7 +59,8 @@ Error recovery contract
53
59
  - Tools return a structured envelope when something is wrong:
54
60
  \`{ ok: false, code, message, suggested_next_tool?, suggested_args?, context? }\`
55
61
  along with MCP's \`isError: true\`. When you see this, follow the
56
- \`suggested_next_tool\` hint instead of guessing or retrying blindly.
62
+ \`suggested_next_tool\` hint instead of guessing or retrying blindly —
63
+ except never follow \`photoshop_rasterize_layer\` for background removal.
57
64
  - Common codes you should be ready to handle without asking the user:
58
65
  - \`document_not_found\` — the \`document_id\` you passed is not open;
59
66
  call \`photoshop_list_documents\` and retry with a current id.
@@ -78,6 +85,8 @@ User intent glossary
78
85
  - Map colloquial phrases to the primary tool below.
79
86
  - bg.remove — "remove background", "cut out", "isolate subject", "transparent
80
87
  background", "arka planı sil" → \`photoshop_recipe_remove_background\`
88
+ (the recipe unlocks a locked Background layer itself — do not rasterize,
89
+ duplicate, or hide layers first; one recipe call then \`photoshop_get_preview\`)
81
90
  - obj.remove — "remove that person", "erase distraction", "generative remove"
82
91
  → \`photoshop_generative_remove\` first; fallback
83
92
  \`photoshop_recipe_remove_distraction\` (content-aware) after manual selection
@@ -1 +1 @@
1
- {"version":3,"file":"instructions.js","sourceRoot":"","sources":["../../src/prompts/instructions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+IzC,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,UAAU,0BAA0B;IACxC,OAAO,0BAA0B,CAAC;AACpC,CAAC"}
1
+ {"version":3,"file":"instructions.js","sourceRoot":"","sources":["../../src/prompts/instructions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwJzC,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,UAAU,0BAA0B;IACxC,OAAO,0BAA0B,CAAC;AACpC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"remove-background.d.ts","sourceRoot":"","sources":["../../../src/prompts/templates/remove-background.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,uBAAuB,EAC7B,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,wBAAwB,EAAE,uBAuCtC,CAAC"}
1
+ {"version":3,"file":"remove-background.d.ts","sourceRoot":"","sources":["../../../src/prompts/templates/remove-background.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,uBAAuB,EAC7B,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,wBAAwB,EAAE,uBAoCtC,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { argBool, argInt, userPrompt, } from '../_shared.js';
2
2
  export const removeBackgroundTemplate = {
3
3
  name: 'ps.remove_background',
4
- description: 'Remove the background from the active layer. Default path is Select Subject; uniform/high-key studio shots automatically fall back to Color Range. The keep_shadow argument is accepted but does not yet create a shadow layer (recorded in the recipe response only). Users often say: remove background, cut out, isolate subject, transparent background, arka planı sil.',
4
+ description: 'Remove the background from the active document in one recipe call. The recipe unlocks a Background layer itself and prefers Photoshop\'s native Remove Background. Users often say: remove background, cut out, isolate subject, transparent background, arka planı sil.',
5
5
  arguments: [
6
6
  {
7
7
  name: 'feather_px',
@@ -18,18 +18,15 @@ export const removeBackgroundTemplate = {
18
18
  const feather = Math.max(0, Math.min(20, argInt(args, 'feather_px', 0)));
19
19
  const keepShadow = argBool(args, 'keep_shadow', false);
20
20
  const text = [
21
- `Goal: Remove the background from the subject on the active layer (Select Subject, with Color Range fallback on uniform studio backgrounds).`,
21
+ `Goal: Remove the background. One recipe. Stop.`,
22
22
  ``,
23
- `Plan:`,
24
- `1. Call \`photoshop_get_state\` to confirm an active document with a non-background active layer that contains a subject.`,
25
- `2. Call \`photoshop_get_capabilities\` only if you have not yet this session; verify \`select_subject_v2\` is available.`,
26
- `3. Call \`photoshop_recipe_remove_background\` with { feather_px: ${feather}, keep_shadow: ${keepShadow} }.`,
27
- ` - Default: Select Subject + layer mask. On uniform/high-key (product-on-white) backgrounds the recipe may switch to Color Range; check details.method.`,
28
- ` - keep_shadow is accepted but does not yet create a shadow layer (value is recorded in the response only).`,
29
- `4. Call \`photoshop_get_preview\` to show the result against transparency.`,
30
- `5. If the mask edge needs refinement, ask the user before adding a refine-edge pass — that step is destructive on the mask.`,
23
+ `Do this and nothing else:`,
24
+ `1. \`photoshop_get_state\``,
25
+ `2. \`photoshop_recipe_remove_background\` with { feather_px: ${feather}, keep_shadow: ${keepShadow} }`,
26
+ `3. \`photoshop_get_preview\` once`,
27
+ `4. STOP. Report ok/summary. Do not rasterize, duplicate, hide, select_subject, mask, execute_script, or retry.`,
31
28
  ``,
32
- `End state: the subject layer carries a vector/pixel mask hiding the background; on-canvas background pixels are untouched (mask, not erase). One undo reverts the whole recipe.`,
29
+ `End state: subject isolated with a layer mask; one undo reverts it.`,
33
30
  ].join('\n');
34
31
  return userPrompt(`Remove the background (feather ${feather}px, shadow=${keepShadow}).`, text);
35
32
  },
@@ -1 +1 @@
1
- {"version":3,"file":"remove-background.js","sourceRoot":"","sources":["../../../src/prompts/templates/remove-background.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,MAAM,EACN,UAAU,GAEX,MAAM,eAAe,CAAC;AAEvB,MAAM,CAAC,MAAM,wBAAwB,GAA4B;IAC/D,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EACT,8WAA8W;IAChX,SAAS,EAAE;QACT;YACE,IAAI,EAAE,YAAY;YAClB,WAAW,EACT,0GAA0G;YAC5G,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,IAAI,EAAE,aAAa;YACnB,WAAW,EACT,qIAAqI;YACvI,QAAQ,EAAE,KAAK;SAChB;KACF;IACD,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACzE,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;QAEvD,MAAM,IAAI,GAAG;YACX,6IAA6I;YAC7I,EAAE;YACF,OAAO;YACP,2HAA2H;YAC3H,0HAA0H;YAC1H,qEAAqE,OAAO,kBAAkB,UAAU,KAAK;YAC7G,2JAA2J;YAC3J,+GAA+G;YAC/G,4EAA4E;YAC5E,6HAA6H;YAC7H,EAAE;YACF,iLAAiL;SAClL,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,OAAO,UAAU,CAAC,kCAAkC,OAAO,cAAc,UAAU,IAAI,EAAE,IAAI,CAAC,CAAC;IACjG,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"remove-background.js","sourceRoot":"","sources":["../../../src/prompts/templates/remove-background.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,MAAM,EACN,UAAU,GAEX,MAAM,eAAe,CAAC;AAEvB,MAAM,CAAC,MAAM,wBAAwB,GAA4B;IAC/D,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EACT,0QAA0Q;IAC5Q,SAAS,EAAE;QACT;YACE,IAAI,EAAE,YAAY;YAClB,WAAW,EACT,0GAA0G;YAC5G,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,IAAI,EAAE,aAAa;YACnB,WAAW,EACT,qIAAqI;YACvI,QAAQ,EAAE,KAAK;SAChB;KACF;IACD,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACzE,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;QAEvD,MAAM,IAAI,GAAG;YACX,gDAAgD;YAChD,EAAE;YACF,2BAA2B;YAC3B,4BAA4B;YAC5B,gEAAgE,OAAO,kBAAkB,UAAU,IAAI;YACvG,mCAAmC;YACnC,gHAAgH;YAChH,EAAE;YACF,qEAAqE;SACtE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,OAAO,UAAU,CAAC,kCAAkC,OAAO,cAAc,UAAU,IAAI,EAAE,IAAI,CAAC,CAAC;IACjG,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"remove-background.d.ts","sourceRoot":"","sources":["../../../src/tools/recipes/remove-background.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAc,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAMnE,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,mBAAmB,GAAG,cAAc,CA4CpF"}
1
+ {"version":3,"file":"remove-background.d.ts","sourceRoot":"","sources":["../../../src/tools/recipes/remove-background.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAc,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAKnE,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,mBAAmB,GAAG,cAAc,CA0CpF"}
@@ -1,21 +1,18 @@
1
- import { PhotoshopDetector } from '../../platform/detector.js';
2
- import { clampInt, executeRecipe, toolFailure } from './_shared.js';
1
+ import { clampInt, executeRecipe } from './_shared.js';
3
2
  const TOOL_NAME = 'photoshop_recipe_remove_background';
4
3
  export function bindRemoveBackground(connection) {
5
4
  return {
6
5
  tool: {
7
6
  name: TOOL_NAME,
8
- description: 'One-shot background removal: Select Subject by default, with an automatic Color Range fallback for uniform/high-key studio backgrounds (product-on-white). Attaches a layer mask (source pixels kept). Wrapped in a single undoable history step.\n' +
7
+ description: 'THE tool for "remove background" / "arka planı sil" / cut out / isolate subject. Call this once and stop. Unlocks a locked Background layer, then runs Photoshop native Remove Background (Select Subject / Color Range only if native is unavailable). One undo reverts everything.\n' +
9
8
  '\n' +
10
- 'Users often say: cut out, isolate subject, remove background, transparent background, arka planı sil.\n' +
9
+ 'Use when: the user wants the background gone. Hair, busy interiors, product shots — still this tool.\n' +
10
+ 'Do NOT rasterize, duplicate, hide layers, select_subject, create_layer_mask, or execute_script instead of this recipe.\n' +
11
11
  '\n' +
12
- 'Use when: the user wants the subject isolated from the background non-destructively.\n' +
13
- 'Do NOT use when: the subject is extremely fine-edged (hair against a busy background) — propose a manual Refine Edge pass afterwards.\n' +
12
+ 'Returns: { ok, summary, undo_history_states_consumed, details.method = remove_background | remove_layer_background | select_subject | color_range_fallback }.\n' +
14
13
  '\n' +
15
- 'Returns: { ok, summary, undo_history_states_consumed, details.method = select_subject | color_range_fallback }.\n' +
16
- '\n' +
17
- 'Preconditions: PS ≥ 23 (Select Subject v2) for the default path; Color Range fallback still runs on uniform studio shots if Select Subject is loose or empty.\n' +
18
- 'Side effects: attaches a pixel mask to the active layer; no pixels destroyed; one undo reverts everything.',
14
+ 'Preconditions: an active document. Native Remove Background needs a current Photoshop; Select Subject fallback needs PS ≥ 23.\n' +
15
+ 'Side effects: may unlock/rename the Background layer; attaches a pixel mask; no pixels destroyed; one undo reverts everything.',
19
16
  inputSchema: {
20
17
  type: 'object',
21
18
  properties: {
@@ -46,23 +43,22 @@ async function runRemoveBackground(connection, args) {
46
43
  const feather = clampInt(args.feather_px, 0, 20, 0);
47
44
  const keepShadow = args.keep_shadow === true;
48
45
  await connection.ping().catch(() => undefined);
49
- const info = connection.getPhotoshopInfo();
50
- if (info) {
51
- const detector = new PhotoshopDetector();
52
- if (!detector.supportsSelectSubjectV2(info.version)) {
53
- return toolFailure({
54
- ok: false,
55
- code: 'version_unsupported',
56
- message: `Select Subject v2 requires Photoshop 23.0+; detected version ${info.version}. Upgrade Photoshop or remove the background manually.`,
57
- suggested_next_tool: 'photoshop_get_capabilities',
58
- });
59
- }
60
- }
61
46
  const body = `
62
47
  var doc = app.activeDocument;
63
48
  var layer = doc.activeLayer;
49
+ var convertedBackground = false;
64
50
  if (layer.isBackgroundLayer) {
65
- return { ok: false, code: 'no_active_layer', message: 'Active layer is the Background layer — convert it to a normal layer first.', suggested_next_tool: 'photoshop_rasterize_layer' };
51
+ try {
52
+ var previousName = String(layer.name);
53
+ layer.isBackgroundLayer = false;
54
+ convertedBackground = true;
55
+ layer = doc.activeLayer;
56
+ if (previousName === 'Background' || layer.name === 'Background' || layer.name === 'Layer 0') {
57
+ layer.name = 'Subject';
58
+ }
59
+ } catch (eBg) {
60
+ return { ok: false, code: 'no_active_layer', message: 'Could not unlock the Background layer.', suggested_next_tool: 'photoshop_get_state' };
61
+ }
66
62
  }
67
63
 
68
64
  app.displayDialogs = DialogModes.NO;
@@ -180,6 +176,70 @@ async function runRemoveBackground(connection, args) {
180
176
  }
181
177
  }
182
178
 
179
+ function __mcp_hasMask() {
180
+ try {
181
+ var maskRef = new ActionReference();
182
+ maskRef.putEnumerated(stringIDToTypeID('layer'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
183
+ var maskDesc = executeActionGet(maskRef);
184
+ return maskDesc.hasKey(stringIDToTypeID('userMaskEnabled'));
185
+ } catch (eMask) {
186
+ return false;
187
+ }
188
+ }
189
+
190
+ function __mcp_tryNativeRemoveBackground() {
191
+ try {
192
+ executeAction(stringIDToTypeID('removeBackground'), new ActionDescriptor(), DialogModes.NO);
193
+ return __mcp_hasMask();
194
+ } catch (eNative) {
195
+ return false;
196
+ }
197
+ }
198
+
199
+ function __mcp_tryRemoveLayerBackground() {
200
+ try {
201
+ var rlDesc = new ActionDescriptor();
202
+ var rlRef = new ActionReference();
203
+ rlRef.putEnumerated(stringIDToTypeID('layer'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
204
+ rlDesc.putReference(stringIDToTypeID('null'), rlRef);
205
+ executeAction(stringIDToTypeID('removeLayerBackground'), rlDesc, DialogModes.NO);
206
+ return __mcp_hasMask();
207
+ } catch (eLayerBg) {
208
+ return false;
209
+ }
210
+ }
211
+
212
+ if (__mcp_tryNativeRemoveBackground()) {
213
+ return {
214
+ ok: true,
215
+ summary: 'Background removed via native Remove Background + layer mask',
216
+ undo_history_states_consumed: 1,
217
+ next_suggested_tool: 'photoshop_get_preview',
218
+ details: {
219
+ feather_px: ${feather},
220
+ keep_shadow: ${keepShadow ? 'true' : 'false'},
221
+ layer_name: layer.name,
222
+ method: 'remove_background',
223
+ converted_background: convertedBackground
224
+ }
225
+ };
226
+ }
227
+ if (__mcp_tryRemoveLayerBackground()) {
228
+ return {
229
+ ok: true,
230
+ summary: 'Background removed via Remove Layer Background + layer mask',
231
+ undo_history_states_consumed: 1,
232
+ next_suggested_tool: 'photoshop_get_preview',
233
+ details: {
234
+ feather_px: ${feather},
235
+ keep_shadow: ${keepShadow ? 'true' : 'false'},
236
+ layer_name: layer.name,
237
+ method: 'remove_layer_background',
238
+ converted_background: convertedBackground
239
+ }
240
+ };
241
+ }
242
+
183
243
  var studio = __mcp_detectStudio();
184
244
  var method = 'select_subject';
185
245
  var subjectOk = __mcp_trySelectSubject();
@@ -227,7 +287,8 @@ async function runRemoveBackground(connection, args) {
227
287
  feather_px: ${feather},
228
288
  keep_shadow: ${keepShadow ? 'true' : 'false'},
229
289
  layer_name: layer.name,
230
- method: method
290
+ method: method,
291
+ converted_background: convertedBackground
231
292
  }
232
293
  };
233
294
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"remove-background.js","sourceRoot":"","sources":["../../../src/tools/recipes/remove-background.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEpE,MAAM,SAAS,GAAG,oCAAoC,CAAC;AAEvD,MAAM,UAAU,oBAAoB,CAAC,UAA+B;IAClE,OAAO;QACL,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS;YACf,WAAW,EACT,qPAAqP;gBACrP,IAAI;gBACJ,yGAAyG;gBACzG,IAAI;gBACJ,wFAAwF;gBACxF,yIAAyI;gBACzI,IAAI;gBACJ,mHAAmH;gBACnH,IAAI;gBACJ,iKAAiK;gBACjK,4GAA4G;YAC9G,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,UAAU,EAAE;wBACV,IAAI,EAAE,QAAQ;wBACd,WAAW,EACT,0GAA0G;wBAC5G,OAAO,EAAE,CAAC;wBACV,OAAO,EAAE,EAAE;wBACX,OAAO,EAAE,CAAC;qBACX;oBACD,WAAW,EAAE;wBACX,IAAI,EAAE,SAAS;wBACf,WAAW,EACT,yGAAyG;wBAC3G,OAAO,EAAE,KAAK;qBACf;oBACD,cAAc,EAAE;wBACd,IAAI,EAAE,SAAS;wBACf,WAAW,EACT,6FAA6F;wBAC/F,OAAO,EAAE,KAAK;qBACf;iBACF;aACF;SACF;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC;KAC/D,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,UAA+B,EAC/B,IAA6B;IAE7B,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC;IAE7C,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,UAAU,CAAC,gBAAgB,EAAE,CAAC;IAC3C,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,QAAQ,GAAG,IAAI,iBAAiB,EAAE,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACpD,OAAO,WAAW,CAAC;gBACjB,EAAE,EAAE,KAAK;gBACT,IAAI,EAAE,qBAAqB;gBAC3B,OAAO,EAAE,gEAAgE,IAAI,CAAC,OAAO,wDAAwD;gBAC7I,mBAAmB,EAAE,4BAA4B;aAClD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAyJL,OAAO;oCACmB,OAAO;;;;;;;;8EAQmC,OAAO,yBAAyB,OAAO;;;;sBAI/F,OAAO;uBACN,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;;;;;GAKjD,CAAC;IAEF,OAAO,aAAa,CAAC,UAAU,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAC;AAC9D,CAAC"}
1
+ {"version":3,"file":"remove-background.js","sourceRoot":"","sources":["../../../src/tools/recipes/remove-background.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEvD,MAAM,SAAS,GAAG,oCAAoC,CAAC;AAEvD,MAAM,UAAU,oBAAoB,CAAC,UAA+B;IAClE,OAAO;QACL,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS;YACf,WAAW,EACT,wRAAwR;gBACxR,IAAI;gBACJ,wGAAwG;gBACxG,0HAA0H;gBAC1H,IAAI;gBACJ,iKAAiK;gBACjK,IAAI;gBACJ,iIAAiI;gBACjI,gIAAgI;YAClI,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,UAAU,EAAE;wBACV,IAAI,EAAE,QAAQ;wBACd,WAAW,EACT,0GAA0G;wBAC5G,OAAO,EAAE,CAAC;wBACV,OAAO,EAAE,EAAE;wBACX,OAAO,EAAE,CAAC;qBACX;oBACD,WAAW,EAAE;wBACX,IAAI,EAAE,SAAS;wBACf,WAAW,EACT,yGAAyG;wBAC3G,OAAO,EAAE,KAAK;qBACf;oBACD,cAAc,EAAE;wBACd,IAAI,EAAE,SAAS;wBACf,WAAW,EACT,6FAA6F;wBAC/F,OAAO,EAAE,KAAK;qBACf;iBACF;aACF;SACF;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC;KAC/D,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,UAA+B,EAC/B,IAA6B;IAE7B,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC;IAE7C,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAE/C,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA6KS,OAAO;yBACN,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;;;;;;;;;;;;;;wBAc9B,OAAO;yBACN,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAuC5C,OAAO;oCACmB,OAAO;;;;;;;;8EAQmC,OAAO,yBAAyB,OAAO;;;;sBAI/F,OAAO;uBACN,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;;;;;;GAMjD,CAAC;IAEF,OAAO,aAAa,CAAC,UAAU,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAC;AAC9D,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alisaitteke/photoshop-mcp",
3
- "version": "1.7.13",
3
+ "version": "1.7.15",
4
4
  "description": "MCP server for Adobe Photoshop — 116 tools (generative AI + recipes), standalone web UI. Control Photoshop from Cursor, Claude, or natural language.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",