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

# Register TypeScript Functions

> Expose your existing TypeScript functions so agents can call them in a remote sandbox

Register your existing TypeScript functions so agents can call them. Raysurfer wraps your callbacks with `tool(...)`, and routes tool calls back to your app during sandbox execution.

<Note>
  Source: [rayxc-org/raysurfer-ts](https://github.com/rayxc-org/raysurfer-ts)
</Note>

## Setup

Install the SDK and set `RAYSURFER_API_KEY` in your environment.

```bash theme={null}
bun add raysurfer
```

## Register Tools

`tool(name, description, parameters, callback)` can wrap any local callback you want to expose. The `description` is included in the tool payload.

```typescript theme={null}
import { RaySurfer } from "raysurfer";

const rs = new RaySurfer({ apiKey: "your_api_key" });

rs.tool("add", "Add two numbers", { a: "integer", b: "integer" }, async (args) => {
  return String(Number(args.a) + Number(args.b));
});
```

## How Functions Get Passed Back To The Agent

`tool(...)` registers two things locally in your app process:

* A tool schema (name, description, parameters) that Raysurfer sends to the sandbox run
* A callback function that stays local and is invoked when the sandbox requests that tool

Execution flow:

1. `execute()` opens a callback session and sends tool schemas plus your task to Raysurfer.
2. Sandbox code calls a tool (for example `add(5, 3)`).
3. Raysurfer sends a `tool_call` message back to your app.
4. Your local callback runs, and the SDK sends `tool_result` back to the sandbox.
5. The sandbox continues running with that result.

This is the mechanism that passes tool execution back into your running agent app.

## Execute Modes

Use exactly one mode per `execute()` call:

### Primary Mode: Pass `userCode`

```typescript theme={null}
const result = await rs.execute("Compute 5 + 3", {
  userCode: "print(add(5, 3))",
});
```

### End-To-End Sandbox Example

```typescript theme={null}
import { RaySurfer } from "raysurfer";

const rs = new RaySurfer({ apiKey: "your_api_key" });

rs.tool("add", "Add two numbers", { a: "integer", b: "integer" }, async (args) => {
  return String(Number(args.a) + Number(args.b));
});

const result = await rs.execute("Compute 5 + 3", {
  userCode: "result = add(5, 3)\nprint(result)",
});

console.log(result.result);    // "8"
console.log(result.toolCalls); // tool call history
```

### Optional Mode: Sandbox Codegen

In this mode, code is generated inside Raysurfer's remote sandbox from your prompt.

```typescript theme={null}
const result = await rs.execute("Compute 5 + 3", {
  codegen: {
    provider: "anthropic",
    apiKey: "YOUR_ANTHROPIC_API_KEY",
    model: "claude-opus-4-6",
    prompt: "Write Python code that calls add(a, b) for 5 and 3, then prints the result.",
  },
});
```

## Full SDK Reference

See [TypeScript SDK](/sdk/typescript#programmatic-tool-calling) for full method signatures and response fields.
