Skip to main content

Connections

The bindai-connections package provides a common interface for communicating with external services. A connection exposes a name, lifecycle methods, and a send() operation. The actual behavior and payload format depend on the specific implementation. The package exports connection classes for:
  • Webhooks
  • GitHub
  • Slack
  • Notion
  • Jira
  • Discord
  • Resend
  • Vercel
  • Netlify
  • Google Sheets
  • Google Docs
  • Gmail
  • Google Drive
Important: An exported connection class is not necessarily registered for dynamic lookup, configured for use, or verified to work with every operation of its external service. The package currently registers 12 connection types; GitHubConnection is exported but is not included in that registration list.

Architecture

The package provides three principal components:
  • Connection: the abstract interface implemented by connection classes.
  • ConnectionRegistry: stores named connection classes for dynamic lookup.
  • ConnectionManager: manages connection instances in memory.
The registry provides class lookup; the manager stores instantiated connections. Neither component, by itself, establishes that an external service is reachable or that credentials are valid.

Connection interface

Import the base interface from bindai_connections:
The abstract interface requires these members: A typical usage pattern is:
This is an illustrative lifecycle pattern, not a guarantee that every integration performs a network handshake in connect(). Check the selected implementation’s constructor, accepted payload, authentication behavior, and error handling before using it. Exceptions from connection operations may propagate to the caller. Applications should handle errors at an appropriate boundary.

Connection lifecycle

A connection commonly follows this sequence:
  1. Instantiate the connection with the required configuration.
  2. Call connect().
  3. Check is_connected() if appropriate.
  4. Call send(payload).
  5. Call disconnect() when finished.
The lifecycle methods do not have identical semantics across all implementations. For example, the current Google Sheets, Google Docs, Gmail, Google Drive, and webhook implementations use a local Boolean flag for connection state. Their connect() methods toggle that state; they do not, by themselves, verify that the remote service is reachable. For these implementations, the network request occurs during send(). A successful is_connected() result therefore does not guarantee a successful request.

Connection registry

ConnectionRegistry stores named connection classes. Use names() to inspect the registered names and provider(name) to retrieve a class.
provider() returns the class, not an instantiated or connected object. Constructor arguments depend on the chosen implementation. Unknown names raise KeyError.

Currently registered types

The package initialization registers these names:
  • webhook
  • slack
  • notion
  • jira
  • discord
  • resend
  • vercel
  • netlify
  • google_sheets
  • google_docs
  • gmail
  • google_drive
For example:
GitHubConnection is also exported by the package, but it is not included in the default registry registrations. Importing a class and registering it for dynamic lookup are separate operations.

Registering a connection class

A custom connection class can be registered explicitly:
This illustrates the interface and registration shape only. Replace the placeholder methods with real behavior before using the connection. In particular, is_connected() and send() must reflect the implementation’s actual state and operations. Registry names are used as supplied when stored, so use consistent lowercase names. The registry does not instantiate or connect a class for you.

Connection manager

ConnectionManager stores connection instances in an in-memory mapping keyed by each instance’s name.
The manager provides these operations: The manager does not persist instances across process restarts. Adding another instance under an existing name replaces the previous mapping entry. Do not rely on add() to disconnect the replaced instance automatically. The manager also does not validate remote service availability, automatically refresh credentials, or retry failed requests.

Built-in integrations

The package exports multiple integration classes. Their constructors and request behavior differ, so do not assume a uniform authentication scheme or a universal payload format.

Webhook

WebhookConnection sends JSON payloads to a configured URL using HTTP POST.
The URL must be non-empty and the timeout must be positive. send() requires the connection to be in its connected state. The result contains status_code and the response text in body. Network and HTTP errors can propagate to the caller. Only send payloads to trusted destinations, and avoid including secrets or unnecessary personal data in webhook payloads.

Google Sheets and Google Docs

The package exports GoogleSheetsConnection and GoogleDocsConnection. Both use an HTTP request pattern with configurable base URLs and timeouts. The default base URLs are:
  • Google Sheets: https://sheets.googleapis.com/v4/spreadsheets
  • Google Docs: https://docs.googleapis.com/v1/documents
A request payload can specify:
  • path: the path appended to the configured base URL
  • method: the HTTP method, defaulting to GET
  • body: an optional JSON request body
For example:
Authentication security caveat: In the current implementations, the Sheets and Docs connections append the supplied token as an access_token URL query parameter. Query-string credentials can be exposed through logs, monitoring systems, proxies, or other URL-recording mechanisms. This behavior should not be treated as a recommended production security pattern. Review and improve the implementation before using sensitive credentials in production. The example documents the current interface; it does not guarantee that the request path, permissions, or Google API operation is valid for a particular document or spreadsheet.

Gmail and Google Drive

The package also exports GmailConnection and GoogleDriveConnection. Their default base URLs are:
  • Gmail: https://gmail.googleapis.com/gmail/v1/users
  • Google Drive: https://www.googleapis.com/drive/v3
These implementations send the supplied token in an HTTP Authorization: Bearer ... header. Their default request paths are /me/profile for Gmail and /files for Drive. They accept a request payload with path, method, and optional body, and return a dictionary containing status_code and response text in body. These examples describe the current HTTP wrapper behavior, not a complete Google OAuth flow. Token acquisition, consent, scopes, expiration, and refresh are not performed by these connection classes. Use valid access tokens with the necessary permissions and review each API’s requirements.

Other exported connections

The package also exports connection classes for GitHub, Slack, Notion, Jira, Discord, Resend, Vercel, and Netlify. Their presence in the public package does not establish that every API operation is supported or that each class is registered for dynamic lookup. Consult the corresponding implementation for required constructor arguments, supported payloads, authentication behavior, and limitations before relying on a provider.

