import type { ConnectionTokenIssuanceOutcome, ConnectionTokenIssuancePath, SecretProjectionClass, ToolActionRequestStatus, ToolApplicationStatus, ToolApplicationType, ToolAuditEventType, ToolAuditOutcome, ToolCatalogEntryKind, ToolCatalogEntryStatus, ToolConnectionHealthStatus, ToolConnectionKind, ToolConnectionLifecycleEventType, ToolInvocationApprovalState, ToolInvocationStatus, ToolMcpGatewayContextScopeType, ToolMcpGatewayDefaultProfileMode, ToolMcpGatewayStatus, ToolMcpGatewayTokenAction, ToolMcpGatewayTokenSubjectType, ToolPolicyDecision, ToolPolicyType, ToolProfileBindingTargetType, ToolProfileDefaultAction, ToolProfileEntryEffect, ToolProfileEntrySelectorType, ToolProfileStatus, ToolRateLimitWindowKind, ToolRiskLevel, ToolRuntimeKind, ToolRuntimeSlotStatus } from "../constants.js"; export type { ConnectionTokenIssuanceOutcome, ConnectionTokenIssuancePath, SecretProjectionClass, ToolActionRequestStatus, ToolApplicationStatus, ToolApplicationType, ToolAuditEventType, ToolAuditOutcome, ToolCatalogEntryKind, ToolCatalogEntryStatus, ToolConnectionHealthStatus, ToolConnectionKind, ToolConnectionLifecycleEventType, ToolInvocationApprovalState, ToolInvocationStatus, ToolMcpGatewayContextScopeType, ToolMcpGatewayDefaultProfileMode, ToolMcpGatewayStatus, ToolMcpGatewayTokenAction, ToolMcpGatewayTokenSubjectType, ToolPolicyDecision, ToolPolicyType, ToolProfileBindingTargetType, ToolProfileDefaultAction, ToolProfileEntryEffect, ToolProfileEntrySelectorType, ToolProfileStatus, ToolRateLimitWindowKind, ToolRiskLevel, ToolRuntimeKind, ToolRuntimeSlotStatus, }; export type ToolActorType = "agent" | "user" | "system" | "plugin"; export type ToolConnectionTransport = "mcp_remote" | "rest_api" | "local_stdio" | "chat_sdk" | "runtime_auth" | "voice"; export type ToolConnectionPurpose = "tool" | "channel" | "ai"; export type ToolConnectionAuthKind = "oauth" | "api_key" | "none"; export type ToolConnectionOwnership = "platform_shared" | "platform_provisioned" | "customer" | "dcr"; export type ToolConnectionCredentialSource = "paperclip_vault" | "vercel_connect"; export type ToolConnectionStatus = "draft" | "active" | "disabled" | "archived"; export type ToolConnectionInstallTargetType = "company" | "agent"; export type ConnectionGrantKind = "organization" | "user" | "agent"; export type ConnectionGrantStatus = "active" | "revoked" | "expired" | "needs_reauthorization"; export type ToolConnectionCredentialPolicy = "shared" | "per_user" | "per_user_with_fallback" | "per_agent"; export type ConnectionGrantMemberSubjectType = "user"; export type ToolCredentialPlacement = "header" | "env" | "url"; export interface McpConnectionCredentialRef { name: string; secretId: string; version?: number | "latest"; placement: ToolCredentialPlacement; key: string; prefix?: string | null; } export interface ToolCredentialSecretRef { secretId: string; versionSelector?: number | "latest"; configPath: string; required?: boolean; label?: string | null; projectionClass?: SecretProjectionClass; projectionAllowlistKey?: string | null; keyScope?: string; expiresAt?: string; } export interface ToolRedactedValueSummary { summary: string; sizeBytes?: number | null; sha256?: string | null; redactedFields?: string[]; artifactId?: string | null; } export type VercelConnectPrincipalMode = "app" | "user"; /** Durable, non-secret connector provenance safe to return to the board UI. */ export interface VercelConnectCredentialSummary { provider: "vercel_connect"; connectorId: string; connectorUid: string; service: string; connectorType: string; principalMode: VercelConnectPrincipalMode; headerName: string; headerPrefix?: string | null; scopes: string[]; } export type VercelConnectCredentialReference = VercelConnectCredentialSummary; /** Redacted issuance metadata. Subject ids, bearer values, claims and vendor metadata are omitted. */ export interface VercelConnectGrantSummary { provider: "vercel_connect"; subjectType: "app" | "user"; installationId?: string; tenantId?: string; tokenId?: string; expiresAt?: string; lastVerifiedAt?: string; } /** Server-only persisted form; API mappers must remove the pseudonymous subject id. */ export interface VercelConnectGrantReference extends VercelConnectGrantSummary { subjectId?: string; } export interface ToolApplication { id: string; companyId: string; applicationKey?: string; name: string; description: string | null; type: ToolApplicationType; status: ToolApplicationStatus; pluginId: string | null; ownerAgentId: string | null; ownerUserId: string | null; metadata: Record | null; archivedAt: Date | null; createdAt: Date; updatedAt: Date; } export interface ToolConnection { agentInstructions?: import("../connection-instructions.js").ConnectionAgentInstructions | null; id: string; companyId: string; applicationId: string; name: string; uid: string; connectionKind: ToolConnectionKind; connectionPurpose: ToolConnectionPurpose; ownership: ToolConnectionOwnership; transport: ToolConnectionTransport; authKind: ToolConnectionAuthKind; credentialSource: ToolConnectionCredentialSource; externalCredential?: VercelConnectCredentialSummary | null; credentialPolicy: ToolConnectionCredentialPolicy; status?: ToolConnectionStatus; transportConfig: Record; config?: Record; credentialSecretRefs: ToolCredentialSecretRef[]; /** Saved client secret for the requesting user, or the shared connection. Never includes secret material. */ hasSavedOAuthClientSecret?: boolean; credentialRefs?: McpConnectionCredentialRef[]; healthStatus: ToolConnectionHealthStatus; /** Managed GitHub grant state; transient health failures do not require sign-in. */ requiresReauthorization?: boolean; healthMessage?: string | null; healthCheckedAt: Date | null; lastHealthAt?: Date | string | null; lastCatalogRefreshAt?: Date | string | null; lastError: string | null; /** Most recent tool-call event timestamp for this connection; only populated by list endpoints. */ lastUsedAt?: Date | string | null; enabled: boolean; createdByAgentId: string | null; createdByUserId: string | null; createdAt: Date; updatedAt: Date; installs?: ToolConnectionInstall[]; grants?: ConnectionGrant[]; } export interface ConnectionGrant { id: string; companyId: string; connectionId: string; kind: ConnectionGrantKind; subjectUserId: string | null; subjectAgentId?: string | null; providerTenant: { name?: string; externalId?: string; oauth?: { strategy?: string; accessTokenExpiresAt?: string | null; scopes?: string[]; /** * Whether `scopes` is what the provider asserted, or only what we requested. * `requested_fallback` means the token response carried no `scope`, so the value is * inferred from the request per RFC 6749 §5.1 and is not a provider assertion. */ scopeSource?: "provider" | "requested_fallback"; /** Scopes the provider asserted that we never asked for. Empty unless it over-granted. */ unrequestedScopes?: string[]; /** * The scopes the authorization URL sent for *this* grant, kept per-grant because two * users can authorize the same connection with different scopes. A refresh has no fresh * request, so this is the baseline its response is judged against. */ requestedScopes?: string[]; tokenType?: string; refreshTokenExpiresAt?: string; refreshedAt?: string; refreshLease?: { id?: string; expiresAt?: string; }; }; slackSearch?: { endpointId: string; workspaceId: string; slackUserId: string; clientRevision: string; }; github?: { userId: string; login: string; avatarUrl?: string; installationCount: number; repositoryCount: number; repositorySelection: "all" | "selected" | "mixed" | "none"; installationIds: string[]; installationOwnerLogins: string[]; /** Repository metadata visible to this credential; refreshed from GitHub. */ repositories?: Array<{ id: string; fullName: string; installationId: string; ownerType?: "personal" | "organization"; private?: boolean; }>; installationUrl?: string; managementUrl?: string; appSlug?: string; accessRevision?: string; lastAccessRefreshAt?: string; lastWebhookAt?: string; webhookHealth?: "pending" | "healthy" | "unhealthy"; }; } | null; credentialSecretRefs: ToolCredentialSecretRef[]; externalCredential?: VercelConnectGrantSummary | null; status: ConnectionGrantStatus; isDefault: boolean; createdByAgentId: string | null; createdByUserId: string | null; revokedAt: Date | null; revokedByAgentId: string | null; revokedByUserId: string | null; lastUsedAt: Date | null; createdAt: Date; updatedAt: Date; members?: ConnectionGrantMember[]; delegations?: ConnectionGrantDelegation[]; /** * Server-computed authorization for this grant (PAP-17835). The UI renders the * §3 permission matrix from these booleans; it must never rebuild policy from * `membershipRole` strings, because grant authorization also depends on * creator/subject identity that the client cannot evaluate. */ capabilities?: ConnectionGrantCapabilities; } export interface ConnectionGrantCapabilities { canRevoke: boolean; canEditAudience: boolean; } /** * Connection-level capabilities for the personal-connections UX. Policy-forbidden * actions are omitted from the UI entirely; `false` here means "do not render", * not "render disabled". */ export interface ToolConnectionCapabilities { canConfigure: boolean; canCreateOrganizationGrant: boolean; canSetCompanyInstall: boolean; canConnectAsCurrentUser: boolean; canManageAgentInstalls: boolean; canViewOtherPersonalIdentities: boolean; editableAgentIds: string[]; } /** * Capabilities needed before a tool connection exists. These are returned by * the company-scoped app gallery read so create flows do not have to infer * authorization from membership roles or wait for a connection id. */ export interface ToolConnectionCreateCapabilities { canCreateOrganizationGrant: boolean; organizationGrantReason: string | null; canSetCompanyInstall: boolean; companyInstallReason: string | null; } export interface ConnectionGrantsResponse { connection: { id: string; uid: string; }; grants: ConnectionGrant[]; capabilities: ToolConnectionCapabilities; currentUserId: string | null; members: ConnectionAudienceMember[]; } /** A company member that can appear in an organization grant's audience. */ export interface ConnectionAudienceMember { userId: string; name: string | null; email: string | null; } export interface ConnectionGrantDelegation { id: string; companyId: string; grantId: string; agentId: string; createdByUserId: string; createdAt: Date; } export interface ConnectionGrantMember { id: string; companyId: string; grantId: string; subjectType: ConnectionGrantMemberSubjectType; subjectId: string; createdAt: Date; } export interface ToolConnectionInstall { id: string; companyId: string; connectionId: string; targetType: ToolConnectionInstallTargetType; targetId: string; createdByAgentId: string | null; createdByUserId: string | null; createdAt: Date; } export interface ToolConnectionInstallSnapshot { connectionId: string; installs: ToolConnectionInstall[]; } /** * What a connection removal actually tore down (PAP-17119). * * Removing an app is a revocation boundary, not a cosmetic archive, so the * receipt is counts and outcomes only — never a secret name, key, or value, * because this summary is echoed into the activity log the whole company reads. */ export interface ToolConnectionRemovalSummary { /** Connection-owned secrets revoked at the provider and deleted locally. */ secretsRevoked: number; /** Secrets left in place because another consumer still binds them. */ secretsRetainedShared: number; /** Credential refs cleared off the connection row. */ credentialRefsCleared: number; /** `company_secret_bindings` rows removed for this connection. */ secretBindingsRemoved: number; grantsRevoked: number; installsRemoved: number; /** * `deleted` when the app-managed `app:` profile could go away, * `archived` when a gateway still references it (the row survives with no * entries and a non-active status), `absent` when there was never one. */ appProfile: "deleted" | "archived" | "absent"; appProfileEntriesRemoved: number; appProfileBindingsRemoved: number; catalogEntriesMarkedRemoved: number; oauthStatesDiscarded: number; /** Token hashes wiped from the retained connection-token issuance ledger. */ tokenIssuanceHashesCleared: number; /** * Live local runtimes shut down. A running child process holds the injected * credential in memory, so it is an access path of its own. */ runtimeSlotsStopped: number; gatewayTokensRevoked: number; gatewaySessionsRevoked: number; applicationArchived: boolean; externalCredentialCleanup?: { provider: "vercel_connect"; userSubjectsAttempted: number; userSubjectsRevoked: number; userSubjectFailures: number; appSubjectCleanup: "not_applicable" | "manage_in_vercel"; manageUrl: string; } | null; } export interface ToolConnectionRemovalResult { connection: ToolConnection; removal: ToolConnectionRemovalSummary; } export type ConnectionTokenScope = string | string[]; export type ConnectionTokenSubject = { type: "app"; } | { type: "user"; userId: string; }; export declare const CONNECTION_RECOVERABLE_ERROR_CODES: readonly ["user_authorization_required", "agent_authorization_required", "organization_authorization_required", "grant_audience_denied", "grant_revoked", "needs_reauthorization", "installation_required", "connection_not_installed", "subject_not_permitted", "standing_delegation_required"]; export type ConnectionRecoverableErrorCode = (typeof CONNECTION_RECOVERABLE_ERROR_CODES)[number]; export interface ConnectionRecoverableErrorPayload { code: ConnectionRecoverableErrorCode; connection: { uid: string; }; subject?: ConnectionTokenSubject; remediation?: Record; } export interface ConnectionTokenRequest { subject?: ConnectionTokenSubject; scope?: ConnectionTokenScope; requestedTtlSeconds?: number; grantId?: string; } export interface ConnectionTokenAttribution { agentId: string; runId: string; issueId: string | null; projectId: string | null; responsibleUserId: string | null; } export interface ConnectionTokenMintedResponse { status: "minted"; connectionId: string; connection: { id: string; uid: string; }; grantId: string; providerTenantId?: string; externalSubject?: string; metadata?: Record; path: "exchange"; token: string; tokenType: "Bearer" | string; expiresAt: string; ttlSeconds: number; scope: string[]; attribution: ConnectionTokenAttribution; } export interface ConnectionTokenUseEnvLeaseResponse { status: "use_env_lease"; code: "use_env_lease"; connectionId: string; connection: { id: string; uid: string; }; grantId: string; path: "static"; message: string; scope: string[]; attribution: ConnectionTokenAttribution; } export type ConnectionTokenResponse = ConnectionTokenMintedResponse | ConnectionTokenUseEnvLeaseResponse; export interface StartConnectionAuthorizationRequest { subjectUserId: string; scopes?: string[]; returnTo?: string; } export interface StartConnectionAuthorizationResponse { url: string; } export interface ConnectionUsageDailyBucket { date: string; issuances: { total: number; byOutcome: Record; byPath: Record; }; invocations: { total: number; byRiskLevel: Record; }; deliveries: { received: number; forwarded: number; }; } export interface ConnectionUsageResponse { connection: { id: string; uid: string; }; range: "7d" | "30d"; buckets: ConnectionUsageDailyBucket[]; } export interface ConnectionTokenIssuance { id: string; companyId: string; applicationId: string | null; connectionId: string; agentId: string; runId: string | null; issueId: string | null; projectId: string | null; responsibleUserId: string | null; path: ConnectionTokenIssuancePath; requestedScope: string[]; issuedScope: string[]; ttlSeconds: number | null; expiresAt: Date | null; tokenHash: string | null; outcome: ConnectionTokenIssuanceOutcome; errorCode: string | null; metadata: Record | null; createdAt: Date; } export interface ToolCatalogEntry { id: string; companyId: string; applicationId: string | null; connectionId: string; entryKind: ToolCatalogEntryKind; name?: string; toolName: string; title: string | null; description: string | null; inputSchema: Record | null; outputSchema: Record | null; annotations: Record | null; riskLevel: ToolRiskLevel; isReadOnly: boolean; isWrite: boolean; isDestructive: boolean; status: ToolCatalogEntryStatus; addedAt: Date; version: string | null; versionHash?: string | null; schemaHash: string | null; firstSeenAt: Date; lastSeenAt: Date; reviewedAt: Date | null; reviewedByAgentId: string | null; reviewedByUserId: string | null; quarantinedAt?: Date | string | null; quarantineReason?: string | null; createdAt: Date; updatedAt: Date; } export interface ToolProfile { id: string; companyId: string; profileKey: string; name: string; description: string | null; status: ToolProfileStatus; defaultAction: ToolProfileDefaultAction; newToolsReviewedAt: Date | null; newToolsPendingCount?: number; metadata: Record | null; createdAt: Date; updatedAt: Date; } export interface ToolProfileEntry { id: string; companyId: string; profileId: string; selectorType: ToolProfileEntrySelectorType; effect: ToolProfileEntryEffect; applicationId: string | null; connectionId: string | null; catalogEntryId: string | null; toolName: string | null; riskLevel: ToolRiskLevel | null; conditions: Record | null; createdAt: Date; updatedAt: Date; } export interface ToolProfileBinding { id: string; companyId: string; profileId: string; targetType: ToolProfileBindingTargetType; targetId: string; priority: number; metadata: Record | null; createdByAgentId: string | null; createdByUserId: string | null; createdAt: Date; updatedAt: Date; } export interface ToolMcpGatewayBearerAuthConfig { enabled: boolean; tokenPrefix: "pcgw"; defaultTtlSeconds: number | null; requireFiniteExpiry: boolean; longLivedTokenRequiresOverride: boolean; } export interface ToolMcpGatewayOAuthReservedConfig { enabled: false; reservedFor: "v1_5"; protectedResourceMetadataPath?: string | null; dynamicClientRegistration?: false; authorizationCodePkce?: false; } export interface ToolMcpGatewayAuthConfig { version: 1; bearer: ToolMcpGatewayBearerAuthConfig; oauth: ToolMcpGatewayOAuthReservedConfig; } export interface ToolMcpGatewayStaticHeaderPolicy { name: string; valueRef?: string | null; value?: string | null; } export interface ToolMcpGatewayCallerHeaderPolicy { enabled: boolean; allowedHeaders: string[]; } export interface ToolMcpGatewayGeneratedMetadataHeaderPolicy { enabled: boolean; allowedHeaders: string[]; } export interface ToolMcpGatewayResponseHeaderPolicy { forwardMcpRequiredHeaders: boolean; forwardSafeCacheHeaders: boolean; } export interface ToolMcpGatewayHeaderPolicy { version: 1; callerPassthrough: ToolMcpGatewayCallerHeaderPolicy; staticHeaders: ToolMcpGatewayStaticHeaderPolicy[]; generatedMetadata: ToolMcpGatewayGeneratedMetadataHeaderPolicy; responseHeaders: ToolMcpGatewayResponseHeaderPolicy; } export interface ToolMcpGatewayMetadataPolicy { version: 1; forwardCompanyId: boolean; forwardGatewayId: boolean; forwardProjectId: boolean; forwardIssueId: boolean; forwardAgentId: boolean; forwardRunId: boolean; forwardCorrelationId: boolean; } export interface ToolMcpGatewayOnDemandToolsConfig { enabled: boolean; searchToolName: "search_tools"; runToolName: "run_tool"; } export interface ToolMcpGateway { id: string; companyId: string; gatewayPublicId: string; name: string; displaySlug: string; /** @deprecated Use displaySlug for UI labels and gatewayPublicId for protocol URLs. */ slug: string; description: string | null; status: ToolMcpGatewayStatus; profileId: string; defaultProfileMode: ToolMcpGatewayDefaultProfileMode; contextScopeType: ToolMcpGatewayContextScopeType; contextScopeId: string | null; agentId: string | null; projectId: string | null; issueId: string | null; approvalIssueId: string | null; endpointPath: string; authConfig: ToolMcpGatewayAuthConfig; headerPolicy: ToolMcpGatewayHeaderPolicy; metadataPolicy: ToolMcpGatewayMetadataPolicy; onDemandToolsConfig: ToolMcpGatewayOnDemandToolsConfig; metadata: Record | null; createdByAgentId: string | null; createdByUserId: string | null; archivedAt: Date | null; createdAt: Date; updatedAt: Date; } export interface ToolMcpGatewayToken { id: string; companyId: string; gatewayId: string; name: string; tokenPrefix: string; subjectType: ToolMcpGatewayTokenSubjectType; subjectId: string | null; clientLabel: string; ownerNote: string; allowedActions: ToolMcpGatewayTokenAction[]; expiresAt: Date | string | null; expiryOverrideReason: string | null; expiryOverrideByUserId: string | null; expiryOverrideByAgentId: string | null; expiryOverrideAt: Date | string | null; lastUsedAt: Date | string | null; revokedAt: Date | string | null; createdByAgentId: string | null; createdByUserId: string | null; createdAt: Date | string; updatedAt: Date | string; } export interface ToolMcpGatewayTokenCreated extends ToolMcpGatewayToken { token: string; } export interface ToolMcpGatewayClientSnippet { client: "cursor" | "claude_desktop" | "vscode" | "claude_code" | "opencode"; label: string; config: Record; notes: string[]; } export interface ToolMcpGatewayWithTokens extends ToolMcpGateway { tokens: ToolMcpGatewayToken[]; clientSnippets: ToolMcpGatewayClientSnippet[]; } export interface ToolProfileSummary { accessMode: "selected" | "all_except"; allowedToolCount: number; allowedApplicationCount: number; excludedToolCount: number; totalToolCount: number; assignmentCount: number; appliesToAgentCount: number; isCompanyDefault: boolean; } export interface ToolProfileWithDetails extends ToolProfile { entries: ToolProfileEntry[]; bindings: ToolProfileBinding[]; summary: ToolProfileSummary; } export type ToolProfileNewToolReviewDecision = "allow" | "keep_blocked"; export interface ToolProfileNewToolReviewItem { catalogEntryId: string; applicationId: string | null; applicationName: string | null; connectionId: string; connectionName: string | null; toolName: string; title: string | null; description: string | null; capability: ToolRiskLevel; riskLevel: ToolRiskLevel; addedAt: Date; firstSeenAt: Date; } export interface ToolProfileNewToolsReview { profileId: string; reviewedAt: Date | null; pendingCount: number; tools: ToolProfileNewToolReviewItem[]; } export interface ToolProfileNewToolsReviewResult { profile: ToolProfileWithDetails; reviewedAt: Date; allowedCount: number; keptBlockedCount: number; entriesCreated: ToolProfileEntry[]; reviewedCatalogEntryIds: string[]; } export interface ToolProfileEffectiveSummary { agentId: string; profiles: ToolProfileWithDetails[]; entries: ToolProfileEntry[]; bindings: ToolProfileBinding[]; allowedTools: ToolCatalogEntry[]; allowedToolNames: string[]; installedConnections: ToolConnection[]; } export interface ToolPolicy { id: string; companyId: string; name: string; description: string | null; policyType: ToolPolicyType; priority: number; enabled: boolean; selectors: Record; conditions: Record | null; config: Record | null; createdByAgentId: string | null; createdByUserId: string | null; createdAt: Date; updatedAt: Date; } export interface ToolRuntimeSlot { id: string; companyId: string; applicationId: string | null; connectionId: string | null; projectWorkspaceId: string | null; executionWorkspaceId: string | null; issueId: string | null; ownerScopeType: string; ownerScopeId: string | null; runtimeKind: ToolRuntimeKind; slotKey?: string; status: ToolRuntimeSlotStatus; reuseKey: string | null; workspaceScope: string | null; credentialScopeHash: string | null; provider: string | null; providerRef: string | null; processId: number | null; commandTemplateKey: string | null; healthStatus: string | null; healthMessage?: string | null; lastHealthCheckAt: Date | null; lastStartedAt?: Date | string | null; idleExpiresAt: Date | null; idleDeadlineAt?: Date | string | null; startedAt: Date | null; stoppedAt: Date | null; lastUsedAt: Date | null; lastError: string | null; metadata: Record | null; createdAt: Date; updatedAt: Date; } export interface ToolStdioTemplateToolSummary { name: string; title?: string | null; description?: string | null; inputSchema?: Record | null; annotations?: Record | null; } export interface ToolStdioCommandTemplate { id?: string; companyId?: string; templateId: string; name: string; title?: string | null; description?: string | null; status: "active" | "disabled"; source: "built_in" | "admin"; command?: string | null; args: string[]; envKeys: string[]; tools: ToolStdioTemplateToolSummary[]; createdByAgentId?: string | null; createdByUserId?: string | null; disabledAt?: Date | string | null; createdAt?: Date | string | null; updatedAt?: Date | string | null; } export type ToolRuntimeAlertSeverity = "info" | "warning" | "critical"; export type ToolRuntimeAlertStatus = "ok" | "firing" | "not_instrumented"; export interface ToolRuntimeAlertRecommendation { name: string; severity: ToolRuntimeAlertSeverity; status: ToolRuntimeAlertStatus; threshold: string; observed: string; description: string; firstResponderAction: string; runbookSection: string; } export interface ToolRuntimeMetricSnapshot { windowStartedAt: Date | string; windowEndedAt: Date | string; activeSlots: number; startingSlots: number; runningSlots: number; idleSlots: number; failedSlots: number; stoppedSlots: number; stuckStartingSlots: number; stuckRunningSlots: number; capacityDeferralsLastHour: number; restartAttemptsLastHour: number; restartSuppressionsLastHour: number; idleEvictionsLastHour: number; toolCallsLastHour: number; toolTimeoutsLastHour: number; toolFailuresLastHour: number; timeoutRateLastHour: number; failureRateLastHour: number; averageToolLatencyMsLastHour: number | null; p95ToolLatencyMsLastHour: number | null; missingSecretFailuresLastHour: number; auditWriteFailuresLastHour: number; activeConnections: number; disabledConnections: number; degradedConnections: number; remoteHttpConnections: number; localStdioConnections: number; } export interface ToolRuntimeSupportMatrix { remoteHttp: { supported: boolean; note: string; }; localStdio: { supported: boolean; note: string; }; } export interface ToolRuntimeHealthSummary { status: "ok" | "degraded" | "critical"; generatedAt: Date | string; runbookPath: string; metrics: ToolRuntimeMetricSnapshot; supportMatrix: ToolRuntimeSupportMatrix; alerts: ToolRuntimeAlertRecommendation[]; recommendations: ToolRuntimeAlertRecommendation[]; } export interface ToolConnectionHealthCheckResult { connection: ToolConnection; runtimeSlot: ToolRuntimeSlot | null; } export interface ToolCatalogRefreshResult { connection: ToolConnection; catalog: ToolCatalogEntry[]; discoveredCount: number; quarantinedCount: number; } export type ToolAppAttentionReason = "health" | "quarantined_catalog_entries" | "pending_action_requests" | "profile_new_tools"; export interface ToolAppAttentionProfileNewTools { profileId: string; profileName: string; pendingCount: number; } export interface ToolAppAttentionItem { connection: ToolConnection; healthNeedsAttention: boolean; quarantinedCatalogEntryCount: number; pendingActionRequestCount: number; newToolsPendingReviewCount: number; newToolsPendingProfiles: ToolAppAttentionProfileNewTools[]; reasons: ToolAppAttentionReason[]; } export interface ToolAppsAttentionResponse { generatedAt: Date | string; apps: ToolAppAttentionItem[]; totals: { connections: number; health: number; quarantinedCatalogEntries: number; pendingActionRequests: number; newToolsPendingReview: number; newToolsPendingProfiles: number; }; } /** * A connection-level lifecycle event (install, pause/resume, allowlist change, * reconnect/disconnect, new-actions quarantine) surfaced on the per-app * Activity tab alongside tool-call events (PAP-11284). Derived from the * company activity log rows scoped to a single tool connection. */ export interface ToolConnectionLifecycleEvent { id: string; connectionId: string; type: ToolConnectionLifecycleEventType; actorType: ToolActorType; /** Raw actor id (user id, agent id, or "board"/"system"); use actorDisplayName for rendering. */ actorId: string | null; agentId: string | null; /** Server-resolved display name for the actor (agent name or user name/email), null when unknown. */ actorDisplayName: string | null; /** Event-specific structured detail, e.g. `{ added, removed }` for allowlist or `{ count }` for quarantine. */ details: Record | null; createdAt: Date; } /** Recent tool-call and lifecycle events for a single app connection (App detail · Recent activity). */ export interface ToolConnectionActivityResponse { connectionId: string; events: ToolCallEvent[]; lifecycleEvents: ToolConnectionLifecycleEvent[]; issues: Record; actionRequests: Record; } /** * A pending (or recently resolved) "Ask first" request, enriched with the * connection/app context the review-queue card needs to render a prosumer * sentence without extra round-trips. */ export interface ToolActionRequestListItem { request: ToolActionRequest; toolName: string; toolTitle: string | null; connectionId: string | null; connectionName: string | null; applicationName: string | null; riskLevel: ToolRiskLevel | null; requestedByAgentId: string | null; } export interface ToolActionRequestsResponse { actionRequests: ToolActionRequestListItem[]; } export interface ToolExampleSummary { id: string; title: string; description: string; fixture: { transport: ToolConnectionTransport; templateId: string; available: boolean; tools: Array<{ name: string; description?: string | null; riskLevel: ToolRiskLevel; readOnly: boolean; }>; }; safeDefaultProfile: { profileKey: string; name: string; defaultAction: ToolProfileDefaultAction; allowedToolNames: string[]; }; install: { installed: boolean; canInstall: boolean; reason?: string | null; applicationId?: string | null; connectionId?: string | null; profileId?: string | null; profileBindingId?: string | null; }; } export interface ToolExampleInstallResult { example: ToolExampleSummary; created: boolean; application: ToolApplication; connection: ToolConnection; profile: ToolProfile; profileEntries: ToolProfileEntry[]; profileBinding: ToolProfileBinding; catalog: ToolCatalogEntry[]; } export interface ToolExampleSmokeCheck { name: string; ok: boolean; toolName?: string | null; expectedDecision?: ToolPolicyDecision | null; decision?: ToolPolicyDecision | null; reasonCode?: ToolAccessReasonCode | string | null; explanation?: string | null; auditEventId?: string | null; toolCallEventId?: string | null; details?: Record | null; } export interface ToolExampleSmokeResult { exampleId: string; ok: boolean; actor: { actorType: ToolActorType; actorId: string; agentId?: string | null; }; connection: ToolConnection; profile: ToolProfile; checks: ToolExampleSmokeCheck[]; } export interface ToolAppConnectionActionSummary { catalogEntryId: string; toolName: string; title: string | null; description: string | null; riskLevel: ToolRiskLevel; isReadOnly: boolean; isWrite: boolean; isDestructive: boolean; status: ToolCatalogEntryStatus; } /** * How Paperclip obtained the OAuth client it will use for a connection * (PAP-17087). Ordered by preference: a client the deployment preconfigured for * that issuer, then a Client ID Metadata Document, then dynamic registration, * then client credentials the operator preregistered and pasted in. */ export type ToolOAuthClientRegistrationSource = "preconfigured" | "cimd" | "dcr" | "manual"; /** Opaque managed-Cloud exchange; clients never treat the session as a URL. */ export interface ToolOAuthHandoff { kind: "paperclip_cloud"; session: string; } /** * What an unknown remote MCP endpoint told Paperclip it needs, so the wizard can * branch without re-probing. `manualClientRequired` means discovery succeeded but * the authorization server supports neither CIMD nor DCR, so the operator has to * supply a preregistered client under Advanced authentication. */ export interface ConnectToolAppAuthChallenge { kind: "oauth"; startUrl: string | null; handoff?: ToolOAuthHandoff; issuer?: string | null; resource?: string | null; registrationSource?: ToolOAuthClientRegistrationSource | null; manualClientRequired?: boolean; } export interface ConnectToolAppResult { connectionId: string; application: ToolApplication; connection: ToolConnection; catalog: ToolCatalogEntry[]; actions: { readOnly: ToolAppConnectionActionSummary[]; canMakeChanges: ToolAppConnectionActionSummary[]; }; suggestedDefaults: Record; auth?: ConnectToolAppAuthChallenge | null; } export interface ToolAppMetadataPreflightAttempt { kind: "endpoint" | "oauth_metadata"; url: string; status: number; ok: boolean; contentType: string | null; } /** Credential-free inspection of a curated app's public MCP/OAuth metadata. */ export interface ToolAppMetadataPreflightResult { galleryKey: string; methodKey: string; serverUrl: string; endpointReachable: boolean; oauth: { metadataFound: boolean; registrationAdvertised: boolean; clientIdMetadataDocumentSupported: boolean; } | null; attempts: ToolAppMetadataPreflightAttempt[]; checkedAt: string; } export interface ToolOAuthStartResult { connectionId: string; provider: string; authorizationUrl: string; expiresAt: string; /** * Opaque Paperclip Cloud authorization handoff. The board submits this only * to its fixed same-origin Cloud endpoint; it is never treated as a URL. */ handoff?: ToolOAuthHandoff; /** Canonical authorization-server issuer this run is bound to, when discovered. */ issuer?: string | null; /** RFC 8707 resource indicator sent with the request. */ resource?: string | null; registrationSource?: ToolOAuthClientRegistrationSource | null; } export interface FinishToolAppResult { connection: ToolConnection; profile: ToolProfile; profileEntries: ToolProfileEntry[]; profileBindings: ToolProfileBinding[]; policies: ToolPolicy[]; } export interface McpJsonImportDraft { name: string; transport: ToolConnectionTransport; status: ToolConnectionStatus; config: Record; credentialRefs: McpConnectionCredentialRef[]; credentialFields: Array<{ configPath: string; label: string; placement: ToolCredentialPlacement; key: string; prefix: string | null; required: boolean; }>; warnings: string[]; } export interface McpJsonImportPreview { drafts: McpJsonImportDraft[]; } export interface ToolInvocation { id: string; companyId: string; idempotencyKey: string | null; actorType: ToolActorType; actorId: string | null; agentId: string | null; issueId: string | null; runId: string | null; applicationId: string | null; connectionId: string | null; catalogEntryId: string | null; toolName: string; argumentsHash: string | null; argumentsSummary: ToolRedactedValueSummary | null; policyDecision: ToolPolicyDecision | null; matchedPolicyIds: string[]; approvalState: ToolInvocationApprovalState; status: ToolInvocationStatus; upstreamRequestId: string | null; resultHash: string | null; resultSummary: ToolRedactedValueSummary | null; resultSizeBytes: number | null; resultArtifactId: string | null; errorCode: string | null; errorMessage: string | null; startedAt: Date | null; completedAt: Date | null; createdAt: Date; updatedAt: Date; } export interface ToolActionRequest { id: string; companyId: string; invocationId: string; issueId: string | null; interactionId: string | null; approvalId: string | null; status: ToolActionRequestStatus; canonicalArgumentsHash: string; canonicalArgumentsSummary: ToolRedactedValueSummary; signedArguments: string | null; previewMarkdown: string | null; requestedByAgentId: string | null; requestedByUserId: string | null; resolvedByAgentId: string | null; resolvedByUserId: string | null; decidedByAgentId?: string | null; decidedByUserId?: string | null; decidedAt?: Date | null; expiresAt: Date | null; resolvedAt: Date | null; createdAt: Date; updatedAt: Date; } export interface ToolCallEvent { id: string; companyId: string; eventType: ToolAuditEventType; actorType: ToolActorType; actorId: string | null; agentId: string | null; runId: string | null; issueId: string | null; applicationId: string | null; connectionId: string | null; catalogEntryId: string | null; invocationId: string | null; actionRequestId: string | null; runtimeSlotId: string | null; toolName: string | null; decision: ToolPolicyDecision | null; matchedPolicyIds: string[]; reasonCode: string | null; outcome: ToolAuditOutcome; latencyMs: number | null; argumentsSummary?: ToolRedactedValueSummary | null; requestHash: string | null; requestSummary: ToolRedactedValueSummary | null; resultHash: string | null; resultSummary: ToolRedactedValueSummary | null; resultSizeBytes: number | null; redactionPlan: Record | null; rateLimitState: Record | null; metadata: Record | null; errorCode: string | null; errorMessage: string | null; createdAt: Date; } export interface ToolRunDecision { invocation: ToolInvocation; actionRequest: ToolActionRequest | null; auditEvents: ToolCallEvent[]; latestAuditEvent: ToolCallEvent | null; decision: ToolPolicyDecision | null; outcome: ToolAuditOutcome | null; reasonCode: string | null; denialReason: string | null; pendingAction: { actionRequestId: string; issueId: string | null; interactionId: string | null; approvalId: string | null; status: ToolActionRequestStatus; previewMarkdown: string | null; } | null; } export interface ToolRunDecisionLookup { runId: string; decisions: ToolRunDecision[]; } export interface ToolRateLimitCounter { id: string; companyId: string; policyId: string; counterKey: string; scopeType: string; scopeId: string; windowKind: ToolRateLimitWindowKind; windowStartAt: Date; limit: number; remaining: number; resetAt: Date; createdAt: Date; updatedAt: Date; } export type ToolAccessReasonCode = "allow_trust_rule" | "allow_profile" | "allow_explicit_grant" | "allow_policy" | "requires_review_changed_tool" | "requires_approval_policy" | "deny_default" | "deny_company_boundary" | "deny_disabled_connection" | "deny_disabled_application" | "deny_archived_application" | "deny_missing_tool" | "deny_policy_block" | "deny_run_context_mismatch" | "deny_missing_agent" | "rate_limited"; export interface ToolAccessSelector { actorType?: ToolActorType; actorTypes?: ToolActorType[]; agentId?: string; agentIds?: string[]; projectId?: string; projectIds?: string[]; routineId?: string; routineIds?: string[]; issueId?: string; issueIds?: string[]; gatewayId?: string; gatewayIds?: string[]; gatewayPublicId?: string; gatewayPublicIds?: string[]; gatewayTokenId?: string; gatewayTokenIds?: string[]; clientSubjectType?: ToolMcpGatewayTokenSubjectType; clientSubjectTypes?: ToolMcpGatewayTokenSubjectType[]; clientName?: string; clientNames?: string[]; externalClient?: boolean; applicationId?: string; applicationIds?: string[]; connectionId?: string; connectionIds?: string[]; catalogEntryId?: string; catalogEntryIds?: string[]; toolName?: string; toolNames?: string[]; riskLevel?: ToolRiskLevel; riskLevels?: ToolRiskLevel[]; } export interface ToolRateLimitRule { limit: number; windowSeconds: number; keyBy?: Array<"company" | "agent" | "application" | "connection" | "tool">; } export interface ToolTrustRuleArgumentFilters { allowAny?: boolean; exactHash?: string | null; allowedHashes?: string[]; fieldEquals?: Record; fieldNotEquals?: Record; fieldIn?: Record; fieldMatches?: Record; fieldExists?: string[]; fieldAbsent?: string[]; } export interface ToolPolicyConditions { arguments?: { fieldEquals?: Record; fieldNotEquals?: Record; fieldIn?: Record; fieldMatches?: Record; fieldExists?: string[]; fieldAbsent?: string[]; }; args?: ToolPolicyConditions["arguments"]; actor?: ToolAccessSelector; context?: ToolAccessSelector & { requireIssue?: boolean; requireProject?: boolean; requireRoutine?: boolean; }; risk?: { levels?: ToolRiskLevel[]; max?: ToolRiskLevel; isWrite?: boolean; isDestructive?: boolean; }; credentialScope?: Pick & { applicationKey?: string; applicationKeys?: string[]; providerType?: string; providerTypes?: string[]; }; trustBoundary?: { providerType?: string; providerTypes?: string[]; applicationKey?: string; applicationKeys?: string[]; remoteHttpOnly?: boolean; paperclipSelfOnly?: boolean; }; timeWindow?: { startAt?: string; endAt?: string; daysOfWeekUtc?: number[]; startHourUtc?: number; endHourUtc?: number; }; } export interface ToolTrustRuleScopeInput { includeAgent?: boolean; includeProject?: boolean; includeIssue?: boolean; includeApplication?: boolean; includeConnection?: boolean; includeCatalogEntry?: boolean; includeTool?: boolean; } export interface ToolTrustRuleBatchApprovalConfig { enabled?: boolean; maxBatchSize?: number; windowSeconds?: number; } export interface CreateToolTrustRuleFromActionRequest { argumentMode?: "exact" | "action"; name?: string; description?: string | null; priority?: number; approvalThreshold?: number; selectors?: ToolAccessSelector; scope?: ToolTrustRuleScopeInput; argumentFilters?: ToolTrustRuleArgumentFilters; expiresAt?: Date | string | null; batchApproval?: ToolTrustRuleBatchApprovalConfig | null; } export interface RevokeToolTrustRule { reason?: string | null; } export interface ToolAccessDecisionInput { companyId: string; actor: { actorType: ToolActorType; actorId: string; agentId?: string | null; userId?: string | null; }; runContext?: { heartbeatRunId?: string | null; issueId?: string | null; projectId?: string | null; routineId?: string | null; gatewayId?: string | null; gatewayPublicId?: string | null; gatewayTokenId?: string | null; clientSubjectType?: ToolMcpGatewayTokenSubjectType | null; clientSubjectId?: string | null; clientName?: string | null; externalClient?: boolean | null; } | null; request: { applicationId?: string | null; connectionId?: string | null; catalogEntryId?: string | null; providerType?: string | null; applicationKey?: string | null; upstreamToolName?: string | null; riskLevel?: ToolRiskLevel | string | null; toolName: string; arguments?: unknown; idempotencyKey?: string | null; sideEffecting?: boolean; }; consumeRateLimit?: boolean; writeAuditEvent?: boolean; } export interface ToolAccessDecision { decision: ToolPolicyDecision; allowed: boolean; reasonCode: ToolAccessReasonCode; explanation: string; effectiveProfileIds: string[]; matchedPolicyIds: string[]; redactionPlan?: Record | null; policyExplanation?: Record | null; argumentsSummary?: ToolRedactedValueSummary | null; rateLimitState?: Record | null; invocationId?: string | null; actionRequestId?: string | null; } /** * How an action would behave for a given agent if they ran it right now — * the same three-way outcome the Test tab and Permissions surface. */ export type ToolConnectionTestDecision = "allowed" | "ask_first" | "off"; /** Per-action access summary for one agent on one connection. */ export interface ToolConnectionTestToolAccess { /** Upstream tool name; what `test-calls` expects as `toolName`. */ toolName: string; /** Gateway-namespaced tool name (matches the catalog gateway entry). */ gatewayToolName: string; displayName: string | null; risk: "read" | "write" | "destructive"; decision: ToolConnectionTestDecision; reasonCode: ToolAccessReasonCode | string | null; matchedPolicyIds: string[]; } /** Roll-up of how every action on a connection behaves for one agent. */ export interface ToolConnectionAccessSummary { connectionId: string; toolCount: number; allowedCount: number; askFirstCount: number; offCount: number; /** * When this agent's access to the connection was last reconfigured (ISO * timestamp), powering the "Last changed by {Actor} · {relativeTime}" hint in * the Test tab Off side panel. Null when no governing config has a timestamp. */ lastChangedAt: string | null; /** Agent who made the most recent change, when attributable (policy/binding edits only). */ lastChangedByAgentId: string | null; /** Resolved display name for {@link lastChangedByAgentId}. */ lastChangedByName: string | null; tools: ToolConnectionTestToolAccess[]; } /** An agent the board member may impersonate in the Test tab. */ export interface ToolConnectionTestAgent { id: string; name: string; role: string; title: string | null; status: string; /** Zero-based depth in the company reporting tree; roots are highest-ranked. */ orgDepth: number; } export interface ToolConnectionTestAgentsResponse { agents: ToolConnectionTestAgent[]; } /** Display summary for one selected Test-tab agent. */ export interface ToolConnectionTestAgentAccessResponse { access: ToolConnectionAccessSummary; } export interface ToolUpstreamPending { kind: "authorization" | "approval"; links: Array<{ url: string; host: string; elicitationId?: string; }>; executionId?: string; elicitationId?: string; resumeTool?: string; expiresAt?: string; message?: string; requestedSchema?: Record; } /** Result of `POST /tool-connections/:id/test-calls`. */ export interface ToolConnectionTestCallResult { decision: ToolConnectionTestDecision; invocationId: string; /** Present (with `decision: "allowed"`) when the call ran to completion. */ result?: unknown; /** Present on a failed allowed run, or as the explanation for an off action. */ error?: { message: string; reasonCode: ToolAccessReasonCode | string | null; }; /** Present (with `decision: "ask_first"`) — the parked approval request. */ actionRequestId?: string; /** Provider handoff, distinct from a Paperclip permission approval. */ upstreamPending?: ToolUpstreamPending; } /** * Lifecycle phase of an ask-first test call, polled through * `GET /tool-connections/:id/test-calls/:actionRequestId`. * * - `waiting` — approval still pending in the Review tab. * - `running` — approved; the tool is executing for the test. * - `done` — approved and finished; see `result` / `error`. * - `denied` — declined in the Review tab. * - `cancelled` — request was cancelled or invalidated before approval. * - `expired` — the approval window lapsed. */ export type ToolConnectionTestCallStatusPhase = "waiting" | "running" | "done" | "denied" | "cancelled" | "expired"; /** Live status of an ask-first test call (`GET /tool-connections/:id/test-calls/:actionRequestId`). */ export interface ToolConnectionTestCallStatus { actionRequestId: string; invocationId: string; phase: ToolConnectionTestCallStatusPhase; /** Redacted snapshot of the parameters the call was made with — powers the "Where" row. */ parameters?: Record | null; /** Present once `phase === "done"` and the tool succeeded. */ result?: unknown; upstreamPending?: ToolUpstreamPending; /** Present once `phase === "done"` and the tool failed, or when the request was denied/expired. */ error?: { message: string; reasonCode: ToolAccessReasonCode | string | null; }; /** Wall-clock duration of the executed call in ms, when known. */ durationMs?: number | null; /** ISO timestamp the request was created — for the "Waiting · {time}" label. */ requestedAt: string; /** ISO timestamp the request was resolved (approved/denied/cancelled), when applicable. */ resolvedAt?: string | null; } //# sourceMappingURL=tool-access.d.ts.map