Mastra
Use @codespar/mastra to give Mastra agents commerce capabilities in Latin America.
Mastra Adapter
The @codespar/mastra adapter converts CodeSpar session tools into Mastra's tool format. Tools are returned as a keyed record (by tool name) ready to pass directly to a Mastra Agent. Each tool's execute method routes through the CodeSpar session for billing and audit.
Installation
npm install @codespar/sdk @codespar/mastrapnpm add @codespar/sdk @codespar/mastrayarn add @codespar/sdk @codespar/mastra@codespar/mastra has a peer dependency on @codespar/sdk@^0.2.0. You also need @mastra/core for the Mastra runtime.
API Reference
getTools(session): Promise<Record<string, MastraTool>>
Fetches all tools from the session and returns them as a keyed record. Each tool has id, description, inputSchema (JSON Schema), and an execute method.
import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/mastra";
const codespar = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });
const session = await codespar.sessions.create({
servers: ["stripe", "mercadopago"],
});
const tools = await getTools(session);
console.log(Object.keys(tools)); // ["codespar_checkout", "codespar_pay", ...]toMastraTool(tool, session): MastraTool
Converts a single CodeSpar tool to Mastra format with a bound execute method.
import { toMastraTool } from "@codespar/mastra";
const allTools = await session.tools();
const paymentTool = toMastraTool(
allTools.find((t) => t.name === "codespar_pay")!,
session
);handleToolCall(session, toolName, args): Promise<ToolResult>
Convenience executor that routes a tool call through the CodeSpar session.
Full agent loop
This is a complete example of a Mastra Agent with CodeSpar tools:
import { Agent } from "@mastra/core";
import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/mastra";
const codespar = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });
async function run(userMessage: string) {
// 1. Create a session
const session = await codespar.sessions.create({
servers: ["stripe", "asaas", "correios"],
});
// 2. Get tools in Mastra format (keyed record)
const tools = await getTools(session);
// 3. Create and run the agent
const agent = new Agent({
name: "commerce-assistant",
instructions:
"You are a commerce assistant for a Brazilian e-commerce store. " +
"Handle payments, invoicing, and shipping. " +
"Respond in the same language the user writes in.",
model: { provider: "OPEN_AI", name: "gpt-4o" },
tools,
});
const result = await agent.generate(userMessage);
// 4. Clean up
await session.close();
return result.text;
}
const reply = await run("Generate a boleto for R$250 due in 7 days");
console.log(reply);Handling parallel tool calls
Mastra handles parallel tool execution automatically through its agent runtime. If you need manual control:
const toolEntries = Object.entries(tools);
const results = await Promise.all(
toolEntries
.filter(([name]) => name.startsWith("codespar_pay"))
.map(([, tool]) => tool.execute({ context: { amount: 5000 } }))
);Streaming
Mastra supports streaming via the agent's stream method:
import { Agent } from "@mastra/core";
import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/mastra";
const codespar = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });
async function runStreaming(userMessage: string) {
const session = await codespar.sessions.create({
servers: ["stripe", "mercadopago"],
});
const tools = await getTools(session);
const agent = new Agent({
name: "commerce-assistant",
instructions: "You are a commerce assistant for a Brazilian store.",
model: { provider: "OPEN_AI", name: "gpt-4o" },
tools,
});
const stream = await agent.stream(userMessage);
for await (const chunk of stream.textStream) {
process.stdout.write(chunk);
}
await session.close();
}
await runStreaming("Create a Pix payment for R$150");Error handling
Tool execution errors are handled by the Mastra runtime. For manual error handling:
const tool = tools["codespar_checkout"];
try {
const result = await tool.execute({
context: { provider: "stripe", amount: 4990, currency: "BRL" },
});
console.log("Success:", result);
} catch (error) {
console.error("Failed:", error instanceof Error ? error.message : error);
}The Mastra agent runtime automatically catches tool execution errors and feeds them back to the LLM for reasoning.
Best practices
-
Always close sessions. Use
try/finallyto ensuresession.close()runs. -
Scope servers narrowly. Only connect the MCP servers your agent needs.
-
Use clear instructions. Mastra agents work best with specific, domain-focused instructions.
-
Leverage the keyed record. Access tools by name (
tools["codespar_pay"]) for direct invocation. -
Combine with Mastra workflows. Use tools inside Mastra Workflows for complex multi-step operations.
-
Filter tools when possible. Use
session.findTools()to get only relevant tools before converting.
Next steps
- Sessions -- Session lifecycle and configuration
- Tools and Meta-Tools -- Understand the 6 meta-tools and routing
- Vercel AI SDK -- Similar keyed-record pattern
- LangChain Adapter -- Use with LangChain.js agents
- Quickstart -- End-to-end setup in under 5 minutes