> ## Documentation Index
> Fetch the complete documentation index at: https://agent.minimax.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Node API reference

> Signatures, parameters, and return types for start(context), lifecycle, logging, Host Connector, and unified tool access.

This reference targets MiniMax Code v3.1.6 and describes public interfaces passed to the Node entry. No SDK is installed at runtime; the Skill's `miniapp-api.ts` is a type snapshot. See [Node runtime](https://agent.minimax.io/docs/miniapp/authors/node-runtime.md) for a complete example and [Agent API reference](https://agent.minimax.io/docs/miniapp/reference/agent-api.md) for Agent methods.

## start and dispose

```typescript theme={null}
interface MiniAppLifecycle {
  dispose(): void | Promise<void>;
}

interface MiniAppModule {
  start(context: MiniAppContext): Promise<void | MiniAppLifecycle>;
}

// The host accepts synchronous values and also awaits a Promise.
declare function start(context: MiniAppContext):
  void | MiniAppLifecycle | Promise<void | MiniAppLifecycle>;
```

The entry must export a named `start` function. The type snapshot recommends `async start(context): Promise<void | MiniAppLifecycle>`; the implementation also accepts a synchronous `undefined` or an object with a `dispose` function. Other return values fail startup.

* **Input**: the host creates `context`; plugin code must not construct or substitute host clients.
* **Readiness**: listen with `node:http` at `context.listen` and install every route before completing `start`. The host also probes port authentication; resolving `start` alone does not establish complete service readiness.
* **Return**: returning nothing is supported when no cleanup is needed. Return `{ dispose }` for listeners, child processes, timers, subscriptions, or other resources. Start Agent or tool business calls from request handling after activation, not from `start`.
* **Stop**: the host aborts `context.signal` before awaiting `dispose()`. It does not repeat that cleanup function for the same stop; failed cleanup and a process that does not exit remain subject to host retirement.

