@scalar/agent 0.2.0 → 0.3.0
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.
- package/README.md +41 -90
- package/dist/constants.d.ts +6 -0
- package/dist/constants.js +11 -0
- package/dist/index.d.ts +63 -108
- package/dist/index.js +84 -206
- package/package.json +7 -7
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -7
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Scalar Agent SDK
|
|
2
2
|
|
|
3
|
-
Connect your AI agent to Scalar's OpenAPI MCP servers. Provides native integrations for the Vercel AI SDK, OpenAI Agents SDK, and Anthropic Claude SDK.
|
|
3
|
+
Connect your AI agent to Scalar's OpenAPI MCP servers. Provides native integrations for the Vercel AI SDK, OpenAI Agents SDK, and Anthropic Claude Agent SDK.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -22,20 +22,12 @@ bun i @scalar/agent
|
|
|
22
22
|
import { agentScalar } from '@scalar/agent'
|
|
23
23
|
|
|
24
24
|
const scalar = agentScalar({
|
|
25
|
-
|
|
25
|
+
token: 'your-personal-token',
|
|
26
26
|
})
|
|
27
27
|
|
|
28
|
-
const
|
|
29
|
-
apis: [{ namespace: 'scalar', slug: 'galaxy' }],
|
|
30
|
-
})
|
|
28
|
+
const installation = await scalar.installation('your-installation-id')
|
|
31
29
|
```
|
|
32
30
|
|
|
33
|
-
# Agent Key
|
|
34
|
-
|
|
35
|
-
An agent key allows access to private APIs as well as a default set of APIs if configured for a key. [Learn more about agent keys](https://scalar.com/products/agent/key).
|
|
36
|
-
|
|
37
|
-
Agent keys also identify your team for billing and analytics.
|
|
38
|
-
|
|
39
31
|
## Providers
|
|
40
32
|
|
|
41
33
|
### Vercel AI SDK
|
|
@@ -43,126 +35,85 @@ Agent keys also identify your team for billing and analytics.
|
|
|
43
35
|
Uses `@ai-sdk/mcp` natively. Returns a tool set ready for `generateText` / `streamText`.
|
|
44
36
|
|
|
45
37
|
```ts
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
38
|
+
import { agentScalar } from '@scalar/agent'
|
|
39
|
+
import { generateText, stepCountIs } from 'ai'
|
|
48
40
|
|
|
49
41
|
const scalar = agentScalar({
|
|
50
|
-
|
|
42
|
+
token: 'your-personal-token',
|
|
51
43
|
})
|
|
52
44
|
|
|
53
|
-
const
|
|
54
|
-
apis: [{ namespace: 'scalar', slug: 'galaxy' }],
|
|
55
|
-
})
|
|
45
|
+
const installation = await scalar.installation('your-installation-id')
|
|
56
46
|
|
|
57
|
-
const tools = await
|
|
47
|
+
const tools = await installation.createVercelAITools()
|
|
58
48
|
|
|
59
49
|
const { text } = await generateText({
|
|
60
|
-
model
|
|
50
|
+
model,
|
|
61
51
|
tools,
|
|
62
|
-
|
|
52
|
+
stopWhen: stepCountIs(5),
|
|
53
|
+
prompt: 'How do I create a planet?',
|
|
63
54
|
})
|
|
64
55
|
```
|
|
65
56
|
|
|
66
57
|
### OpenAI Agents SDK
|
|
67
58
|
|
|
68
|
-
Returns
|
|
59
|
+
Returns options for `MCPServerStreamableHttp` from `@openai/agents`. The agent runtime handles tool discovery and execution natively.
|
|
69
60
|
|
|
70
61
|
```ts
|
|
62
|
+
import { agentScalar } from '@scalar/agent'
|
|
71
63
|
import { Agent, MCPServerStreamableHttp, run } from '@openai/agents'
|
|
72
64
|
|
|
73
65
|
const scalar = agentScalar({
|
|
74
|
-
|
|
66
|
+
token: 'your-token',
|
|
75
67
|
})
|
|
76
68
|
|
|
77
|
-
const
|
|
78
|
-
apis: [{ namespace: 'scalar', slug: 'galaxy' }],
|
|
79
|
-
})
|
|
69
|
+
const installation = await scalar.installation('your-installation-id')
|
|
80
70
|
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
await Promise.all(servers.map((s) => s.connect()))
|
|
71
|
+
const server = new MCPServerStreamableHttp(installation.createOpenAIMCP())
|
|
72
|
+
await server.connect()
|
|
84
73
|
|
|
85
74
|
const agent = new Agent({
|
|
86
75
|
name: 'api-agent',
|
|
87
|
-
|
|
88
|
-
mcpServers: servers,
|
|
76
|
+
mcpServers: [server],
|
|
89
77
|
})
|
|
90
78
|
|
|
91
79
|
const result = await run(
|
|
92
80
|
agent,
|
|
93
|
-
'
|
|
81
|
+
'Which APIs are available that let me create a planet?',
|
|
94
82
|
)
|
|
95
83
|
|
|
96
|
-
await
|
|
84
|
+
await server.close()
|
|
97
85
|
```
|
|
98
86
|
|
|
99
|
-
### Anthropic Claude SDK
|
|
87
|
+
### Anthropic Claude Agent SDK
|
|
100
88
|
|
|
101
|
-
|
|
89
|
+
Returns an MCP server configuration for `@anthropic-ai/claude-agent-sdk`.
|
|
102
90
|
|
|
103
91
|
```ts
|
|
104
|
-
import
|
|
92
|
+
import { agentScalar } from '@scalar/agent'
|
|
93
|
+
import { query } from '@anthropic-ai/claude-agent-sdk'
|
|
105
94
|
|
|
106
95
|
const scalar = agentScalar({
|
|
107
|
-
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
const session = await scalar.session({
|
|
111
|
-
apis: [{ namespace: 'scalar', slug: 'galaxy' }],
|
|
96
|
+
token: 'your-token',
|
|
112
97
|
})
|
|
113
98
|
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
tools,
|
|
127
|
-
messages,
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
messages.push({ role: 'assistant', content: response.content })
|
|
131
|
-
|
|
132
|
-
if (response.stop_reason !== 'tool_use') break
|
|
133
|
-
|
|
134
|
-
const toolResults: Anthropic.ToolResultBlockParam[] = await Promise.all(
|
|
135
|
-
response.content
|
|
136
|
-
.filter(
|
|
137
|
-
(block): block is Anthropic.ToolUseBlock => block.type === 'tool_use',
|
|
138
|
-
)
|
|
139
|
-
.map(async (block) => ({
|
|
140
|
-
type: 'tool_result',
|
|
141
|
-
tool_use_id: block.id,
|
|
142
|
-
content: await executeTool(
|
|
143
|
-
block.name,
|
|
144
|
-
block.input as Record<string, unknown>,
|
|
145
|
-
),
|
|
146
|
-
})),
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
messages.push({ role: 'user', content: toolResults })
|
|
99
|
+
const installation = await scalar.installation('your-installation-id')
|
|
100
|
+
|
|
101
|
+
for await (const message of query({
|
|
102
|
+
prompt: 'Which APIs are available that let me create a planet?',
|
|
103
|
+
options: {
|
|
104
|
+
mcpServers: {
|
|
105
|
+
scalar: installation.createAnthropicMCP(),
|
|
106
|
+
},
|
|
107
|
+
allowedTools: ['mcp__scalar__*'],
|
|
108
|
+
},
|
|
109
|
+
})) {
|
|
110
|
+
if ('result' in message) console.log(message.result)
|
|
150
111
|
}
|
|
151
112
|
```
|
|
152
113
|
|
|
153
114
|
## Configuration
|
|
154
115
|
|
|
155
|
-
| Option
|
|
156
|
-
|
|
|
157
|
-
| `
|
|
158
|
-
| `baseUrl`
|
|
159
|
-
|
|
160
|
-
## How it works
|
|
161
|
-
|
|
162
|
-
Each Scalar API is exposed as an MCP (Model Context Protocol) server. The SDK connects to these servers and surfaces their tools to your AI framework of choice. Every API exposes three tools:
|
|
163
|
-
|
|
164
|
-
- **`get-openapi-specs-summary`** — lists the available endpoints
|
|
165
|
-
- **`get-mini-openapi-spec`** — fetches a trimmed OpenAPI spec for specific endpoints
|
|
166
|
-
- **`execute-request`** — executes an HTTP request against the API
|
|
167
|
-
|
|
168
|
-
Tools are namespaced by API to avoid collisions when connecting multiple APIs at once: `{namespace}{delimiter}{slug}__{toolName}`.
|
|
116
|
+
| Option | Type | Description |
|
|
117
|
+
| --------- | -------- | --------------------------------------------------------------------- |
|
|
118
|
+
| `token` | `string` | Your Scalar Personal Token used to authenticate requests to your MCP |
|
|
119
|
+
| `baseUrl` | `string` | Base URL of the Scalar MCP server. Defaults to the Scalar environment |
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
var Provider = /* @__PURE__ */ ((Provider2) => {
|
|
2
|
+
Provider2["VERCEL"] = "VERCEL";
|
|
3
|
+
Provider2["OPENAI"] = "OPENAI";
|
|
4
|
+
Provider2["ANTHROPIC"] = "ANTHROPIC";
|
|
5
|
+
return Provider2;
|
|
6
|
+
})(Provider || {});
|
|
7
|
+
const SDK_PROVIDER_HEADER_NAME = "X-Scalar-SDK-Provider";
|
|
8
|
+
export {
|
|
9
|
+
Provider,
|
|
10
|
+
SDK_PROVIDER_HEADER_NAME
|
|
11
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,158 +1,113 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import
|
|
1
|
+
import type { McpServerConfig } from '@anthropic-ai/claude-agent-sdk';
|
|
2
|
+
import type { ToolSet } from 'ai';
|
|
3
3
|
export interface AgentSDKConfig {
|
|
4
4
|
/** Base URL of the Scalar MCP server. Defaults to the Scalar staging environment. */
|
|
5
5
|
baseUrl?: string;
|
|
6
|
-
/**
|
|
7
|
-
|
|
6
|
+
/** Your Scalar Personal Token used to authenticate requests to your MCP. */
|
|
7
|
+
token: string;
|
|
8
8
|
}
|
|
9
|
-
type Api = {
|
|
10
|
-
namespace: string;
|
|
11
|
-
slug: string;
|
|
12
|
-
};
|
|
13
9
|
export type MCPServerOptions = {
|
|
14
10
|
url: string;
|
|
15
11
|
name: string;
|
|
16
12
|
fetch: (url: RequestInfo | URL, options?: RequestInit) => Promise<Response>;
|
|
17
13
|
};
|
|
18
|
-
export declare const EXECUTE_REQUEST_TOOL_NAME = "execute-request";
|
|
19
|
-
export declare const executeRequestToolInputSchema: z.ZodObject<{
|
|
20
|
-
method: z.ZodString;
|
|
21
|
-
path: z.ZodString;
|
|
22
|
-
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
23
|
-
body: z.ZodOptional<z.ZodString>;
|
|
24
|
-
}, z.core.$strip>;
|
|
25
|
-
export declare const mcpToolSchemas: {
|
|
26
|
-
"execute-request": {
|
|
27
|
-
inputSchema: z.ZodObject<{
|
|
28
|
-
method: z.ZodString;
|
|
29
|
-
path: z.ZodString;
|
|
30
|
-
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
31
|
-
body: z.ZodOptional<z.ZodString>;
|
|
32
|
-
}, z.core.$strip>;
|
|
33
|
-
};
|
|
34
|
-
"get-mini-openapi-spec": {
|
|
35
|
-
inputSchema: z.ZodObject<{
|
|
36
|
-
question: z.ZodString;
|
|
37
|
-
}, z.core.$strip>;
|
|
38
|
-
};
|
|
39
|
-
"get-openapi-specs-summary": {
|
|
40
|
-
inputSchema: z.ZodObject<{}, z.core.$strip>;
|
|
41
|
-
};
|
|
42
|
-
};
|
|
43
14
|
/**
|
|
44
15
|
* Creates a Scalar agent client configured to connect to Scalar's MCP servers.
|
|
45
16
|
*
|
|
46
17
|
* @example
|
|
47
18
|
* ```ts
|
|
48
|
-
* const scalar = agentScalar({
|
|
19
|
+
* const scalar = agentScalar({ token: 'your-personal-token' })
|
|
20
|
+
* const installation = await scalar.installation('your-installation-id')
|
|
49
21
|
* ```
|
|
50
22
|
*/
|
|
51
|
-
export declare const agentScalar: (config
|
|
52
|
-
|
|
53
|
-
apis: Api[];
|
|
54
|
-
}) => Promise<{
|
|
23
|
+
export declare const agentScalar: (config: AgentSDKConfig) => {
|
|
24
|
+
installation: (installationId: string) => Promise<{
|
|
55
25
|
/**
|
|
56
26
|
* Returns tools in Vercel AI SDK format.
|
|
57
27
|
* Uses `@ai-sdk/mcp` natively.
|
|
58
28
|
*
|
|
59
29
|
* @example
|
|
60
30
|
* ```ts
|
|
61
|
-
* import { agentScalar } from
|
|
62
|
-
* import { generateText } from
|
|
63
|
-
* import { openai } from '@ai-sdk/openai'
|
|
31
|
+
* import { agentScalar } from "@scalar/agent";
|
|
32
|
+
* import { generateText, stepCountIs } from "ai";
|
|
64
33
|
*
|
|
65
|
-
* const scalar = agentScalar({
|
|
66
|
-
*
|
|
34
|
+
* const scalar = agentScalar({
|
|
35
|
+
* token: "your-personal-token",
|
|
36
|
+
* });
|
|
37
|
+
* const installation = await scalar.installation("0c1ea059-58ad-41ec-bcf7-331fefa0f61c");
|
|
67
38
|
*
|
|
68
|
-
* const tools = await
|
|
39
|
+
* const tools = await installation.createVercelAITools();
|
|
69
40
|
*
|
|
70
41
|
* const { text } = await generateText({
|
|
71
|
-
* model
|
|
42
|
+
* model,
|
|
72
43
|
* tools,
|
|
73
|
-
*
|
|
74
|
-
*
|
|
44
|
+
* stopWhen: stepCountIs(5),
|
|
45
|
+
* prompt: "How do I create a planet?",
|
|
46
|
+
* });
|
|
75
47
|
* ```
|
|
76
48
|
*/
|
|
77
|
-
createVercelAITools: () => Promise<
|
|
49
|
+
createVercelAITools: () => Promise<ToolSet>;
|
|
78
50
|
/**
|
|
79
|
-
* Returns options for creating `MCPServerStreamableHttp`
|
|
51
|
+
* Returns options for creating an `MCPServerStreamableHttp` instance via `@openai/agents`.
|
|
80
52
|
* The agent handles tool discovery and execution natively.
|
|
81
53
|
*
|
|
82
54
|
* @example
|
|
83
55
|
* ```ts
|
|
84
|
-
* import { agentScalar } from
|
|
85
|
-
* import { Agent, MCPServerStreamableHttp, run } from
|
|
56
|
+
* import { agentScalar } from "@scalar/agent";
|
|
57
|
+
* import { Agent, MCPServerStreamableHttp, run } from "@openai/agents";
|
|
86
58
|
*
|
|
87
|
-
* const scalar = agentScalar({
|
|
88
|
-
*
|
|
59
|
+
* const scalar = agentScalar({
|
|
60
|
+
* token: "your-token",
|
|
61
|
+
* });
|
|
62
|
+
* const installation = await scalar.installation("your-installation-id");
|
|
89
63
|
*
|
|
90
|
-
* const
|
|
91
|
-
* await
|
|
64
|
+
* const server = new MCPServerStreamableHttp(installation.createOpenAIMCP());
|
|
65
|
+
* await server.connect();
|
|
92
66
|
*
|
|
93
67
|
* const agent = new Agent({
|
|
94
|
-
* name:
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
68
|
+
* name: "api-agent",
|
|
69
|
+
* mcpServers: [server],
|
|
70
|
+
* });
|
|
71
|
+
*
|
|
72
|
+
* const result = await run(
|
|
73
|
+
* agent,
|
|
74
|
+
* "Which APIs are available that let me create a planet?",
|
|
75
|
+
* );
|
|
98
76
|
*
|
|
99
|
-
*
|
|
100
|
-
* await Promise.all(servers.map((s) => s.close()))
|
|
77
|
+
* await server.close();
|
|
101
78
|
* ```
|
|
102
79
|
*/
|
|
103
|
-
createOpenAIMCP: () =>
|
|
80
|
+
createOpenAIMCP: () => {
|
|
81
|
+
url: string;
|
|
82
|
+
name: string;
|
|
83
|
+
fetch: (url: RequestInfo | URL, options?: RequestInit) => Promise<Response>;
|
|
84
|
+
};
|
|
104
85
|
/**
|
|
105
|
-
* Returns
|
|
106
|
-
* Uses `@modelcontextprotocol/sdk` Client directly — `listTools()` already returns
|
|
107
|
-
* JSON Schema so no conversion needed. Tool calls are routed back via `callTool()`.
|
|
86
|
+
* Returns an MCP server configuration for `@anthropic-ai/claude-agent-sdk`.
|
|
108
87
|
*
|
|
109
88
|
* @example
|
|
110
89
|
* ```ts
|
|
111
|
-
* import { agentScalar } from
|
|
112
|
-
* import
|
|
113
|
-
*
|
|
114
|
-
* const scalar = agentScalar({
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* const
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
* tools,
|
|
130
|
-
* messages,
|
|
131
|
-
* })
|
|
132
|
-
*
|
|
133
|
-
* messages.push({ role: 'assistant', content: response.content })
|
|
134
|
-
*
|
|
135
|
-
* if (response.stop_reason !== 'tool_use') break
|
|
136
|
-
*
|
|
137
|
-
* const toolResults = await Promise.all(
|
|
138
|
-
* response.content
|
|
139
|
-
* .filter((b): b is Anthropic.ToolUseBlock => b.type === 'tool_use')
|
|
140
|
-
* .map(async (b) => ({
|
|
141
|
-
* type: 'tool_result' as const,
|
|
142
|
-
* tool_use_id: b.id,
|
|
143
|
-
* content: await executeTool(b.name, b.input as Record<string, unknown>),
|
|
144
|
-
* })),
|
|
145
|
-
* )
|
|
146
|
-
*
|
|
147
|
-
* messages.push({ role: 'user', content: toolResults })
|
|
90
|
+
* import { agentScalar } from "@scalar/agent";
|
|
91
|
+
* import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
92
|
+
*
|
|
93
|
+
* const scalar = agentScalar({
|
|
94
|
+
* token: "your-token",
|
|
95
|
+
* });
|
|
96
|
+
* const installation = await scalar.installation("your-installation-id");
|
|
97
|
+
*
|
|
98
|
+
* for await (const message of query({
|
|
99
|
+
* prompt: "Which APIs are available that let me create a planet?",
|
|
100
|
+
* options: {
|
|
101
|
+
* mcpServers: {
|
|
102
|
+
* scalar: installation.createAnthropicMCP(),
|
|
103
|
+
* },
|
|
104
|
+
* allowedTools: ["mcp__scalar__*"],
|
|
105
|
+
* },
|
|
106
|
+
* })) {
|
|
107
|
+
* if ("result" in message) console.log(message.result);
|
|
148
108
|
* }
|
|
149
109
|
* ```
|
|
150
110
|
*/
|
|
151
|
-
|
|
152
|
-
tools: Anthropic.Tool[];
|
|
153
|
-
executeTool: (toolName: string, input: Record<string, unknown>) => Promise<string>;
|
|
154
|
-
}>;
|
|
111
|
+
createAnthropicMCP: () => McpServerConfig;
|
|
155
112
|
}>;
|
|
156
113
|
};
|
|
157
|
-
export {};
|
|
158
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,78 +1,22 @@
|
|
|
1
1
|
import { createMCPClient } from "@ai-sdk/mcp";
|
|
2
|
-
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
3
2
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
method: z.string(),
|
|
15
|
-
path: z.string(),
|
|
16
|
-
headers: z.record(z.string(), z.string()).optional(),
|
|
17
|
-
body: z.string().optional()
|
|
18
|
-
});
|
|
19
|
-
const mcpToolSchemas = {
|
|
20
|
-
[EXECUTE_REQUEST_TOOL_NAME]: { inputSchema: executeRequestToolInputSchema },
|
|
21
|
-
[GET_MINI_OPENAPI_SPEC_TOOL_NAME]: {
|
|
22
|
-
inputSchema: getMiniOpenAPIDocToolInputSchema
|
|
23
|
-
},
|
|
24
|
-
[GET_OPENAPI_SPECS_SUMMARY_TOOL_NAME]: { inputSchema: z.object({}) }
|
|
25
|
-
};
|
|
26
|
-
function safeParseJson(value) {
|
|
27
|
-
try {
|
|
28
|
-
return { success: true, data: JSON.parse(value) };
|
|
29
|
-
} catch {
|
|
30
|
-
return { success: false };
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
async function resolveActiveServerUrl(api) {
|
|
34
|
-
const store = createWorkspaceStore();
|
|
35
|
-
const key = `${api.namespace}/${api.slug}`;
|
|
36
|
-
await store.addDocument({
|
|
37
|
-
name: key,
|
|
38
|
-
url: `https://registry.scalar.com/@${api.namespace}/apis/${api.slug}`
|
|
39
|
-
});
|
|
40
|
-
return store.workspace.documents[key]?.servers?.[0]?.url ?? "";
|
|
41
|
-
}
|
|
42
|
-
function buildMCPUrl(api, baseUrl, serverUrl) {
|
|
43
|
-
return new URL(
|
|
44
|
-
`/vector/mcp/${api.namespace}/${api.slug}?activeServerUrl=${encodeURIComponent(serverUrl)}`,
|
|
45
|
-
baseUrl
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
function buildFetch(agentKey) {
|
|
49
|
-
return (url, options) => {
|
|
50
|
-
const parsed = safeParseJson(options?.body);
|
|
51
|
-
if (!parsed.success) return fetch(url, options);
|
|
52
|
-
if (parsed.data.params) {
|
|
53
|
-
parsed.data.params._meta = { securitySchemes: [] };
|
|
3
|
+
import { Provider, SDK_PROVIDER_HEADER_NAME } from "./constants";
|
|
4
|
+
function buildFetch(token, provider) {
|
|
5
|
+
return async (url, options) => await fetch(url, {
|
|
6
|
+
...options,
|
|
7
|
+
headers: {
|
|
8
|
+
"content-type": "application/json",
|
|
9
|
+
accept: "application/json, text/event-stream",
|
|
10
|
+
[SDK_PROVIDER_HEADER_NAME]: provider,
|
|
11
|
+
...options?.headers,
|
|
12
|
+
...token && { Authorization: token }
|
|
54
13
|
}
|
|
55
|
-
|
|
56
|
-
...options,
|
|
57
|
-
headers: {
|
|
58
|
-
"Content-Type": "application/json",
|
|
59
|
-
Accept: "application/json, text/event-stream",
|
|
60
|
-
...options?.headers,
|
|
61
|
-
...agentKey && { "x-scalar-agent-key": agentKey }
|
|
62
|
-
},
|
|
63
|
-
body: JSON.stringify(parsed.data)
|
|
64
|
-
});
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
function namespaceTool(api, toolName) {
|
|
68
|
-
return `${api.namespace}${TOOL_NAMESPACE_SLUG_DELIMITER}${api.slug}__${toolName}`;
|
|
14
|
+
});
|
|
69
15
|
}
|
|
70
|
-
const agentScalar = (config
|
|
16
|
+
const agentScalar = (config) => {
|
|
71
17
|
const baseUrl = config.baseUrl ?? "https://services.scalar.com";
|
|
72
|
-
const
|
|
73
|
-
const
|
|
74
|
-
const serverUrls = await Promise.all(apis.map(resolveActiveServerUrl));
|
|
75
|
-
const mcpUrl = (api) => buildMCPUrl(api, baseUrl, serverUrls[apis.indexOf(api)]);
|
|
18
|
+
const installation = async (installationId) => {
|
|
19
|
+
const url = new URL(`/vector/mcp/${installationId}`, baseUrl);
|
|
76
20
|
return {
|
|
77
21
|
/**
|
|
78
22
|
* Returns tools in Vercel AI SDK format.
|
|
@@ -80,175 +24,109 @@ const agentScalar = (config = {}) => {
|
|
|
80
24
|
*
|
|
81
25
|
* @example
|
|
82
26
|
* ```ts
|
|
83
|
-
* import { agentScalar } from
|
|
84
|
-
* import { generateText } from
|
|
85
|
-
* import { openai } from '@ai-sdk/openai'
|
|
27
|
+
* import { agentScalar } from "@scalar/agent";
|
|
28
|
+
* import { generateText, stepCountIs } from "ai";
|
|
86
29
|
*
|
|
87
|
-
* const scalar = agentScalar({
|
|
88
|
-
*
|
|
30
|
+
* const scalar = agentScalar({
|
|
31
|
+
* token: "your-personal-token",
|
|
32
|
+
* });
|
|
33
|
+
* const installation = await scalar.installation("0c1ea059-58ad-41ec-bcf7-331fefa0f61c");
|
|
89
34
|
*
|
|
90
|
-
* const tools = await
|
|
35
|
+
* const tools = await installation.createVercelAITools();
|
|
91
36
|
*
|
|
92
37
|
* const { text } = await generateText({
|
|
93
|
-
* model
|
|
38
|
+
* model,
|
|
94
39
|
* tools,
|
|
95
|
-
*
|
|
96
|
-
*
|
|
40
|
+
* stopWhen: stepCountIs(5),
|
|
41
|
+
* prompt: "How do I create a planet?",
|
|
42
|
+
* });
|
|
97
43
|
* ```
|
|
98
44
|
*/
|
|
99
45
|
createVercelAITools: async () => {
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
fetch: mcpFetch
|
|
105
|
-
})
|
|
106
|
-
}),
|
|
107
|
-
api
|
|
108
|
-
}))
|
|
109
|
-
);
|
|
110
|
-
const toolSets = await Promise.all(
|
|
111
|
-
clients.map(async ({ client, api }) => {
|
|
112
|
-
const tools = await client.tools({ schemas: mcpToolSchemas });
|
|
113
|
-
return Object.fromEntries(
|
|
114
|
-
Object.entries(tools).map(([toolName, tool]) => [
|
|
115
|
-
namespaceTool(api, toolName),
|
|
116
|
-
tool
|
|
117
|
-
])
|
|
118
|
-
);
|
|
46
|
+
const mcpFetch = buildFetch(config.token, Provider.VERCEL);
|
|
47
|
+
const client = await createMCPClient({
|
|
48
|
+
transport: new StreamableHTTPClientTransport(url, {
|
|
49
|
+
fetch: mcpFetch
|
|
119
50
|
})
|
|
120
|
-
);
|
|
121
|
-
return
|
|
51
|
+
});
|
|
52
|
+
return client.tools();
|
|
122
53
|
},
|
|
123
54
|
/**
|
|
124
|
-
* Returns options for creating `MCPServerStreamableHttp`
|
|
55
|
+
* Returns options for creating an `MCPServerStreamableHttp` instance via `@openai/agents`.
|
|
125
56
|
* The agent handles tool discovery and execution natively.
|
|
126
57
|
*
|
|
127
58
|
* @example
|
|
128
59
|
* ```ts
|
|
129
|
-
* import { agentScalar } from
|
|
130
|
-
* import { Agent, MCPServerStreamableHttp, run } from
|
|
60
|
+
* import { agentScalar } from "@scalar/agent";
|
|
61
|
+
* import { Agent, MCPServerStreamableHttp, run } from "@openai/agents";
|
|
131
62
|
*
|
|
132
|
-
* const scalar = agentScalar({
|
|
133
|
-
*
|
|
63
|
+
* const scalar = agentScalar({
|
|
64
|
+
* token: "your-token",
|
|
65
|
+
* });
|
|
66
|
+
* const installation = await scalar.installation("your-installation-id");
|
|
134
67
|
*
|
|
135
|
-
* const
|
|
136
|
-
* await
|
|
68
|
+
* const server = new MCPServerStreamableHttp(installation.createOpenAIMCP());
|
|
69
|
+
* await server.connect();
|
|
137
70
|
*
|
|
138
71
|
* const agent = new Agent({
|
|
139
|
-
* name:
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* })
|
|
72
|
+
* name: "api-agent",
|
|
73
|
+
* mcpServers: [server],
|
|
74
|
+
* });
|
|
143
75
|
*
|
|
144
|
-
* const result = await run(
|
|
145
|
-
*
|
|
76
|
+
* const result = await run(
|
|
77
|
+
* agent,
|
|
78
|
+
* "Which APIs are available that let me create a planet?",
|
|
79
|
+
* );
|
|
80
|
+
*
|
|
81
|
+
* await server.close();
|
|
146
82
|
* ```
|
|
147
83
|
*/
|
|
148
|
-
createOpenAIMCP:
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
84
|
+
createOpenAIMCP: () => {
|
|
85
|
+
const mcpFetch = buildFetch(config.token, Provider.OPENAI);
|
|
86
|
+
return {
|
|
87
|
+
url: url.toString(),
|
|
88
|
+
name: installationId,
|
|
152
89
|
fetch: mcpFetch
|
|
153
|
-
}
|
|
154
|
-
|
|
90
|
+
};
|
|
91
|
+
},
|
|
155
92
|
/**
|
|
156
|
-
* Returns
|
|
157
|
-
* Uses `@modelcontextprotocol/sdk` Client directly — `listTools()` already returns
|
|
158
|
-
* JSON Schema so no conversion needed. Tool calls are routed back via `callTool()`.
|
|
93
|
+
* Returns an MCP server configuration for `@anthropic-ai/claude-agent-sdk`.
|
|
159
94
|
*
|
|
160
95
|
* @example
|
|
161
96
|
* ```ts
|
|
162
|
-
* import { agentScalar } from
|
|
163
|
-
* import
|
|
164
|
-
*
|
|
165
|
-
* const scalar = agentScalar({
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* const
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
* tools,
|
|
181
|
-
* messages,
|
|
182
|
-
* })
|
|
183
|
-
*
|
|
184
|
-
* messages.push({ role: 'assistant', content: response.content })
|
|
185
|
-
*
|
|
186
|
-
* if (response.stop_reason !== 'tool_use') break
|
|
187
|
-
*
|
|
188
|
-
* const toolResults = await Promise.all(
|
|
189
|
-
* response.content
|
|
190
|
-
* .filter((b): b is Anthropic.ToolUseBlock => b.type === 'tool_use')
|
|
191
|
-
* .map(async (b) => ({
|
|
192
|
-
* type: 'tool_result' as const,
|
|
193
|
-
* tool_use_id: b.id,
|
|
194
|
-
* content: await executeTool(b.name, b.input as Record<string, unknown>),
|
|
195
|
-
* })),
|
|
196
|
-
* )
|
|
197
|
-
*
|
|
198
|
-
* messages.push({ role: 'user', content: toolResults })
|
|
97
|
+
* import { agentScalar } from "@scalar/agent";
|
|
98
|
+
* import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
99
|
+
*
|
|
100
|
+
* const scalar = agentScalar({
|
|
101
|
+
* token: "your-token",
|
|
102
|
+
* });
|
|
103
|
+
* const installation = await scalar.installation("your-installation-id");
|
|
104
|
+
*
|
|
105
|
+
* for await (const message of query({
|
|
106
|
+
* prompt: "Which APIs are available that let me create a planet?",
|
|
107
|
+
* options: {
|
|
108
|
+
* mcpServers: {
|
|
109
|
+
* scalar: installation.createAnthropicMCP(),
|
|
110
|
+
* },
|
|
111
|
+
* allowedTools: ["mcp__scalar__*"],
|
|
112
|
+
* },
|
|
113
|
+
* })) {
|
|
114
|
+
* if ("result" in message) console.log(message.result);
|
|
199
115
|
* }
|
|
200
116
|
* ```
|
|
201
117
|
*/
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
});
|
|
209
|
-
await client.connect(
|
|
210
|
-
new StreamableHTTPClientTransport(mcpUrl(api), {
|
|
211
|
-
fetch: mcpFetch
|
|
212
|
-
})
|
|
213
|
-
);
|
|
214
|
-
return { client, api };
|
|
215
|
-
})
|
|
216
|
-
);
|
|
217
|
-
const toolRoutes = /* @__PURE__ */ new Map();
|
|
218
|
-
const anthropicTools = [];
|
|
219
|
-
for (const { client, api } of clients) {
|
|
220
|
-
const { tools } = await client.listTools();
|
|
221
|
-
for (const tool of tools) {
|
|
222
|
-
const name = namespaceTool(api, tool.name);
|
|
223
|
-
anthropicTools.push({
|
|
224
|
-
name,
|
|
225
|
-
description: tool.description,
|
|
226
|
-
input_schema: tool.inputSchema
|
|
227
|
-
});
|
|
228
|
-
toolRoutes.set(name, { client, originalName: tool.name });
|
|
229
|
-
}
|
|
118
|
+
createAnthropicMCP: () => ({
|
|
119
|
+
type: "http",
|
|
120
|
+
url: url.toString(),
|
|
121
|
+
headers: {
|
|
122
|
+
Authorization: config.token,
|
|
123
|
+
[SDK_PROVIDER_HEADER_NAME]: Provider.ANTHROPIC
|
|
230
124
|
}
|
|
231
|
-
|
|
232
|
-
const route = toolRoutes.get(toolName);
|
|
233
|
-
if (!route) {
|
|
234
|
-
throw new Error(`Tool "${toolName}" not found`);
|
|
235
|
-
}
|
|
236
|
-
const result = await route.client.callTool({
|
|
237
|
-
name: route.originalName,
|
|
238
|
-
arguments: input
|
|
239
|
-
});
|
|
240
|
-
const content = result.content;
|
|
241
|
-
return content.filter((c) => c.type === "text").map((c) => c.text ?? "").join("\n");
|
|
242
|
-
};
|
|
243
|
-
return { tools: anthropicTools, executeTool };
|
|
244
|
-
}
|
|
125
|
+
})
|
|
245
126
|
};
|
|
246
127
|
};
|
|
247
|
-
return {
|
|
128
|
+
return { installation };
|
|
248
129
|
};
|
|
249
130
|
export {
|
|
250
|
-
|
|
251
|
-
agentScalar,
|
|
252
|
-
executeRequestToolInputSchema,
|
|
253
|
-
mcpToolSchemas
|
|
131
|
+
agentScalar
|
|
254
132
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scalar/agent",
|
|
3
3
|
"description": "Scalar Agent SDK",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"author": "Scalar (https://github.com/scalar)",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"private": false,
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
"import": "./dist/index.js",
|
|
18
18
|
"types": "./dist/index.d.ts",
|
|
19
19
|
"default": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./constants": {
|
|
22
|
+
"import": "./dist/constants.js",
|
|
23
|
+
"types": "./dist/constants.d.ts",
|
|
24
|
+
"default": "./dist/constants.js"
|
|
20
25
|
}
|
|
21
26
|
},
|
|
22
27
|
"dependencies": {
|
|
23
|
-
"@
|
|
24
|
-
"@anthropic-ai/sdk": "^0.78.0",
|
|
25
|
-
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
26
|
-
"@scalar/workspace-store": "^0.34.2",
|
|
27
|
-
"@scalar/agent-chat": "^0.5.16",
|
|
28
|
-
"zod": "^4.3.6"
|
|
28
|
+
"@modelcontextprotocol/sdk": "^1.27.1"
|
|
29
29
|
}
|
|
30
30
|
}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAA;AAG9C,OAAO,CAAC,MAAM,KAAK,CAAA;AAUnB,MAAM,WAAW,cAAc;IAC7B,qFAAqF;IACrF,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,KAAK,GAAG,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAE9C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,CAAC,GAAG,EAAE,WAAW,GAAG,GAAG,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;CAC5E,CAAA;AAED,eAAO,MAAM,yBAAyB,oBAAoB,CAAA;AAE1D,eAAO,MAAM,6BAA6B;;;;;iBAKxC,CAAA;AAEF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;CAM1B,CAAA;AA2DD;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAI,SAAQ,cAAmB;wBAuBpB;QAAE,IAAI,EAAE,GAAG,EAAE,CAAA;KAAE;QAS5C;;;;;;;;;;;;;;;;;;;;;WAqBG;;QA6BH;;;;;;;;;;;;;;;;;;;;;;;;WAwBG;+BACwB,OAAO,CAAC,gBAAgB,EAAE,CAAC;QAStD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA8CG;oCAC6B,OAAO,CAAC;YACtC,KAAK,EAAE,SAAS,CAAC,IAAI,EAAE,CAAA;YACvB,WAAW,EAAE,CACX,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC3B,OAAO,CAAC,MAAM,CAAC,CAAA;SACrB,CAAC;;CAyEP,CAAA"}
|
package/dist/index.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { createMCPClient, type MCPClient } from '@ai-sdk/mcp'\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'\nimport { createNeverpanic } from 'neverpanic'\nimport z from 'zod'\n\nimport {\n GET_MINI_OPENAPI_SPEC_TOOL_NAME,\n GET_OPENAPI_SPECS_SUMMARY_TOOL_NAME,\n getMiniOpenAPIDocToolInputSchema,\n TOOL_NAMESPACE_SLUG_DELIMITER,\n} from '@scalar/agent-chat/entities'\n\nexport type AgentError<D> = {\n code: string\n detail: D\n}\n\nexport const n = createNeverpanic<unknown, AgentError<unknown>>()\n\nexport interface AgentSDKConfig {\n baseUrl?: string\n agentKey?: string\n}\n\ntype Api = {\n namespace: string\n slug: string\n}\n\nexport const EXECUTE_REQUEST_TOOL_NAME = 'execute-request'\n\nexport const executeRequestToolInputSchema = z.object({\n method: z.string(),\n path: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n body: z.string().optional(),\n})\n\nexport const mcpToolSchemas = {\n [EXECUTE_REQUEST_TOOL_NAME]: { inputSchema: executeRequestToolInputSchema },\n [GET_MINI_OPENAPI_SPEC_TOOL_NAME]: {\n inputSchema: getMiniOpenAPIDocToolInputSchema,\n },\n [GET_OPENAPI_SPECS_SUMMARY_TOOL_NAME]: {\n inputSchema: z.object(),\n },\n}\n\nexport const safeParseJson = n.safeFn(\n (value: any) => ({ success: true, data: JSON.parse(value) }),\n (originalError) =>\n n.err({ code: 'FAILED_TO_PARSE_JSON', detail: originalError }),\n)\n\nconst createClients = n.safeFn(\n async ({\n baseUrl,\n agentKey,\n apis,\n }: {\n baseUrl: string\n agentKey?: string\n apis: Api[]\n }) => {\n const clients = await Promise.all(\n apis.map(async (api) => {\n const mcpUrl = new URL(\n `/vector/mcp/${api.namespace}/${api.slug}?activeServerUrl=${encodeURIComponent('https://galaxy.scalar.com')}`,\n baseUrl,\n )\n\n const mcpClient = await createMCPClient({\n transport: new StreamableHTTPClientTransport(mcpUrl, {\n fetch(url, options) {\n const parsedJsonBodyResult = safeParseJson(options?.body)\n if (!parsedJsonBodyResult.success) return fetch(url, options)\n\n if (parsedJsonBodyResult.data.params)\n parsedJsonBodyResult.data.params._meta = {\n securitySchemes: [],\n }\n\n return fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json, text/event-stream',\n ...options?.headers,\n ...(agentKey && {\n 'x-scalar-agent-key': agentKey,\n }),\n },\n body: JSON.stringify(parsedJsonBodyResult.data),\n })\n },\n }),\n })\n\n return {\n mcpClient,\n api,\n }\n }),\n )\n\n return {\n success: true,\n data: clients,\n }\n },\n (originalError) =>\n n.err({ code: 'FAILED_TO_CREATE_MCP_CLIENTS', detail: originalError }),\n)\n\n/**\n * Create AI SDK tools from an MCP clients returned tools.\n * Applies prefix for tool name uniqueness.\n */\nexport const createTools = n.safeFn(\n async (mcpClients: { mcpClient: MCPClient; api: Api }[]) => {\n const toolSets = await Promise.all(\n mcpClients.map(async ({ mcpClient, api }) => {\n const tools = await mcpClient.tools({\n schemas: mcpToolSchemas,\n })\n\n return Object.fromEntries(\n Object.entries(tools).map(([toolName, tool]) => [\n `${api.namespace}${TOOL_NAMESPACE_SLUG_DELIMITER}${api.slug}__${toolName}`,\n tool,\n ]),\n ) as any\n }),\n )\n\n function merge<T>(sources: T[]): T {\n return Object.assign({}, ...sources)\n }\n\n return {\n success: true,\n data: merge(toolSets),\n }\n },\n (originalError) =>\n n.err({ code: 'FAILED_TO_CREATE_MCP_TOOLS', detail: originalError }),\n)\n\nexport const agentScalar = (config: AgentSDKConfig = {}) => {\n const baseUrl = config.baseUrl ?? 'https://services.staging.scalar.com'\n\n const session = async ({ apis }: { apis: Api[] }) => {\n const createClientsResult = await createClients({\n agentKey: config.agentKey,\n baseUrl,\n apis,\n })\n\n if (!createClientsResult.success) {\n throw createClientsResult.error\n }\n\n return {\n tools: async () => {\n const toolsResult = await createTools(createClientsResult.data)\n\n if (!toolsResult.success) {\n throw Error(toolsResult.error.code)\n }\n\n return toolsResult.data\n },\n }\n }\n\n return {\n session,\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|