/**
 * MCP Connector Manager
 *
 * Connects the Studiograph agent to third-party MCP servers so the agent can
 * query external data sources on demand.
 *
 * Supports two transports:
 *   - HTTP (Streamable HTTP) — `url` + optional `headers`
 *   - Stdio — `command` + `args` + optional `env`
 *
 * Two-layer config:
 *
 *   Workspace layer (.studiograph/connectors/<name>.json)
 *     Non-secret transport config committed to git. Secrets replaced with
 *     $ENV_VAR placeholders resolved at runtime.
 *
 *   Homedir layer (~/.studiograph/connectors/<name>.json)
 *     Full config with literal secrets (mode 0600, never committed).
 *     When present, homedir fields override workspace fields.
 *
 * Each connector's tools are injected into the agent with a namespaced prefix:
 *   linear__search_issues, etc.
 *
 * Connection failures are non-fatal — the failing connector is skipped with a warning.
 */
import type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
import type { AuthService } from '../services/auth-service.js';
export declare const CONNECTORS_DIR: string;
export interface ConnectorConfig {
    /** Unique name used as the tool prefix (e.g. "linear" → "linear__search_issues") */
    name: string;
    /** Remote MCP server URL */
    url: string;
    /** HTTP headers (e.g. { "Authorization": "Bearer ..." }) */
    headers?: Record<string, string>;
    /** Human-readable description shown in tool labels */
    description?: string;
    /** Pre-registered OAuth app credentials (for servers that don't support dynamic registration) */
    oauth?: {
        client_id: string;
        client_secret?: string;
    };
    /** Auto-detected: server advertises OAuth support via .well-known */
    requiresOAuth?: boolean;
}
export declare class ConnectorManager {
    /**
     * Load all connector configs, merging workspace + homedir layers.
     */
    static loadConfigs(workspacePath?: string): ConnectorConfig[];
    /**
     * Load connector configs from workspace .studiograph/connectors/ only.
     */
    static loadWorkspaceConfigs(workspacePath: string): ConnectorConfig[];
    /**
     * Save full config to homedir (mode 0600, never committed).
     *
     * Phase 5 dual-write: when the encrypted store has been initialized,
     * the connector's secret-bearing fields (`headers.Authorization`,
     * `oauth.client_secret`) are mirrored into the store under
     * workspace-scope keys (`connector.<name>.auth`,
     * `connector.<name>.oauth_secret`). Failures never block the file
     * write — see dual-write.ts. The legacy file remains authoritative
     * through Phase 5; Phase 6 flipped the read path.
     */
    static saveConfig(config: ConnectorConfig): void;
    /**
     * Lazy import of the dual-write helper so the secrets store is only
     * loaded when the flag is on. Best-effort — failures log + swallow.
     */
    private static _dualWrite;
    /** Save sanitized config to workspace .studiograph/connectors/ (git-tracked). */
    static saveWorkspaceConfig(config: ConnectorConfig, workspacePath: string): void;
    static removeConfig(name: string, workspacePath?: string): boolean;
    /** Load a single connector, merging workspace + homedir layers. */
    static loadConfig(name: string, workspacePath?: string): ConnectorConfig | null;
    /**
     * Strip secret fields from a connector config, replacing them with $ENV_VAR
     * placeholders. Safe to commit to git.
     */
    static stripSecrets(config: ConnectorConfig): ConnectorConfig;
    /** Expands $ENV_VAR references; returns the literal string otherwise. */
    static resolveEnvVar(value: string): string;
    /**
     * Parse a JSON config block into ConnectorConfig(s).
     * Supports three formats:
     *   A) Single server: { command, args, env } or { url, headers }
     *   B) Named servers: { mcpServers: { name: { ... } } }
     *   C) Single named: { name: "...", command/url: "..." }
     */
    static parseConfigBlock(json: string, defaultName?: string): ConnectorConfig[];
    private static _normalizeServerConfig;
    /** Try to infer a connector name from the URL. */
    private static _inferName;
    /**
     * For each connector config: connect to the MCP server, fetch its tool list,
     * and return tool objects with namespaced names.
     *
     * Auth precedence (single rule across the codebase):
     *   1. Per-user OAuth tokens (when `opts.userId` + `opts.authService` resolve
     *      `hasOAuthTokens === true`) — restores the original `McpOAuthProvider`
     *      design intent: tokens stored per `(user, connector)` are actually
     *      *used* upstream. The provider's `tokens()` returns the user's row;
     *      the SDK refreshes via `saveTokens` writing back to the same row.
     *   2. Workspace static `Authorization` header (`config.headers.Authorization`)
     *      — admin-configured shared identity. Used when the caller has no user
     *      session (CLI, MCP server, agent pool spawned without `userId`) or
     *      when the user hasn't bound their own OAuth credential yet.
     *   3. Skip — `requiresOAuth` connector with neither per-user OAuth nor a
     *      workspace header has no usable credential.
     *
     * Failures are non-fatal — the connector is skipped with a console.warn.
     */
    static buildTools(configs: ConnectorConfig[], opts?: {
        userId?: number;
        authService?: AuthService;
        /** Studiograph server URL — only consulted if a refresh fails and the SDK
         *  initiates a re-auth flow (which the runtime can't complete anyway —
         *  we surface a 401 to the UI instead). Safe to pass an empty string. */
        serverUrl?: string;
        timeoutMs?: number;
    }): Promise<any[]>;
    /**
     * Decide which credential to use for a connector. Public so the precedence
     * rule can be unit-tested without spinning up a real MCP server.
     *
     * Returns one of:
     *   - `{ mode: 'user-oauth', authProvider }`: per-user OAuth tokens win. The
     *     transport will read tokens via the provider's `tokens()` and refresh
     *     back to the user's row.
     *   - `{ mode: 'workspace-header' }`: the workspace static `Authorization`
     *     header is used. The transport gets the header directly; the OAuth
     *     machinery is not touched.
     *   - `{ mode: 'skip-placeholder' }`: the workspace header contains an
     *     unresolved `$ENV_VAR` placeholder — nothing usable, skip silently.
     *   - `{ mode: 'skip-no-credential' }`: connector requires OAuth but has
     *     neither per-user tokens nor a workspace header.
     */
    static resolveConnectorAuth(config: ConnectorConfig, opts?: {
        userId?: number;
        authService?: AuthService;
        serverUrl?: string;
    }): {
        mode: 'user-oauth';
        authProvider: OAuthClientProvider;
    } | {
        mode: 'workspace-header';
    } | {
        mode: 'skip-placeholder';
    } | {
        mode: 'skip-no-credential';
    };
    /** Resolve OAuth credentials from a connector config or fall back to broker. */
    private static _resolveOAuthCredentials;
    private static _readDir;
    private static _merge;
    private static _validate;
    private static _buildConnectorTools;
}
