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

# Scripts

> TypeScript handlers and transforms that extend tool behavior beyond configuration.

Scripts extend tool behavior beyond what configuration can express. A handler script replaces database execution entirely. Transform scripts modify inputs before execution and results after. All three are TypeScript: Hyperterse includes them when you build, then runs them in a sandboxed environment without extra runtimes on the host.

## Script hooks

There are three hooks, each corresponding to a stage in the execution pipeline:

| Hook             | Default export         | Purpose                                |
| ---------------- | ---------------------- | -------------------------------------- |
| Handler          | `export default (...)` | Replaces DB execution entirely         |
| Input transform  | `export default (...)` | Pre-process arguments before execution |
| Output transform | `export default (...)` | Post-process results before returning  |

## Selecting exported functions

For all script references, you can target a non-default export with `#`:

```yaml theme={null}
handler: "./weather-handler.ts#weather"
mappers:
  input: "./input.ts#normalize"
  output: "./output.ts#shape"
```

Without `#exportName`, Hyperterse calls the script's `export default` function.\
The function name itself is optional; Hyperterse does not use it.

## Handler

A handler replaces adapter-based execution. When `handler` is configured, no `use` or `statement` is needed. The return value becomes the tool's result payload.

```typescript theme={null}
export default function handler(payload: {
  inputs: Record<string, any>
  tool: string
}) {
  const { inputs } = payload
  return {
    location: inputs.city || 'unknown',
    temperature_c: 22.5,
    conditions: 'partly cloudy',
  }
}
```

## Input transform

An input transform pre-processes arguments before they reach the executor or handler. Use it for validation, normalization, or rejection. The returned object replaces the original inputs for all subsequent pipeline stages. Throwing an error aborts execution.

```typescript theme={null}
export default function inputTransform(payload: {
  inputs: Record<string, any>
  tool: string
}) {
  if (
    typeof payload.inputs.user_id !== 'number' ||
    payload.inputs.user_id <= 0
  ) {
    throw new Error('user_id must be a positive integer')
  }
  return { ...payload.inputs, user_id: Math.floor(payload.inputs.user_id) }
}
```

## Output transform

An output transform post-processes results before they are returned. Use it for field mapping, formatting, or redaction.

```typescript theme={null}
export default function outputTransform(payload: { results: any[]; tool: string }) {
  return payload.results.map((row) => ({
    id: row.id,
    name: row.name,
    created_at_iso: new Date(row.created_at).toISOString(),
  }))
}
```

## Runtime APIs

Scripts execute in a sandboxed runtime with two injected globals:

* `fetch(url, options?)` — HTTP client for outbound requests. Returns `{ status, ok, text(), json() }`.
* `console` — `log`, `error`, `warn`, `info`, `debug` — wired to the structured logger with the tool name as context.

Scripts cannot access the host filesystem, spawn processes, or open network sockets. `setTimeout` and `setInterval` are not available — use `async`/`await` instead.

## Convention discovery

When script paths are omitted in tool config, Hyperterse auto-discovers script files
from the tool directory. Convention names include:

* `handler.ts`
* `input.ts` (or `*input*validator*.ts`)
* `output.ts` (or `*data*mapper*.ts`)

## npm packages

If your scripts import external packages, add a `package.json` at the project root. The build process packages dependencies with your scripts, so deployment does not require `node_modules/`.

```typescript theme={null}
import dayjs from 'dayjs'
import { v4 as uuidv4 } from 'uuid'
```

## Error handling

Errors thrown from scripts propagate as MCP error responses. The error message is included in the response; stack traces are logged at debug level but not exposed to callers.

## Further reading

See [Execution pipeline](/runtime/execution-pipeline) for how scripts fit into the request lifecycle, and [Tool configuration reference](/reference/tool-config) for `handler` and `mappers` configuration.
