@efectoapp/mcp-studio 0.1.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/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # @efectoapp/mcp-studio
2
+
3
+ MCP server for **Efecto Studio** — give AI agents the full power of Studio's web design tools.
4
+
5
+ Every tool is first-class. No proxy pattern, no session ID juggling. Create a session, and all 33 design tools are immediately available.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npx @efectoapp/mcp-studio install
11
+ ```
12
+
13
+ This registers the MCP server in `~/.claude.json` and installs the Studio skill file. Restart Claude Code after installing.
14
+
15
+ ## Uninstall
16
+
17
+ ```bash
18
+ npx @efectoapp/mcp-studio uninstall
19
+ ```
20
+
21
+ ## How It Works
22
+
23
+ 1. Agent calls `create_session` → gets a Studio URL
24
+ 2. User opens the URL in their browser
25
+ 3. Agent uses any of the 36 tools directly — they execute in the browser in real-time
26
+ 4. User sees every change live as the agent builds the design
27
+
28
+ ## Tools (36 total)
29
+
30
+ ### Session (3)
31
+
32
+ | Tool | Description |
33
+ |------|-------------|
34
+ | `create_session` | Create a session, returns URL for the user |
35
+ | `session_status` | Check browser connection status |
36
+ | `close_session` | Close session and clean up |
37
+
38
+ ### Reading State (4)
39
+
40
+ | Tool | Description |
41
+ |------|-------------|
42
+ | `get_document` | Get full document as JSX markup |
43
+ | `list_artboards` | List all artboards with metadata |
44
+ | `find_nodes` | Search nodes by name/type/class |
45
+ | `get_node_tree` | Get JSX for one node/artboard subtree (faster than full doc) |
46
+
47
+ ### Creating Content (4)
48
+
49
+ | Tool | Description |
50
+ |------|-------------|
51
+ | `create_artboard` | Create a new artboard |
52
+ | `add_section` | Add complex layouts from JSX (preferred) |
53
+ | `add_node` | Add a single node |
54
+ | `replace_section` | Replace a node with new JSX |
55
+
56
+ ### Modifying Content (4)
57
+
58
+ | Tool | Description |
59
+ |------|-------------|
60
+ | `update_node` | Update any node property |
61
+ | `update_class` | Update only className |
62
+ | `update_artboard` | Update artboard properties |
63
+ | `batch_update` | Bulk update multiple nodes |
64
+
65
+ ### Organizing Structure (6)
66
+
67
+ | Tool | Description |
68
+ |------|-------------|
69
+ | `move_node` | Reparent or reorder |
70
+ | `duplicate_node` | Clone a node |
71
+ | `duplicate_artboard` | Clone an artboard |
72
+ | `group_nodes` | Wrap nodes in a frame |
73
+ | `ungroup_node` | Unwrap a group container |
74
+ | `reorder_node` | Z-order (front/back) |
75
+
76
+ ### Display & Deletion (5)
77
+
78
+ | Tool | Description |
79
+ |------|-------------|
80
+ | `select_nodes` | Highlight nodes for the user |
81
+ | `deselect_all` | Clear the selection |
82
+ | `set_visibility` | Show/hide nodes |
83
+ | `delete_nodes` | Delete nodes |
84
+ | `delete_artboard` | Delete an artboard |
85
+
86
+ ### Alignment & Distribution (2)
87
+
88
+ | Tool | Description |
89
+ |------|-------------|
90
+ | `align_nodes` | Align nodes (left/center/right/top/middle/bottom) |
91
+ | `distribute_nodes` | Distribute evenly (horizontal/vertical) |
92
+
93
+ ### History (2)
94
+
95
+ | Tool | Description |
96
+ |------|-------------|
97
+ | `undo` | Undo last action |
98
+ | `redo` | Redo last undone action |
99
+
100
+ ### Viewport & Document (5)
101
+
102
+ | Tool | Description |
103
+ |------|-------------|
104
+ | `zoom_to_artboard` | Zoom to show an artboard |
105
+ | `zoom_to_fit` | Zoom to fit all artboards |
106
+ | `set_viewport` | Set zoom level and pan position |
107
+ | `rename_document` | Rename the document |
108
+ | `new_document` | Start a new blank document |
109
+
110
+ ### Canvas (1)
111
+
112
+ | Tool | Description |
113
+ |------|-------------|
114
+ | `move_artboard` | Reposition artboard on canvas for multi-screen flows |
115
+
116
+ ## Auto-Session
117
+
118
+ The MCP process holds the active session in memory. After `create_session`, all design tools automatically use it — no need to pass `sessionId`. For multi-session edge cases, every tool accepts an optional `sessionId` override.
119
+
120
+ ## Links
121
+
122
+ - **Docs**: https://efecto.app/docs/studio
123
+ - **App**: https://efecto.app/studio
124
+ - **GitHub**: https://github.com/pablostanley/efecto-app
package/dist/cli.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Efecto Studio MCP CLI
4
+ *
5
+ * Simple commands:
6
+ * npx @efectoapp/mcp-studio install - Add Efecto Studio to Claude Code
7
+ * npx @efectoapp/mcp-studio uninstall - Remove Efecto Studio from Claude Code
8
+ */
9
+ export declare function runCLI(): boolean;
10
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;GAMG;AAwPH,wBAAgB,MAAM,IAAI,OAAO,CAoBhC"}
package/dist/cli.js ADDED
@@ -0,0 +1,276 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * Efecto Studio MCP CLI
5
+ *
6
+ * Simple commands:
7
+ * npx @efectoapp/mcp-studio install - Add Efecto Studio to Claude Code
8
+ * npx @efectoapp/mcp-studio uninstall - Remove Efecto Studio from Claude Code
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.runCLI = runCLI;
45
+ const fs = __importStar(require("fs"));
46
+ const path = __importStar(require("path"));
47
+ const os = __importStar(require("os"));
48
+ // ANSI colors for pretty output
49
+ const green = (s) => `\x1b[32m${s}\x1b[0m`;
50
+ const red = (s) => `\x1b[31m${s}\x1b[0m`;
51
+ const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
52
+ const yellow = (s) => `\x1b[33m${s}\x1b[0m`;
53
+ const bold = (s) => `\x1b[1m${s}\x1b[0m`;
54
+ const dim = (s) => `\x1b[2m${s}\x1b[0m`;
55
+ // The MCP server config we add
56
+ const EFECTOSTUDIO_CONFIG = {
57
+ command: 'npx',
58
+ args: ['-y', '@efectoapp/mcp-studio'],
59
+ };
60
+ const SERVER_KEY = 'efectostudio';
61
+ const SKILLS_DIR_NAME = 'efectostudio';
62
+ // Get the path to ~/.claude.json
63
+ function getClaudeConfigPath() {
64
+ return path.join(os.homedir(), '.claude.json');
65
+ }
66
+ // Read ~/.claude.json file
67
+ function readClaudeConfig(filePath) {
68
+ try {
69
+ if (fs.existsSync(filePath)) {
70
+ const content = fs.readFileSync(filePath, 'utf-8');
71
+ return JSON.parse(content);
72
+ }
73
+ }
74
+ catch {
75
+ // Invalid JSON, return empty
76
+ }
77
+ return {};
78
+ }
79
+ // Write ~/.claude.json file
80
+ function writeClaudeConfig(filePath, config) {
81
+ fs.writeFileSync(filePath, JSON.stringify(config, null, 2) + '\n');
82
+ }
83
+ // Check if Claude Code is installed
84
+ function isClaudeCodeInstalled() {
85
+ const claudeDir = path.join(os.homedir(), '.claude');
86
+ return fs.existsSync(claudeDir);
87
+ }
88
+ // Get the path to the bundled skills directory
89
+ function getSkillsSourceDir() {
90
+ return path.join(__dirname, '..', 'skills');
91
+ }
92
+ // Get the target directory for skills (~/.claude/skills/efectostudio/)
93
+ function getSkillsTargetDir() {
94
+ return path.join(os.homedir(), '.claude', 'skills', SKILLS_DIR_NAME);
95
+ }
96
+ // Install the design skill files
97
+ function installSkills() {
98
+ const sourceDir = getSkillsSourceDir();
99
+ const targetDir = getSkillsTargetDir();
100
+ const skillFile = path.join(sourceDir, 'STUDIO-SKILL.md');
101
+ if (!fs.existsSync(skillFile)) {
102
+ return false;
103
+ }
104
+ fs.mkdirSync(targetDir, { recursive: true });
105
+ const files = ['STUDIO-SKILL.md'];
106
+ for (const file of files) {
107
+ const src = path.join(sourceDir, file);
108
+ const dest = path.join(targetDir, file);
109
+ if (fs.existsSync(src)) {
110
+ fs.copyFileSync(src, dest);
111
+ }
112
+ }
113
+ return true;
114
+ }
115
+ // Remove the design skill files
116
+ function uninstallSkills() {
117
+ const targetDir = getSkillsTargetDir();
118
+ if (fs.existsSync(targetDir)) {
119
+ const files = ['STUDIO-SKILL.md'];
120
+ for (const file of files) {
121
+ const filePath = path.join(targetDir, file);
122
+ if (fs.existsSync(filePath)) {
123
+ fs.unlinkSync(filePath);
124
+ }
125
+ }
126
+ try {
127
+ fs.rmdirSync(targetDir);
128
+ const skillsDir = path.dirname(targetDir);
129
+ fs.rmdirSync(skillsDir);
130
+ }
131
+ catch {
132
+ // Directory not empty, that's fine
133
+ }
134
+ }
135
+ }
136
+ // Install
137
+ function install() {
138
+ console.log('');
139
+ console.log(bold(' 🎨 Efecto Studio MCP Installer'));
140
+ console.log(dim(' ────────────────────────────────'));
141
+ console.log('');
142
+ if (!isClaudeCodeInstalled()) {
143
+ console.log(red(' ✗ Claude Code not found'));
144
+ console.log('');
145
+ console.log(' Make sure Claude Code is installed:');
146
+ console.log(cyan(' https://claude.ai/code'));
147
+ console.log('');
148
+ process.exit(1);
149
+ }
150
+ const configPath = getClaudeConfigPath();
151
+ const config = readClaudeConfig(configPath);
152
+ if (!config.mcpServers || typeof config.mcpServers !== 'object') {
153
+ config.mcpServers = {};
154
+ }
155
+ const mcpServers = config.mcpServers;
156
+ if (mcpServers[SERVER_KEY]) {
157
+ console.log(yellow(' ⚠ Efecto Studio is already installed'));
158
+ console.log('');
159
+ console.log(dim(` Config: ${configPath}`));
160
+ console.log('');
161
+ console.log(' To reinstall, run:');
162
+ console.log(cyan(' npx @efectoapp/mcp-studio uninstall'));
163
+ console.log(cyan(' npx @efectoapp/mcp-studio install'));
164
+ console.log('');
165
+ process.exit(0);
166
+ }
167
+ mcpServers[SERVER_KEY] = EFECTOSTUDIO_CONFIG;
168
+ writeClaudeConfig(configPath, config);
169
+ console.log(green(' ✓ MCP server installed'));
170
+ const skillsInstalled = installSkills();
171
+ if (skillsInstalled) {
172
+ console.log(green(' ✓ Studio skill installed'));
173
+ console.log(dim(` → ${getSkillsTargetDir()}`));
174
+ }
175
+ console.log('');
176
+ console.log(dim(` Config: ${configPath}`));
177
+ console.log('');
178
+ console.log(bold(' Next steps:'));
179
+ console.log('');
180
+ console.log(' 1. Restart Claude Code');
181
+ console.log('');
182
+ console.log(' 2. Try it out! Just ask Claude:');
183
+ console.log(cyan(' "Design a landing page in Efecto Studio"'));
184
+ console.log(cyan(' "Create a mobile app screen with a dark theme"'));
185
+ console.log(cyan(' "Build a pricing page for my SaaS product"'));
186
+ console.log('');
187
+ console.log(dim(' Docs: https://efecto.app/docs/studio'));
188
+ console.log('');
189
+ }
190
+ // Uninstall
191
+ function uninstall() {
192
+ console.log('');
193
+ console.log(bold(' 🎨 Efecto Studio MCP Uninstaller'));
194
+ console.log(dim(' ────────────────────────────────'));
195
+ console.log('');
196
+ const configPath = getClaudeConfigPath();
197
+ if (!fs.existsSync(configPath)) {
198
+ console.log(yellow(' ⚠ No Claude Code config found'));
199
+ console.log('');
200
+ console.log(' Nothing to uninstall.');
201
+ console.log('');
202
+ process.exit(0);
203
+ }
204
+ const config = readClaudeConfig(configPath);
205
+ const mcpServers = config.mcpServers;
206
+ if (!mcpServers || !mcpServers[SERVER_KEY]) {
207
+ console.log(yellow(' ⚠ Efecto Studio is not installed'));
208
+ console.log('');
209
+ console.log(' Nothing to uninstall.');
210
+ console.log('');
211
+ process.exit(0);
212
+ }
213
+ delete mcpServers[SERVER_KEY];
214
+ if (Object.keys(mcpServers).length === 0) {
215
+ delete config.mcpServers;
216
+ }
217
+ writeClaudeConfig(configPath, config);
218
+ uninstallSkills();
219
+ console.log(green(' ✓ Efecto Studio uninstalled'));
220
+ console.log('');
221
+ console.log(dim(` Config: ${configPath}`));
222
+ console.log('');
223
+ console.log(' Restart Claude Code to apply changes.');
224
+ console.log('');
225
+ console.log(' To reinstall later:');
226
+ console.log(cyan(' npx @efectoapp/mcp-studio install'));
227
+ console.log('');
228
+ }
229
+ // Show help
230
+ function showHelp() {
231
+ console.log('');
232
+ console.log(bold(' 🎨 Efecto Studio MCP'));
233
+ console.log(dim(' ────────────────────'));
234
+ console.log('');
235
+ console.log(' Design web pages with AI. Create artboards, add sections,');
236
+ console.log(' style with Tailwind CSS — all from Claude Code.');
237
+ console.log('');
238
+ console.log(bold(' Commands:'));
239
+ console.log('');
240
+ console.log(` ${cyan('npx @efectoapp/mcp-studio install')}`);
241
+ console.log(' Add Efecto Studio to Claude Code');
242
+ console.log('');
243
+ console.log(` ${cyan('npx @efectoapp/mcp-studio uninstall')}`);
244
+ console.log(' Remove Efecto Studio from Claude Code');
245
+ console.log('');
246
+ console.log(bold(' After installing:'));
247
+ console.log('');
248
+ console.log(' 1. Restart Claude Code');
249
+ console.log(' 2. Ask Claude to create something:');
250
+ console.log(cyan(' "Design a landing page in Studio"'));
251
+ console.log('');
252
+ console.log(dim(' Docs: https://efecto.app/docs/studio'));
253
+ console.log('');
254
+ }
255
+ // Main CLI entry point
256
+ function runCLI() {
257
+ const args = process.argv.slice(2);
258
+ const command = args[0]?.toLowerCase();
259
+ switch (command) {
260
+ case 'install':
261
+ install();
262
+ return true;
263
+ case 'uninstall':
264
+ case 'remove':
265
+ uninstall();
266
+ return true;
267
+ case 'help':
268
+ case '--help':
269
+ case '-h':
270
+ showHelp();
271
+ return true;
272
+ default:
273
+ return false;
274
+ }
275
+ }
276
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Efecto Studio MCP Server
4
+ *
5
+ * Gives AI agents the full power of Efecto Studio's design tools.
6
+ * Every tool is first-class — no proxy pattern, no session ID juggling.
7
+ *
8
+ * INSTALL:
9
+ * npx @efectoapp/mcp-studio install
10
+ *
11
+ * UNINSTALL:
12
+ * npx @efectoapp/mcp-studio uninstall
13
+ *
14
+ * Then restart Claude Code and ask:
15
+ * "Design a landing page in Efecto Studio"
16
+ */
17
+ export {};
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;GAcG"}
package/dist/index.js ADDED
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * Efecto Studio MCP Server
5
+ *
6
+ * Gives AI agents the full power of Efecto Studio's design tools.
7
+ * Every tool is first-class — no proxy pattern, no session ID juggling.
8
+ *
9
+ * INSTALL:
10
+ * npx @efectoapp/mcp-studio install
11
+ *
12
+ * UNINSTALL:
13
+ * npx @efectoapp/mcp-studio uninstall
14
+ *
15
+ * Then restart Claude Code and ask:
16
+ * "Design a landing page in Efecto Studio"
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ const cli_js_1 = require("./cli.js");
20
+ // Check if this is a CLI command (install, uninstall, help)
21
+ if ((0, cli_js_1.runCLI)()) {
22
+ process.exit(0);
23
+ }
24
+ // Otherwise, run as MCP server
25
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
26
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
27
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
28
+ const session_js_1 = require("./tools/session.js");
29
+ const studio_js_1 = require("./tools/studio.js");
30
+ // Combine all tools
31
+ const allTools = [...session_js_1.sessionTools, ...studio_js_1.studioTools];
32
+ // Create server instance
33
+ const server = new index_js_1.Server({
34
+ name: 'efectostudio-mcp',
35
+ version: '0.1.0',
36
+ }, {
37
+ capabilities: {
38
+ tools: {},
39
+ },
40
+ });
41
+ // Handle tool listing
42
+ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
43
+ return { tools: allTools };
44
+ });
45
+ // Handle tool calls
46
+ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
47
+ const { name, arguments: args } = request.params;
48
+ try {
49
+ // Session tools
50
+ if (session_js_1.sessionTools.some(t => t.name === name)) {
51
+ return await (0, session_js_1.handleSessionTool)(name, args);
52
+ }
53
+ // Studio design tools
54
+ if (studio_js_1.studioTools.some(t => t.name === name)) {
55
+ return await (0, studio_js_1.handleStudioTool)(name, args);
56
+ }
57
+ return {
58
+ content: [{ type: 'text', text: `Unknown tool: ${name}` }],
59
+ isError: true,
60
+ };
61
+ }
62
+ catch (error) {
63
+ return {
64
+ content: [
65
+ {
66
+ type: 'text',
67
+ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
68
+ },
69
+ ],
70
+ isError: true,
71
+ };
72
+ }
73
+ });
74
+ // Start the server
75
+ async function main() {
76
+ const transport = new stdio_js_1.StdioServerTransport();
77
+ await server.connect(transport);
78
+ console.error('Efecto Studio MCP server running on stdio');
79
+ }
80
+ main().catch((error) => {
81
+ console.error('Server error:', error);
82
+ process.exit(1);
83
+ });
84
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAEA;;;;;;;;;;;;;;GAcG;;AAEH,qCAAiC;AAEjC,4DAA4D;AAC5D,IAAI,IAAA,eAAM,GAAE,EAAE,CAAC;IACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC;AAED,+BAA+B;AAC/B,wEAAkE;AAClE,wEAAgF;AAChF,iEAG2C;AAE3C,mDAAoE;AACpE,iDAAiE;AAEjE,oBAAoB;AACpB,MAAM,QAAQ,GAAG,CAAC,GAAG,yBAAY,EAAE,GAAG,uBAAW,CAAC,CAAA;AAElD,yBAAyB;AACzB,MAAM,MAAM,GAAG,IAAI,iBAAM,CACvB;IACE,IAAI,EAAE,kBAAkB;IACxB,OAAO,EAAE,OAAO;CACjB,EACD;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE;KACV;CACF,CACF,CAAA;AAED,sBAAsB;AACtB,MAAM,CAAC,iBAAiB,CAAC,iCAAsB,EAAE,KAAK,IAAI,EAAE;IAC1D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;AAC5B,CAAC,CAAC,CAAA;AAEF,oBAAoB;AACpB,MAAM,CAAC,iBAAiB,CAAC,gCAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAA;IAEhD,IAAI,CAAC;QACH,gBAAgB;QAChB,IAAI,yBAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YAC5C,OAAO,MAAM,IAAA,8BAAiB,EAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAC5C,CAAC;QAED,sBAAsB;QACtB,IAAI,uBAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YAC3C,OAAO,MAAM,IAAA,4BAAgB,EAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAC3C,CAAC;QAED,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,IAAI,EAAE,EAAE,CAAC;YAC1D,OAAO,EAAE,IAAI;SACd,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE;iBAC3E;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAA;IACH,CAAC;AACH,CAAC,CAAC,CAAA;AAEF,mBAAmB;AACnB,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAA;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC/B,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAA;AAC5D,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAA;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Studio Session Tools
3
+ *
4
+ * Manages the lifecycle of a Studio session. The MCP process holds
5
+ * the active session ID in memory so agents don't have to pass it around.
6
+ *
7
+ * - create_session: Create a new session, store internally, return URL
8
+ * - session_status: Check browser connection + pending calls
9
+ * - close_session: Close session, clear internal state
10
+ */
11
+ import type { Tool } from '@modelcontextprotocol/sdk/types.js';
12
+ /** Get the active session ID (used by studio tools) */
13
+ export declare function getActiveSessionId(): string | null;
14
+ export declare const sessionTools: Tool[];
15
+ export declare function handleSessionTool(name: string, args: Record<string, unknown> | undefined): Promise<{
16
+ content: Array<{
17
+ type: string;
18
+ text: string;
19
+ }>;
20
+ }>;
21
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/tools/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAA;AAW9D,uDAAuD;AACvD,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAElD;AAMD,eAAO,MAAM,YAAY,EAAE,IAAI,EAiD9B,CAAA;AAMD,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACxC,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAiO7D"}