Connector catalog

This catalog is the entry point for choosing a connector, wiring its trigger manifest, and finding a ready-to-customize example. It reflects the current runtime split:

  • Cron, generic webhook, A2A push, and stream ingress are core runtime providers.
  • Provider business logic belongs in pure-Harn connector packages.
  • Community connectors are Harn packages that export connector contract v1 and pass harn connector test.

For the architecture and ownership split that closes the old connector-library epic, see Connector architecture status.

GitHub, Slack, Linear, and Notion are first-party pure-Harn packages: harn-github-connector, harn-slack-connector, harn-linear-connector, and harn-notion-connector. Configure one by setting connector = { harn = "..." } on the [[providers]] table. See the Rust-to-Harn-package migration guide for the cutover pattern.

For an LLM-sized version of this page, use docs/llm/harn-triggers-quickref.md. That file is generated from the live provider catalog and checked by CI.

Built-in runtime providers

ProviderUse whenSignatureRequired secretsRecipes
cronRun scheduled local workflows.None.None.Daily report, enrichment pass, health check.
webhookAccept generic Standard Webhooks-style HTTP events.HMAC-SHA256, webhook-signature, webhook-timestamp, webhook-id.webhook/signing_secret.Stripe/Square-style handlers, HMAC-gated callbacks.
a2a-pushAccept A2A task/update pushes from another orchestrator.Transport auth is handled by the A2A layer.None at catalog level.Multi-orchestrator fanout, remote reviewer dispatch.
kafka, nats, pulsar, postgres-cdc, email, websocketConsume stream-shaped ingress through the shared stream connector.Provider-specific transport configuration.None at catalog level.Fan-in, windowing, classifier routing.

Cron daily report

[[triggers]]
id = "daily-digest"
kind = "cron"
provider = "cron"
schedule = "0 9 * * 1-5"
timezone = "America/Los_Angeles"
handler = "send_daily_digest"

See examples/triggers/cron-daily-digest.

Generic webhook with HMAC

[[triggers]]
id = "stripe-webhook"
kind = "webhook"
provider = "webhook"
match = { path = "/hooks/stripe", events = ["invoice.payment_succeeded"] }
handler = "handlers::on_webhook"
dedupe_key = "event.dedupe_key"
secrets = { signing_secret = "webhook/stripe-signing-secret" }

See examples/triggers/webhook-generic-hmac.

A2A fanout

[[triggers]]
id = "reviewer-fanout"
kind = "a2a-push"
provider = "a2a-push"
match = { events = ["task.completed"] }
handler = "route_review_result"

See examples/triggers/a2a-reviewer-fanout.

First-party pure-Harn packages

Each first-party connector repo should publish:

  • repository URL and package install command
  • harn connector test command
  • required secrets and provider scopes
  • supported trigger/event types
  • mocked fixtures so CI does not need live provider credentials