Provider credentials and CLI configuration

BindAI also has a separate provider-configuration layer for AI model providers. This is distinct from the external-service connection classes described above. The bindai connections CLI currently recognizes these model-provider names:
  • openai
  • anthropic
  • google
  • groq
  • ollama
  • openrouter
The CLI commands manage provider credentials and metadata; they do not automatically configure all external-service classes such as Slack, Google Drive, or GitHub. Run these commands from the project directory whose connection configuration you want to manage.

Add a provider credential

You can optionally assign a name:
The CLI prompts for the credential with input hidden. It stores the credential through KeyringProviderCredentialStore and records non-secret metadata in .bindai/connections.toml under the current working directory. Provider names are validated against the model-provider configuration registry. An unknown provider is rejected.

List configured connections

The list command reads the metadata manifest and checks whether each named credential exists in the keyring. It reports the name, provider, and credential status (Configured or Missing). A Configured result only indicates that a credential is present in the credential store. It does not verify that the credential is valid or that the provider is reachable.

Remove a provider credential

The remove command deletes the credential and removes the corresponding metadata entry. The name must exist in the manifest.

Credential storage details

The current credential-store implementations include:
  • InMemoryProviderCredentialStore: stores credentials in process memory.
  • KeyringProviderCredentialStore: uses the Python keyring package to access the operating system’s credential store.
The keyring implementation uses the service name bindai by default. Its optional dependency is installed with:
The keyring store does not provide portable credential-name enumeration; its list() method returns an empty list. The CLI obtains names from the metadata manifest and checks each credential individually. The manifest stores provider metadata, not credential values. By default, ConnectionManifest uses .bindai/connections.toml relative to the current working directory. The CLI explicitly constructs the manifest at that location. Treat credentials as secrets. Do not commit credentials, tokens, or other sensitive values to source control. Restrict access to the project configuration and use a suitable operating-system credential store where available.

Errors and operational considerations

Connection operations may fail because of invalid credentials, insufficient permissions, malformed payloads, unsupported endpoints, network problems, timeouts, or remote API errors. The behavior varies by implementation. For example, the HTTP-based integrations use a timeout for requests and can propagate network or HTTP exceptions. The common Connection interface does not guarantee automatic retries, uniform error objects, rate-limit handling, or credential refresh. Applications should:
  • Handle exceptions at the appropriate application boundary.
  • Avoid logging tokens, authorization headers, or sensitive payloads.
  • Validate external inputs before using them to construct request paths or payloads.
  • Apply application-level retry and rate-limit handling only where appropriate for the operation.
  • Distinguish local connection state from verified remote availability.
  • Check provider permissions and API requirements before deployment.
Do not assume a request is idempotent. Before retrying a failed request, determine whether the remote operation could already have succeeded.

Security considerations

External-service connections can carry sensitive information. Apply least-privilege permissions and send only the data needed for the operation. For production use:
  • Store secrets in an appropriate credential store rather than source code.
  • Keep tokens out of URLs, logs, error reports, and documentation examples.
  • Use HTTPS for external requests.
  • Validate destinations and payloads, especially when URLs or paths come from untrusted input.
  • Restrict webhook destinations to trusted endpoints and consider server-side protections against requests to unintended internal or private network addresses.
  • Review each integration’s authentication and error-handling implementation before using it with sensitive data.
The Google Sheets and Docs query-string token behavior described above deserves particular attention before production use.

Testing and local development

When testing a connection, verify each stage separately:
  1. Construction succeeds with the intended configuration.
  2. connect() and is_connected() behave as expected for that implementation.
  3. send() sends the intended method, URL, headers, and payload.
  4. Successful responses are handled correctly.
  5. Invalid credentials, HTTP failures, and network timeouts are handled appropriately.
  6. disconnect() and manager cleanup behave as expected.
Prefer mocked HTTP requests or controlled test endpoints for unit tests. Use real provider credentials only in appropriately secured integration tests. Avoid using production data or credentials in examples and test fixtures.

Adding a custom connection

To implement a custom connection:
  1. Subclass Connection.
  2. Implement name, connect(), disconnect(), is_connected(), and send(payload).
  3. Define and document the constructor arguments and accepted payload format.
  4. Register the class with ConnectionRegistry if dynamic lookup is required.
  5. Instantiate and manage it directly or through ConnectionManager.
  6. Test its success and failure behavior.
A minimal implementation should not claim to be connected when no connection has been established, and its send() method should fail clearly when required setup has not occurred. The registry and manager provide class lookup and instance management; they do not supply missing authentication, API behavior, or network functionality.

Current scope and limitations

The following distinctions matter when integrating connections into an application:
  • Exported classes and registered connection names are different sets.
  • Registry lookup returns a class, not a live connection.
  • The connection manager keeps instances in memory and does not persist them.
  • Connection state is implementation-specific and may only represent local state.
  • The provider-credential CLI manages AI model-provider credentials, not every external-service connection.
  • The current connection interface does not guarantee a shared payload schema, common authentication flow, automatic retries, or token refresh.
  • A class being present in the package does not guarantee support for every operation offered by its external service.
Verify the concrete implementation before documenting or depending on a capability.

Summary

BindAI Connections provides a shared interface, a registry for connection classes, and a manager for connection instances. The package includes webhook and service-specific integrations, while a separate CLI supports storing credentials for a defined set of AI model providers. Use the concrete implementation as the source of truth for request formats, authentication, lifecycle semantics, and error handling. In particular, distinguish local connection state from remote connectivity, keep credentials out of source control and logs, and address the Google Sheets and Docs query-string token behavior before production use.