> ## 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.

# Function Registry

> Publish a registry of your functions so agents can discover and call them across sessions

Publish a registry of your functions so agents can discover and call them across sessions. Raysurfer auto-infers the function name, description, and input schema from the function signature, type hints, and docstring — so you don't need to write schemas by hand.

Once registered, functions can be:

* Published to Raysurfer for agent discovery via `publish_function_registry` / `publishFunctionRegistry`
* Converted to Anthropic tool definitions via `to_anthropic_tool` / `toAnthropicTool` for direct use with Claude's tool calling
* Tracked automatically — every call records execution duration, inputs, outputs, and success/failure

## Which Path Passes Functions Back To The Running Agent?

These three paths are related, but they are not the same runtime:

| Path                                                    | Purpose                                                  | How functions are wired at runtime                                                                        |
| ------------------------------------------------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `publish_function_registry` / `publishFunctionRegistry` | Persist reusable functions for discovery across sessions | Functions are uploaded as registry snippets and made available to Raysurfer sandbox runs for that scope   |
| `to_anthropic_tool` / `toAnthropicTool`                 | Generate Anthropic-compatible tool schemas               | You pass the returned schema to your Claude tool-calling loop and handle tool execution in your app       |
| `@rs.tool` / `tool(...)` + `execute(...)`               | Live tool calling in Raysurfer sandbox                   | Raysurfer opens a callback channel and routes each tool call back to your local callback during execution |

If your question is "how does the function call get passed back into my agent process during execution?", use `@rs.tool` / `tool(...)` with `execute(...)`. See [Register Python Functions](/integrations/register-python-functions) or [Register TypeScript Functions](/integrations/register-ts-functions).

## Python

### Auto-inferred (no explicit params)

```python theme={null}
from raysurfer import AsyncRaySurfer, agent_accessible

rs = AsyncRaySurfer()

@agent_accessible()
def generate_board_report(company: str, quarter: str) -> str:
    """Generate a quarterly board report.

    Args:
        company: The company name to generate the report for.
        quarter: The fiscal quarter (e.g. "Q1 2026").
    """
    return build_report(company=company, quarter=quarter)
```

Name, description, and input schema are all inferred from the function name, docstring, and type hints.

### With explicit description

```python theme={null}
@agent_accessible("Generate a quarterly board report")
def generate_board_report(company: str, quarter: str) -> str:
    return build_report(company=company, quarter=quarter)
```

### Org/workspace scoping

```python theme={null}
@agent_accessible(org_id="acme-corp", workspace_id="finance-team")
def generate_board_report(company: str, quarter: str) -> str:
    """Generate a quarterly board report."""
    return build_report(company=company, quarter=quarter)
```

### Converting to Anthropic tool format

```python theme={null}
from raysurfer import agent_accessible, to_anthropic_tool

@agent_accessible()
def generate_board_report(company: str, quarter: str) -> str:
    """Generate a quarterly board report."""
    return build_report(company=company, quarter=quarter)

tool = to_anthropic_tool(generate_board_report)
# Returns: {"name": "generate_board_report", "description": "...", "input_schema": {...}}
```

### Publishing to Raysurfer

```python theme={null}
rs = AsyncRaySurfer()
await rs.publish_function_registry([generate_board_report])
```

## TypeScript

### Auto-inferred (no explicit options)

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

const rs = new RaySurfer();

const generateBoardReport = agentAccessible(
  (company: string, quarter: string) => buildReport(company, quarter),
);
```

Name and parameters are inferred from the function.

### With explicit options

```typescript theme={null}
const generateBoardReport = agentAccessible(
  (company: string, quarter: string) => buildReport(company, quarter),
  {
    name: "generateBoardReport",
    description: "Generate a quarterly board report",
  },
);
```

### Org/workspace scoping

```typescript theme={null}
const generateBoardReport = agentAccessible(
  (company: string, quarter: string) => buildReport(company, quarter),
  { orgId: "acme-corp", workspaceId: "finance-team" },
);
```

### Converting to Anthropic tool format

```typescript theme={null}
import { agentAccessible, toAnthropicTool } from "raysurfer";

const generateBoardReport = agentAccessible(
  (company: string, quarter: string) => buildReport(company, quarter),
  { description: "Generate a quarterly board report" },
);

const tool = toAnthropicTool(generateBoardReport);
// Returns: { name: "generateBoardReport", description: "...", input_schema: {...} }
```

### Publishing to Raysurfer

```typescript theme={null}
const rs = new RaySurfer();
await rs.publishFunctionRegistry([generateBoardReport]);
```

## Persistent Sandbox

Previously published functions are available in the sandbox execution environment, scoped by org and workspace. When an agent runs code through Raysurfer's sandbox, functions published via `publish_function_registry` / `publishFunctionRegistry` for that scope are available without re-uploading each session.

For live callback routing during a run, use `@rs.tool` / `tool(...)` with `execute(...)`.

## Running In Raysurfer Sandbox

To run a coding agent in Raysurfer's remote sandbox with tool callbacks:

1. Register callbacks with `@rs.tool` (Python) or `tool(...)` (TypeScript).
2. Call `execute(...)` with either `user_code` / `userCode` or optional sandbox codegen inputs.
3. Handle results from `ExecuteResult` (`result`, `error`, and `tool_calls` / `toolCalls`).

Use the end-to-end guides:

* [Register Python Functions](/integrations/register-python-functions)
* [Register TypeScript Functions](/integrations/register-ts-functions)
