Add Ingestr Source

SkillProductivity

With this skill added, your AI can add support for a new data source in the Bruin CLI, following a guided path from configuration code through to documentation and tests. A request to implement a new ingestr connection or source type becomes a complete piece of work that covers assets, source tables, docs, and tests.

Available today. Use it from your connected AI after setup.

Add the skill, then ask your AI to implement the data source you want Bruin to support. It will work through the full workflow, including changes needed after code review.

Then ask your AI: use the Add Ingestr Source skill

What your AI can do with it

  • Implement a new ingestr connection or source type
  • Wire a new source into Bruin ingestr assets
  • Update the list of available source tables
  • Add ingestion docs and example assets
  • Regenerate connection schema expectations
  • Address review feedback on source changes

What this skill tells your AI

The instructions your AI receives, as published by bruin-data/bruin in .agents/skills/add-ingestr-source/SKILL.md and read by ahel’s review.

Workflow

  1. Read the ingestr docs first: https://getbruin.com/docs/ingestr/. Then read the upstream source-specific docs or PR. Capture the source URI scheme, required URI parameters, optional URI parameters, supported source_table values, incremental behavior, primary keys, and any file/table hints.
  2. Inspect similar Bruin sources before editing. Prefer an existing package with the same shape: API/table source, OAuth/API-key source, database-like source, or file/path source.
  3. Implement the connection config and URI builder.
  4. Wire the connection into config loading, connection manager registration, and ingestr asset source discovery.
  5. Add source-table registry entries, docs, example assets, tests, and regenerated expectations.
  6. Run the checks required by the repo instructions before committing.

Implementation Checklist

Add or update these files for a new source named <source>:

  • pkg/<source>/config.go: the Config struct and GetIngestrURI().
  • pkg/<source>/db.go (or client.go, matching the package you copy from): the Client and NewClient.
  • pkg/config/connections.go: add <Source>Connection with YAML/JSON/mapstructure tags and GetName(). Tag every credential/secret field — anything that must not be printed in logs (API keys, tokens, passwords, client secrets, access keys, etc.) — with sensitive:"true" so it is redacted. For fields that hold a path to a credential file (e.g. a service-account JSON or private-key file), use sensitive_file:"true" instead — sensitive:"true" would mask only the path, while sensitive_file:"true" redacts the file's contents.
  • pkg/config/manager.go: add the connection slice to Connections, then update AddConnection, DeleteConnection, and MergeFrom.
  • pkg/connection/connection.go: import the package, add a Manager map, add Add<Source>ConnectionFromConfig, store it in availableConnections and AllConnectionDetails, and process it in NewManagerFromConfigWithContext.
  • pkg/pipeline/pipeline.go: add a defaultMapping entry "<source>": "<source>-default".
  • pkg/ingestr/sources.go: add SourceTablesRegistry["<source>"].
  • docs/ingestion/<source>.md: document .bruin.yml config, ingestr asset YAML, source tables, options, incremental behavior, and example assets.
  • docs/.vitepress/config.mjs: add the docs sidebar entry.
  • pkg/config/manager_test.go: cover the new connection in AddConnection/DeleteConnection/MergeFrom.
  • pkg/config/testdata/simple.yml: add a sample connection block.
  • pkg/config/testdata/simple_win.yml: add the same block (keep in sync with simple.yml).
  • integration-tests/expectations/expected_connections_schema.json: regenerate after the connection schema changes.

Add every required and optional parameter from the source URI — do not stop at the common ones. Take the authoritative list from the ingestr repo (bruin-data/ingestr) source code — the source's URI/DSN parser — not just the docs, and match each param's name and type exactly.

For sources without fixed tables, add representative source_table formats instead of pretending the source has enumerated tables. File/path sources usually need examples for exact paths, globs, and format hints.

URI Builder Pattern

Build ingestr URIs with net/url.Values; do not concatenate unescaped query parameters.

Validate required fields in deterministic order using a slice, not a map. This keeps user-facing errors stable and makes tests precise.

type requiredField struct {
    key   string
    value string
}

requiredFields := []requiredField{
    {"tenant_id", c.TenantID},
    {"client_id", c.ClientID},
}

for _, field := range requiredFields {
    field.value = strings.TrimSpace(field.value)
    if field.value == "" {
        return "", fmt.Errorf("%s: %s must be provided", sourceName, field.key)
    }
    params.Set(field.key, field.value)
}

Use pointer fields for optional numeric values where zero is meaningful, such as max_files: 0. Reject negative limits before adding them to the URI.

Tests

Add focused tests for:

  • URI encoding, optional parameters, zero-valued pointer options, missing required fields, and invalid limits in pkg/<source>.
  • Add<Source>ConnectionFromConfig registering the client and connection details.
  • Config.AddConnection, Config.DeleteConnection, and Connections.MergeFrom.
  • GetSourceTables("<source>") when source-table examples are added.

Regenerate the connection schema expectation after adding a connection type:

go run -tags="no_duckdb_arrow" . internal connections | jq . > integration-tests/expectations/expected_connections_schema.json

Inspect the generated diff. Ordering-only movement can happen, but keep only intentional changes.

Docs

Base docs on ingestr's source documentation, not guesses. Include:

  • .bruin.yml connection config with required and optional fields.
  • One minimal ingestr asset.
  • Several realistic example assets when source_table syntax has variants.
  • A table of available fixed tables, or available source_table formats for path/query-based sources.
  • Primary keys, metadata columns, and whether extraction is incremental or full-refresh.

Keep examples executable-looking but generic. Use the same destination pattern as nearby ingestion docs unless the source needs something different.

Version Caveat

Check the pinned ingestr version before bumping it, usually in pkg/python/uv.go. If the upstream source exists only in an unreleased ingestr PR or commit, wire Bruin support but do not bump to a nonexistent release. Mention the release dependency in the final note or PR when relevant.

Validation

During iteration, run focused package tests first. Before finishing app-code changes, follow the repo instructions exactly: run make format and make test.

For docs-only follow-ups, use the smallest relevant validation such as git diff --check, Markdown inspection, or docs build if the repo has a fast docs check.

Signals

GitHub stars
2k
Forks
90
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
add-ingestr-source
Source
github.com/bruin-data/bruin