integrate-sdk 0.6.5 → 0.6.7
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/dist/adapters/auto-routes.js +268 -0
- package/dist/adapters/base-handler.js +144 -0
- package/dist/adapters/nextjs-oauth-redirect.js +152 -0
- package/dist/adapters/nextjs.js +405 -0
- package/dist/adapters/node.js +280 -0
- package/dist/adapters/solid-start.js +27 -0
- package/dist/adapters/svelte-kit.js +34 -0
- package/dist/adapters/tanstack-start.js +26 -0
- package/dist/index.js +203 -96
- package/dist/src/adapters/node.d.ts +48 -0
- package/dist/src/adapters/node.d.ts.map +1 -0
- package/dist/src/adapters/solid-start.d.ts +54 -0
- package/dist/src/adapters/solid-start.d.ts.map +1 -0
- package/dist/src/adapters/svelte-kit.d.ts +82 -0
- package/dist/src/adapters/svelte-kit.d.ts.map +1 -0
- package/dist/src/adapters/tanstack-start.d.ts +28 -144
- package/dist/src/adapters/tanstack-start.d.ts.map +1 -1
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/integrations/anthropic.d.ts +208 -0
- package/dist/src/integrations/anthropic.d.ts.map +1 -0
- package/dist/src/integrations/cloudflare.d.ts +158 -0
- package/dist/src/integrations/cloudflare.d.ts.map +1 -0
- package/dist/src/integrations/google.d.ts +159 -0
- package/dist/src/integrations/google.d.ts.map +1 -0
- package/dist/src/integrations/index.d.ts +79 -0
- package/dist/src/integrations/index.d.ts.map +1 -0
- package/dist/src/integrations/langchain.d.ts +139 -0
- package/dist/src/integrations/langchain.d.ts.map +1 -0
- package/dist/src/integrations/llamaindex.d.ts +125 -0
- package/dist/src/integrations/llamaindex.d.ts.map +1 -0
- package/dist/src/integrations/mastra.d.ts +138 -0
- package/dist/src/integrations/mastra.d.ts.map +1 -0
- package/dist/src/integrations/openai-agents.d.ts +117 -0
- package/dist/src/integrations/openai-agents.d.ts.map +1 -0
- package/dist/src/integrations/openai.d.ts +158 -0
- package/dist/src/integrations/openai.d.ts.map +1 -0
- package/dist/src/integrations/utils.d.ts +56 -0
- package/dist/src/integrations/utils.d.ts.map +1 -0
- package/dist/src/integrations/vercel-ai.d.ts +2 -16
- package/dist/src/integrations/vercel-ai.d.ts.map +1 -1
- package/integrations.ts +9 -0
- package/package.json +104 -9
|
@@ -2,168 +2,52 @@
|
|
|
2
2
|
* TanStack Start OAuth Route Adapter
|
|
3
3
|
* Provides OAuth route handlers for TanStack Start
|
|
4
4
|
*/
|
|
5
|
-
import { type OAuthHandlerConfig } from './base-handler.js';
|
|
6
5
|
/**
|
|
7
6
|
* Create TanStack Start OAuth route handlers
|
|
8
7
|
*
|
|
9
8
|
* Use this to create secure OAuth API routes in your TanStack Start application
|
|
10
9
|
* that handle authorization with server-side secrets.
|
|
11
10
|
*
|
|
12
|
-
* @param
|
|
13
|
-
* @returns Object with
|
|
11
|
+
* @param handler - Handler function from createMCPServer
|
|
12
|
+
* @returns Object with GET and POST handlers for catch-all routes
|
|
14
13
|
*
|
|
15
14
|
* @example
|
|
16
15
|
* ```typescript
|
|
17
|
-
* //
|
|
18
|
-
* import {
|
|
19
|
-
* import { json } from '@tanstack/start';
|
|
16
|
+
* // lib/integrate-server.ts
|
|
17
|
+
* import { createMCPServer, githubPlugin } from 'integrate-sdk/server';
|
|
20
18
|
*
|
|
21
|
-
* const handler =
|
|
22
|
-
*
|
|
23
|
-
*
|
|
19
|
+
* export const { client: serverClient, handler } = createMCPServer({
|
|
20
|
+
* plugins: [
|
|
21
|
+
* githubPlugin({
|
|
24
22
|
* clientId: process.env.GITHUB_CLIENT_ID!,
|
|
25
23
|
* clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
26
|
-
* },
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
24
|
+
* }),
|
|
25
|
+
* ],
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* // app/routes/api/auth/$.ts
|
|
29
|
+
* import { toTanStackStartHandler } from 'integrate-sdk/adapters/tanstack-start';
|
|
30
|
+
* import { handler } from '@/lib/integrate-server';
|
|
31
|
+
*
|
|
32
|
+
* const handlers = toTanStackStartHandler(handler);
|
|
33
|
+
*
|
|
34
|
+
* export const Route = createFileRoute('/api/auth/$')({
|
|
35
|
+
* server: {
|
|
36
|
+
* handlers: {
|
|
37
|
+
* GET: handlers.GET,
|
|
38
|
+
* POST: handlers.POST,
|
|
30
39
|
* },
|
|
31
40
|
* },
|
|
32
41
|
* });
|
|
33
|
-
*
|
|
34
|
-
* export const POST = handler.authorize;
|
|
35
42
|
* ```
|
|
36
43
|
*/
|
|
37
|
-
export declare function
|
|
38
|
-
|
|
39
|
-
* POST /api/integrate/oauth/authorize
|
|
40
|
-
*
|
|
41
|
-
* Request authorization URL from MCP server with server-side OAuth credentials
|
|
42
|
-
*
|
|
43
|
-
* Request body:
|
|
44
|
-
* ```json
|
|
45
|
-
* {
|
|
46
|
-
* "provider": "github",
|
|
47
|
-
* "scopes": ["repo", "user"],
|
|
48
|
-
* "state": "random-state-string",
|
|
49
|
-
* "codeChallenge": "pkce-code-challenge",
|
|
50
|
-
* "codeChallengeMethod": "S256",
|
|
51
|
-
* "redirectUri": "https://yourapp.com/oauth/callback"
|
|
52
|
-
* }
|
|
53
|
-
* ```
|
|
54
|
-
*
|
|
55
|
-
* Response:
|
|
56
|
-
* ```json
|
|
57
|
-
* {
|
|
58
|
-
* "authorizationUrl": "https://github.com/login/oauth/authorize?..."
|
|
59
|
-
* }
|
|
60
|
-
* ```
|
|
61
|
-
*
|
|
62
|
-
* @example
|
|
63
|
-
* ```typescript
|
|
64
|
-
* // app/routes/api/integrate/oauth/authorize.ts
|
|
65
|
-
* import { createTanStackOAuthHandler } from 'integrate-sdk';
|
|
66
|
-
*
|
|
67
|
-
* const handler = createTanStackOAuthHandler({
|
|
68
|
-
* * providers: {
|
|
69
|
-
* github: {
|
|
70
|
-
* clientId: process.env.GITHUB_CLIENT_ID!,
|
|
71
|
-
* clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
72
|
-
* },
|
|
73
|
-
* },
|
|
74
|
-
* });
|
|
75
|
-
*
|
|
76
|
-
* export const POST = handler.authorize;
|
|
77
|
-
* ```
|
|
78
|
-
*/
|
|
79
|
-
authorize({ request }: {
|
|
80
|
-
request: Request;
|
|
81
|
-
}): Promise<Response>;
|
|
82
|
-
/**
|
|
83
|
-
* POST /api/integrate/oauth/callback
|
|
84
|
-
*
|
|
85
|
-
* Exchange authorization code for session token
|
|
86
|
-
*
|
|
87
|
-
* Request body:
|
|
88
|
-
* ```json
|
|
89
|
-
* {
|
|
90
|
-
* "provider": "github",
|
|
91
|
-
* "code": "authorization-code",
|
|
92
|
-
* "codeVerifier": "pkce-code-verifier",
|
|
93
|
-
* "state": "state-from-authorize"
|
|
94
|
-
* }
|
|
95
|
-
* ```
|
|
96
|
-
*
|
|
97
|
-
* Response:
|
|
98
|
-
* ```json
|
|
99
|
-
* {
|
|
100
|
-
* "sessionToken": "session-token-123",
|
|
101
|
-
* "provider": "github",
|
|
102
|
-
* "scopes": ["repo", "user"],
|
|
103
|
-
* "expiresAt": 1234567890
|
|
104
|
-
* }
|
|
105
|
-
* ```
|
|
106
|
-
*
|
|
107
|
-
* @example
|
|
108
|
-
* ```typescript
|
|
109
|
-
* // app/routes/api/integrate/oauth/callback.ts
|
|
110
|
-
* import { createTanStackOAuthHandler } from 'integrate-sdk';
|
|
111
|
-
*
|
|
112
|
-
* const handler = createTanStackOAuthHandler({
|
|
113
|
-
* * providers: {
|
|
114
|
-
* github: {
|
|
115
|
-
* clientId: process.env.GITHUB_CLIENT_ID!,
|
|
116
|
-
* clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
117
|
-
* },
|
|
118
|
-
* },
|
|
119
|
-
* });
|
|
120
|
-
*
|
|
121
|
-
* export const POST = handler.callback;
|
|
122
|
-
* ```
|
|
123
|
-
*/
|
|
124
|
-
callback({ request }: {
|
|
44
|
+
export declare function toTanStackStartHandler(handler: (request: Request) => Promise<Response>): {
|
|
45
|
+
GET: ({ request }: {
|
|
125
46
|
request: Request;
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
* GET /api/integrate/oauth/status?provider=github
|
|
129
|
-
*
|
|
130
|
-
* Check if a provider is currently authorized
|
|
131
|
-
*
|
|
132
|
-
* Query parameters:
|
|
133
|
-
* - provider: Provider to check (e.g., "github")
|
|
134
|
-
*
|
|
135
|
-
* Headers:
|
|
136
|
-
* - X-Session-Token: Session token from previous authorization
|
|
137
|
-
*
|
|
138
|
-
* Response:
|
|
139
|
-
* ```json
|
|
140
|
-
* {
|
|
141
|
-
* "authorized": true,
|
|
142
|
-
* "provider": "github",
|
|
143
|
-
* "scopes": ["repo", "user"],
|
|
144
|
-
* "expiresAt": 1234567890
|
|
145
|
-
* }
|
|
146
|
-
* ```
|
|
147
|
-
*
|
|
148
|
-
* @example
|
|
149
|
-
* ```typescript
|
|
150
|
-
* // app/routes/api/integrate/oauth/status.ts
|
|
151
|
-
* import { createTanStackOAuthHandler } from 'integrate-sdk';
|
|
152
|
-
*
|
|
153
|
-
* const handler = createTanStackOAuthHandler({
|
|
154
|
-
* * providers: {
|
|
155
|
-
* github: {
|
|
156
|
-
* clientId: process.env.GITHUB_CLIENT_ID!,
|
|
157
|
-
* clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
158
|
-
* },
|
|
159
|
-
* },
|
|
160
|
-
* });
|
|
161
|
-
*
|
|
162
|
-
* export const GET = handler.status;
|
|
163
|
-
* ```
|
|
164
|
-
*/
|
|
165
|
-
status({ request }: {
|
|
47
|
+
}) => Promise<Response>;
|
|
48
|
+
POST: ({ request }: {
|
|
166
49
|
request: Request;
|
|
167
|
-
})
|
|
50
|
+
}) => Promise<Response>;
|
|
168
51
|
};
|
|
52
|
+
export declare const createTanStackOAuthHandler: typeof toTanStackStartHandler;
|
|
169
53
|
//# sourceMappingURL=tanstack-start.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tanstack-start.d.ts","sourceRoot":"","sources":["../../../src/adapters/tanstack-start.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH
|
|
1
|
+
{"version":3,"file":"tanstack-start.d.ts","sourceRoot":"","sources":["../../../src/adapters/tanstack-start.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC;uBAC7C;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,KAAG,OAAO,CAAC,QAAQ,CAAC;wBAAxC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,KAAG,OAAO,CAAC,QAAQ,CAAC;EAQjF;AAGD,eAAO,MAAM,0BAA0B,+BAAyB,CAAC"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -13,7 +13,10 @@ export type { OAuthHandlerConfig, AuthorizeRequest, AuthorizeResponse, CallbackR
|
|
|
13
13
|
export { createNextOAuthHandler } from "./adapters/nextjs.js";
|
|
14
14
|
export { createOAuthRedirectHandler } from "./adapters/nextjs-oauth-redirect.js";
|
|
15
15
|
export type { OAuthRedirectConfig } from "./adapters/nextjs-oauth-redirect.js";
|
|
16
|
-
export {
|
|
16
|
+
export { toNodeHandler, fromNodeHeaders } from "./adapters/node.js";
|
|
17
|
+
export { toSolidStartHandler } from "./adapters/solid-start.js";
|
|
18
|
+
export { toSvelteKitHandler, svelteKitHandler } from "./adapters/svelte-kit.js";
|
|
19
|
+
export { toTanStackStartHandler, createTanStackOAuthHandler } from "./adapters/tanstack-start.js";
|
|
17
20
|
export type { MCPClientConfig, ReauthContext, ReauthHandler } from "./config/types.js";
|
|
18
21
|
export { IntegrateSDKError, AuthenticationError, AuthorizationError, TokenExpiredError, ConnectionError, ToolCallError, isAuthError, isTokenExpiredError, isAuthorizationError, parseServerError, } from "./errors.js";
|
|
19
22
|
export type { MCPPlugin, OAuthConfig, ExtractPluginIds, ExtractPluginTools, } from "./plugins/types.js";
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC3E,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,aAAa,EAAE,0BAA0B,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrI,YAAY,EACV,eAAe,EACf,YAAY,EACZ,UAAU,EACV,WAAW,EACX,wBAAwB,EACxB,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic Claude Integration
|
|
3
|
+
*
|
|
4
|
+
* Helper functions to convert MCP tools to Anthropic Claude API format
|
|
5
|
+
*/
|
|
6
|
+
import type { MCPClient } from "../client.js";
|
|
7
|
+
import type { MCPTool } from "../protocol/messages.js";
|
|
8
|
+
import { type AIToolsOptions } from "./utils.js";
|
|
9
|
+
/**
|
|
10
|
+
* Anthropic tool definition
|
|
11
|
+
* Compatible with Anthropic's Claude API
|
|
12
|
+
*/
|
|
13
|
+
export interface AnthropicTool {
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
input_schema: {
|
|
17
|
+
type: 'object';
|
|
18
|
+
properties?: Record<string, unknown>;
|
|
19
|
+
required?: string[];
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Options for converting MCP tools to Anthropic format
|
|
25
|
+
*/
|
|
26
|
+
export interface AnthropicToolsOptions extends AIToolsOptions {
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Anthropic tool use block from message content
|
|
30
|
+
*/
|
|
31
|
+
export interface AnthropicToolUseBlock {
|
|
32
|
+
type: 'tool_use';
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
input: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Anthropic tool result block for responses
|
|
39
|
+
*/
|
|
40
|
+
export interface AnthropicToolResultBlock {
|
|
41
|
+
type: 'tool_result';
|
|
42
|
+
tool_use_id: string;
|
|
43
|
+
content: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Convert a single MCP tool to Anthropic Claude API format
|
|
47
|
+
*
|
|
48
|
+
* @param mcpTool - The MCP tool definition
|
|
49
|
+
* @param client - The MCP client instance (used for executing the tool)
|
|
50
|
+
* @param options - Optional configuration including provider tokens
|
|
51
|
+
* @returns Anthropic compatible tool definition
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* const anthropicTool = convertMCPToolToAnthropic(mcpTool, client);
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function convertMCPToolToAnthropic(mcpTool: MCPTool, _client: MCPClient<any>, _options?: AnthropicToolsOptions): AnthropicTool;
|
|
59
|
+
/**
|
|
60
|
+
* Convert all enabled MCP tools to Anthropic Claude API format
|
|
61
|
+
*
|
|
62
|
+
* @param client - The MCP client instance (must be connected)
|
|
63
|
+
* @param options - Optional configuration including provider tokens
|
|
64
|
+
* @returns Array of Anthropic compatible tool definitions
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* // Client-side usage
|
|
69
|
+
* const tools = convertMCPToolsToAnthropic(mcpClient);
|
|
70
|
+
*
|
|
71
|
+
* // Server-side with provider tokens
|
|
72
|
+
* const tools = convertMCPToolsToAnthropic(serverClient, {
|
|
73
|
+
* providerTokens: { github: 'ghp_...', gmail: 'ya29...' }
|
|
74
|
+
* });
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export declare function convertMCPToolsToAnthropic(client: MCPClient<any>, options?: AnthropicToolsOptions): AnthropicTool[];
|
|
78
|
+
/**
|
|
79
|
+
* Execute a tool call from Anthropic's response
|
|
80
|
+
*
|
|
81
|
+
* @param client - The MCP client instance
|
|
82
|
+
* @param toolUse - The tool use block from Anthropic response
|
|
83
|
+
* @param options - Optional configuration including provider tokens
|
|
84
|
+
* @returns Tool execution result as JSON string
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const result = await executeAnthropicToolCall(client, {
|
|
89
|
+
* type: 'tool_use',
|
|
90
|
+
* id: 'toolu_123',
|
|
91
|
+
* name: 'github_create_issue',
|
|
92
|
+
* input: { owner: 'user', repo: 'repo', title: 'Bug' }
|
|
93
|
+
* }, { providerTokens });
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function executeAnthropicToolCall(client: MCPClient<any>, toolUse: AnthropicToolUseBlock, options?: AnthropicToolsOptions): Promise<string>;
|
|
97
|
+
/**
|
|
98
|
+
* Handle all tool calls from Anthropic's message response
|
|
99
|
+
* Executes all tool use blocks and returns tool result blocks
|
|
100
|
+
*
|
|
101
|
+
* @param client - The MCP client instance
|
|
102
|
+
* @param messageContent - Array of content blocks from Anthropic message
|
|
103
|
+
* @param options - Optional configuration including provider tokens
|
|
104
|
+
* @returns Array of tool result blocks ready to send back to Claude
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* const response = await anthropic.messages.create({
|
|
109
|
+
* model: 'claude-3-5-sonnet-20241022',
|
|
110
|
+
* max_tokens: 1024,
|
|
111
|
+
* tools,
|
|
112
|
+
* messages: [{ role: 'user', content: 'Create a GitHub issue' }]
|
|
113
|
+
* });
|
|
114
|
+
*
|
|
115
|
+
* // Handle tool calls
|
|
116
|
+
* const toolResults = await handleAnthropicToolCalls(
|
|
117
|
+
* client,
|
|
118
|
+
* response.content,
|
|
119
|
+
* { providerTokens }
|
|
120
|
+
* );
|
|
121
|
+
*
|
|
122
|
+
* // Continue conversation with tool results
|
|
123
|
+
* const finalResponse = await anthropic.messages.create({
|
|
124
|
+
* model: 'claude-3-5-sonnet-20241022',
|
|
125
|
+
* max_tokens: 1024,
|
|
126
|
+
* tools,
|
|
127
|
+
* messages: [
|
|
128
|
+
* { role: 'user', content: 'Create a GitHub issue' },
|
|
129
|
+
* { role: 'assistant', content: response.content },
|
|
130
|
+
* { role: 'user', content: toolResults }
|
|
131
|
+
* ]
|
|
132
|
+
* });
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
export declare function handleAnthropicToolCalls(client: MCPClient<any>, messageContent: Array<{
|
|
136
|
+
type: string;
|
|
137
|
+
[key: string]: any;
|
|
138
|
+
}>, options?: AnthropicToolsOptions): Promise<AnthropicToolResultBlock[]>;
|
|
139
|
+
/**
|
|
140
|
+
* Get tools in a format compatible with Anthropic Claude API
|
|
141
|
+
*
|
|
142
|
+
* Automatically connects the client if not already connected.
|
|
143
|
+
*
|
|
144
|
+
* @param client - The MCP client instance
|
|
145
|
+
* @param options - Optional configuration including provider tokens for server-side usage
|
|
146
|
+
* @returns Array of tools ready to pass to Claude API
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* // Client-side usage
|
|
151
|
+
* import { createMCPClient, githubPlugin } from 'integrate-sdk';
|
|
152
|
+
* import { getAnthropicTools } from 'integrate-sdk/integrations/anthropic';
|
|
153
|
+
* import Anthropic from '@anthropic-ai/sdk';
|
|
154
|
+
*
|
|
155
|
+
* const client = createMCPClient({
|
|
156
|
+
* plugins: [githubPlugin({ clientId: '...' })],
|
|
157
|
+
* });
|
|
158
|
+
*
|
|
159
|
+
* const tools = await getAnthropicTools(client);
|
|
160
|
+
* const anthropic = new Anthropic({ apiKey: '...' });
|
|
161
|
+
*
|
|
162
|
+
* const message = await anthropic.messages.create({
|
|
163
|
+
* model: 'claude-3-5-sonnet-20241022',
|
|
164
|
+
* max_tokens: 1024,
|
|
165
|
+
* tools,
|
|
166
|
+
* messages: [{ role: 'user', content: 'Create a GitHub issue' }]
|
|
167
|
+
* });
|
|
168
|
+
* ```
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```typescript
|
|
172
|
+
* // Server-side usage with tokens from client
|
|
173
|
+
* import { createMCPServer, githubPlugin } from 'integrate-sdk/server';
|
|
174
|
+
* import { getAnthropicTools, handleAnthropicToolCalls } from 'integrate-sdk/integrations/anthropic';
|
|
175
|
+
*
|
|
176
|
+
* const { client: serverClient } = createMCPServer({
|
|
177
|
+
* plugins: [githubPlugin({
|
|
178
|
+
* clientId: '...',
|
|
179
|
+
* clientSecret: '...'
|
|
180
|
+
* })],
|
|
181
|
+
* });
|
|
182
|
+
*
|
|
183
|
+
* // In your API route
|
|
184
|
+
* export async function POST(req: Request) {
|
|
185
|
+
* const providerTokens = JSON.parse(req.headers.get('x-integrate-tokens') || '{}');
|
|
186
|
+
* const tools = await getAnthropicTools(serverClient, { providerTokens });
|
|
187
|
+
*
|
|
188
|
+
* const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
|
|
189
|
+
* const message = await anthropic.messages.create({
|
|
190
|
+
* model: 'claude-3-5-sonnet-20241022',
|
|
191
|
+
* max_tokens: 1024,
|
|
192
|
+
* tools,
|
|
193
|
+
* messages: [{ role: 'user', content: 'Create a GitHub issue' }]
|
|
194
|
+
* });
|
|
195
|
+
*
|
|
196
|
+
* // Handle any tool calls
|
|
197
|
+
* const toolResults = await handleAnthropicToolCalls(
|
|
198
|
+
* serverClient,
|
|
199
|
+
* message.content,
|
|
200
|
+
* { providerTokens }
|
|
201
|
+
* );
|
|
202
|
+
*
|
|
203
|
+
* return Response.json({ message, toolResults });
|
|
204
|
+
* }
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
export declare function getAnthropicTools(client: MCPClient<any>, options?: AnthropicToolsOptions): Promise<AnthropicTool[]>;
|
|
208
|
+
//# sourceMappingURL=anthropic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/integrations/anthropic.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAA+C,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAE9F;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACZ,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,cAAc;CAAI;AAEjE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,EACvB,QAAQ,CAAC,EAAE,qBAAqB,GAC/B,aAAa,CAUf;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,aAAa,EAAE,CAGjB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,OAAO,EAAE,qBAAqB,EAC9B,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,cAAc,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAA,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,CAAC,EAC1D,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAkCrC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,aAAa,EAAE,CAAC,CAG1B"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare Workers AI Integration
|
|
3
|
+
*
|
|
4
|
+
* Helper functions to convert MCP tools to Cloudflare Workers AI format
|
|
5
|
+
*/
|
|
6
|
+
import type { MCPClient } from "../client.js";
|
|
7
|
+
import type { MCPTool } from "../protocol/messages.js";
|
|
8
|
+
import { type AIToolsOptions } from "./utils.js";
|
|
9
|
+
/**
|
|
10
|
+
* Cloudflare AI tool definition
|
|
11
|
+
* Compatible with Cloudflare Workers AI
|
|
12
|
+
*/
|
|
13
|
+
export interface CloudflareTool {
|
|
14
|
+
type: 'function';
|
|
15
|
+
function: {
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
parameters: {
|
|
19
|
+
type: 'object';
|
|
20
|
+
properties: Record<string, {
|
|
21
|
+
type: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
}>;
|
|
24
|
+
required: string[];
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Options for converting MCP tools to Cloudflare format
|
|
30
|
+
*/
|
|
31
|
+
export interface CloudflareToolsOptions extends AIToolsOptions {
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Convert a single MCP tool to Cloudflare Workers AI format
|
|
35
|
+
*
|
|
36
|
+
* @param mcpTool - The MCP tool definition
|
|
37
|
+
* @param client - The MCP client instance (used for executing the tool)
|
|
38
|
+
* @param options - Optional configuration including provider tokens
|
|
39
|
+
* @returns Cloudflare compatible tool definition
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const cloudflareTool = convertMCPToolToCloudflare(mcpTool, client);
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function convertMCPToolToCloudflare(mcpTool: MCPTool, _client: MCPClient<any>, _options?: CloudflareToolsOptions): CloudflareTool;
|
|
47
|
+
/**
|
|
48
|
+
* Convert all enabled MCP tools to Cloudflare Workers AI format
|
|
49
|
+
* Returns a dictionary keyed by tool name
|
|
50
|
+
*
|
|
51
|
+
* @param client - The MCP client instance (must be connected)
|
|
52
|
+
* @param options - Optional configuration including provider tokens
|
|
53
|
+
* @returns Dictionary of Cloudflare compatible tool definitions
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* // Client-side usage
|
|
58
|
+
* const tools = convertMCPToolsToCloudflare(mcpClient);
|
|
59
|
+
*
|
|
60
|
+
* // Server-side with provider tokens
|
|
61
|
+
* const tools = convertMCPToolsToCloudflare(serverClient, {
|
|
62
|
+
* providerTokens: { github: 'ghp_...', gmail: 'ya29...' }
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare function convertMCPToolsToCloudflare(client: MCPClient<any>, options?: CloudflareToolsOptions): Record<string, CloudflareTool>;
|
|
67
|
+
/**
|
|
68
|
+
* Execute a tool call from Cloudflare Workers AI
|
|
69
|
+
*
|
|
70
|
+
* @param client - The MCP client instance
|
|
71
|
+
* @param toolCall - The tool call with name and arguments
|
|
72
|
+
* @param options - Optional configuration including provider tokens
|
|
73
|
+
* @returns Tool execution result as JSON string
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* const result = await executeCloudflareToolCall(client, {
|
|
78
|
+
* name: 'github_create_issue',
|
|
79
|
+
* arguments: { owner: 'user', repo: 'repo', title: 'Bug' }
|
|
80
|
+
* }, { providerTokens });
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export declare function executeCloudflareToolCall(client: MCPClient<any>, toolCall: {
|
|
84
|
+
name: string;
|
|
85
|
+
arguments: Record<string, unknown> | string;
|
|
86
|
+
}, options?: CloudflareToolsOptions): Promise<string>;
|
|
87
|
+
/**
|
|
88
|
+
* Get tools in a format compatible with Cloudflare Workers AI
|
|
89
|
+
*
|
|
90
|
+
* Automatically connects the client if not already connected.
|
|
91
|
+
*
|
|
92
|
+
* @param client - The MCP client instance
|
|
93
|
+
* @param options - Optional configuration including provider tokens for server-side usage
|
|
94
|
+
* @returns Dictionary of tools ready to use with Cloudflare Workers AI
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* // Cloudflare Worker usage
|
|
99
|
+
* import { createMCPClient, githubPlugin } from 'integrate-sdk';
|
|
100
|
+
* import { getCloudflareTools, executeCloudflareToolCall } from 'integrate-sdk/integrations/cloudflare';
|
|
101
|
+
*
|
|
102
|
+
* export default {
|
|
103
|
+
* async fetch(request: Request, env: Env): Promise<Response> {
|
|
104
|
+
* const client = createMCPClient({
|
|
105
|
+
* plugins: [githubPlugin({ clientId: env.GITHUB_CLIENT_ID })],
|
|
106
|
+
* });
|
|
107
|
+
*
|
|
108
|
+
* const tools = await getCloudflareTools(client);
|
|
109
|
+
* const ai = new Ai(env.AI);
|
|
110
|
+
*
|
|
111
|
+
* const response = await ai.run('@cf/meta/llama-3-8b-instruct', {
|
|
112
|
+
* messages: [{ role: 'user', content: 'Create a GitHub issue' }],
|
|
113
|
+
* tools: Object.values(tools)
|
|
114
|
+
* });
|
|
115
|
+
*
|
|
116
|
+
* return Response.json(response);
|
|
117
|
+
* }
|
|
118
|
+
* };
|
|
119
|
+
* ```
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* // Server-side usage with tokens from client
|
|
124
|
+
* import { createMCPServer, githubPlugin } from 'integrate-sdk/server';
|
|
125
|
+
* import { getCloudflareTools, executeCloudflareToolCall } from 'integrate-sdk/integrations/cloudflare';
|
|
126
|
+
*
|
|
127
|
+
* const { client: serverClient } = createMCPServer({
|
|
128
|
+
* plugins: [githubPlugin({
|
|
129
|
+
* clientId: '...',
|
|
130
|
+
* clientSecret: '...'
|
|
131
|
+
* })],
|
|
132
|
+
* });
|
|
133
|
+
*
|
|
134
|
+
* // In your API route
|
|
135
|
+
* export async function POST(req: Request) {
|
|
136
|
+
* const providerTokens = JSON.parse(req.headers.get('x-integrate-tokens') || '{}');
|
|
137
|
+
* const tools = await getCloudflareTools(serverClient, { providerTokens });
|
|
138
|
+
*
|
|
139
|
+
* // Use with Cloudflare AI
|
|
140
|
+
* const ai = new Ai(env.AI);
|
|
141
|
+
* const response = await ai.run('@cf/meta/llama-3-8b-instruct', {
|
|
142
|
+
* messages: [{ role: 'user', content: 'Create a GitHub issue' }],
|
|
143
|
+
* tools: Object.values(tools)
|
|
144
|
+
* });
|
|
145
|
+
*
|
|
146
|
+
* // Handle tool calls
|
|
147
|
+
* if (response.tool_calls) {
|
|
148
|
+
* for (const toolCall of response.tool_calls) {
|
|
149
|
+
* await executeCloudflareToolCall(serverClient, toolCall, { providerTokens });
|
|
150
|
+
* }
|
|
151
|
+
* }
|
|
152
|
+
*
|
|
153
|
+
* return Response.json(response);
|
|
154
|
+
* }
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
export declare function getCloudflareTools(client: MCPClient<any>, options?: CloudflareToolsOptions): Promise<Record<string, CloudflareTool>>;
|
|
158
|
+
//# sourceMappingURL=cloudflare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../../src/integrations/cloudflare.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAA+C,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAE9F;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ,CAAC;YACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;gBACzB,IAAI,EAAE,MAAM,CAAC;gBACb,WAAW,CAAC,EAAE,MAAM,CAAC;aACtB,CAAC,CAAC;YACH,QAAQ,EAAE,MAAM,EAAE,CAAC;SACpB,CAAC;KACH,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,cAAc;CAAI;AAElE;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,EACvB,QAAQ,CAAC,EAAE,sBAAsB,GAChC,cAAc,CAahB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAShC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,QAAQ,EAAE;IACR,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC;CAC7C,EACD,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAGzC"}
|