import { type EnvironmentId, PreviewAutomationUnavailableError, type ProviderInstanceId, type ThreadId, } from "@t3tools/contracts"; import * as Context from "effect/Context"; import * as Effect from "effect/Effect"; export type McpCapability = "preview"; export interface McpInvocationScope { readonly environmentId: EnvironmentId; readonly threadId: ThreadId; readonly providerSessionId: string; readonly providerInstanceId: ProviderInstanceId; readonly capabilities: ReadonlySet; readonly issuedAt: number; readonly expiresAt: number; } export class McpInvocationContext extends Context.Service< McpInvocationContext, McpInvocationScope >()("t3/mcp/McpInvocationContext") {} export const requireMcpCapability = Effect.fn("mcp.requireCapability")(function* ( capability: McpCapability, ) { const invocation = yield* McpInvocationContext; if (!invocation.capabilities.has(capability)) { return yield* new PreviewAutomationUnavailableError({ capability, environmentId: invocation.environmentId, threadId: invocation.threadId, providerSessionId: invocation.providerSessionId, providerInstanceId: invocation.providerInstanceId, }); } return invocation; });