Skip to Content
HomeMastraManaging user authorization

Dynamic Tool Loading with Toolsets

Mastra lets you dynamically provide tools to an at runtime using toolsets. This approach is essential when integrating Arcade in web applications where each needs their own authentication flow.

Per-User Tool Authentication in Web Applications

In web applications serving multiple users, implement -specific authentication flows with these steps:

First, set up your Mastra configuration and in separate files:

TypeScript
// @/mastra/index.ts import { Mastra } from "@mastra/core"; import { githubAgent } from "./agents/githubAgent"; // Initialize Mastra export const mastra = new Mastra({ agents: { githubAgent, }, });
TypeScript
// @/mastra/agents/githubAgent.ts import { Agent } from "@mastra/core/agent"; import { anthropic } from "@ai-sdk/anthropic"; // Create the agent without tools - we'll add them at runtime export const githubAgent = new Agent({ name: "githubAgent", instructions: `You are a GitHub Agent that helps with repository management. You can help with tasks like: - Listing repositories - Creating and managing issues - Viewing pull requests - Managing repository settings If a tool requires authorization, you will receive an authorization URL. When that happens, clearly present this URL to the user and ask them to visit it to grant permissions.`, model: anthropic("claude-3-7-sonnet-20250219"), // No tools defined here - will be provided dynamically at runtime });

Then, create an API endpoint that provides dynamically:

TypeScript
// app/api/chat/route.ts import { NextRequest, NextResponse } from "next/server"; import { mastra } from "@/mastra"; import { Arcade } from "@arcadeai/arcadejs"; import { getUserSession } from "@/lib/auth"; // Your authentication handling import { toZodToolSet } from "@arcadeai/arcadejs/lib"; import { executeOrAuthorizeZodTool } from "@arcadeai/arcadejs/lib"; export async function POST(req: NextRequest) { // Extract request data const { messages, threadId } = await req.json(); // Authenticate the user const session = await getUserSession(req); if (!session) { return NextResponse.json({ message: "Unauthorized" }, { status: 401 }); } try { // Get the agent from Mastra const githubAgent = mastra.getAgent("githubAgent"); const arcade = new Arcade(); const githubToolkit = await arcade.tools.list({ toolkit: "github", limit: 30 }); // Fetch user-specific Arcade tools for GitHub const arcadeTools = toZodToolSet({ tools: githubToolkit.items, client: arcade, userId: session.user.email, executeFactory: executeOrAuthorizeZodTool, }); // Stream the response with dynamically provided tools const response = await githubAgent.stream(messages, { threadId, // Optional: For maintaining conversation context resourceId: session.user.id, // Optional: For associating memory with user toolChoice: "auto", toolsets: { arcade: arcadeTools, // Provide tools in a named toolset }, }); // Return streaming response return response.toDataStreamResponse(); } catch (error) { console.error("Error processing GitHub request:", error); return NextResponse.json( { message: "Failed to process request" }, { status: 500 }, ); } }

This approach provides several benefits:

  • Each user gets their own separate authentication flow with Arcade
  • A single instance works with multiple -specific toolsets
The toolsets parameter provides tools only for the current request without modifying the agent’s base configuration. This makes it ideal for multi-user applications where each user needs their own secure OAuth flow with Arcade.

Handling Tool Authorization

When a tool requires user authorization, the receives a response with:

TypeScript
{ authorization_required: true, url: "https://auth.arcade.com/...", message: "Forward this url to the user for authorization" }

Your should recognize this pattern and present the URL to the . To create a better user experience:

  • Display the authorization URL as a clickable link in your UI
  • Explain which service needs authorization and why
  • Provide a way for to retry their request after authorization

Tips for Selecting Tools

  • Focus on relevance: Choose tools that directly support your ’s specific purpose
  • Consider performance: Some may have higher latency than others
  • Handle errors gracefully: Implement robust error handling for third-party service failures
  • Create clear flows: Design intuitive authorization experiences

Next Steps

After integrating Arcade tools into your Mastra , you can:

For more detailed information on Mastra’s capabilities, visit the Mastra documentation .

Last updated on