Search⌘KHide sidebarOpen menu
Switch to dark mode
Copy page content as Markdown⌘⌥C
Login
Build integrations

Building with a coding agent

The workflow for writing an integration with a coding agent.

Coding agents such as Claude Code, Cursor or Codex can write most of a Connect package. The SDK CLI runs on your machine, so an agent can build, run and check its own work before you look at it.

Give the agent the right context

An agent writes a better integration when it reads the real contract instead of guessing from memory.

The SDK

@beetlio/connect is open source under the Apache-2.0 license, so the agent can read its full source and type definitions in the GitHub repository and the user guide. Once the SDK is installed, the type definitions are also in node_modules/@beetlio/connect/dist/. For how Beetl runs a package, add Authoring a sync, Materialization, Authentication and The sandbox.

The target API's documentation

Give the agent the provider's official reference for authentication, pagination, rate limits, filtering by last change, and how deleted records are reported. An agent left to infer an API from examples tends to miss the edge cases.

An example package

The SDK repository has runnable examples: a basic one with connection verification, an all-features one with OAuth, pagination and checkpoints, and a Wikidata one against a public API.

Plan before code

Ask the agent for a short written plan first and review it. A useful plan states:

  • what the integration syncs and what it leaves out
  • how authentication works, which permissions it needs, and how credentials are renewed
  • for each sync: the source endpoint, a stable record ID to use as the primary key, full or incremental reads, what goes into the checkpoint, and how deletions are handled
  • the pagination style and rate limits, with links to the docs that support each choice

The plan is cheap to correct. Sync keys, record schemas and primary keys are not: they become part of the package's contract once it is installed.

A loop that works

Scaffold

Have the agent create package.json with "type": "module" and a files allowlist, install the SDK with npm install --save-dev @beetlio/connect, and create integration.ts. The quickstart is a good template.

Implement authentication and one sync

Use the SDK's auth helpers in connection.auth and add a verify function that makes one small authenticated request. Then write one representative sync and leave the others until it works.

Run it locally

configure asks for credentials and needs an interactive terminal, so run it yourself:

npx beetl-connect configure . orders

The agent can then run the sync on its own and read the output:

npx beetl-connect sync . orders --output orders.ndjson

For syncs that take no credentials, the agent can pass settings with --inputs and configure without prompts. Both commands exit with a non-zero status on failure.

Check the records

The SDK validates every record against the sync's schema, so a passing run proves the shape. Ask the agent to check what validation does not cover: the record count matches what the API reports, primary keys are unique across the whole output, and fields that should be filled are not empty. Compare a few records with the provider's own UI yourself. For a Merge sync, the output file holds batches of records and deletions rather than one record per line.

Add incremental checkpoints

Declare a checkpoint and save the position after each batch. Local runs store checkpoints under .beetl/state/, so running the same sync twice shows whether the second run reads only what changed. Delete the state file, or pass --state with a new path, to start from scratch.

Add the remaining syncs, then pack

Repeat the loop for each sync. Finish with npx beetl-connect pack . --output acme.tgz and read the printed file list. See Pack and upload.

A starting prompt

Adapt this to your agent and API:

Build a Beetl Connect integration for the Acme Orders API using @beetlio/connect.

Read first:
- The SDK user guide: https://beetlio.github.io/connect/
- The SDK source and examples: https://github.com/beetlio/connect
- The Acme API reference: <link>

Write a plan before any code: syncs, primary keys, auth, pagination,
incremental strategy, deletions, rate limits, with doc links. Wait for my review.

Then implement auth with verify() and the "orders" sync only. I will run
`npx beetl-connect configure . orders` myself. You run
`npx beetl-connect sync . orders --output orders.ndjson` and report the record
count, duplicate primary keys and empty required fields.

Never print, log or commit credentials. Only read from the API.

Keep credentials away from the agent

Credentials saved by configure live in your operating system's user configuration folder, not in the project. They are readable by your user account but not encrypted, so an agent with full disk access could read them. Use a test account with the narrowest permissions the API allows, and keep any local secrets files out of version control. pack refuses .env* files and the .beetl folder in any case.

Review before you upload

Read the code yourself before a TenantAdmin uploads it. Check that:

  • credentials are declared in connection.auth, never as ordinary inputs, custom secret fields are marked with secret(), and verify fails on bad access
  • pagination reaches the last page, and API errors fail the run instead of returning an empty result
  • every primary key is stable, unique, required and never null
  • each batch carries the checkpoint to resume after it, and a repeated run does not duplicate records
  • the integration only reads from the provider
  • nothing logs tokens, request headers or full responses, and ctx.log is used for messages
  • the files allowlist ships only what the package needs

Run the whole loop again after any change to the code or its dependencies. A result from an earlier version says nothing about the new package.

Last updated on

On this page