@@ -105,14 +105,14 @@ func (h *JSHandler) handleExecuteJS(
105
105
ctx context.Context ,
106
106
request mcp.CallToolRequest ,
107
107
) (* mcp.CallToolResult , error ) {
108
- code , err := request .RequireString ("scriptCode " )
108
+ code , err := request .RequireString ("code " )
109
109
if err != nil {
110
110
return nil , err
111
111
}
112
112
113
113
// Check if this looks like HTTP server code
114
114
isServerCode := strings .Contains (code , "serve(" ) || strings .Contains (code , "require('ski/http/server')" )
115
-
115
+
116
116
if isServerCode {
117
117
// For server code, run in a goroutine and return immediately
118
118
return h .handleServerCode (ctx , code )
@@ -161,14 +161,14 @@ func (h *JSHandler) handleServerCode(ctx context.Context, code string) (*mcp.Cal
161
161
serverStarted <- false
162
162
return
163
163
}
164
-
164
+
165
165
// If no server was started, signal false and let goroutine exit
166
166
select {
167
167
case serverStarted <- false :
168
168
default :
169
169
// Channel already has a value, meaning a server was started
170
170
}
171
-
171
+
172
172
// Check if we should keep the goroutine alive
173
173
select {
174
174
case started := <- serverStarted :
@@ -200,41 +200,41 @@ func (h *JSHandler) setupHTTPModuleWithCallback(vm js.VM, serverStarted chan boo
200
200
vm .Runtime ().Set ("__originalRequire" , vm .Runtime ().Get ("require" ))
201
201
vm .Runtime ().Set ("require" , vm .Runtime ().ToValue (func (call sobek.FunctionCall ) sobek.Value {
202
202
moduleName := call .Argument (0 ).String ()
203
-
203
+
204
204
// If requesting the HTTP server module, return our wrapped version
205
205
if moduleName == "ski/http/server" {
206
206
httpServer := & httpmodule.Server {}
207
207
value , err := httpServer .Instantiate (vm .Runtime ())
208
208
if err != nil {
209
209
panic (vm .Runtime ().NewGoError (err ))
210
210
}
211
-
211
+
212
212
// Wrap the serve function to detect when a server is actually started
213
213
wrappedServe := vm .Runtime ().ToValue (func (call sobek.FunctionCall ) sobek.Value {
214
214
// Call the original serve function
215
215
serveFunc , ok := sobek .AssertFunction (value )
216
216
if ! ok {
217
217
panic (vm .Runtime ().NewTypeError ("serve is not a function" ))
218
218
}
219
-
219
+
220
220
result , err := serveFunc (sobek .Undefined (), call .Arguments ... )
221
221
if err != nil {
222
222
panic (vm .Runtime ().NewGoError (err ))
223
223
}
224
-
224
+
225
225
// Signal that a server was started
226
226
select {
227
227
case serverStarted <- true :
228
228
default :
229
229
// Channel already has a value
230
230
}
231
-
231
+
232
232
return result
233
233
})
234
-
234
+
235
235
return wrappedServe
236
236
}
237
-
237
+
238
238
// For all other modules, use the original require
239
239
originalRequire , _ := sobek .AssertFunction (vm .Runtime ().Get ("__originalRequire" ))
240
240
result , err := originalRequire (sobek .Undefined (), call .Arguments ... )
@@ -275,7 +275,7 @@ func (h *JSHandler) handleRegularCode(ctx context.Context, code string) (*mcp.Ca
275
275
// Execute the JavaScript code with a timeout for regular code
276
276
execCtx , cancel := context .WithTimeout (ctx , time .Second * 10 )
277
277
defer cancel ()
278
-
278
+
279
279
result , err := vm .RunString (execCtx , code )
280
280
281
281
if err != nil {
@@ -314,19 +314,19 @@ func (h *JSHandler) setupHTTPModule(vm js.VM) {
314
314
vm .Runtime ().Set ("__originalRequire" , vm .Runtime ().Get ("require" ))
315
315
vm .Runtime ().Set ("require" , vm .Runtime ().ToValue (func (call sobek.FunctionCall ) sobek.Value {
316
316
moduleName := call .Argument (0 ).String ()
317
-
317
+
318
318
// If requesting the HTTP server module, return our wrapped version
319
319
if moduleName == "ski/http/server" {
320
320
httpServer := & httpmodule.Server {}
321
321
value , err := httpServer .Instantiate (vm .Runtime ())
322
322
if err != nil {
323
323
panic (vm .Runtime ().NewGoError (err ))
324
324
}
325
-
325
+
326
326
// Don't wrap or unref - let the server run normally
327
327
return value
328
328
}
329
-
329
+
330
330
// For all other modules, use the original require
331
331
originalRequire , _ := sobek .AssertFunction (vm .Runtime ().Get ("__originalRequire" ))
332
332
result , err := originalRequire (sobek .Undefined (), call .Arguments ... )
@@ -374,7 +374,7 @@ func NewJSServerWithConfig(config ModuleConfig) (*server.MCPServer, error) {
374
374
s .AddTool (mcp .NewTool (
375
375
"executeJS" ,
376
376
mcp .WithDescription (description ),
377
- mcp .WithString ("scriptCode " ,
377
+ mcp .WithString ("code " ,
378
378
mcp .Description ("Complete JavaScript source code to execute in the ski runtime environment. This parameter accepts a full JavaScript program including variable declarations, function definitions, control flow statements, async/await operations, and module imports via require(). The code will be executed in a sandboxed environment with access to enabled ski modules. Supports modern JavaScript syntax (ES2020+) including arrow functions, destructuring, template literals, and promises. Use require() for module imports (e.g., 'const serve = require(\" ski/http/server\" )') rather than ES6 import statements. The execution context includes a console object for output, and any returned values will be displayed along with console output. For HTTP servers, they will run in the background without blocking execution completion." ),
379
379
mcp .Required (),
380
380
),
@@ -427,21 +427,21 @@ func buildToolDescription(enabledModules []string) string {
427
427
description .WriteString ("// Basic JavaScript execution\n " )
428
428
description .WriteString ("const result = 2 + 3;\n " )
429
429
description .WriteString ("console.log('Result:', result);\n \n " )
430
-
430
+
431
431
// Create a set for faster lookup
432
432
enabledSet := make (map [string ]bool )
433
433
for _ , module := range enabledModules {
434
434
enabledSet [module ] = true
435
435
}
436
-
436
+
437
437
// Add examples only for enabled modules
438
438
if enabledSet ["fetch" ] {
439
439
description .WriteString ("// Fetch API (available globally when enabled)\n " )
440
440
description .WriteString ("const response = await fetch('https://api.example.com/data');\n " )
441
441
description .WriteString ("const data = await response.json();\n " )
442
442
description .WriteString ("console.log(data);\n \n " )
443
443
}
444
-
444
+
445
445
if enabledSet ["http" ] {
446
446
description .WriteString ("// HTTP server (require import - NOT import statement)\n " )
447
447
description .WriteString ("const serve = require('ski/http/server');\n " )
@@ -450,44 +450,44 @@ func buildToolDescription(enabledModules []string) string {
450
450
description .WriteString ("});\n " )
451
451
description .WriteString ("console.log('Server running at:', server.url);\n \n " )
452
452
}
453
-
453
+
454
454
if enabledSet ["cache" ] {
455
455
description .WriteString ("// Cache operations (require import)\n " )
456
456
description .WriteString ("const cache = require('ski/cache');\n " )
457
457
description .WriteString ("cache.set('key', 'value');\n " )
458
458
description .WriteString ("console.log(cache.get('key'));\n \n " )
459
459
}
460
-
460
+
461
461
if enabledSet ["crypto" ] {
462
462
description .WriteString ("// Crypto operations (require import)\n " )
463
463
description .WriteString ("const crypto = require('ski/crypto');\n " )
464
464
description .WriteString ("const hash = crypto.md5('hello').hex();\n " )
465
465
description .WriteString ("console.log('MD5 hash:', hash);\n \n " )
466
466
}
467
-
467
+
468
468
if enabledSet ["timers" ] {
469
469
description .WriteString ("// Timers (available globally)\n " )
470
470
description .WriteString ("setTimeout(() => {\n " )
471
471
description .WriteString (" console.log('Hello after 1 second');\n " )
472
472
description .WriteString ("}, 1000);\n \n " )
473
473
}
474
-
474
+
475
475
if enabledSet ["buffer" ] {
476
476
description .WriteString ("// Buffer operations (available globally)\n " )
477
477
description .WriteString ("const buffer = Buffer.from('hello', 'utf8');\n " )
478
478
description .WriteString ("console.log(buffer.toString('base64'));\n \n " )
479
479
}
480
-
480
+
481
481
description .WriteString ("```\n " )
482
482
description .WriteString ("\n Important notes:\n " )
483
483
description .WriteString ("• Use require() for modules, NOT import statements\n " )
484
484
description .WriteString ("• Modern JavaScript features supported (const/let, arrow functions, destructuring, etc.)\n " )
485
-
485
+
486
486
// Add HTTP-specific note only if HTTP is enabled
487
487
if enabledSet ["http" ] {
488
488
description .WriteString ("• HTTP servers automatically run in background and don't block execution\n " )
489
489
}
490
-
490
+
491
491
description .WriteString ("• Async/await and Promises are fully supported\n " )
492
492
493
493
return description .String ()
0 commit comments