import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import type { SlackWebApi } from "@mono-agent/slack-adapter"; import type { TelegramMessageSender } from "@mono-agent/telegram-adapter"; import type { MonoAgentAppConfigInput } from "./app-config.js"; /** * Model-visible send tools for explicitly allowed, already-enabled communication adapters. * * This mirrors `MemoryRecall`: agent-app injects a stdio MCP server through * per-request runtime options. The adapter config remains the source of truth: * if Slack or Telegram is disabled, invalid, blocked by tool policy, or lacks an * allowed destination policy, the corresponding send tool is not exposed. When * exposed, each tool enforces the same adapter allowlist before calling the * adapter-owned sender. */ export declare const ADAPTER_SEND_TOOLS_MCP_SERVER_NAME = "mono-agent-adapter-send"; export interface SlackSendToolSettings { readonly botToken: string; readonly allowedChannelIds: readonly string[]; readonly allowAllChannels: boolean; } export interface TelegramSendToolSettings { readonly botToken: string; readonly allowedChatIds: readonly string[]; readonly allowAllChats: boolean; /** Self-hosted Bot API base URL (also unlocks file:// for non-strict path uploads). */ readonly apiRoot?: string; /** Upload cap for the TelegramSendFile tool; the resolver fills the 20 MiB default. */ readonly maxUploadBytes?: number; /** Which telegram tools the policy permits (the adapter config gates the rest). */ readonly tools: { readonly send: boolean; /** The single TelegramSendFile tool (document + photo via a `kind` param). */ readonly file: boolean; }; readonly sendTools?: { readonly scope?: "producing-conversation"; readonly pathScope?: "run-output"; }; /** Trusted exact request conversation, injected by the app-owned parent. */ readonly producingConversationId?: string; /** Trusted current-run output directory, injected by the app-owned parent. */ readonly runOutputDir?: string; /** Identity of the app-created directory object; prevents root path swaps. */ readonly runOutputIdentity?: FileIdentity; } /** * Blocking ask-the-user tool, backed by the app's interaction bridge. Channel * agnostic: the tool only talks to the bridge; the bridge posts the question * through whichever channel sink owns the conversation. `conversationId` is * present only in the spawned child (from the per-request env) — without it the * tool has no target and is not registered. */ export interface AskUserToolSettings { readonly bridgeUrl: string; readonly bridgeToken: string; readonly timeoutMs: number; readonly producerConversationId?: string; readonly interactionConversationId?: string; readonly runId?: string; } export interface AdapterSendToolsSettings { readonly slack?: SlackSendToolSettings; readonly telegram?: TelegramSendToolSettings; readonly askUser?: AskUserToolSettings; } export interface AdapterSendToolsClients { readonly slack?: Pick; readonly telegram?: Partial>; } export interface AdapterSendToolsHttpOptions { readonly fetchImpl?: typeof fetch; readonly deliveryHistory?: AdapterSendToolsDeliveryHistory; } export interface AdapterSendToolsDeliveryHistory { readonly bridgeUrl: string; readonly bridgeToken: string; } export interface AdapterSendToolsDeliveryHistoryCapabilityIssuer { issueDeliveryHistoryCapability(input: { readonly runId: string; readonly producerConversationId: string; readonly allowedChannels: readonly ("slack" | "telegram")[]; }): { readonly url: string; readonly token: string; release(): void; }; } export interface AdapterSendToolsRuntimeExtension { readonly runtimeOptions: { readonly mcpServers: Record; }; readonly cleanup: () => Promise; readonly settleCleanup?: () => Promise; } /** * Where a posted message should be linked back to its producing conversation. * Forwarded to the stdio child so `SlackSendMessage` can record * `(channel, ts) → conversationId` — see {@link appendPostedMessage}. */ export interface AdapterSendToolsIndexing { readonly conversationId: string; readonly indexPath: string; } /** Minimal shape of the per-request runtime-options input we read. */ interface AdapterSendToolsRequestInput { readonly request?: { readonly conversationId?: string; readonly replyTo?: { readonly conversationId?: string; }; }; readonly runId?: string; } export interface AdapterSendToolsResolveOptions { readonly allowedTools?: readonly string[] | undefined; readonly disallowedTools?: readonly string[] | undefined; readonly logger?: { warn?: (message: string, metadata?: Record) => void; } | undefined; /** Suppress bridge-backed AskUser for MCP-incompatible routes. */ readonly suppressInteractionTools?: boolean | undefined; /** App-owned master bridge settings; never sourced from project MCP config. */ readonly interaction?: AdapterSendToolsInteractionEnv | undefined; } export declare function resolveAdapterSendToolsSettings(input: MonoAgentAppConfigInput, options?: AdapterSendToolsResolveOptions): Promise; export declare function adapterSendToolNames(settings: AdapterSendToolsSettings): readonly string[]; /** * Public re-export of the per-tool allow check so callers (e.g. the Telegram * channel driver) can gate behavior on whether a specific adapter send tool is * permitted by `tools.allowedTools`/`disallowedTools`, matching this module's policy. */ export declare function isAdapterSendToolAllowed(name: string, policy: { readonly allowedTools?: readonly string[]; readonly disallowedTools?: readonly string[]; }): boolean; /** * Per-request context forwarded to the stdio child. `conversationId` alone * targets AskUser at the producing conversation; `indexPath` additionally * enables the posted-message index (Slack reply continuity). */ export interface AdapterSendToolsChildContext { readonly conversationId?: string; readonly interactionConversationId?: string; readonly runId?: string; readonly indexPath?: string; readonly runOutputDir?: string; readonly runOutputIdentity?: FileIdentity; readonly deliveryHistory?: AdapterSendToolsDeliveryHistory; } export interface AdapterSendToolsInteractionEnv { readonly bridgeUrl: string; readonly bridgeToken: string; readonly timeoutMs: number; } export declare function adapterSendToolsMcpEnv(configPath: string, allowedTools: readonly string[], context?: AdapterSendToolsChildContext, interaction?: AdapterSendToolsInteractionEnv): Record; export interface AdapterSendToolsChildConfig { readonly input: MonoAgentAppConfigInput; readonly allowedTools: readonly string[]; readonly indexing?: AdapterSendToolsIndexing; readonly deliveryHistory?: AdapterSendToolsDeliveryHistory; } export declare function adapterSendToolsChildConfigFromEnv(env: Record, cwd: string): AdapterSendToolsChildConfig; export declare function adapterSendToolsMcpServerSpec(configPath: string, cwd: string, allowedTools: readonly string[], context?: AdapterSendToolsChildContext, interaction?: AdapterSendToolsInteractionEnv): Record; /** * Per-request runtime extension that injects the adapter-send stdio MCP server. It * reads the request's producing conversationId and, when an `indexPath` is * configured, forwards both to the child so a `SlackSendMessage` post is linked * back to this conversation (so a later in-thread reply resumes it). */ export declare function createAdapterSendToolsRuntimeExtension(configPath: string, cwd: string, allowedTools: readonly string[], indexPath?: string, interaction?: AdapterSendToolsInteractionEnv, runOutputRoot?: string, deliveryHistoryCapabilityIssuer?: AdapterSendToolsDeliveryHistoryCapabilityIssuer): (input: AdapterSendToolsRequestInput) => Promise; export declare function createAdapterSendToolsClients(settings: AdapterSendToolsSettings, options?: AdapterSendToolsHttpOptions): Promise; export declare function createAdapterSendToolsServer(settings: AdapterSendToolsSettings, clients: AdapterSendToolsClients, indexing?: AdapterSendToolsIndexing, options?: AdapterSendToolsHttpOptions): Promise; interface FileIdentity { readonly dev: number; readonly ino: number; } export {}; //# sourceMappingURL=adapter-send-tools.d.ts.map