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

# Mastra + Declaw

> Define a Mastra createTool that executes Python in a Declaw sandbox, wire it into a Mastra Agent, and run it with agent.generate(). Input validated with Zod schemas.

## What You'll Learn

* Defining a `createTool` with `@mastra/core/tools` that executes Python in a Declaw sandbox
* Validating tool inputs with Zod schemas
* Creating a Mastra `Agent` with the tool and an OpenAI model
* Demo mode that exercises the sandbox tool directly without needing an OpenAI key

## Prerequisites

* Declaw instance running and `DECLAW_API_KEY` / `DECLAW_DOMAIN` set
* `OPENAI_API_KEY` (optional — the example runs in demo mode without it)

```bash theme={null}
npm install @declaw/sdk @mastra/core @ai-sdk/openai zod dotenv
```

## Code Walkthrough

### 1. Define the Declaw sandbox tool

`createTool` accepts an `id`, `description`, a Zod `inputSchema`, and an async `execute` function. The `context` parameter contains the validated input:

```typescript theme={null}
import { Sandbox } from "@declaw/sdk";
import { createTool } from "@mastra/core/tools";
import { z } from "zod";

const executePython = createTool({
  id: "execute-python",
  description: "Execute Python code in a secure Declaw sandbox",
  inputSchema: z.object({
    code: z.string().describe("Python code to execute"),
  }),
  execute: async ({ context }) => {
    const sbx = await Sandbox.create({ template: "python", timeout: 300 });
    try {
      await sbx.files.write("/tmp/code.py", context.code);
      const result = await sbx.commands.run("python3 /tmp/code.py", {
        timeout: 30,
      });
      return {
        stdout: result.stdout,
        stderr: result.stderr,
        exitCode: result.exitCode,
      };
    } finally {
      await sbx.kill();
    }
  },
});
```

Zod validates the input before `execute` is called, so `context.code` is always a `string`. The tool returns a structured object — Mastra serializes it as JSON for the LLM to read.

### 2. Create a Mastra Agent

```typescript theme={null}
import { Agent } from "@mastra/core/agent";
import { openai } from "@ai-sdk/openai";

const agent = new Agent({
  name: "Code Runner",
  instructions:
    "You are a helpful assistant that can execute Python code in a secure sandbox. Use the execute-python tool to run code.",
  model: openai("gpt-4o-mini"),
  tools: { executePython },
});
```

### 3. Run the agent

```typescript theme={null}
const prompt =
  "Write Python code to compute the first 15 numbers of the Fibonacci sequence and print them.";
const result = await agent.generate(prompt);
console.log(result.text);
```

### 4. Demo mode (no API key needed)

Run the sandbox tool directly without creating a Mastra Agent:

```typescript theme={null}
import { Sandbox } from "@declaw/sdk";

const code = `
a, b = 0, 1
fibs = []
for _ in range(15):
    fibs.append(a)
    a, b = b, a + b
print("Fibonacci:", fibs)
`.trim();

const sbx = await Sandbox.create({ template: "python", timeout: 300 });
try {
  await sbx.files.write("/tmp/code.py", code);
  const result = await sbx.commands.run("python3 /tmp/code.py", {
    timeout: 30,
  });
  console.log(result.stdout);
} finally {
  await sbx.kill();
}
```

## Expected Output

In demo mode:

```
=======================================================
Mastra + Declaw Sandbox Example
=======================================================
No OPENAI_API_KEY found -- running demo mode.

--- Tool Definition ---
const executePython = createTool({
    id: 'execute-python',
    description: 'Execute Python code in a secure Declaw sandbox',
    inputSchema: z.object({ code: z.string() }),
    execute: async ({ context }) => {
        const sbx = await Sandbox.create({ template: 'python', timeout: 300 });
        ...
    },
});

--- Running Code Directly in Declaw Sandbox ---
Code:
a, b = 0, 1
fibs = []
for _ in range(15):
    fibs.append(a)
    a, b = b, a + b
print("Fibonacci:", fibs)

stdout: Fibonacci: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
stderr:
exitCode: 0

Sandbox cleaned up.

=======================================================
Done!
=======================================================
```