ProviderPackage repoInstallPackage gateRequired secrets/scopesSupported trigger/event types
GitHubhttps://github.com/burin-labs/harn-github-connectorharn add github.com/burin-labs/harn-github-connector@v0.2.0harn connector test . --provider githubWebhook secret; for outbound, GitHub App id, installation id, and private key. App permissions depend on methods: issues, pull requests, contents/metadata, checks, deployments.issues, pull_request, issue_comment, pull_request_review, push, workflow_run, deployment_status, check_run, check_suite, status, merge_group, installation, installation_repositories; outbound REST/GraphQL escape hatches. Each event also exposes the connector's stable github.<event>[.<action>] topic plus normalized repo/repository fields.
Slackhttps://github.com/burin-labs/harn-slack-connectorharn add github.com/burin-labs/harn-slack-connector@v0.1.0harn connector test . --provider slackSigning secret; for outbound, bot token. Typical scopes: app_mentions:read, channels:history, reactions:read, chat:write, reactions:write, users:read, files:write.URL verification, message, app_mention, reaction_added, app_home_opened, assistant_thread_started; outbound Web API calls.
Linearhttps://github.com/burin-labs/harn-linear-connectorharn add github.com/burin-labs/harn-linear-connector@v0.1.0harn connector test . --provider linearWebhook signing secret; optional API key/access token for outbound GraphQL.Issue, Comment, IssueLabel, Project, Cycle, Customer, CustomerRequest; outbound GraphQL.
Notionhttps://github.com/burin-labs/harn-notion-connectorharn add github.com/burin-labs/harn-notion-connector@v0.1.0harn connector test . --provider notion --run-poll-tickWebhook verification token; outbound API token. Notion integration capabilities depend on pages/databases/comments used.Webhook events such as subscription verification, page updates, comments, data source schema updates; poll_tick database/page watchers; outbound Notion API via notion-sdk-harn.
GitLabhttps://github.com/burin-labs/harn-gitlab-connectorharn add github.com/burin-labs/harn-gitlab-connector@v0.1.0harn connector test . --provider gitlabWebhook signing secret (plain shared-secret X-Gitlab-Token, not HMAC); for outbound, an OAuth2 access token, PAT, or project/group access token with api scope.push, tag_push, merge_request, note, issue, pipeline; outbound REST (notes, MR update/changes/approve, commit status, repository files), GraphQL passthrough, OAuth2 helpers, and shared GitForgePullRequestEvent emission for merge requests.
Forgejohttps://github.com/burin-labs/harn-forgejo-connectorharn add github.com/burin-labs/harn-forgejo-connector@v0.1.0harn connector test . --provider forgejoWebhook signing secret verified as HMAC-SHA256 from X-Gitea-Signature; for outbound, a user, organization, or repository access token accepted by the instance API.push, pull_request, issues, issue_comment, release, repository, star; outbound REST for comments, PR updates, commit statuses, repository contents, raw API passthrough, and shared GitForgePullRequestEvent emission for pull requests.
Giteahttps://github.com/burin-labs/harn-gitea-connectorharn add github.com/burin-labs/harn-gitea-connector@v0.1.0harn connector test . --provider giteaWebhook signing secret verified as HMAC-SHA256 from X-Gitea-Signature; for outbound, an access token scoped to the target self-hosted instance.push, pull_request, issues, issue_comment, release, repository, star; outbound REST for comments, PR updates, commit statuses, repository contents, raw API passthrough, and shared GitForgePullRequestEvent emission for pull requests.
Bitbuckethttps://github.com/burin-labs/harn-bitbucket-connectorharn add github.com/burin-labs/harn-bitbucket-connector@v0.1.0harn connector test . --provider bitbucketOptional webhook signing secret verified as HMAC-SHA256 from X-Hub-Signature; X-Hook-UUID and X-Request-UUID are preserved for dedupe. For outbound, app password, OAuth2 token, or Data Center PAT.Cloud and Data Center repo:push, pullrequest:*, issue:*, repo:commit_status_*; outbound PR comments/updates, commit statuses, repository file fetches, and raw API passthrough.
CircleCIhttps://github.com/burin-labs/harn-circleci-connectorharn add github.com/burin-labs/harn-circleci-connector@v0.1.0harn connector test . --provider circleciWebhook signing secret verified as circleci-signature v1= HMAC-SHA256 over the raw body; for outbound, a CircleCI personal API token sent as Circle-Token.workflow-completed, job-completed; failure normalization, workflow rerun from failed, cancel, workflow/job lookups, and artifact listing. Use the shared GitHub commit-to-PR resolver when the webhook has no PR number.
Buildkitehttps://github.com/burin-labs/harn-buildkite-connectorharn add github.com/burin-labs/harn-buildkite-connector@v0.1.0harn connector test . --provider buildkitePreferred webhook verification is X-Buildkite-Signature: timestamp=...,signature=... HMAC-SHA256 over "<timestamp>.<raw_body>" with a 5-minute freshness window; X-Buildkite-Token is accepted as a simpler fallback. Outbound calls use Authorization: Bearer.build.finished, job.finished; failure normalization, job retry, rebuild, cancel, job log fetches, raw REST, optional GraphQL, and shared GitHub commit-to-PR lookup when build.pull_request is absent.
SourceHuthttps://github.com/burin-labs/harn-sourcehut-connectorharn add github.com/burin-labs/harn-sourcehut-connector@v0.1.0harn connector test . --provider sourcehutWebhook public key verified with Ed25519 over the raw payload; outbound GraphQL/REST calls use an OAuth2 token or PAT.Repository push/update events, todo/ticket changes, build notifications, mailing-list oriented message metadata; outbound GraphQL/REST passthrough.
Subversionhttps://github.com/burin-labs/harn-svn-connectorharn add github.com/burin-labs/harn-svn-connector@v0.1.0harn connector test . --provider svn --run-poll-tickOptional post-commit hook HMAC secret; polling credentials are repository URL plus username/password, SSH key, or ambient host-managed credential helper.commit, branch, tag, property_change; webhook-style post-commit normalization plus poll_tick revision scanning for repositories that cannot install hooks.

Direct GitHub installs are the MVP path. Registry names such as @burin/notion-connector should be used once the hosted first-party index is available.

GitHub stale PR nudger

[[triggers]]
id = "github-stale-pr-nudger"
kind = "cron"
provider = "cron"
schedule = "0 15 * * 1-5"
handler = "nudge_stale_prs"

