Run JavaScript in a sandboxed Node.js VM. Chain tool calls, transform data, and create files — all in a single request.
For full tool parameters and schemas, see the code-execution server reference.
Quick Start
Send code, get a result. All you need is a runtime token.
curl -s -X POST "https://mcp.app.pinkfish.ai/restricted/code-execution" \
-H "Authorization: Bearer $PINKFISH_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "code-execution_execute",
"arguments": {
"code": "return { message: \"hello world\", timestamp: new Date().toISOString() };"
}
},
"id": 1
}'
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"structuredContent": {
"result": {
"message": "hello world",
"timestamp": "2026-02-15T07:30:00.000Z"
},
"executionTime": 12
}
}
}
That’s it. Your code runs, you get the return value back. No chat ID, no setup — just send code and get a result.
Your code is wrapped in an async function, so you can use await and return directly.
Every response includes:
| Field | Type | Description |
|---|
result | any | Whatever your code returns |
executionTime | number | Milliseconds elapsed |
logs | string[] | Output from console.log, console.warn, console.error (only present if non-empty) |
createdArtifacts | object[] | Files created with createArtifact() (only present if non-empty) |
Sandbox Environment
Code runs in a Node.js VM sandbox. You get standard JavaScript built-ins (JSON, Date, Math, Array, Promise, etc.) plus these helpers:
| Helper | Description |
|---|
callTool(serverPath, toolName, args) | Call any MCP tool. The primary way to chain tools. |
readArtifact(identifier) | Read a file by ID, filename, or platform URL |
createArtifact(filename, content, fileType) | Create and store a file |
console.log() / warn() / error() | Debug output (captured in logs) |
setTimeout / setInterval | Timer functions (cleaned up after execution) |
Not available: require(), import(), fetch(), eval(), process, fs, or any npm packages. All external access goes through callTool().
Examples
Search the web and summarize the results — two tool calls composed in a single execution:
const searchResults = await callTool("/web-search", "search_googlesearch", {
query: "latest AI developments 2026",
});
const summary = await callTool("/embedded-groq", "embedded-groq_generate", {
prompt: JSON.stringify(searchResults),
systemPrompt: "Summarize these search results into 5 bullet points.",
});
return summary;
Use Connected Services
External integrations require a PCID (connection ID). Discover it first:
const caps = await callTool("/pinkfish-sidekick", "capabilities_discover", {
request: "search gmail",
});
const gmailPCID = caps.connections.find((c) => c.application === "gmail")?.id;
const emails = await callTool("/gmail", "gmail_search_emails", {
PCID: gmailPCID,
query: "is:unread",
});
return emails;
Process and reshape data between tool calls:
const raw = await callTool("/datastore-structured", "datastore-structured_query", {
collection: "orders",
filter: { status: "pending" }
});
const summary = raw.items.map(order => ({
id: order.id,
total: order.items.reduce((sum, item) => sum + item.price, 0),
itemCount: order.items.length
}));
return { orderCount: summary.length, orders: summary };
Working with Artifacts
Artifacts let you create and read files that persist across executions. This is useful for generating reports, storing intermediate results, or building files that your application retrieves later.
When You Need a Chat ID
The Quick Start above works for stateless code execution — send code, get a result. But artifacts require a chat context (the X-Chat-Id header) so the platform knows where to store files.
There are two ways to get a chat ID:
Option 1: Use chat_create (recommended)
Use the Agent Management chat_create tool:
# Create a chat session
CHAT_ID=$(curl -s -X POST "https://mcp.app.pinkfish.ai/agent-management" \
-H "Authorization: Bearer $PINKFISH_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "agent-management_chat_create",
"arguments": {
"agentId": "YOUR_AGENT_ID",
"name": "Code execution session"
}
},
"id": 1
}' | jq -r '.result.structuredContent.id')
Option 2: Create an automation directly
CHAT_ID=$(curl -s -X POST "https://app-api.app.pinkfish.ai/service/automations" \
-H "Authorization: Bearer $PINKFISH_TOKEN" \
-H "X-Selected-Org: $ORG_ID" \
-H "Content-Type: application/json" \
-d '{"name": "my-code-session"}' | jq -r '.id')
Using Your Chat ID
Once you have a chat ID, include the X-Chat-Id header in your code execution requests:
curl -s -X POST "https://mcp.app.pinkfish.ai/restricted/code-execution" \
-H "Authorization: Bearer $PINKFISH_TOKEN" \
-H "X-Chat-Id: $CHAT_ID" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "code-execution_execute",
"arguments": {
"code": "const data = { report: \"Monthly summary\", items: [1, 2, 3] };\nconst file = await createArtifact(\"report.json\", JSON.stringify(data, null, 2), \"json\");\nreturn file;"
}
},
"id": 1
}'
Create a File
const data = { report: "Monthly summary", items: [1, 2, 3] };
const file = await createArtifact(
"report.json",
JSON.stringify(data, null, 2),
"json"
);
return file;
// { success: true, filename: "report.json", id: "file-abc123", mimeType: "application/json", size: 56 }
The file appears in createdArtifacts in the response and is stored in the platform.
Supported file types: csv, txt, json, html, xml, js, ts, md, py
Read a File
In a later execution (same chat ID), read it back:
const data = await readArtifact("report.json");
if (data.success) {
const parsed = JSON.parse(data.content);
return parsed;
}
return { error: data.error };
// readArtifact returns: { success, content, size, filename, mimeType, error }
You can also read by file ID or platform URL instead of filename.
Retrieve Artifacts via API
Outside of code execution, list and download artifacts using the Agent Management tools or the REST API:
Using chat_list_artifacts:
curl -s -X POST "https://mcp.app.pinkfish.ai/agent-management" \
-H "Authorization: Bearer $PINKFISH_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "agent-management_chat_list_artifacts",
"arguments": { "chatId": "'$CHAT_ID'" }
},
"id": 1
}'
Using the REST API directly:
# List files for a chat
curl -s "https://app-api.app.pinkfish.ai/service/automations/$CHAT_ID/files" \
-H "Authorization: Bearer $PINKFISH_TOKEN" \
-H "X-Selected-Org: $ORG_ID"
# Get a specific file by ID
curl -s "https://app-api.app.pinkfish.ai/service/files/by-id/$FILE_ID" \
-H "Authorization: Bearer $PINKFISH_TOKEN" \
-H "X-Selected-Org: $ORG_ID"
Limits
| Constraint | Value |
|---|
| Timeout | 10 minutes (max 15 minutes via timeout parameter) |
| Code size | 100 KB |
| Network | No direct network access — use callTool() for external services |
| File system | No file system — use createArtifact() / readArtifact() for files |
| Libraries | No npm packages — only built-in JavaScript and sandbox helpers |
When to Use Code Execution
| Use Case | Recommended Approach |
|---|
| Single tool call | Call the tool directly via tools/call |
| Chaining multiple tools with logic | Code execution |
| Transforming data between tool calls | Code execution |
| Retry logic or error handling across tools | Code execution |
| Persistent automation, triggers, scheduling | Workflows |