/**
* Type definitions for MCP Server
*/
// Environment bindings (from wrangler.jsonc)
export interface Env {
// Durable Object binding
MCP_OBJECT: DurableObjectNamespace;
// KV for OAuth state
OAUTH_KV: KVNamespace;
// KV for encrypted token storage (@jezweb/oauth-token-manager)
TOKEN_KV: KVNamespace;
TOKEN_ENCRYPTION_KEY: string;
// D1 for auth + conversation memory (required for better-auth)
DB: D1Database;
// Workers AI binding (for admin chat + AI Gateway)
AI?: Ai;
// better-auth configuration
BETTER_AUTH_SECRET: string; // Encryption secret (generate: openssl rand -base64 32)
BETTER_AUTH_URL: string; // Base URL (e.g., https://my.mcp.jezweb.ai)
// Server display info (used by @jezweb/mcp-ui homepage)
SERVER_DISPLAY_NAME?: string; // Server name for homepage (default: from code)
SERVER_DESCRIPTION?: string; // Server description for SEO
SERVER_TAGLINE?: string; // Tagline shown below title
// Identity provider selection (legacy - better-auth manages this now)
// Options: 'google' | 'microsoft' | 'github'
IDENTITY_PROVIDER?: string;
// OAuth credentials - only needed for the selected provider
// Google OAuth (set via wrangler secret put)
GOOGLE_CLIENT_ID: string;
GOOGLE_CLIENT_SECRET: string;
// Microsoft Entra OAuth (only needed if IDENTITY_PROVIDER=microsoft)
MICROSOFT_CLIENT_ID?: string;
MICROSOFT_CLIENT_SECRET?: string;
MICROSOFT_TENANT_ID?: string; // Optional: 'common', 'organizations', 'consumers', or tenant ID
// GitHub OAuth (only needed if IDENTITY_PROVIDER=github)
GITHUB_CLIENT_ID?: string;
GITHUB_CLIENT_SECRET?: string;
// Cookie encryption key (required for all providers)
COOKIE_ENCRYPTION_KEY: string;
// Optional: Bearer token for programmatic access (legacy single token)
AUTH_TOKEN?: string;
// Optional: Comma-separated list of admin emails
ADMIN_EMAILS?: string;
// AI Gateway configuration (for external providers)
AI_GATEWAY_ID?: string; // Gateway ID (default: "default")
CF_ACCOUNT_ID?: string; // Cloudflare account ID (optional if set in wrangler)
CF_AIG_TOKEN?: string; // AI Gateway auth token (if Authenticated Gateway is enabled)
// External provider API keys (optional - can use BYOK in AI Gateway instead)
// Set via: echo "key" | npx wrangler secret put SECRET_NAME
OPENAI_API_KEY?: string;
ANTHROPIC_API_KEY?: string;
GOOGLE_AI_API_KEY?: string;
GROQ_API_KEY?: string;
// Conversation memory configuration
ENABLE_CONVERSATION_MEMORY?: string; // 'true' to enable D1 storage
CONVERSATION_TTL_HOURS?: string; // Default: 168 (7 days)
MAX_CONTEXT_MESSAGES?: string; // Default: 50
// Internal agent configuration
ENABLE_INTERNAL_AGENT?: string; // 'true' to enable ask_agent tool
INTERNAL_AGENT_MODEL?: string; // Default: @cf/qwen/qwen2.5-coder-32b-instruct
// Admin dashboard configuration
ENABLE_ADMIN_CHAT?: string; // 'true' to show AI chat panel (default: false)
// Lead generation chat widget (L2Chat)
ENABLE_LEAD_CHAT?: string; // 'true' to show L2Chat widget on homepage
}
// Admin session stored in KV
export interface AdminSession {
id: string; // Session UUID
email: string; // Admin email
name: string; // Display name
picture?: string; // Profile picture URL
expiresAt: number; // Session expiry timestamp (ms)
}
// OAuth user props (stored in encrypted session)
// Uses index signature to satisfy McpAgent type constraint
export interface Props {
[key: string]: unknown;
id: string; // Provider user ID (stable identifier)
email: string; // User email
name: string; // User display name
picture?: string; // Profile picture URL
accessToken: string; // OAuth access token
refreshToken?: string; // OAuth refresh token (not available for GitHub)
tokenExpiresAt?: number; // Token expiry timestamp (ms) - undefined for GitHub
identityProvider?: string; // 'google' | 'microsoft' | 'github'
}
// =============================================================================
// Tool Registry & Metadata (for tool search / defer_loading support)
// =============================================================================
/**
* Tool metadata for introspection and defer_loading support.
* Supports Anthropic's tool search beta for 85% token reduction.
*/
export interface ToolMetadata {
name: string; // Tool identifier (snake_case)
description: string; // Tool description for LLM
inputSchema: Record<string, unknown>; // JSON Schema from Zod
defer_loading?: boolean; // Mark for lazy loading (Anthropic beta)
category?: ToolCategory; // Tool classification
tags?: string[]; // Searchable tags (e.g., 'google-api', 'expensive')
requiresAuth?: string; // OAuth provider needed (e.g., 'google')
authScopes?: string[]; // Required OAuth scopes
}
/** Tool categories for organization and filtering */
export type ToolCategory = 'query' | 'mutation' | 'integration' | 'utility';
// =============================================================================
// AI Chat Types (for admin AI chat interface)
// =============================================================================
/** Chat message roles */
export type ChatRole = 'user' | 'assistant' | 'system' | 'tool';
/** Chat message in conversation */
export interface ChatMessage {
role: ChatRole;
content: string;
toolCallId?: string; // For tool results
toolCalls?: ToolCall[]; // For assistant tool calls
timestamp?: number;
}
/** Tool call made by AI */
export interface ToolCall {
id: string;
name: string;
arguments: Record<string, unknown>;
}
/** Admin chat session stored in KV */
export interface AdminChatSession {
id: string;
adminEmail: string;
messages: ChatMessage[];
createdAt: number;
updatedAt: number;
provider?: string; // Selected AI provider
model?: string; // Selected model
}
// =============================================================================
// AI Provider Types (for multi-provider support via AI Gateway)
// =============================================================================
/** Supported AI providers */
export type AIProvider =
| 'cloudflare' // Workers AI (free edge models)
| 'openai' // OpenAI via AI Gateway
| 'anthropic' // Anthropic via AI Gateway
| 'google-ai-studio'; // Google AI via AI Gateway
/** Chat completion options */
export interface ChatOptions {
provider: AIProvider;
model: string;
tools?: ToolMetadata[];
stream?: boolean;
maxTokens?: number;
temperature?: number;
}
/** Streaming delta from AI response */
export interface ChatDelta {
content?: string;
toolCalls?: ToolCall[];
finishReason?: 'stop' | 'tool_calls' | 'length';
}
/** SSE event types for streaming chat */
export type SSEEventType =
| 'content' // Text content delta
| 'tool_call' // Tool call request
| 'tool_result' // Tool execution result
| 'error' // Error occurred
| 'done'; // Stream complete
// =============================================================================
// Conversation Memory Types (D1-backed)
// =============================================================================
/** Conversation stored in D1 */
export interface Conversation {
id: string; // UUID - unguessable = implicit access control
createdAt: number; // Unix timestamp (seconds)
updatedAt: number; // Unix timestamp (seconds)
metadata?: ConversationMetadata;
}
/** Conversation metadata (stored as JSON) */
export interface ConversationMetadata {
provider?: string; // AI provider (cloudflare, anthropic, etc.)
model?: string; // Model name
userEmail?: string; // For admin chat context
source?: 'admin' | 'mcp' | 'api'; // Where conversation originated
[key: string]: unknown; // Extensible
}
/** Message stored in D1 */
export interface ConversationMessage {
id: string; // UUID
conversationId: string; // FK to conversations.id
role: ChatRole; // 'user' | 'assistant' | 'tool' | 'system'
content: string; // Message text
toolCalls?: ToolCall[]; // For assistant messages with tool calls
toolCallId?: string; // For tool result messages
createdAt: number; // Unix timestamp (seconds)
}
/** Response including conversation context */
export interface ConversationResponse {
conversationId: string; // UUID - client stores this
messages: ConversationMessage[]; // Recent history (configurable limit)
response: ChatDelta; // AI response
}
// =============================================================================
// Internal Agent Types (optional Workers AI gatekeeper)
// =============================================================================
/** Internal agent configuration */
export interface InternalAgentConfig {
enabled: boolean; // ENABLE_INTERNAL_AGENT
model: string; // Workers AI model for gatekeeper
maxToolCalls: number; // Max tool calls per request
systemPrompt?: string; // Custom system prompt
}
/** Result from internal agent */
export interface AgentResult {
conversationId?: string;
response: string; // Clean text response
toolsUsed?: string[]; // Names of tools that were called
}