Lifecycle actions report startup and stop errors; these are not page `Error.message` codes. See [Runtime errors](https://agent.minimax.io/docs/miniapp/reference/errors.md#runtime) and [Running and updating](https://agent.minimax.io/docs/miniapp/host/lifecycle.md).

## MiniAppContext

The host supplies these fields; do not overwrite them.

| Field | Type | Meaning and availability |
| - | - | - |
| `pluginId` | `string` | Adopted plugin ID |
| `pluginRoot` | `string` | This run's runtime copy, not the workspace or installation directory |
| `dataDir` | `string` | Persistent directory isolated for the plugin; write business state here |
| `listen` | `{ host: '127.0.0.1', port: number }` | Assigned listener address; do not select a port yourself |
| `signal` | `AbortSignal` | Entry lifecycle signal, aborted on stop or failed startup; it does not close plugin-owned resources automatically |
| `logger` | `MiniAppLogger` | The four-level logging interface below |
| `hostConnector?` | `HostConnectorClient` | Injected when `hostConnectorAccess.providers` declares at least one provider |
| `tool?` | `MiniAppToolClient` | Injected when `toolAccess: ["call"]` is declared |
| `agent?` | `MiniAppAgentClient` | Injected when `agentAccess` contains `session.run` or `session.read` |
| `capabilities?` | `{ has(name: string): boolean }` | Host interface support probe; older hosts may omit the object |

The manifest determines whether `hostConnector`, `tool`, and `agent` are injected. A permission switch leaves the object present but rejects new calls or applies the restrictions below; presence does not establish authorization. See [miniapp.json fields](https://agent.minimax.io/docs/miniapp/reference/manifest.md#permissions) for declarations.

`context.signal` and a call's `options.signal` are distinct: the former represents runtime lifecycle, and the caller supplies the latter to cancel an individual request. Pass the lifecycle signal as a request option when appropriate.

## Request budget

Each Node process has 16 ordinary in-flight request slots, shared by Connector `list` / `call`, tool `list` / `call` / `request`, and Agent `run` / `answer` / `models` / `agents` / `create` / `sessions` / `session`. Once the budget is full, new requests are refused before dispatch.

Agent `reply` has 16 separate slots, and `observe` has 4 separate slots, so approvals can still be answered while ordinary requests fill their budget. These process communication budgets are separate from the `agentConcurrency` turn limit. See [Agent concurrency and cancellation limits](https://agent.minimax.io/docs/miniapp/reference/agent-api.md#limits).

Every Node-to-host request must also fit within 256 KiB of UTF-8 JSON, including the request ID, method, and parameters. A Connector or tool call that exceeds this limit rejects locally with `INVALID_ARGUMENTS`, `disposition: 'not_dispatched'`, and `retryable: false`; it may have no `diagnostic`. Reduce, paginate, or split the arguments before retrying. This request-size limit is separate from the 8 MiB response-frame limit.

## JSON types

Connector and tool arguments, schemas, and results use these JSON types. Functions, `undefined`, and cyclic references are not valid values.

```typescript theme={null}
type JsonPrimitive = null | boolean | number | string;
type JsonObject = { readonly [key: string]: JsonValue };
type JsonValue = JsonPrimitive | JsonObject | readonly JsonValue[];

declare const HOST_CONNECTOR_TOOL_REF: unique symbol;
type HostConnectorToolRef = string & {
  readonly [HOST_CONNECTOR_TOOL_REF]: 'HostConnectorToolRef';
};

interface HostConnectorCallOptions {
  readonly signal?: AbortSignal;
}
```

## logger

```typescript theme={null}
interface MiniAppLogger {
  debug(message: string, fields?: JsonObject): void;
  info(message: string, fields?: JsonObject): void;
  warn(message: string, fields?: JsonObject): void;
  error(message: string, fields?: JsonObject): void;
}
```

All four methods accept the same parameters and return `void`; only the log level changes. Use a stable event name or diagnostic text without business content for `message`. `fields` is optional.

In v3.1.6, the implementation truncates `message` to its first 4096 UTF-16 code units and forwards the **keys** of `fields`, not their values. This is not complete structured business-log storage. Diagnostic retention is bounded; do not rely on every record being kept, or include credentials, raw inputs, or user data.

## hostConnector

Available only in Node, using third-party accounts authorized by the user. Manifest fragment:

```json miniapp/miniapp.json theme={null}
{
  "hostConnectorAccess": { "providers": ["notion"] }
}
```

### list(options?)

```typescript theme={null}
interface HostConnectorClient {
  list(options?: HostConnectorCallOptions): Promise<HostConnectorListResult>;
  call(
    toolRef: HostConnectorToolRef,
    arguments_: JsonObject,
    options?: HostConnectorCallOptions,
  ): Promise<HostConnectorCallResult>;
}

interface HostConnectorListResult {
  readonly tools: readonly HostConnectorTool[];
  readonly partial: boolean;
}

interface HostConnectorTool {
  readonly toolRef: HostConnectorToolRef;
  readonly provider: string;
  readonly name: string;
  readonly description?: string;
  readonly inputSchema: JsonValue;
  readonly outputSchema?: JsonValue;
}
```

| Parameter or result | Description |
| - | - |
| `options.signal` | Optional; aborts this listing |
| `tools` | Inventory available under the current user, manifest, and permission switches; select by `provider`, `name`, and actual schema |
| `partial` | The inventory is incomplete; available entries remain usable but are not the complete tool set |
| `toolRef` | Opaque host-issued reference, typed as a branded string; obtain it only from the inventory |
| `inputSchema` / `outputSchema?` | Service-provided JSON schemas, not a normalized business-data format |

`list()` is available before and after activation and performs no business tool call. References are bound to the current run and account; relisting replaces this process's Connector inventory. Do not construct, persist, or send a `toolRef` to the page. List after startup, a stale-reference error, or an account change.

### call(toolRef, arguments\_, options?)

```typescript theme={null}
interface HostConnectorCallResult {
  readonly invocationId: string;
  readonly value: JsonValue;
}
```

| Parameter or result | Description |
| - | - |
| `toolRef` | Reference obtained from the latest `list()` |
| `arguments_` | JSON object matching the tool's `inputSchema` |
| `options.signal` | Optional; cancels the request and wait, without proving an external write did not run |
| `invocationId` | Host-assigned identifier for this call |
| `value` | Raw provider JSON result: object, array, string, or another JSON value; the host does not normalize it |

Call only from request handling after service activation, never inside `start`. A normal result resolves the Promise; a provider-reported error rejects with `CONNECTOR_PROVIDER_ERROR`. Requests have a default 30-second limit. After cancellation, timeout, or connection loss, use the error's `disposition` to determine whether the operation may have run.

When a provider is switched off, new listings omit it and calls to its references fail with `CONNECTOR_NOT_PERMITTED`. Sign-out revokes the inventory and references. List again after the same account signs back in; references from another account cannot be reused.

Verify the actual result shape before decoding `value`; arbitrary `content`, `text`, and `value` fields are not host envelopes. See [Data access](https://agent.minimax.io/docs/miniapp/authors/data.md#host-connector) for handling examples and [Host Connector errors](https://agent.minimax.io/docs/miniapp/reference/errors.md#connector) for codes.

## tool

With `toolAccess: ["call"]`, Node can call plugin MCP, user MCP, host built-in MCP, and connected Connector tools mounted by the host. This interface does not provide Agent built-in file, shell, or browser tools.

```typescript theme={null}
type MiniAppToolPermission = 'allow' | 'ask' | 'deny';

interface MiniAppToolClient {
  list(options?: HostConnectorCallOptions): Promise<MiniAppToolListResult>;
  call(
    name: string,
    arguments_: JsonObject,
    options?: HostConnectorCallOptions,
  ): Promise<MiniAppToolCallResult>;
  request(
    names: readonly string[],
    options?: HostConnectorCallOptions,
  ): Promise<Record<string, MiniAppToolPermission>>;
}
```

### list(options?)

```typescript theme={null}
type MiniAppTool = {
  readonly name: string;
  readonly tool: string;
  readonly description?: string;
  readonly inputSchema: JsonValue;
  readonly permission: MiniAppToolPermission;
} & (
  | { readonly kind: 'connector'; readonly provider: string }
  | { readonly kind: 'mcp'; readonly server: string }
);

interface MiniAppToolListResult {
  readonly tools: readonly MiniAppTool[];
  readonly partial: boolean;
}
```

* `options.signal` can abort the listing; `list()` also works before activation.
* `name` is the runtime call name; `tool` is the underlying provider or MCP tool name. Match `kind`, `server` / `provider`, and `tool`, then read `name` from the inventory instead of constructing it.
* `permission` is a snapshot taken while listing. Every `call` is judged again; a previous `allow` does not bypass permission checks.
* `partial: true` means the inventory is incomplete: a source may be unavailable or metadata problems may have omitted tools. Listed entries remain callable subject to current permissions. Listing can reject if every source fails.
* With `tool:call` switched off, listing still works but every entry has `permission: 'deny'`.

### call(name, arguments\_, options?)

```typescript theme={null}
type MiniAppToolCallResult =
  | {
      readonly invocationId: string;
      readonly kind: 'connector';
      readonly value: JsonValue;
    }
  | {
      readonly invocationId: string;
      readonly kind: 'mcp';
      readonly isError: boolean;
      readonly content: readonly JsonValue[];
      readonly structuredContent?: JsonObject;
    };
```

| Parameter or result | Description |
| - | - |
| `name` | Listed runtime name; refresh the inventory to investigate an unknown name |
| `arguments_` | JSON object matching the tool schema |
| `options.signal` | Optional; cancels this call but does not guarantee an external operation already sent was rolled back |
| `kind: 'connector'` | `value` is the raw provider JSON result |
| `kind: 'mcp'` | `content` preserves MCP content blocks; `structuredContent` is an optional structured result |
| `isError` | The MCP tool reported a business failure; the Promise still resolves when true, so the caller must inspect it |
| `invocationId` | Call identifier for diagnostic correlation |

Call only from request handling after activation. Do not route back through this Mini App's own managed MCP endpoint; reuse its local business function directly.

Every call is judged by the user's **global tool rules and global permission mode**, without an Agent's or session's rules. `deny` refuses the call; `ask` displays a host-owned Allow once / Always allow / Deny prompt. Only the user's Always allow choice writes a global rule. Host built-in tools keep their existing host allowance. Agent tool hooks do not run on this path.

If nobody can approve, the call rejects with `TOOL_APPROVAL_REQUIRED`. Approval waits at most 5 minutes. After approval, Connector calls have a default 30-second limit and MCP calls at most 120 seconds; an MCP server's own timeout can fire earlier. A result must fit a single 8 MiB frame. Exceeding it rejects with `TOOL_RESULT_TOO_LARGE` even if the tool already ran.

Switching tool permission off refuses new calls; a dispatched call can finish. The host does not automatically retry a dispatched business operation. If a Connector handle is stale before dispatch, it relists and attempts the call once. For timeouts, cancellation, and unknown outcomes, inspect `disposition` below instead of deciding whether to repeat a write from the code alone.

### request(names, options?)

`names` must contain 1–10 distinct runtime names obtained from `list()`. `options.signal` can cancel the request. This method asks ahead for approval; it does not execute the tools.

* The host prompts only for tools still at `ask`, leaving `allow` and `deny` entries out. The user can tick tools to always allow them globally.
* The resolved object includes every requested name's current `allow`, `ask`, or `deny` state. It is a UI snapshot; later calls are judged again.
* When nobody can approve, Node rejects with `TOOL_APPROVAL_REQUIRED`. Its error also carries a `permissions` property containing the unchanged permission map.
* With `tool:call` switched off, no prompt appears and every name resolves to `deny`. Invalid names still fail.
* The page can also request approval, but cannot list or call tools; see [Page tool approval](https://agent.minimax.io/docs/miniapp/reference/client-api.md#tool-request). Node is not subject to the page's user-gesture requirement, but a host prompt must still be able to reach the user.

`context.tool` and `context.hostConnector` share this process's Connector inventory. Relisting through `hostConnector` can supersede the unified tool entry's Connector handles; `tool` relists once itself. Saved `hostConnector` references are not refreshed automatically.

## Node tool errors

Host Connector and unified tool rejections use this shape. Do not depend on `instanceof` across processes:

```typescript theme={null}
interface HostConnectorError extends Error {
  readonly code: string;
  readonly disposition:
    | 'not_dispatched'
    | 'provider_reported'
    | 'unknown_after_dispatch';
  readonly retryable: boolean;
  readonly invocationId?: string;
  readonly diagnostic?: {
    readonly issues: readonly {
      readonly path: string;
      readonly constraint: string;
      readonly limit?: number;
    }[];
  };
}
```

`string` here shows how to read `code`; known values are listed under [Connector errors](https://agent.minimax.io/docs/miniapp/reference/errors.md#connector) and [Tool errors](https://agent.minimax.io/docs/miniapp/reference/errors.md#tools). When present, `diagnostic.issues` describes schema violations without rejected argument values; `INVALID_ARGUMENTS` can also arise from local input or request-size validation without this field. A `TOOL_APPROVAL_REQUIRED` error from `request()` can also carry the `permissions` map.

| Field | Handling |
| - | - |
| `disposition: 'not_dispatched'` | Nothing reached the tool. Correct the cause, then retry the same request only when `retryable` is true |
| `disposition: 'provider_reported'` | The provider reported failure; handle the business error without assuming the write had no side effects |
| `disposition: 'unknown_after_dispatch'` | The tool may have run; read business state before repeating a write |
| `retryable` | Whether the host considers the original request retryable later; it does not replace `disposition` |

## agent

See [Agent API reference](https://agent.minimax.io/docs/miniapp/reference/agent-api.md) for `context.agent` execution, approvals, questionnaires, models, session reads, and observations. Node cancels through `options.signal`; the page's `cancel` and `open` methods are not Node interfaces.

## capabilities

```typescript theme={null}
interface MiniAppHostCapabilities {
  has(name: string): boolean;
}
```

`has` is synchronous. The capability table is fixed per host version and shared by Node and the page. A `true` result does not mean the manifest declared the capability, the user granted it, or the named interface exists on Node. Older hosts may omit the object. See [Capability names](https://agent.minimax.io/docs/miniapp/reference/client-api.md#capabilities) for names, supported surfaces, and declarations.
