@phake/mcp 0.0.1
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/LICENSE +21 -0
- package/README.md +187 -0
- package/dist/adapters/http-node/http/app.d.ts +5 -0
- package/dist/adapters/http-node/http/auth-app.d.ts +5 -0
- package/dist/adapters/http-node/http/middlewares/auth.d.ts +39 -0
- package/dist/adapters/http-node/http/middlewares/cors.d.ts +8 -0
- package/dist/adapters/http-node/http/routes/health.d.ts +5 -0
- package/dist/adapters/http-node/http/routes/mcp.d.ts +11 -0
- package/dist/adapters/http-node/middleware.security.d.ts +6 -0
- package/dist/adapters/http-node/routes.discovery.d.ts +6 -0
- package/dist/adapters/http-node/routes.oauth.d.ts +7 -0
- package/dist/adapters/http-worker/index.d.ts +48 -0
- package/dist/adapters/http-worker/mcp.handler.d.ts +24 -0
- package/dist/adapters/http-worker/routes.discovery.d.ts +7 -0
- package/dist/adapters/http-worker/routes.oauth.d.ts +8 -0
- package/dist/adapters/http-worker/security.d.ts +7 -0
- package/dist/index-1zyem3xr.js +14893 -0
- package/dist/index-4f4xvtt9.js +19552 -0
- package/dist/index-sbqy8kgq.js +3478 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +1083 -0
- package/dist/mcp-server.d.ts +18 -0
- package/dist/runtime/node/capabilities.d.ts +2 -0
- package/dist/runtime/node/context.d.ts +29 -0
- package/dist/runtime/node/index.d.ts +5 -0
- package/dist/runtime/node/index.js +27 -0
- package/dist/runtime/node/mcp.d.ts +28 -0
- package/dist/runtime/node/storage/file.d.ts +44 -0
- package/dist/runtime/node/storage/sqlite.d.ts +213 -0
- package/dist/runtime/worker/index.d.ts +1 -0
- package/dist/runtime/worker/index.js +12 -0
- package/dist/shared/auth/index.d.ts +1 -0
- package/dist/shared/auth/strategy.d.ts +71 -0
- package/dist/shared/config/env.d.ts +52 -0
- package/dist/shared/config/index.d.ts +2 -0
- package/dist/shared/config/metadata.d.ts +5 -0
- package/dist/shared/crypto/aes-gcm.d.ts +37 -0
- package/dist/shared/crypto/index.d.ts +1 -0
- package/dist/shared/http/cors.d.ts +20 -0
- package/dist/shared/http/index.d.ts +2 -0
- package/dist/shared/http/response.d.ts +52 -0
- package/dist/shared/mcp/dispatcher.d.ts +81 -0
- package/dist/shared/mcp/index.d.ts +3 -0
- package/dist/shared/mcp/security.d.ts +23 -0
- package/dist/shared/mcp/server-internals.d.ts +79 -0
- package/dist/shared/oauth/cimd.d.ts +43 -0
- package/dist/shared/oauth/discovery-handlers.d.ts +14 -0
- package/dist/shared/oauth/discovery.d.ts +26 -0
- package/dist/shared/oauth/endpoints.d.ts +11 -0
- package/dist/shared/oauth/flow.d.ts +31 -0
- package/dist/shared/oauth/index.d.ts +9 -0
- package/dist/shared/oauth/input-parsers.d.ts +43 -0
- package/dist/shared/oauth/refresh.d.ts +61 -0
- package/dist/shared/oauth/ssrf.d.ts +31 -0
- package/dist/shared/oauth/types.d.ts +78 -0
- package/dist/shared/schemas/prompts.d.ts +1 -0
- package/dist/shared/services/http-client.d.ts +16 -0
- package/dist/shared/services/index.d.ts +1 -0
- package/dist/shared/storage/index.d.ts +4 -0
- package/dist/shared/storage/interface.d.ts +99 -0
- package/dist/shared/storage/kv.d.ts +68 -0
- package/dist/shared/storage/memory.d.ts +91 -0
- package/dist/shared/storage/singleton.d.ts +4 -0
- package/dist/shared/tools/echo.d.ts +16 -0
- package/dist/shared/tools/health.d.ts +13 -0
- package/dist/shared/tools/index.d.ts +4 -0
- package/dist/shared/tools/registry.d.ts +64 -0
- package/dist/shared/tools/types.d.ts +161 -0
- package/dist/shared/types/auth.d.ts +35 -0
- package/dist/shared/types/context.d.ts +79 -0
- package/dist/shared/types/index.d.ts +8 -0
- package/dist/shared/types/provider.d.ts +28 -0
- package/dist/shared/utils/base64.d.ts +12 -0
- package/dist/shared/utils/cancellation.d.ts +13 -0
- package/dist/shared/utils/elicitation.d.ts +247 -0
- package/dist/shared/utils/formatting.d.ts +106 -0
- package/dist/shared/utils/index.d.ts +11 -0
- package/dist/shared/utils/limits.d.ts +6 -0
- package/dist/shared/utils/logger.d.ts +20 -0
- package/dist/shared/utils/pagination.d.ts +11 -0
- package/dist/shared/utils/progress.d.ts +56 -0
- package/dist/shared/utils/roots.d.ts +62 -0
- package/dist/shared/utils/sampling.d.ts +155 -0
- package/dist/shared/utils/security.d.ts +6 -0
- package/package.json +55 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ProviderTokens, RsRecord, SessionRecord, SessionStore, TokenStore, Transaction } from "./interface.js";
|
|
2
|
+
import { MemorySessionStore, MemoryTokenStore } from "./memory.js";
|
|
3
|
+
type KVNamespace = {
|
|
4
|
+
get(key: string): Promise<string | null>;
|
|
5
|
+
put(key: string, value: string, options?: {
|
|
6
|
+
expiration?: number;
|
|
7
|
+
expirationTtl?: number;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
delete(key: string): Promise<void>;
|
|
10
|
+
};
|
|
11
|
+
type EncryptFn = (plaintext: string) => Promise<string> | string;
|
|
12
|
+
type DecryptFn = (ciphertext: string) => Promise<string> | string;
|
|
13
|
+
export declare class KvTokenStore implements TokenStore {
|
|
14
|
+
private kv;
|
|
15
|
+
private encrypt;
|
|
16
|
+
private decrypt;
|
|
17
|
+
private fallback;
|
|
18
|
+
constructor(kv: KVNamespace, options?: {
|
|
19
|
+
encrypt?: EncryptFn;
|
|
20
|
+
decrypt?: DecryptFn;
|
|
21
|
+
fallback?: MemoryTokenStore;
|
|
22
|
+
});
|
|
23
|
+
private putJson;
|
|
24
|
+
private getJson;
|
|
25
|
+
storeRsMapping(rsAccess: string, provider: ProviderTokens, rsRefresh?: string): Promise<RsRecord>;
|
|
26
|
+
getByRsAccess(rsAccess: string): Promise<RsRecord | null>;
|
|
27
|
+
getByRsRefresh(rsRefresh: string): Promise<RsRecord | null>;
|
|
28
|
+
updateByRsRefresh(rsRefresh: string, provider: ProviderTokens, maybeNewRsAccess?: string): Promise<RsRecord | null>;
|
|
29
|
+
saveTransaction(txnId: string, txn: Transaction, ttlSeconds?: number): Promise<void>;
|
|
30
|
+
getTransaction(txnId: string): Promise<Transaction | null>;
|
|
31
|
+
deleteTransaction(txnId: string): Promise<void>;
|
|
32
|
+
saveCode(code: string, txnId: string, ttlSeconds?: number): Promise<void>;
|
|
33
|
+
getTxnIdByCode(code: string): Promise<string | null>;
|
|
34
|
+
deleteCode(code: string): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* KV-based session store for Cloudflare Workers.
|
|
38
|
+
* Provides persistent session storage with multi-tenant support.
|
|
39
|
+
*
|
|
40
|
+
* Storage structure:
|
|
41
|
+
* - session:{sessionId} → SessionRecord (main session data)
|
|
42
|
+
* - session:apikey:{apiKey} → string[] (list of session IDs for this API key)
|
|
43
|
+
*/
|
|
44
|
+
export declare class KvSessionStore implements SessionStore {
|
|
45
|
+
private kv;
|
|
46
|
+
private encrypt;
|
|
47
|
+
private decrypt;
|
|
48
|
+
private fallback;
|
|
49
|
+
constructor(kv: KVNamespace, options?: {
|
|
50
|
+
encrypt?: EncryptFn;
|
|
51
|
+
decrypt?: DecryptFn;
|
|
52
|
+
fallback?: MemorySessionStore;
|
|
53
|
+
});
|
|
54
|
+
private putSession;
|
|
55
|
+
private getSession;
|
|
56
|
+
private getApiKeySessionIds;
|
|
57
|
+
private setApiKeySessionIds;
|
|
58
|
+
create(sessionId: string, apiKey: string): Promise<SessionRecord>;
|
|
59
|
+
get(sessionId: string): Promise<SessionRecord | null>;
|
|
60
|
+
update(sessionId: string, data: Partial<SessionRecord>): Promise<void>;
|
|
61
|
+
delete(sessionId: string): Promise<void>;
|
|
62
|
+
getByApiKey(apiKey: string): Promise<SessionRecord[]>;
|
|
63
|
+
countByApiKey(apiKey: string): Promise<number>;
|
|
64
|
+
deleteOldestByApiKey(apiKey: string): Promise<void>;
|
|
65
|
+
ensure(sessionId: string): Promise<void>;
|
|
66
|
+
put(sessionId: string, value: SessionRecord): Promise<void>;
|
|
67
|
+
}
|
|
68
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { ProviderTokens, RsRecord, SessionRecord, SessionStore, TokenStore, Transaction } from "./interface.js";
|
|
2
|
+
/**
|
|
3
|
+
* Wrapper for entries with expiration time.
|
|
4
|
+
*/
|
|
5
|
+
interface TimedEntry<T> {
|
|
6
|
+
value: T;
|
|
7
|
+
expiresAt: number;
|
|
8
|
+
createdAt: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class MemoryTokenStore implements TokenStore {
|
|
11
|
+
protected rsAccessMap: Map<string, RsRecord & {
|
|
12
|
+
expiresAt: number;
|
|
13
|
+
}>;
|
|
14
|
+
protected rsRefreshMap: Map<string, RsRecord & {
|
|
15
|
+
expiresAt: number;
|
|
16
|
+
}>;
|
|
17
|
+
protected transactions: Map<string, TimedEntry<Transaction>>;
|
|
18
|
+
protected codes: Map<string, TimedEntry<string>>;
|
|
19
|
+
private cleanupIntervalId;
|
|
20
|
+
constructor();
|
|
21
|
+
/**
|
|
22
|
+
* Start periodic cleanup of expired entries.
|
|
23
|
+
*/
|
|
24
|
+
startCleanup(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Stop periodic cleanup.
|
|
27
|
+
*/
|
|
28
|
+
stopCleanup(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Run cleanup of all expired entries.
|
|
31
|
+
*/
|
|
32
|
+
cleanup(): {
|
|
33
|
+
tokens: number;
|
|
34
|
+
transactions: number;
|
|
35
|
+
codes: number;
|
|
36
|
+
};
|
|
37
|
+
storeRsMapping(rsAccess: string, provider: ProviderTokens, rsRefresh?: string, ttlMs?: number): Promise<RsRecord>;
|
|
38
|
+
getByRsAccess(rsAccess: string): Promise<RsRecord | null>;
|
|
39
|
+
getByRsRefresh(rsRefresh: string): Promise<RsRecord | null>;
|
|
40
|
+
updateByRsRefresh(rsRefresh: string, provider: ProviderTokens, maybeNewRsAccess?: string, ttlMs?: number): Promise<RsRecord | null>;
|
|
41
|
+
saveTransaction(txnId: string, txn: Transaction, ttlSeconds?: number): Promise<void>;
|
|
42
|
+
getTransaction(txnId: string): Promise<Transaction | null>;
|
|
43
|
+
deleteTransaction(txnId: string): Promise<void>;
|
|
44
|
+
saveCode(code: string, txnId: string, ttlSeconds?: number): Promise<void>;
|
|
45
|
+
getTxnIdByCode(code: string): Promise<string | null>;
|
|
46
|
+
deleteCode(code: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Get current store statistics.
|
|
49
|
+
*/
|
|
50
|
+
getStats(): {
|
|
51
|
+
rsTokens: number;
|
|
52
|
+
transactions: number;
|
|
53
|
+
codes: number;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** Internal session type with expiration */
|
|
57
|
+
type InternalSession = SessionRecord & {
|
|
58
|
+
expiresAt: number;
|
|
59
|
+
sessionId: string;
|
|
60
|
+
};
|
|
61
|
+
export declare class MemorySessionStore implements SessionStore {
|
|
62
|
+
protected sessions: Map<string, InternalSession>;
|
|
63
|
+
private cleanupIntervalId;
|
|
64
|
+
constructor();
|
|
65
|
+
/**
|
|
66
|
+
* Start periodic cleanup of expired sessions.
|
|
67
|
+
*/
|
|
68
|
+
startCleanup(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Stop periodic cleanup.
|
|
71
|
+
*/
|
|
72
|
+
stopCleanup(): void;
|
|
73
|
+
/**
|
|
74
|
+
* Remove expired sessions.
|
|
75
|
+
*/
|
|
76
|
+
cleanup(): number;
|
|
77
|
+
create(sessionId: string, apiKey: string, ttlMs?: number): Promise<SessionRecord>;
|
|
78
|
+
get(sessionId: string): Promise<SessionRecord | null>;
|
|
79
|
+
update(sessionId: string, data: Partial<SessionRecord>): Promise<void>;
|
|
80
|
+
delete(sessionId: string): Promise<void>;
|
|
81
|
+
getByApiKey(apiKey: string): Promise<SessionRecord[]>;
|
|
82
|
+
countByApiKey(apiKey: string): Promise<number>;
|
|
83
|
+
deleteOldestByApiKey(apiKey: string): Promise<void>;
|
|
84
|
+
ensure(sessionId: string, ttlMs?: number): Promise<void>;
|
|
85
|
+
put(sessionId: string, value: SessionRecord, ttlMs?: number): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Get current session count.
|
|
88
|
+
*/
|
|
89
|
+
getSessionCount(): number;
|
|
90
|
+
}
|
|
91
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SessionStore, TokenStore } from "./interface.js";
|
|
2
|
+
export declare function initializeStorage(tokenStore: TokenStore, sessionStore: SessionStore): void;
|
|
3
|
+
export declare function getTokenStore(): TokenStore;
|
|
4
|
+
export declare function getSessionStore(): SessionStore;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Input schema for echo tool.
|
|
4
|
+
*/
|
|
5
|
+
export declare const echoInputSchema: z.ZodObject<{
|
|
6
|
+
message: z.ZodString;
|
|
7
|
+
uppercase: z.ZodOptional<z.ZodBoolean>;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
/**
|
|
10
|
+
* Echo tool - works in both Node and Workers.
|
|
11
|
+
* Simple test tool that echoes back input.
|
|
12
|
+
*/
|
|
13
|
+
export declare const echoTool: import("./types.js").SharedToolDefinition<{
|
|
14
|
+
message: z.ZodString;
|
|
15
|
+
uppercase: z.ZodOptional<z.ZodBoolean>;
|
|
16
|
+
}>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Input schema for health tool.
|
|
4
|
+
*/
|
|
5
|
+
export declare const healthInputSchema: z.ZodObject<{
|
|
6
|
+
verbose: z.ZodOptional<z.ZodBoolean>;
|
|
7
|
+
}, z.core.$strip>;
|
|
8
|
+
/**
|
|
9
|
+
* Health check tool - works in both Node and Workers.
|
|
10
|
+
*/
|
|
11
|
+
export declare const healthTool: import("./types.js").SharedToolDefinition<{
|
|
12
|
+
verbose: z.ZodOptional<z.ZodBoolean>;
|
|
13
|
+
}>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared tool registry - single source of truth for all tools.
|
|
3
|
+
* Tools defined here work in both Node.js and Cloudflare Workers.
|
|
4
|
+
*/
|
|
5
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
+
import type { ZodObject, ZodRawShape } from "zod";
|
|
7
|
+
import type { SharedToolDefinition, ToolContext, ToolResult } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Optional context resolver for Node.js runtime.
|
|
10
|
+
* Allows looking up auth context by requestId.
|
|
11
|
+
*/
|
|
12
|
+
export type ContextResolver = (requestId: string | number) => {
|
|
13
|
+
authStrategy?: ToolContext["authStrategy"];
|
|
14
|
+
providerToken?: string;
|
|
15
|
+
provider?: ToolContext["provider"];
|
|
16
|
+
resolvedHeaders?: Record<string, string>;
|
|
17
|
+
} | undefined;
|
|
18
|
+
export type { SharedToolDefinition, ToolContext, ToolResult } from "./types.js";
|
|
19
|
+
export { defineTool } from "./types.js";
|
|
20
|
+
/**
|
|
21
|
+
* Simplified tool interface for the registry (type-erased for storage).
|
|
22
|
+
* This is the "any tool" type used when storing heterogeneous tools in an array.
|
|
23
|
+
*/
|
|
24
|
+
export interface RegisteredTool {
|
|
25
|
+
name: string;
|
|
26
|
+
title?: string;
|
|
27
|
+
description: string;
|
|
28
|
+
inputSchema: ZodObject<ZodRawShape>;
|
|
29
|
+
outputSchema?: ZodRawShape;
|
|
30
|
+
requiresAuth?: boolean;
|
|
31
|
+
annotations?: Record<string, unknown>;
|
|
32
|
+
handler: (args: Record<string, unknown>, context: ToolContext) => Promise<ToolResult>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* All shared tools available in both runtimes.
|
|
36
|
+
* Add new tools here to make them available everywhere.
|
|
37
|
+
*/
|
|
38
|
+
export declare const sharedTools: RegisteredTool[];
|
|
39
|
+
/**
|
|
40
|
+
* Get a tool by name.
|
|
41
|
+
*/
|
|
42
|
+
export declare function getSharedTool(name: string): RegisteredTool | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Get all tool names.
|
|
45
|
+
*/
|
|
46
|
+
export declare function getSharedToolNames(): string[];
|
|
47
|
+
/**
|
|
48
|
+
* Execute a shared tool by name.
|
|
49
|
+
* Handles input validation, output validation, and error wrapping.
|
|
50
|
+
*
|
|
51
|
+
* Per MCP spec: When outputSchema is defined, structuredContent is required
|
|
52
|
+
* (unless isError is true). The SDK validates this automatically for Node,
|
|
53
|
+
* and we replicate that behavior here for Workers.
|
|
54
|
+
*/
|
|
55
|
+
export declare function executeSharedTool(name: string, args: Record<string, unknown>, context: ToolContext, tools?: SharedToolDefinition[]): Promise<ToolResult>;
|
|
56
|
+
/**
|
|
57
|
+
* Register all tools with an MCP server.
|
|
58
|
+
* This is the main entry point for Node.js runtime.
|
|
59
|
+
*
|
|
60
|
+
* @param server - MCP server instance
|
|
61
|
+
* @param contextResolver - Optional function to resolve auth context by requestId.
|
|
62
|
+
* Required for tools to receive auth data in Node.js.
|
|
63
|
+
*/
|
|
64
|
+
export declare function registerTools(server: McpServer, contextResolver?: ContextResolver): void;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared tool types for cross-runtime compatibility.
|
|
3
|
+
* These definitions work in both Node.js (Hono) and Cloudflare Workers.
|
|
4
|
+
*
|
|
5
|
+
* Uses Zod for schema validation (works in both runtimes).
|
|
6
|
+
*/
|
|
7
|
+
import type { ZodObject, ZodRawShape, z } from "zod";
|
|
8
|
+
import type { AuthStrategy } from "../types/auth.js";
|
|
9
|
+
import type { ProviderInfo } from "../types/provider.js";
|
|
10
|
+
export type { AuthStrategy } from "../types/auth.js";
|
|
11
|
+
/**
|
|
12
|
+
* Context passed to every tool handler.
|
|
13
|
+
* Provides access to auth, session, and cancellation.
|
|
14
|
+
*/
|
|
15
|
+
export interface ToolContext {
|
|
16
|
+
/** Current MCP session ID */
|
|
17
|
+
sessionId: string;
|
|
18
|
+
/** Abort signal for cancellation support */
|
|
19
|
+
signal?: AbortSignal;
|
|
20
|
+
/** Request metadata from MCP */
|
|
21
|
+
meta?: {
|
|
22
|
+
progressToken?: string | number;
|
|
23
|
+
requestId?: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Active auth strategy.
|
|
27
|
+
* - 'oauth': Full OAuth flow with RS token mapping
|
|
28
|
+
* - 'bearer': Static bearer token from BEARER_TOKEN env
|
|
29
|
+
* - 'api_key': Static API key from API_KEY env
|
|
30
|
+
* - 'custom': Custom headers from CUSTOM_HEADERS env
|
|
31
|
+
* - 'none': No authentication
|
|
32
|
+
*/
|
|
33
|
+
authStrategy?: AuthStrategy;
|
|
34
|
+
/**
|
|
35
|
+
* Provider access token (e.g., Google, Spotify, GitHub token).
|
|
36
|
+
* Use this to call external APIs on behalf of the user.
|
|
37
|
+
*
|
|
38
|
+
* For OAuth: the mapped provider token
|
|
39
|
+
* For Bearer: the BEARER_TOKEN value
|
|
40
|
+
* For API Key: the API_KEY value
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const response = await fetch('https://api.example.com/data', {
|
|
45
|
+
* headers: { Authorization: `Bearer ${context.providerToken}` }
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
providerToken?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Provider information (OAuth only).
|
|
52
|
+
* Uses camelCase (JS convention) - converted from storage format.
|
|
53
|
+
*/
|
|
54
|
+
provider?: ProviderInfo;
|
|
55
|
+
/**
|
|
56
|
+
* Resolved headers ready for API calls.
|
|
57
|
+
* This includes the appropriate auth header based on strategy:
|
|
58
|
+
* - OAuth: Authorization header with provider token
|
|
59
|
+
* - Bearer: Authorization header from config
|
|
60
|
+
* - API Key: Custom header (e.g., x-api-key) from config
|
|
61
|
+
* - Custom: All custom headers from config
|
|
62
|
+
*
|
|
63
|
+
* Use these headers directly in fetch calls:
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const response = await fetch('https://api.example.com/data', {
|
|
67
|
+
* headers: context.resolvedHeaders
|
|
68
|
+
* });
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
resolvedHeaders?: Record<string, string>;
|
|
72
|
+
/**
|
|
73
|
+
* Raw authorization headers from the request (before resolution).
|
|
74
|
+
* Usually you should use `resolvedHeaders` instead.
|
|
75
|
+
* @deprecated Use `resolvedHeaders` for API calls
|
|
76
|
+
*/
|
|
77
|
+
authHeaders?: Record<string, string>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Type guard to assert providerToken is present.
|
|
81
|
+
* Use this when you know auth is required (e.g., tools with requiresAuth: true).
|
|
82
|
+
*/
|
|
83
|
+
export declare function assertProviderToken(context: ToolContext): asserts context is ToolContext & {
|
|
84
|
+
providerToken: string;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Content block in tool results.
|
|
88
|
+
*/
|
|
89
|
+
export type ToolContentBlock = {
|
|
90
|
+
type: "text";
|
|
91
|
+
text: string;
|
|
92
|
+
} | {
|
|
93
|
+
type: "image";
|
|
94
|
+
data: string;
|
|
95
|
+
mimeType: string;
|
|
96
|
+
} | {
|
|
97
|
+
type: "resource";
|
|
98
|
+
uri: string;
|
|
99
|
+
mimeType?: string;
|
|
100
|
+
text?: string;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Result returned from tool handlers.
|
|
104
|
+
*/
|
|
105
|
+
export interface ToolResult {
|
|
106
|
+
content: ToolContentBlock[];
|
|
107
|
+
/** If true, indicates the tool encountered an error */
|
|
108
|
+
isError?: boolean;
|
|
109
|
+
/** Structured output matching outputSchema (if defined) */
|
|
110
|
+
structuredContent?: Record<string, unknown>;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Context passed to handlers of tools that require authentication.
|
|
114
|
+
* The dispatcher guarantees providerToken is present.
|
|
115
|
+
*/
|
|
116
|
+
export interface AuthenticatedToolContext extends ToolContext {
|
|
117
|
+
providerToken: string;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Framework-agnostic tool definition using Zod schemas.
|
|
121
|
+
* Can be registered with McpServer (Node) or custom dispatcher (Workers).
|
|
122
|
+
*/
|
|
123
|
+
export interface SharedToolDefinition<TShape extends ZodRawShape = ZodRawShape> {
|
|
124
|
+
/** Unique tool name (lowercase, underscores allowed) */
|
|
125
|
+
name: string;
|
|
126
|
+
/** Human-readable title */
|
|
127
|
+
title?: string;
|
|
128
|
+
/** Tool description for LLM */
|
|
129
|
+
description: string;
|
|
130
|
+
/** Zod schema for input validation */
|
|
131
|
+
inputSchema: ZodObject<TShape>;
|
|
132
|
+
/** Optional Zod schema for structured output */
|
|
133
|
+
outputSchema?: ZodRawShape;
|
|
134
|
+
/** Tool handler function */
|
|
135
|
+
handler: (args: z.infer<ZodObject<TShape>>, context: ToolContext) => Promise<ToolResult>;
|
|
136
|
+
/**
|
|
137
|
+
* Whether this tool requires authentication.
|
|
138
|
+
* If true, the handler will automatically return an error if providerToken is missing.
|
|
139
|
+
*/
|
|
140
|
+
requiresAuth?: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Tool annotations per MCP specification.
|
|
143
|
+
* These are hints for clients about tool behavior (not enforced by SDK).
|
|
144
|
+
*/
|
|
145
|
+
annotations?: {
|
|
146
|
+
/** Human-readable display title */
|
|
147
|
+
title?: string;
|
|
148
|
+
/** Tool does NOT modify environment (default: false) */
|
|
149
|
+
readOnlyHint?: boolean;
|
|
150
|
+
/** Tool may delete/overwrite data (default: true) */
|
|
151
|
+
destructiveHint?: boolean;
|
|
152
|
+
/** Repeated calls have no additional effect (default: false) */
|
|
153
|
+
idempotentHint?: boolean;
|
|
154
|
+
/** Tool interacts with external entities (default: true) */
|
|
155
|
+
openWorldHint?: boolean;
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Helper to create a type-safe tool definition.
|
|
160
|
+
*/
|
|
161
|
+
export declare function defineTool<TShape extends ZodRawShape>(def: SharedToolDefinition<TShape>): SharedToolDefinition<TShape>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical authentication types.
|
|
3
|
+
* Single source of truth for auth strategy definitions.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Supported authentication strategies.
|
|
7
|
+
*
|
|
8
|
+
* - 'oauth': Full OAuth 2.1 PKCE flow with RS token → provider token mapping
|
|
9
|
+
* - 'bearer': Simple static Bearer token (from BEARER_TOKEN env)
|
|
10
|
+
* - 'api_key': API key in custom header (from API_KEY env)
|
|
11
|
+
* - 'custom': Arbitrary headers from CUSTOM_HEADERS config
|
|
12
|
+
* - 'none': No authentication required
|
|
13
|
+
*/
|
|
14
|
+
export type AuthStrategy = "oauth" | "bearer" | "api_key" | "custom" | "none";
|
|
15
|
+
/**
|
|
16
|
+
* Auth headers extracted from incoming requests.
|
|
17
|
+
*/
|
|
18
|
+
export interface AuthHeaders {
|
|
19
|
+
authorization?: string;
|
|
20
|
+
"x-api-key"?: string;
|
|
21
|
+
"x-auth-token"?: string;
|
|
22
|
+
[key: string]: string | undefined;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Resolved authentication result.
|
|
26
|
+
* Contains headers ready for API calls and token information.
|
|
27
|
+
*/
|
|
28
|
+
export interface ResolvedAuth {
|
|
29
|
+
/** Auth strategy used */
|
|
30
|
+
strategy: AuthStrategy;
|
|
31
|
+
/** Headers to pass to API calls */
|
|
32
|
+
headers: Record<string, string>;
|
|
33
|
+
/** Raw access token (if bearer/oauth) */
|
|
34
|
+
accessToken?: string;
|
|
35
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { CancellationToken } from "../utils/cancellation.js";
|
|
2
|
+
import type { AuthHeaders, AuthStrategy } from "./auth.js";
|
|
3
|
+
import type { ProviderTokens } from "./provider.js";
|
|
4
|
+
export type { AuthHeaders, AuthStrategy } from "./auth.js";
|
|
5
|
+
/**
|
|
6
|
+
* Request context passed to tool handlers.
|
|
7
|
+
* Contains metadata and utilities for the current request.
|
|
8
|
+
*/
|
|
9
|
+
export interface RequestContext {
|
|
10
|
+
/**
|
|
11
|
+
* Session ID from the MCP transport (if available).
|
|
12
|
+
* This is managed by the SDK's StreamableHTTPServerTransport.
|
|
13
|
+
*/
|
|
14
|
+
sessionId?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Cancellation token for the current request.
|
|
17
|
+
* Tools should check this periodically and throw CancellationError if cancelled.
|
|
18
|
+
*/
|
|
19
|
+
cancellationToken: CancellationToken;
|
|
20
|
+
/**
|
|
21
|
+
* Request ID from JSON-RPC message.
|
|
22
|
+
*/
|
|
23
|
+
requestId?: string | number;
|
|
24
|
+
/**
|
|
25
|
+
* Timestamp when the request was received.
|
|
26
|
+
*/
|
|
27
|
+
timestamp: number;
|
|
28
|
+
/**
|
|
29
|
+
* Active auth strategy.
|
|
30
|
+
* - 'oauth': Full OAuth flow with RS token mapping
|
|
31
|
+
* - 'bearer': Static bearer token from BEARER_TOKEN env
|
|
32
|
+
* - 'api_key': Static API key from API_KEY env
|
|
33
|
+
* - 'custom': Custom headers from CUSTOM_HEADERS env
|
|
34
|
+
* - 'none': No authentication
|
|
35
|
+
*/
|
|
36
|
+
authStrategy?: AuthStrategy;
|
|
37
|
+
/**
|
|
38
|
+
* Raw auth headers from the request (before resolution).
|
|
39
|
+
* @deprecated Use resolvedHeaders for API calls
|
|
40
|
+
*/
|
|
41
|
+
authHeaders?: AuthHeaders;
|
|
42
|
+
/**
|
|
43
|
+
* Resolved headers ready for API calls.
|
|
44
|
+
* This includes the appropriate auth header based on strategy:
|
|
45
|
+
* - OAuth: Authorization header with provider token
|
|
46
|
+
* - Bearer: Authorization header from config
|
|
47
|
+
* - API Key: Custom header (e.g., x-api-key) from config
|
|
48
|
+
* - Custom: All custom headers from config
|
|
49
|
+
*/
|
|
50
|
+
resolvedHeaders?: Record<string, string>;
|
|
51
|
+
/**
|
|
52
|
+
* Original RS token (if OAuth was used).
|
|
53
|
+
*/
|
|
54
|
+
rsToken?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Provider access token (e.g., Google, Spotify, GitHub token).
|
|
57
|
+
* This is the token to use when calling external APIs.
|
|
58
|
+
*
|
|
59
|
+
* For OAuth: the mapped provider token
|
|
60
|
+
* For Bearer: the BEARER_TOKEN value
|
|
61
|
+
* For API Key: the API_KEY value
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const response = await fetch('https://api.example.com/data', {
|
|
66
|
+
* headers: { Authorization: `Bearer ${context.providerToken}` }
|
|
67
|
+
* });
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
providerToken?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Full provider token information (OAuth only).
|
|
73
|
+
* Uses snake_case to match storage format.
|
|
74
|
+
* Use this to check expiry or access scopes.
|
|
75
|
+
*/
|
|
76
|
+
provider?: ProviderTokens;
|
|
77
|
+
/** @deprecated Use providerToken instead */
|
|
78
|
+
serviceToken?: string;
|
|
79
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical types index.
|
|
3
|
+
* Import types from here for consistency across the codebase.
|
|
4
|
+
*/
|
|
5
|
+
export type { AuthHeaders, AuthStrategy, ResolvedAuth } from "./auth.js";
|
|
6
|
+
export type { RequestContext } from "./context.js";
|
|
7
|
+
export type { ProviderInfo, ProviderTokens } from "./provider.js";
|
|
8
|
+
export { toProviderInfo, toProviderTokens } from "./provider.js";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider token types and conversion utilities.
|
|
3
|
+
*
|
|
4
|
+
* ProviderTokens (snake_case) - storage/OAuth API format, defined in storage/interface.ts
|
|
5
|
+
* ProviderInfo (camelCase) - tool handler format, defined here
|
|
6
|
+
*/
|
|
7
|
+
export type { ProviderTokens } from "../storage/interface.js";
|
|
8
|
+
import type { ProviderTokens } from "../storage/interface.js";
|
|
9
|
+
/**
|
|
10
|
+
* Provider info in camelCase for tool handlers.
|
|
11
|
+
* Converted from ProviderTokens when passing to tools.
|
|
12
|
+
*/
|
|
13
|
+
export interface ProviderInfo {
|
|
14
|
+
accessToken: string;
|
|
15
|
+
refreshToken?: string;
|
|
16
|
+
expiresAt?: number;
|
|
17
|
+
scopes?: string[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Convert snake_case ProviderTokens to camelCase ProviderInfo.
|
|
21
|
+
* Use when bridging storage layer to tool context.
|
|
22
|
+
*/
|
|
23
|
+
export declare function toProviderInfo(tokens: ProviderTokens): ProviderInfo;
|
|
24
|
+
/**
|
|
25
|
+
* Convert camelCase ProviderInfo to snake_case ProviderTokens.
|
|
26
|
+
* Use when storing tool-provided data.
|
|
27
|
+
*/
|
|
28
|
+
export declare function toProviderTokens(info: ProviderInfo): ProviderTokens;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base64/base64url utilities for Cloudflare Workers.
|
|
3
|
+
* Uses Web APIs (btoa/atob).
|
|
4
|
+
*/
|
|
5
|
+
export declare function base64Encode(input: string): string;
|
|
6
|
+
export declare function base64Decode(input: string): string;
|
|
7
|
+
export declare function base64UrlEncode(bytes: Uint8Array): string;
|
|
8
|
+
export declare function base64UrlDecode(str: string): Uint8Array;
|
|
9
|
+
export declare function base64UrlEncodeString(input: string): string;
|
|
10
|
+
export declare function base64UrlDecodeString(input: string): string;
|
|
11
|
+
export declare function base64UrlEncodeJson(obj: unknown): string;
|
|
12
|
+
export declare function base64UrlDecodeJson<T = unknown>(value: string): T | null;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class CancellationError extends Error {
|
|
2
|
+
constructor(message?: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class CancellationToken {
|
|
5
|
+
private _isCancelled;
|
|
6
|
+
private _listeners;
|
|
7
|
+
get isCancelled(): boolean;
|
|
8
|
+
cancel(): void;
|
|
9
|
+
onCancelled(listener: () => void): void;
|
|
10
|
+
throwIfCancelled(): void;
|
|
11
|
+
}
|
|
12
|
+
export declare function createCancellationToken(): CancellationToken;
|
|
13
|
+
export declare function withCancellation<T>(operation: (token: CancellationToken) => Promise<T>, token: CancellationToken): Promise<T>;
|