See examples/triggers/github-stale-pr-nudger.

Slack keyword router

[[triggers]]
id = "slack-keyword-router"
kind = "webhook"
provider = "slack"
match = { path = "/hooks/slack", events = ["message", "app_mention"] }
handler = "route_message"
secrets = { signing_secret = "slack/signing-secret" }

See examples/triggers/slack-keyword-router.

Linear SLA breach alert

[[triggers]]
id = "linear-sla-breach"
kind = "cron"
provider = "cron"
schedule = "*/30 * * * *"
handler = "scan_for_sla_breaches"

See examples/triggers/linear-sla-breach.

Notion database watcher

[[triggers]]
id = "notion-database-watcher"
kind = "poll"
provider = "notion"
handler = "on_database_change"
poll = { interval = "5m", state_key = "notion:database:watcher", max_batch_size = 50 }
secrets = { verification_token = "notion/verification-token" }

See examples/triggers/notion-database-watcher.

Git forge quickstart demo

GitHub, GitLab, and Forgejo can be wired side by side with only provider package changes. Each provider owns its verification and outbound API details inside its pure-Harn connector package:

[dependencies]
harn-github-connector = { git = "https://github.com/burin-labs/harn-github-connector", rev = "v0.2.0" }
harn-gitlab-connector = { git = "https://github.com/burin-labs/harn-gitlab-connector", rev = "v0.1.0" }
harn-forgejo-connector = { git = "https://github.com/burin-labs/harn-forgejo-connector", rev = "v0.1.0" }

[[providers]]
id = "github"
connector = { harn = "harn-github-connector" }

[[providers]]
id = "gitlab"
connector = { harn = "harn-gitlab-connector" }

[[providers]]
id = "forgejo"
connector = { harn = "harn-forgejo-connector" }

Community connector discovery

A community connector is any Harn package that:

  1. Declares connector_contract = "v1" in package or registry metadata.
  2. Provides a [[providers]] manifest entry with connector = { harn = ... }.
  3. Exports provider_id, kinds, payload_schema, and the relevant normalize_inbound, poll_tick, or call exports.
  4. Declares provider-scoped setup metadata for generic host setup/status UI.
  5. Ships deterministic [connector_contract] fixtures and passes harn connector test ..

Minimal package shape:

[package]
name = "harn-acme-connector"
version = "0.1.0"
connector_contract = "v1"

[exports]
default = "src/lib.harn"

[[providers]]
id = "acme"
connector = { harn = "src/lib.harn" }
capabilities = ["webhook"]

[providers.setup]
auth_type = "api-key"
flow = "api-key"
required_secrets = ["acme/api-key"]
setup_command = ["harn", "connect", "api-key", "--connector", "acme", "--secret-id", "acme/api-key"]
validation_command = ["harn", "connect", "status", "--connector", "acme", "--json"]

[[providers.setup.health_checks]]
id = "api-key"
kind = "secret"
secret = "acme/api-key"

[providers.setup.recovery]
missing_auth = "Store an Acme API key as acme/api-key."
expired_credentials = "Rotate the Acme API key."
revoked_credentials = "Replace the revoked Acme API key."
missing_scopes = "Create an Acme API key with the required scopes."
inaccessible_resource = "Grant the API key access to the target Acme resource."
transient_provider_outage = "Retry after Acme or the credential backend recovers."

[connector_contract]
version = 1

[[connector_contract.fixtures]]
provider = "acme"
name = "sample webhook"
kind = "webhook"
headers = { "content-type" = "application/json" }
body_json = { id = "evt-1", type = "thing.created" }
expect_type = "event"
expect_kind = "acme.thing.created"
expect_dedupe_key = "evt-1"
expect_payload_contains = { provider = "acme", event = "thing.created", id = "evt-1" }
expect_event_count = 1

Run:

harn connector test .

Use live credentials only in provider-specific integration tests. Catalog examples and contract fixtures should run against mocked connector fixtures so Harn CI, connector repo CI, and local authoring all stay deterministic.

Authoring a connector

Start with Connector authoring, then add:

  • a harn.toml package manifest with connector_contract = "v1"
  • contract fixtures that cover normal event, ack-first response, reject, and poll cases where relevant
  • a README.md with install, setup, required secrets/scopes, supported events, and harn connector test command
  • mocked tests for outbound call(...) methods
  • a small recipe example under examples/triggers/ when the connector is first-party or broadly useful

The Harn-side contract is deliberately small. Keep provider SDKs or generated API clients in separate packages when that makes the connector easier to test and reuse, as with notion-sdk-harn.