Skip to main content
Mastra is a TypeScript framework for building AI agents, tools, and workflows. Connect it to Venice by configuring a custom OpenAI-compatible model endpoint.

Prerequisites

Create a Mastra project

npm create mastra@latest
pnpm create mastra
yarn create mastra
bunx create-mastra
Add your Venice API key to the generated project’s .env file:
VENICE_API_KEY=your-venice-api-key
Keep .env out of source control. Do not expose your Venice API key in browser-side code.

Create a Venice-powered agent

Create an agent and point its model configuration at the Venice API:
// src/mastra/agents/venice-agent.ts
import { Agent } from '@mastra/core/agent'

export const veniceAgent = new Agent({
  id: 'venice-agent',
  name: 'Venice Agent',
  instructions: `
    You are a concise, privacy-respecting assistant.
    Give accurate answers and say when you are uncertain.
  `,
  model: {
    id: 'venice/venice-uncensored',
    url: 'https://api.venice.ai/api/v1',
    apiKey: process.env.VENICE_API_KEY,
  },
})
The first segment of id is Mastra’s routing label. Mastra sends the remaining model ID, venice-uncensored, to Venice.
Set url to the base API URL shown above. Do not append /chat/completions; Mastra adds that path.
Register the agent in your Mastra instance:
// src/mastra/index.ts
import { Mastra } from '@mastra/core'
import { veniceAgent } from './agents/venice-agent'

export const mastra = new Mastra({
  agents: { veniceAgent },
})
Start the development server and open the URL shown in your terminal to test the agent in Mastra Studio:
npm run dev

Generate a response

Retrieve the registered agent and call generate():
import { mastra } from './src/mastra/index'

const agent = mastra.getAgentById('venice-agent')
const result = await agent.generate(
  'Explain why zero data retention matters in two sentences.',
)

console.log(result.text)
console.log(result.usage)

Stream a response

Use stream() when you want to display output as it arrives:
const agent = mastra.getAgentById('venice-agent')
const result = await agent.stream(
  'Write a short poem about private AI inference.',
)

for await (const chunk of result.textStream) {
  process.stdout.write(chunk)
}

Add tools

Mastra tools use Zod schemas to validate their inputs and outputs. Use a Venice model that supports function calling when attaching tools to an agent.
// src/mastra/tools/model-info.ts
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'

export const modelInfoTool = createTool({
  id: 'model-info',
  description: 'Returns a short description of a Venice model',
  inputSchema: z.object({
    model: z.string().describe('A Venice model ID'),
  }),
  outputSchema: z.object({
    description: z.string(),
  }),
  execute: async ({ model }) => {
    const descriptions: Record<string, string> = {
      'venice-uncensored': 'A fast, uncensored general-purpose model.',
      'zai-org-glm-5-1': 'A private model for reasoning and tool use.',
    }

    return {
      description: descriptions[model] ?? `No description found for ${model}.`,
    }
  },
})
Attach the tool to an agent:
// src/mastra/agents/model-guide-agent.ts
import { Agent } from '@mastra/core/agent'
import { modelInfoTool } from '../tools/model-info'

export const modelGuideAgent = new Agent({
  id: 'model-guide-agent',
  name: 'Venice Model Guide',
  instructions: 'Help users choose a Venice model. Use modelInfoTool when needed.',
  model: {
    id: 'venice/zai-org-glm-5-1',
    url: 'https://api.venice.ai/api/v1',
    apiKey: process.env.VENICE_API_KEY,
  },
  tools: { modelInfoTool },
})

Generate structured output

Pass a Zod schema through structuredOutput to receive validated data:
import { z } from 'zod'

const result = await veniceAgent.generate(
  'Compare private and data-retaining AI inference.',
  {
    structuredOutput: {
      schema: z.object({
        summary: z.string(),
        privacyBenefits: z.array(z.string()),
        recommendation: z.string(),
      }),
    },
  },
)

console.log(result.object)
If the selected model does not support the API’s structured-output mode, set jsonPromptInjection: true inside structuredOutput to have Mastra add the schema to the prompt instead.

Change models

To use another Venice text model, keep the venice/ routing prefix and replace the remaining model ID:
model: {
  id: 'venice/qwen3-5-9b',
  url: 'https://api.venice.ai/api/v1',
  apiKey: process.env.VENICE_API_KEY,
}
Browse available Venice models and check their capabilities before selecting one for tool calling, vision, or structured output.

Troubleshooting

Confirm that VENICE_API_KEY is present in the environment where Mastra runs, then restart the development server after changing .env.
Use the exact model ID shown on the models page. In Mastra, prefix it with venice/, for example venice/venice-uncensored.
Set the model URL to https://api.venice.ai/api/v1. Do not use the full /chat/completions endpoint.
Choose a model that supports function calling, describe when the agent should use the tool in its instructions, and define the tool with createTool().

Mastra Documentation

Learn more about Mastra agents, tools, and workflows

Venice Models

Browse models and supported capabilities