Adding a Connector Adapter
This guide walks you through implementing and contributing a new connector adapter.
1. Fork and Scaffold
Fork the repo, then create your adapter directory:
examples/connectors/<your-adapter>/
index.ts
<your-adapter>.adapter.ts
<your-adapter>.adapter.spec.ts2. Implement ConnectorAdapterV1
Import the interface from libs/adapters/connector/src/lib/connector-adapter.ts:
import type {
ConnectorAdapterV1,
ConnectorMetadata,
VerifyResult,
DispatchEvent,
DispatchResult,
} from '@lenserfight/adapters/connector'
export class YourAdapter implements ConnectorAdapterV1 {
id(): string {
return 'your-adapter-v1' // stable — never rename after publication
}
metadata(): ConnectorMetadata {
return {
name: 'Your Adapter',
description: 'One-line description of what this connects.',
iconUrl: 'https://example.com/icon.svg',
docsUrl: 'https://example.com/docs',
}
}
async verify(token: string): Promise<VerifyResult> {
// Validate the token against the upstream API.
// Return granted scopes on success; { valid: false } on failure.
}
async dispatch(event: DispatchEvent): Promise<DispatchResult> {
// Must always resolve — never throw.
// Return { ok: false, reason: '...' } for soft failures.
}
}WARNING
dispatch() must never throw. Any unhandled rejection propagates into the workflow engine's dead-letter path. Catch all errors and return a typed failure result instead.
TIP
Use the chainabit-example adapter as the canonical reference implementation. It demonstrates how to wrap HttpConnectorAdapter, declare metadata, and return a ConnectorAdapterV1 value the registry can consume.
3. Register the Adapter
In your index.ts:
import { registerConnectorAdapter } from '@lenserfight/adapters/connector'
import { YourAdapter } from './<your-adapter>.adapter'
registerConnectorAdapter('your-adapter-v1', () => new YourAdapter())Registration is idempotent. Registering the same id twice throws at startup.
4. Write Scope-Validation Specs
describe('YourAdapter.verify', () => {
it('returns valid: false for an expired token', async () => { ... })
it('returns expected scopes for a valid token', async () => { ... })
})5. Submit Your PR
- Label the PR
good-first-adapter. - Link to RFC-0001 (
docs/rfcs/RFC-0001-connector-interface.md) in the PR description. - Ensure
pnpm nx lintandpnpm nx testpass for your adapter project.
Existing adapters
The canonical reference implementation is examples/connectors/chainabit-example/src/adapter.ts. It demonstrates:
- Returning a typed
ConnectorAdapterV1value - Wrapping the built-in
HttpConnectorAdapterfor the commonkind: 'api'case - Declaring
ConnectorMetadatawith the canonical scopes fromCONNECTOR_SCOPES - Structured
ok: falseerror returns (never throws)
For a step-by-step walkthrough of building a new adapter, see the Connector SDK getting started guide. For mentor pairings and the first-PR walkthrough, see Adapter Mentorship Paths and the current Mentor Rotation.
Browse examples/connectors/ for all community adapters. Check there first to avoid duplicating an adapter that already exists.
Review ownership
| Scope | Reviewers required |
|---|---|
ConnectorAdapterV1 interface changes | 1 core maintainer (blocking) |
New adapter in examples/connectors/ | 1 core + 1 community reviewer |
| Bug fix to existing adapter | 1 core maintainer |
| Docs-only change to this guide | 1 core maintainer |
SLA: First review comment within 7 business days of PR open. If you haven't heard back, ping in the issue or add the needs-triage label.
Label PRs with good-first-adapter before requesting review — this surfaces them in the maintainer triage queue.