Skip to main content
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.

Response Format

Every response includes:
FieldTypeDescription
resultanyWhatever your code returns
executionTimenumberMilliseconds elapsed
logsstring[]Output from console.log, console.warn, console.error (only present if non-empty)
createdArtifactsobject[]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:
HelperDescription
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 / setIntervalTimer functions (cleaned up after execution)
Not available: require(), import(), fetch(), eval(), process, fs, or any npm packages. All external access goes through callTool().

Examples

Chain Multiple Tools

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;

Transform Data

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

ConstraintValue
Timeout10 minutes (max 15 minutes via timeout parameter)
Code size100 KB
NetworkNo direct network access — use callTool() for external services
File systemNo file system — use createArtifact() / readArtifact() for files
LibrariesNo npm packages — only built-in JavaScript and sandbox helpers

When to Use Code Execution

Use CaseRecommended Approach
Single tool callCall the tool directly via tools/call
Chaining multiple tools with logicCode execution
Transforming data between tool callsCode execution
Retry logic or error handling across toolsCode execution
Persistent automation, triggers, schedulingWorkflows