Skip to main content

Overview

Your tool code runs in an isolated V8 runtime. There is no file system access, no require(), no import, and no access to the Node.js standard library. Instead, MCPCore injects a curated set of globals:
GlobalWhat it is
sdkBuilt-in helpers: HTTP client, database client, Lodash
paramsThe input parameters the AI passed at call time
envYour encrypted server secrets, accessible by name
consoleStructured log output visible in Traffic Logs

sdk.http() — HTTP requests

Make outbound HTTP requests to any external API or service.
const res = await sdk.http({
  method:  "GET",           // "GET" | "POST" | "PUT" | "PATCH" | "DELETE"
  url:     "https://...",   // Full URL. Use template literals with params.*
  headers: { },             // Key-value header object
  body:    "...",           // String body for POST/PUT/PATCH
});

Response methods

res.status()          // HTTP status code (number)  e.g. 200
res.body()            // Response body as a string — parse with JSON.parse()
res.headers()         // Response headers as an object

Example — GET with auth

const res = await sdk.http({
  method: "GET",
  url: `https://api.github.com/repos/${params.owner}/${params.repo}`,
  headers: {
    Authorization: `Bearer ${env.GITHUB_TOKEN}`,
    "User-Agent":  "MCPCore-Tool/1.0",
  },
});

if (res.status() !== 200) {
  throw new Error(`GitHub API error: ${res.status()}`);
}

return JSON.parse(res.body());

Example — POST with JSON body

const res = await sdk.http({
  method:  "POST",
  url:     "https://api.sendgrid.com/v3/mail/send",
  headers: {
    Authorization:  `Bearer ${env.SENDGRID_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    personalizations: [{ to: [{ email: params.to }] }],
    from:    { email: "noreply@yourapp.com" },
    subject: params.subject,
    content: [{ type: "text/plain", value: params.body }],
  }),
});

return { status: res.status() };

sdk.db() — Database queries

Connect to a relational database and run queries. sdk.db() is powered by Knex.js under the hood — a battle-tested SQL query builder for Node.js. If you’re familiar with Knex, the API will feel natural. MCPCore wraps it with a simplified interface for the most common operations.
const db = await sdk.db({
  type:       "pg",          // "pg" | "mysql" | "mssql"
  connection: {
    host:     env.DB_HOST,
    port:     env.DB_PORT,
    database: env.DB_NAME,
    user:     env.DB_USER,
    password: env.DB_PASSWORD,
  },
});
Always store connection credentials as secrets and reference them as env.*. Never hardcode passwords in tool code.

db.select(table, where?)

Fetch rows from a table, optionally filtered by column values.
// All rows
const allUsers = await db.select("users");

// Filtered rows
const pendingOrders = await db.select("orders", {
  user_id: params.userId,
  status:  "pending",
});

return { count: pendingOrders.length, orders: pendingOrders };

db.insert(table, data)

Insert a single row and return the inserted record.
const record = await db.insert("events", {
  user_id:    params.userId,
  event_type: params.type,
  created_at: new Date().toISOString(),
});

return { id: record.id };

db.update(table, data, where)

Update rows matching the where condition.
const updated = await db.update(
  "subscriptions",
  { status: "cancelled", cancelled_at: new Date().toISOString() },
  { id: params.subscriptionId }
);

return { affected: updated.rowCount };

db.delete(table, where)

Delete rows matching the where condition.
const result = await db.delete("sessions", { user_id: params.userId });
return { deleted: result.rowCount };

db.query(sql, values?)

Run a raw parameterised SQL query for complex operations.
const result = await db.query(
  "SELECT product_id, SUM(quantity) as total FROM order_items WHERE created_at > $1 GROUP BY product_id ORDER BY total DESC LIMIT 10",
  [params.since]
);

return { topProducts: result.rows };
Always use parameterised queries ($1, $2, …) when embedding user input in SQL. Never concatenate params.* values directly into a SQL string.

sdk.lodash — Utility functions

A subset of Lodash is available for data manipulation.
const _ = sdk.lodash;

const grouped = _.groupBy(rows, "category");
const sorted  = _.orderBy(rows, ["created_at"], ["desc"]);
const top5    = _.take(sorted, 5);
const unique  = _.uniqBy(rows, "user_id");
const flat    = _.flatMap(groups, group => group.items);

params — Tool inputs

params is a plain object containing the values the AI passed when calling the tool. The keys are the parameter names you defined in the tool schema.
// If you defined a parameter named "userId" of type "string":
const id = params.userId;

// If you defined "limit" of type "number" with default 10:
const limit = params.limit ?? 10;

// If you defined "filters" of type "object":
const { status, category } = params.filters;
Parameters are validated against the schema you defined before the code runs. If a required parameter is missing or has the wrong type, the tool returns a schema error without executing your code.

env — Secrets

env contains the encrypted secrets you stored in the server’s Secrets tab. Reference them by their key name:
const token    = env.GITHUB_TOKEN;
const password = env.DB_PASSWORD;
const apiKey   = env.OPENAI_API_KEY;
env is read-only. Values are strings. See Secrets for how to create and manage them.

console — Structured logging

Log messages from your tool code. All output is captured and visible in the Traffic Logs dashboard.
console.log("Processing request for user:", params.userId);
console.info("Fetched", rows.length, "rows from database");
console.warn("Rate limit approaching:", remaining, "requests left");
console.error("Database query failed:", error.message);
console.debug("Raw response:", res.body());
MethodLog levelWhen to use
console.logINFOGeneral progress messages
console.infoINFOImportant milestones
console.warnWARNRecoverable issues, degraded operation
console.errorERRORFailures that affect the result
console.debugDEBUGVerbose detail for development
Log output is truncated at 10 KB per entry. For large payloads, log a summary rather than the full object.

Error handling

Throw an error to signal a failure to the AI:
const res = await sdk.http({ method: "GET", url: `...` });

if (res.status() === 404) {
  throw new Error(`Repository not found: ${params.repo}`);
}

if (res.status() !== 200) {
  throw new Error(`Upstream API returned ${res.status()}: ${res.body()}`);
}
Uncaught errors are captured, logged with the full stack trace, and returned to the AI as a tool error. The request is recorded in Error Logs.