<!-- source: https://vectoralix.com/docs/sources/sync | service: Vectoralix | format: markdown twin auto-generated from the canonical HTML page -->

Source Integrations

#  Sync &amp; Updates 

 What happens after a successful first import. The current model is "one-shot import on connect, plus a manual refresh you trigger from the UI". Webhook-driven auto-sync is on the roadmap but not yet shipped — this page is honest about that.

 ## The sync model at a glance

 On connect, the integration runs a full import of the selected branch (with optional path filter). After that, the integration is idle — it does nothing until you trigger a manual refresh, rotate the token, or delete the integration. There is no scheduler, no webhook listener, and no background drift detector.

```
connect  ->  initial import  ->  idle  ->  manual refresh  ->  idle  ->  …
```

## Manual refresh

 Manual refresh is shipped. From the Source Integrations table, the Refresh row action re-runs the read pipeline against the current HEAD of the configured branch. Small repositories run inline; larger ones queue a background job — the same sync-vs-queued split the initial import uses, with a 20-file pre-flight threshold.

 Refresh runs at MCP-server scope and supports two modes:

- Prune deleted (default) — content rows whose paths no longer appear in the remote listing are removed. Requires the contents.can\_delete entitlement on top of the import permission.
- No prune — removed files linger as stale content rows. Useful if you want to keep historical versions around for review before deleting them by hand.
 
 On the MCP server edit page, a "Refresh all integrations" header action queues one refresh job per integration that has a stored access token. Empty-token rows are skipped, and the prune choice threads through to every dispatched job.

## Re-connecting vs refreshing

 Re-completing the OAuth flow against the same MCP server, provider, and repository upserts the integration row. That rotates the access token (and on GitLab, also the branch + path filter) rather than creating a duplicate row. A database-level unique constraint to lock this in is on the roadmap but not yet in place.

## Token rotation on edit

 On the Edit form, the Access Token field is blank by default. Leaving it blank preserves the existing encrypted token; typing a new value replaces it. The new value is validated against the provider before the row is updated, identical to the create-time flow — a bad token surfaces as a field-level error and nothing is written.

## Access-token expiry by provider

    Provider PAT / App Password OAuth access token     GitHub No auto-expiry No auto-expiry   Bitbucket App Password — no auto-expiry Expires after 2 hours; refresh-token handling not yet wired   GitLab (gitlab.com) No auto-expiry Expires after 2 hours; refresh-token handling not yet wired    Until refresh-token handling lands for Bitbucket and GitLab OAuth, prefer the App Password / PAT flow for any production integration that runs more than a one-shot import.

## Deleting an integration

 Removing the integration row stops future refreshes from that repository immediately. Content rows that were already imported into the MCP server are NOT automatically removed — that is a deliberate choice so a bad disconnect cannot nuke production content. If you want a clean slate, delete the corresponding content entries by hand after disconnecting.

## Partial failures

 If a refresh trips a cap — GitHub tree truncation, the Bitbucket BFS caps, or the GitLab page or wall-clock budget — a warning is logged and the partial result is imported. Per-file skips (binary, non-UTF-8, blob too large) are recorded against each file and counted in the result; they do not abort the import. The integration itself is not marked failed for these cases.

 There is one safety gate: if a refresh returns zero blobs, you have more than ten existing content rows for the server, and prune-deleted is on, the refresh aborts with an explicit warning instead of wiping the content. This protects against a mis-edited path filter zeroing out a server.

## What is deliberately not yet supported

- Webhook-driven auto-sync on push.
- Scheduled periodic sync.
- Refresh-token rotation for Bitbucket and GitLab OAuth.
- Multi-branch tracking on a single integration.
- Per-content-row attribution back to the integration that imported it (currently refresh works at MCP-server scope, so two integrations pointing at the same server with prune-deleted on can delete each other's rows — keep one integration per server until that lands).
 
 **Stale content?:** If you cut a new MCP version after a refresh, the version snapshots the freshly upserted content. If you forget to cut a new version, the active version keeps serving the previous snapshot — refresh updates the live content table, not the active version. See Versioning &amp; Releases for the snapshot-vs-live distinction.
