@mastra/mcp-docs-server 1.1.39-alpha.4 → 1.1.39-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,64 +1,126 @@
1
1
  # A2A (Agent-to-Agent)
2
2
 
3
- Mastra supports the Agent-to-Agent (A2A) protocol for exposing agents as remote agents that other agents and services can discover, call, and track over time. A2A is useful when an agent needs to cross a network boundary without exposing the remote agent's internal tools, memory, prompts, or implementation.
3
+ Mastra supports the [Agent-to-Agent (A2A) protocol](https://a2a-protocol.org/latest/) for cross-platform multi-agent systems. Use A2A to expose Mastra agents as remote agents, consume remote A2A agents as Mastra subagents, or call A2A endpoints with the JavaScript client SDK.
4
+
5
+ A2A is an open protocol for delegating work to agents across network, framework, vendor, and language boundaries. A remote agent keeps its own tools, prompts, memory, workflows, and infrastructure private while exposing a protocol endpoint that other systems can discover and call.
4
6
 
5
7
  ## When to use A2A
6
8
 
7
- - A parent agent should delegate work to a specialized agent owned by another service or team.
8
- - A remote agent should keep its tools, prompts, memory, workflows, and infrastructure private.
9
+ - A parent agent should delegate work to a specialized remote agent.
10
+ - A remote agent is owned by another service, team, vendor, or runtime.
9
11
  - A backend, browser app, or another A2A-compatible system needs programmatic access to a Mastra agent.
10
12
  - Long-running remote work needs task IDs, status updates, artifacts, cancellation, resubscription, or push notifications.
11
13
 
12
14
  ## How A2A works
13
15
 
14
- A2A maps to the roles described in the [A2A core concepts](https://a2a-protocol.org/latest/topics/key-concepts/):
16
+ A2A uses an agent card for discovery. The card is a JSON document served from a well-known URL. It describes the remote agent and includes the execution URL that accepts A2A JSON-RPC requests.
15
17
 
16
- - **User**: The human, service, or process that asks for work.
17
- - **Client agent**: The caller that discovers a remote agent, sends messages, and listens for task updates.
18
- - **Remote agent**: The Mastra agent running behind an A2A endpoint.
18
+ When using the default Mastra Server `apiPrefix` of `/api`, an agent registered as `weather-agent` exposes:
19
19
 
20
- Any registered Mastra agent can be called as an A2A remote agent. It keeps using its own instructions, tools, memory, workflows, and server configuration; A2A changes how the agent is reached, not how it's authored.
20
+ - Agent card: `/api/.well-known/weather-agent/agent-card.json`
21
+ - Execution endpoint: `/api/a2a/weather-agent`
21
22
 
22
- The flow is:
23
+ An agent card includes fields like the agent name, description, endpoint URL, provider, capabilities, security metadata, and skills:
23
24
 
24
- 1. Register a standard Mastra agent in your `Mastra` instance.
25
- 2. Start Mastra Server or mount Mastra routes into your own server.
26
- 3. Mastra exposes the agent through an agent card at `/.well-known/:agentId/agent-card.json` and an execution endpoint at `/a2a/:agentId`.
27
- 4. A client reads the card, sends A2A JSON-RPC methods such as `message/send`, `message/stream`, `tasks/get`, `tasks/cancel`, or `tasks/resubscribe`, then receives task, artifact, and status events.
25
+ ```json
26
+ {
27
+ "protocolVersion": "0.3.0",
28
+ "name": "Weather Agent",
29
+ "description": "Provides weather information.",
30
+ "url": "https://agent.example.com/api/a2a/weather-agent",
31
+ "version": "1.0",
32
+ "provider": {
33
+ "organization": "Acme",
34
+ "url": "https://acme.example.com"
35
+ },
36
+ "capabilities": {
37
+ "streaming": true,
38
+ "pushNotifications": true,
39
+ "stateTransitionHistory": false
40
+ },
41
+ "defaultInputModes": ["text/plain"],
42
+ "defaultOutputModes": ["text/plain"],
43
+ "skills": [
44
+ {
45
+ "id": "weather",
46
+ "name": "weather",
47
+ "description": "Gets weather conditions for a location.",
48
+ "tags": ["tool"]
49
+ }
50
+ ]
51
+ }
52
+ ```
28
53
 
29
- Agent cards describe the remote agent's name, description, provider, endpoint URL, capabilities, security metadata, and skills. Capabilities advertise features such as streaming and push notifications. Skills describe what the remote agent can do so callers can decide whether it fits the task.
54
+ A2A represents work as messages and tasks. Messages carry text, file, or structured data parts. Tasks are stateful units of work with IDs and lifecycle states, so clients can follow long-running work, send follow-up turns, cancel work, or resubscribe after a disconnect.
30
55
 
31
- A2A represents work as messages and tasks. Messages carry text, file, or structured data parts. Tasks are stateful units of work with IDs and lifecycle states, so clients can follow long-running work, send follow-up turns, cancel work, or resubscribe after a disconnect. Remote agents can also return artifacts, such as text, files, or structured data, during or after a task.
56
+ ## Get started
32
57
 
33
- ## Quickstart
58
+ A2A has two common paths in Mastra:
34
59
 
35
- Start with any agent registered in your `Mastra` instance. When Mastra Server runs, the agent is available as a remote A2A agent through its registered ID.
60
+ - Consume a remote A2A agent as a Mastra subagent with `A2AAgent`.
61
+ - Send requests to a Mastra A2A endpoint with `MastraClient.getA2A()`.
36
62
 
37
- For an agent registered as `research-agent`, Mastra exposes:
63
+ Use `A2AAgent` when another Mastra agent should delegate work to a remote agent. Use the client SDK when application code needs to call an A2A-enabled Mastra endpoint directly.
38
64
 
39
- - Agent card: `/.well-known/research-agent/agent-card.json`
40
- - Execution endpoint: `/a2a/research-agent`
65
+ ## Consume A2A agents as subagents
41
66
 
42
- Use `MastraClient.getA2A()` to fetch the agent card and call the remote agent:
67
+ Use `A2AAgent` to wrap a remote A2A agent, then add it to a parent agent with the [supervisor agents](https://mastra.ai/docs/agents/supervisor-agents) pattern. Pass an explicit agent card URL when the remote server hosts multiple agents or uses a custom well-known path.
68
+
69
+ ```typescript
70
+ import { Agent } from '@mastra/core/agent'
71
+ import { A2AAgent } from '@mastra/core/a2a'
72
+
73
+ const remoteWeatherAgent = new A2AAgent({
74
+ url: 'https://weather.example.com/api/.well-known/weather-agent/agent-card.json',
75
+ headers: {
76
+ Authorization: `Bearer ${process.env.WEATHER_AGENT_TOKEN}`,
77
+ },
78
+ })
79
+
80
+ export const supportAgent = new Agent({
81
+ id: 'support-agent',
82
+ name: 'Support Agent',
83
+ instructions: 'Answer user questions and delegate weather questions when needed.',
84
+ model: 'openai/gpt-5.4',
85
+ agents: {
86
+ remoteWeatherAgent,
87
+ },
88
+ })
89
+ ```
90
+
91
+ If `url` points to a domain, `A2AAgent` fetches the agent card from `/.well-known/agent-card.json`. Use a domain URL for single-agent servers that follow that discovery path. For multi-agent servers, pass the full card URL, such as `https://agent.example.com/api/.well-known/weather-agent/agent-card.json`.
92
+
93
+ During execution, `A2AAgent`:
94
+
95
+ - Fetches and caches the remote agent card.
96
+ - Reads the execution URL and capabilities from the card.
97
+ - Calls `message/send` for non-streaming runs or `message/stream` when streaming is supported.
98
+ - Converts remote messages, tasks, artifacts, and status updates into Mastra subagent results.
99
+ - Supports `resumeGenerate()` and `resumeStream()` when the remote task requires follow-up input or resubscription.
100
+
101
+ If the remote card doesn't advertise streaming support, `A2AAgent.stream()` falls back to the non-streaming generate path and returns a buffered stream result.
102
+
103
+ ## Send requests with the client SDK
104
+
105
+ Use `MastraClient.getA2A()` when you want application code to call an A2A-enabled Mastra agent. Configure `baseUrl` for the server origin and `apiPrefix` when the server doesn't use the default `/api` prefix.
43
106
 
44
107
  ```typescript
45
108
  import { MastraClient } from '@mastra/client-js'
46
109
 
47
110
  const client = new MastraClient({
48
111
  baseUrl: 'https://agent.example.com',
112
+ headers: {
113
+ Authorization: `Bearer ${process.env.AGENT_API_TOKEN}`,
114
+ },
49
115
  })
50
116
 
51
- const a2a = client.getA2A('research-agent')
117
+ const a2a = client.getA2A('weather-agent')
52
118
  const card = await a2a.getAgentCard()
53
119
 
54
120
  console.log(card.name, card.capabilities)
55
121
  ```
56
122
 
57
- ## Discover and call remote agents
58
-
59
- A2A discovery starts with the agent card. The [A2A discovery guide](https://a2a-protocol.org/latest/topics/agent-discovery/) describes well-known URI discovery, registries, and direct configuration. Mastra supports the well-known route for registered agents at `/.well-known/:agentId/agent-card.json`.
60
-
61
- Use `sendMessageStream()` to receive task status and artifact updates over Server-Sent Events (SSE):
123
+ Use `sendMessageStream()` to send a message and receive task status and artifact updates over Server-Sent Events (SSE):
62
124
 
63
125
  ```typescript
64
126
  const stream = a2a.sendMessageStream({
@@ -66,7 +128,7 @@ const stream = a2a.sendMessageStream({
66
128
  kind: 'message',
67
129
  role: 'user',
68
130
  messageId: crypto.randomUUID(),
69
- parts: [{ kind: 'text', text: 'Summarize this incident report.' }],
131
+ parts: [{ kind: 'text', text: "What's the weather in Prague?" }],
70
132
  },
71
133
  })
72
134
 
@@ -89,7 +151,26 @@ for await (const event of updates) {
89
151
  }
90
152
  ```
91
153
 
92
- Agent cards can contain sensitive information, such as internal URLs or private skill descriptions. Protect restricted cards with access controls, and use agent card verification when a client needs to validate that a card came from a trusted source.
154
+ ## Configure subagent calls
155
+
156
+ `A2AAgent` accepts request options for authenticated or constrained environments:
157
+
158
+ ```typescript
159
+ import { A2AAgent } from '@mastra/core/a2a'
160
+
161
+ const remoteWeatherAgent = new A2AAgent({
162
+ url: 'https://weather.example.com/api/.well-known/weather-agent/agent-card.json',
163
+ headers: {
164
+ Authorization: `Bearer ${process.env.WEATHER_AGENT_TOKEN}`,
165
+ },
166
+ retries: 2,
167
+ backoffMs: 250,
168
+ maxBackoffMs: 1000,
169
+ timeoutMs: 30_000,
170
+ })
171
+ ```
172
+
173
+ You can also pass `credentials`, `fetch`, and `abortSignal` when the runtime needs custom fetch behavior or request cancellation.
93
174
 
94
175
  ## Push notifications
95
176
 
@@ -144,67 +225,13 @@ const card = await a2a.getAgentCard({
144
225
  },
145
226
  },
146
227
  })
147
- ```
148
-
149
- Use client-side signature verification to enforce trusted keys before calling the remote agent.
150
-
151
- ## Use remote agents as subagents
152
-
153
- Use `A2AAgent` when a Mastra parent agent should call a remote A2A agent as a subagent. Create an `A2AAgent` with a remote agent card URL or single-agent domain, then register it in the parent agent's `agents` map.
154
-
155
- ```typescript
156
- import { Agent } from '@mastra/core/agent'
157
- import { A2AAgent } from '@mastra/core/a2a'
158
-
159
- const remoteWeatherAgent = new A2AAgent({
160
- url: 'https://weather.example.com',
161
- })
162
-
163
- export const supportAgent = new Agent({
164
- id: 'support-agent',
165
- name: 'Support Agent',
166
- instructions: 'Answer user questions and delegate weather questions when needed.',
167
- model: 'openai/gpt-5.4',
168
- agents: {
169
- remoteWeatherAgent,
170
- },
171
- })
172
- ```
173
-
174
- > **Tip:** If `url` points to a domain, `A2AAgent` fetches the agent card from `/.well-known/agent-card.json`. Use this for single-agent servers. For multi-agent servers, pass the explicit card URL, such as `https://agent.example.com/.well-known/:agentId/agent-card.json`. If `url` already ends with `/agent-card.json`, Mastra uses that URL directly. `A2AAgent` doesn't discover agent IDs beyond the URL you provide.
175
-
176
- `A2AAgent` implements Mastra's subagent interface. The parent agent can call it like any other subagent, while `A2AAgent` handles the protocol details.
177
228
 
178
- During execution, `A2AAgent`:
179
-
180
- - Fetches and caches the remote agent card.
181
- - Reads the execution URL and capabilities from the card.
182
- - Calls `message/send` for non-streaming runs or `message/stream` when streaming is supported.
183
- - Converts remote messages, tasks, artifacts, and status updates into Mastra subagent results.
184
- - Supports `resumeGenerate()` and `resumeStream()` when the remote task requires follow-up input or resubscription.
185
-
186
- If the remote card doesn't advertise streaming support, `A2AAgent.stream()` falls back to the non-streaming generate path and returns a buffered stream result.
187
-
188
- ## Configure subagent calls
189
-
190
- `A2AAgent` accepts request options for authenticated or constrained environments:
191
-
192
- ```typescript
193
- import { A2AAgent } from '@mastra/core/a2a'
194
-
195
- const remoteWeatherAgent = new A2AAgent({
196
- url: 'https://weather.example.com',
197
- headers: {
198
- Authorization: `Bearer ${process.env.WEATHER_AGENT_TOKEN}`,
199
- },
200
- retries: 2,
201
- backoffMs: 250,
202
- maxBackoffMs: 1000,
203
- timeoutMs: 30_000,
204
- })
229
+ if (!card.signatures?.length) {
230
+ throw new Error('Expected a signed A2A agent card.')
231
+ }
205
232
  ```
206
233
 
207
- You can also pass `credentials`, `fetch`, and `abortSignal` when the runtime needs custom fetch behavior or request cancellation.
234
+ Use client-side signature verification when a client must enforce trusted keys before calling the remote agent.
208
235
 
209
236
  ## Verify subagent cards
210
237
 
@@ -214,7 +241,7 @@ Use `verifyAgentCard` when a parent agent should validate a remote agent before
214
241
  import { A2AAgent } from '@mastra/core/a2a'
215
242
 
216
243
  const remoteWeatherAgent = new A2AAgent({
217
- url: 'https://weather.example.com/.well-known/agent-card.json',
244
+ url: 'https://weather.example.com/api/.well-known/weather-agent/agent-card.json',
218
245
  verifyAgentCard: {
219
246
  verify: async (card, context) => {
220
247
  if (card.provider?.organization !== 'Weather Inc') {
@@ -32,4 +32,32 @@ bun x skills add mastra-ai/skills
32
32
 
33
33
  Mastra skills work with any coding agent that supports the [Skills standard](https://agentskills.io/), including Claude Code, Cursor, Codex, OpenCode, and others.
34
34
 
35
+ ## Update skill
36
+
37
+ To update to the latest version of the Mastra skill, run:
38
+
39
+ **npm**:
40
+
41
+ ```bash
42
+ npx skills update mastra
43
+ ```
44
+
45
+ **pnpm**:
46
+
47
+ ```bash
48
+ pnpm dlx skills update mastra
49
+ ```
50
+
51
+ **Yarn**:
52
+
53
+ ```bash
54
+ yarn dlx skills update mastra
55
+ ```
56
+
57
+ **Bun**:
58
+
59
+ ```bash
60
+ bun x skills update mastra
61
+ ```
62
+
35
63
  They're also available on [GitHub](https://github.com/mastra-ai/skills).
@@ -25,6 +25,7 @@ const mastra = new Mastra({
25
25
  auth: new MastraAuthWorkos({
26
26
  /* ... */
27
27
  fetchMemberships: true,
28
+ mapUserToResourceId: user => user.teamId,
28
29
  }),
29
30
  fga: new MastraFGAWorkos({
30
31
  resourceMapping: {
@@ -39,6 +40,9 @@ const mastra = new Mastra({
39
40
  [MastraFGAPermissions.MEMORY_WRITE]: 'update',
40
41
  },
41
42
  }),
43
+ storedResources: {
44
+ scope: true,
45
+ },
42
46
  },
43
47
  });
44
48
  ```
@@ -47,6 +51,8 @@ When using `MastraFGAWorkos`, set `fetchMemberships: true` on `MastraAuthWorkos`
47
51
 
48
52
  Use `thread` as the resource-mapping key for memory authorization. `MastraFGAWorkos` still accepts the legacy alias `memory`, but new configs should prefer `thread`.
49
53
 
54
+ When `server.fga` is configured, Mastra enforces FGA on protected actions. If a protected action has no authenticated user, Mastra denies it. If `server.fga` is not configured, these FGA checks are skipped and Mastra keeps the previous behavior.
55
+
50
56
  ### Resource mapping
51
57
 
52
58
  The `resourceMapping` tells Mastra how to resolve FGA resource types and IDs from request context. Keys are Mastra resource types, values define the FGA resource type and how to derive the ID:
@@ -67,6 +73,7 @@ resourceMapping: {
67
73
  - `user` — the authenticated user
68
74
  - `resourceId` — the owning Mastra resource ID when available (for example, a thread's `resourceId`)
69
75
  - `requestContext` — the current request context for advanced tenant resolution
76
+ - `metadata` — provider-specific metadata for the attempted action
70
77
 
71
78
  Return `undefined` from `deriveId()` to fall back to the original Mastra resource ID.
72
79
 
@@ -89,9 +96,43 @@ If no mapping exists for a permission, the original string is passed through.
89
96
 
90
97
  Use `validatePermissions()` to validate the full set of permissions Mastra may emit at startup. Use this when a provider requires every Mastra permission to have an explicit provider permission slug.
91
98
 
99
+ ### Stored resource scoping
100
+
101
+ FGA authorizes access to a resource. It does not automatically filter stored records that live in shared storage. Enable stored resource scoping when the built-in stored resource APIs are used in a multi-tenant app.
102
+
103
+ ```typescript
104
+ const mastra = new Mastra({
105
+ server: {
106
+ auth: new MastraAuthWorkos({
107
+ /* ... */
108
+ mapUserToResourceId: user => user.teamId,
109
+ }),
110
+ storedResources: {
111
+ scope: true,
112
+ },
113
+ },
114
+ });
115
+ ```
116
+
117
+ With `scope: true`, Mastra reads `MASTRA_RESOURCE_ID_KEY` from the request context. `mapUserToResourceId()` sets this value after authentication. Stored resource handlers persist the scope in record metadata and filter list, read, update, publish, and delete operations by that scope.
118
+
119
+ Use an object when the scope needs custom request logic:
120
+
121
+ ```typescript
122
+ storedResources: {
123
+ scope: {
124
+ metadataKey: 'teamId',
125
+ resolve: ({ user }) => user.teamId,
126
+ requireScope: true,
127
+ },
128
+ },
129
+ ```
130
+
131
+ If `requireScope` is `true` or omitted, scoped stored resource routes fail when no scope can be resolved.
132
+
92
133
  ### Route policy coverage
93
134
 
94
- Mastra includes route-level FGA metadata for built-in resource routes, including agents, workflows, tools, MCP tools, memory threads, responses, and conversations. A route is checked when it has route-level `fga` metadata, when Mastra can derive built-in metadata for that route, or when the provider supplies metadata with `resolveRouteFGA()`.
135
+ Mastra includes route-level FGA metadata for built-in resource routes, including agents, workflows, tools, MCP tools, memory threads, responses, conversations, and stored resources. Stored resource route coverage includes `/stored/agents`, `/stored/mcp-clients`, `/stored/prompt-blocks`, `/stored/scorers`, `/stored/skills`, and `/stored/workspaces`. A route is checked when it has route-level `fga` metadata, when Mastra can derive built-in metadata for that route, or when the provider supplies metadata with `resolveRouteFGA()`.
95
136
 
96
137
  To deny protected routes that do not resolve FGA metadata, configure route policy coverage on the FGA provider:
97
138
 
@@ -159,16 +200,20 @@ const fga = new MastraFGAWorkos({
159
200
 
160
201
  When an FGA provider is configured, Mastra automatically checks authorization at these lifecycle points:
161
202
 
162
- | Lifecycle point | Permission checked | Resource |
163
- | -------------------------------------- | ---------------------------------------------- | -------------------------------------- |
164
- | Agent execution (`generate`, `stream`) | `agents:execute` | `{ type: 'agent', id: agentId }` |
165
- | Workflow execution | `workflows:execute` | `{ type: 'workflow', id: workflowId }` |
166
- | Tool execution | `tools:execute` | `{ type: 'tool', id: toolName }` |
167
- | Thread/memory access | `memory:read`, `memory:write`, `memory:delete` | `{ type: 'thread', id: threadId }` |
168
- | MCP tool execution | `tools:execute` | `{ type: 'tool', id: toolName }` |
169
- | HTTP resource routes | Configured per route | Configured per route |
203
+ | Lifecycle point | Permission checked | Resource type | Resource ID |
204
+ | ---------------------------------------------------------------- | ----------------------------------------------- | -------------------- | ------------------------------------------------------------------- |
205
+ | Agent execution (`generate`, `stream`) | `agents:execute` | `agent` | `agentId` |
206
+ | Built-in workflow HTTP execution routes and `Workflow.execute()` | `workflows:execute` | `workflow` | `workflowId` |
207
+ | Standalone tool execution | `tools:execute` | `tool` | `toolName` |
208
+ | Agent tool execution | `tools:execute` | `tool` | `${agentId}:${toolName}` |
209
+ | MCP tool execution | `tools:execute` | `tool` | `JSON.stringify([serverName, toolName])` |
210
+ | Thread and memory access | `memory:read`, `memory:write`, `memory:delete` | `thread` | `threadId` |
211
+ | Stored resource routes | Stored resource permission for the route action | Stored resource type | Route record ID, or the stored-resource scope for collection routes |
212
+ | HTTP resource routes | Configured per route | Configured per route | Configured per route |
213
+
214
+ Direct SDK calls to `createRun().start()`, `resume()`, or `restart()` are not independently checked by core FGA in this release. Make those calls from a protected route or guard them in application code. Pass a `requestContext` with an authenticated user when invoking protected entry points directly.
170
215
 
171
- All checks are **no-ops when FGA is not configured**, maintaining backward compatibility.
216
+ Core agent, internal workflow, tool, and memory checks also pass `requestContext` and action metadata to the FGA provider. Route checks pass `requestContext`. Thread checks pass the owning `resourceId` when available.
172
217
 
173
218
  ## Custom FGA provider
174
219
 
@@ -1,6 +1,6 @@
1
1
  # Model Providers
2
2
 
3
- Mastra provides a unified interface for working with LLMs across multiple providers, giving you access to 4182 models from 120 providers through a single API.
3
+ Mastra provides a unified interface for working with LLMs across multiple providers, giving you access to 4219 models from 121 providers through a single API.
4
4
 
5
5
  ## Features
6
6
 
@@ -15,7 +15,7 @@ const agent = new Agent({
15
15
  id: "my-agent",
16
16
  name: "My Agent",
17
17
  instructions: "You are a helpful assistant",
18
- model: "novita-ai/Sao10K/L3-8B-Stheno-v3.2"
18
+ model: "novita-ai/baichuan/baichuan-m2-32b"
19
19
  });
20
20
 
21
21
  // Generate a response
@@ -118,10 +118,10 @@ for await (const chunk of stream) {
118
118
  | `novita-ai/qwen/qwen3.5-27b` | 262K | | | | | | $0.30 | $2 |
119
119
  | `novita-ai/qwen/qwen3.5-35b-a3b` | 262K | | | | | | $0.25 | $2 |
120
120
  | `novita-ai/qwen/qwen3.5-397b-a17b` | 262K | | | | | | $0.60 | $4 |
121
- | `novita-ai/sao10k/l3-70b-euryale-v2.1` | 8K | | | | | | $1 | $1 |
122
- | `novita-ai/sao10k/l3-8b-lunaris` | 8K | | | | | | $0.05 | $0.05 |
123
- | `novita-ai/Sao10K/L3-8B-Stheno-v3.2` | 8K | | | | | | $0.05 | $0.05 |
124
- | `novita-ai/sao10k/l31-70b-euryale-v2.2` | 8K | | | | | | $1 | $1 |
121
+ | `novita-ai/sao10K/l3-70b-euryale-v2.1` | 8K | | | | | | $1 | $1 |
122
+ | `novita-ai/sao10K/l3-8b-lunaris` | 8K | | | | | | $0.05 | $0.05 |
123
+ | `novita-ai/sao10K/L3-8B-stheno-v3.2` | 8K | | | | | | $0.05 | $0.05 |
124
+ | `novita-ai/sao10K/l31-70b-euryale-v2.2` | 8K | | | | | | $1 | $1 |
125
125
  | `novita-ai/xiaomimimo/mimo-v2-flash` | 262K | | | | | | $0.10 | $0.30 |
126
126
  | `novita-ai/zai-org/autoglm-phone-9b-multilingual` | 66K | | | | | | $0.04 | $0.14 |
127
127
  | `novita-ai/zai-org/glm-4.5` | 131K | | | | | | $0.60 | $2 |
@@ -144,7 +144,7 @@ const agent = new Agent({
144
144
  name: "custom-agent",
145
145
  model: {
146
146
  url: "https://api.novita.ai/openai",
147
- id: "novita-ai/Sao10K/L3-8B-Stheno-v3.2",
147
+ id: "novita-ai/baichuan/baichuan-m2-32b",
148
148
  apiKey: process.env.NOVITA_API_KEY,
149
149
  headers: {
150
150
  "X-Custom-Header": "value"
@@ -163,7 +163,7 @@ const agent = new Agent({
163
163
  const useAdvanced = requestContext.task === "complex";
164
164
  return useAdvanced
165
165
  ? "novita-ai/zai-org/glm-5.1"
166
- : "novita-ai/Sao10K/L3-8B-Stheno-v3.2";
166
+ : "novita-ai/baichuan/baichuan-m2-32b";
167
167
  }
168
168
  });
169
169
  ```
@@ -0,0 +1,107 @@
1
+ # ![routing.run logo](https://models.dev/logos/routing-run.svg)routing.run
2
+
3
+ Access 37 routing.run models through Mastra's model router. Authentication is handled automatically using the `ROUTING_RUN_API_KEY` environment variable.
4
+
5
+ Learn more in the [routing.run documentation](https://docs.routing.run).
6
+
7
+ ```bash
8
+ ROUTING_RUN_API_KEY=your-api-key
9
+ ```
10
+
11
+ ```typescript
12
+ import { Agent } from "@mastra/core/agent";
13
+
14
+ const agent = new Agent({
15
+ id: "my-agent",
16
+ name: "My Agent",
17
+ instructions: "You are a helpful assistant",
18
+ model: "routing-run/route/deepseek-v3.2"
19
+ });
20
+
21
+ // Generate a response
22
+ const response = await agent.generate("Hello!");
23
+
24
+ // Stream a response
25
+ const stream = await agent.stream("Tell me a story");
26
+ for await (const chunk of stream) {
27
+ console.log(chunk);
28
+ }
29
+ ```
30
+
31
+ > **Info:** Mastra uses the OpenAI-compatible `/chat/completions` endpoint. Some provider-specific features may not be available. Check the [routing.run documentation](https://docs.routing.run) for details.
32
+
33
+ ## Models
34
+
35
+ | Model | Context | Tools | Reasoning | Image | Audio | Video | Input $/1M | Output $/1M |
36
+ | --------------------------------------------- | ------- | ----- | --------- | ----- | ----- | ----- | ---------- | ----------- |
37
+ | `routing-run/route/deepseek-v3.2` | 164K | | | | | | $0.49 | $0.74 |
38
+ | `routing-run/route/deepseek-v4-flash` | 1.0M | | | | | | $0.49 | $0.74 |
39
+ | `routing-run/route/deepseek-v4-flash-full` | 1.0M | | | | | | $0.49 | $0.74 |
40
+ | `routing-run/route/deepseek-v4-pro` | 1.0M | | | | | | $0.49 | $0.74 |
41
+ | `routing-run/route/deepseek-v4-pro-precision` | 1.0M | | | | | | $0.74 | $1 |
42
+ | `routing-run/route/gemma-4-31b-it` | 131K | | | | | | $0.10 | $0.30 |
43
+ | `routing-run/route/glm-4.7` | 128K | | | | | | $1 | $4 |
44
+ | `routing-run/route/glm-4.7-flash` | 128K | | | | | | $1 | $4 |
45
+ | `routing-run/route/glm-5` | 203K | | | | | | $0.79 | $3 |
46
+ | `routing-run/route/glm-5-highspeed` | 203K | | | | | | $1 | $4 |
47
+ | `routing-run/route/glm-5.1` | 203K | | | | | | $1 | $3 |
48
+ | `routing-run/route/glm-5.1-fp16` | 203K | | | | | | $1 | $4 |
49
+ | `routing-run/route/glm-5.1-full` | 203K | | | | | | $1 | $4 |
50
+ | `routing-run/route/glm-5.1-precision` | 203K | | | | | | $1 | $4 |
51
+ | `routing-run/route/kimi-k2.5` | 262K | | | | | | $0.46 | $2 |
52
+ | `routing-run/route/kimi-k2.5-highspeed` | 131K | | | | | | $0.65 | $3 |
53
+ | `routing-run/route/kimi-k2.6` | 262K | | | | | | $0.46 | $2 |
54
+ | `routing-run/route/kimi-k2.6-full` | 262K | | | | | | $0.46 | $2 |
55
+ | `routing-run/route/kimi-k2.6-precision` | 262K | | | | | | $0.65 | $3 |
56
+ | `routing-run/route/mimo-v2.5` | 256K | | | | | | $0.40 | $2 |
57
+ | `routing-run/route/mimo-v2.5-pro` | 1.0M | | | | | | $0.45 | $1 |
58
+ | `routing-run/route/mimo-v2.5-pro-precision` | 1.0M | | | | | | $0.45 | $1 |
59
+ | `routing-run/route/minimax-m2.5` | 100K | | | | | | $0.19 | $1 |
60
+ | `routing-run/route/minimax-m2.5-highspeed` | 100K | | | | | | $0.19 | $1 |
61
+ | `routing-run/route/minimax-m2.7` | 100K | | | | | | $0.33 | $1 |
62
+ | `routing-run/route/minimax-m2.7-highspeed` | 100K | | | | | | $0.33 | $1 |
63
+ | `routing-run/route/mistral-large-3` | 128K | | | | | | $0.50 | $2 |
64
+ | `routing-run/route/mistral-medium-2505` | 128K | | | | | | $0.40 | $2 |
65
+ | `routing-run/route/mistral-small-2503` | 128K | | | | | | $0.15 | $0.60 |
66
+ | `routing-run/route/qwen3.5-397b-a17b` | 262K | | | | | | $1 | $3 |
67
+ | `routing-run/route/qwen3.5-9b` | 262K | | | | | | $0.20 | $0.60 |
68
+ | `routing-run/route/qwen3.5-9b-chat` | 262K | | | | | | $0.20 | $0.60 |
69
+ | `routing-run/route/qwen3.6-27b` | 262K | | | | | | $1 | $3 |
70
+ | `routing-run/route/step-3.5-flash` | 262K | | | | | | $0.10 | $0.29 |
71
+ | `routing-run/route/step-3.5-flash-2603` | 262K | | | | | | $0.10 | $0.30 |
72
+ | `routing-run/route/step-3.5-flash-full` | 262K | | | | | | $0.10 | $0.29 |
73
+ | `routing-run/route/stepfun-3.5-flash` | 262K | | | | | | $0.10 | $0.29 |
74
+
75
+ ## Advanced configuration
76
+
77
+ ### Custom headers
78
+
79
+ ```typescript
80
+ const agent = new Agent({
81
+ id: "custom-agent",
82
+ name: "custom-agent",
83
+ model: {
84
+ url: "https://api.routing.run/v1",
85
+ id: "routing-run/route/deepseek-v3.2",
86
+ apiKey: process.env.ROUTING_RUN_API_KEY,
87
+ headers: {
88
+ "X-Custom-Header": "value"
89
+ }
90
+ }
91
+ });
92
+ ```
93
+
94
+ ### Dynamic model selection
95
+
96
+ ```typescript
97
+ const agent = new Agent({
98
+ id: "dynamic-agent",
99
+ name: "Dynamic Agent",
100
+ model: ({ requestContext }) => {
101
+ const useAdvanced = requestContext.task === "complex";
102
+ return useAdvanced
103
+ ? "routing-run/route/stepfun-3.5-flash"
104
+ : "routing-run/route/deepseek-v3.2";
105
+ }
106
+ });
107
+ ```
@@ -89,6 +89,7 @@ Direct access to individual AI model providers. Each provider offers unique mode
89
89
  - [Qiniu](https://mastra.ai/models/providers/qiniu-ai)
90
90
  - [Regolo AI](https://mastra.ai/models/providers/regolo-ai)
91
91
  - [Requesty](https://mastra.ai/models/providers/requesty)
92
+ - [routing.run](https://mastra.ai/models/providers/routing-run)
92
93
  - [Sarvam AI](https://mastra.ai/models/providers/sarvam)
93
94
  - [Scaleway](https://mastra.ai/models/providers/scaleway)
94
95
  - [SiliconFlow](https://mastra.ai/models/providers/siliconflow)
@@ -63,6 +63,10 @@ const agent = new Agent({
63
63
  discord: {
64
64
  adapter: createDiscordAdapter(),
65
65
  cards: false,
66
+ cors: {
67
+ origin: ['https://customer-saas.example'],
68
+ credentials: true,
69
+ },
66
70
  gateway: false,
67
71
  },
68
72
  slack: createSlackAdapter(), // Plain adapter uses defaults
@@ -77,6 +81,8 @@ const agent = new Agent({
77
81
 
78
82
  **cards** (`boolean`): Render tool calls as interactive rich cards with buttons. Set to \`false\` to use plain text formatting instead. When disabled and a tool requires approval, the agent uses \`autoResumeSuspendedTools\` to let the LLM decide based on conversation context. (Default: `true`)
79
83
 
84
+ **cors** (`CorsOptions`): CORS configuration for this adapter webhook route. Use this for browser-based channel adapters that need cross-origin credentials.
85
+
80
86
  **formatToolCall** (`(info: { toolName, args, result, isError? }) => PostableMessage | null`): Override how tool calls are rendered in the chat. Called once per tool invocation after the result is available. Return \`null\` to suppress the message entirely.
81
87
 
82
88
  **formatError** (`(error: Error) => PostableMessage`): Override how errors are rendered in the chat. Return a user-friendly message instead of exposing the raw error. (Default: `"❌ Error: <error.message>"`)
@@ -684,16 +684,16 @@ export const mastra = new Mastra({
684
684
 
685
685
  **Type:** `CorsOptions | false`
686
686
 
687
- CORS (Cross-Origin Resource Sharing) configuration for the server. Set to `false` to disable CORS entirely.
688
-
689
- | Property | Type | Default | Description |
690
- | --------------- | -------------------- | ----------------------------------------------------------- | -------------------------------------------- |
691
- | `origin` | `string \| string[]` | `'*'` | Origins for CORS requests |
692
- | `allowMethods` | `string[]` | `['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']` | HTTP methods |
693
- | `allowHeaders` | `string[]` | `['Content-Type', 'Authorization', 'x-mastra-client-type']` | Request headers |
694
- | `exposeHeaders` | `string[]` | `['Content-Length', 'X-Requested-With']` | Browser headers |
695
- | `credentials` | `boolean` | `false` | Credentials (cookies, authorization headers) |
696
- | `maxAge` | `number` | `3600` | Preflight request cache duration in seconds |
687
+ CORS (Cross-Origin Resource Sharing) configuration for the server. Set to `false` to disable CORS entirely. Use this for one policy across all routes. For a custom route-specific policy, use the `cors` option in [`registerApiRoute()`](https://mastra.ai/reference/server/register-api-route).
688
+
689
+ | Property | Type | Default | Description |
690
+ | --------------- | -------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------- |
691
+ | `origin` | `string \| string[]` | `'*'` | Origins for CORS requests |
692
+ | `allowMethods` | `string[]` | `['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']` | HTTP methods |
693
+ | `allowHeaders` | `string[]` | `['Content-Type', 'Authorization', 'x-mastra-client-type', 'x-mastra-dev-playground']` | Request headers |
694
+ | `exposeHeaders` | `string[]` | `['Content-Length', 'X-Requested-With']` | Browser headers |
695
+ | `credentials` | `boolean` | `false` | Credentials (cookies, authorization headers) |
696
+ | `maxAge` | `number` | `3600` | Preflight request cache duration in seconds |
697
697
 
698
698
  ```typescript
699
699
  import { Mastra } from '@mastra/core'
@@ -30,6 +30,8 @@ registerApiRoute("/items/:itemId", { ... })
30
30
 
31
31
  **middleware** (`MiddlewareHandler | MiddlewareHandler[]`): Route-specific middleware functions
32
32
 
33
+ **cors** (`CorsOptions`): Route-specific CORS configuration. Use this when one custom route needs a different cross-origin policy from \`server.cors\`.
34
+
33
35
  **openapi** (`DescribeRouteOptions`): OpenAPI metadata for Swagger UI documentation
34
36
 
35
37
  ## OpenAPI options
@@ -154,6 +156,23 @@ registerApiRoute('/protected', {
154
156
  })
155
157
  ```
156
158
 
159
+ ### Route with CORS
160
+
161
+ Use route-specific CORS when one custom route needs cross-origin credentials, but the rest of the server should keep the global CORS policy.
162
+
163
+ ```typescript
164
+ registerApiRoute('/customer-webhook', {
165
+ method: 'POST',
166
+ cors: {
167
+ origin: ['https://customer-saas.example'],
168
+ credentials: true,
169
+ },
170
+ handler: async c => {
171
+ return c.json({ ok: true })
172
+ },
173
+ })
174
+ ```
175
+
157
176
  ### Route with OpenAPI Documentation
158
177
 
159
178
  ```typescript
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @mastra/mcp-docs-server
2
2
 
3
+ ## 1.1.39-alpha.7
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`5ba7253`](https://github.com/mastra-ai/mastra/commit/5ba7253745c85e8df8012a76d954c640ffa336f7), [`f73980d`](https://github.com/mastra-ai/mastra/commit/f73980d651eb5f7f1ab20582de4615a1b6f10fce), [`9c88701`](https://github.com/mastra-ai/mastra/commit/9c8870195b41a38dc40b6ba2aa55eda04df8fa69), [`4e88dc6`](https://github.com/mastra-ai/mastra/commit/4e88dc6b89f154c0eae37221c8126be0c23c569f), [`19018f0`](https://github.com/mastra-ai/mastra/commit/19018f05722af74a5978781a7731a654b26f7f2a)]:
8
+ - @mastra/core@1.36.0-alpha.2
9
+
10
+ ## 1.1.39-alpha.5
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies [[`8cdb86c`](https://github.com/mastra-ai/mastra/commit/8cdb86ceed1137bc2768e147dce85a0692b9fb26), [`eda90c5`](https://github.com/mastra-ai/mastra/commit/eda90c5bfd7de11805ecc9f4552716c895fbaf78), [`afc004f`](https://github.com/mastra-ai/mastra/commit/afc004f5cc7e30697809e7021820b9f5881e6719), [`408be73`](https://github.com/mastra-ai/mastra/commit/408be73449dfab92b51eab8c6623b6c443debc25)]:
15
+ - @mastra/core@1.36.0-alpha.1
16
+
3
17
  ## 1.1.39-alpha.3
4
18
 
5
19
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/mcp-docs-server",
3
- "version": "1.1.39-alpha.4",
3
+ "version": "1.1.39-alpha.8",
4
4
  "description": "MCP server for accessing Mastra.ai documentation, changelogs, and news.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -29,7 +29,7 @@
29
29
  "jsdom": "^26.1.0",
30
30
  "local-pkg": "^1.1.2",
31
31
  "zod": "^4.3.6",
32
- "@mastra/core": "1.36.0-alpha.0",
32
+ "@mastra/core": "1.36.0-alpha.2",
33
33
  "@mastra/mcp": "^1.7.1-alpha.0"
34
34
  },
35
35
  "devDependencies": {
@@ -46,9 +46,9 @@
46
46
  "tsx": "^4.21.0",
47
47
  "typescript": "^6.0.3",
48
48
  "vitest": "4.1.5",
49
+ "@internal/types-builder": "0.0.71",
49
50
  "@internal/lint": "0.0.96",
50
- "@mastra/core": "1.36.0-alpha.0",
51
- "@internal/types-builder": "0.0.71"
51
+ "@mastra/core": "1.36.0-alpha.2"
52
52
  },
53
53
  "homepage": "https://mastra.ai",
54
54
  "repository": {