Connectors — data in
Connectors pull knowledge from the tools your company already uses into governed memory. Six providers plus bulk upload, at two levels: org-wide connections managed by admins, and personal connections whose imports are private to you.
Two levels: org and personal
Org connectors (Settings → Integrations, admin-only) import shared corpora — the engineering team's GitHub repos, the company Slack channels, the policy Drive folder — into folders the whole workspace can be granted on.
Personal connections (Settings → Account, any member) connect your tools. Imports land in your private folder under /people/<you> — a restricted folder only you hold a grant on — and arrive pre-approved (you are that folder's manager; a draft gate would make you your own reviewer). Your chat and search see this content automatically; nobody else's does.
Workspace owners/admins bypass all scoping by design (standard B2B posture, and every access is audited) — personal folders are private from other members, not cryptographically hidden from admins.
Provider setup
Every provider supports one-click OAuth when your deployment has that provider's app credentials configured (see the environment table below), with a paste-credentials fallback that always works. After connecting, a scope picker lets you choose exactly what to sync.
| Provider | What syncs | Paste credential | OAuth env vars |
|---|---|---|---|
| Linear | Issues from chosen teams | Personal API key (lin_api_…) | LINEAR_CLIENT_ID/SECRET |
| GitHub | Issues, PRs, and docs from chosen repos | Personal access token | GITHUB_OAUTH_CLIENT_ID/SECRET |
| Jira | Issues from chosen projects | Account email + API token + site URL (yourco.atlassian.net) | ATLASSIAN_CLIENT_ID/SECRET |
| Slack | Messages from chosen channels | Bot token (xoxb-…) — org only; personal Slack is OAuth-only | SLACK_CLIENT_ID/SECRET |
| Notion | Pages from the shared workspace | Internal integration token | NOTION_CLIENT_ID/SECRET |
| Google Drive | Files from chosen folders | Service account JSON (org-level only) | — (service account only) |
Provider notes
- Linear — OAuth tokens are short-lived and refresh automatically; nothing to rotate by hand.
- GitHub — the OAuth app requests the
reposcope, which technically grants read/write although Engram only reads. Use a fine-grained PAT if that bothers you. - Jira — OAuth (Atlassian 3LO) uses rotating refresh tokens; Engram refreshes and persists them around every sync. If a connection sits unused for ~90 days Atlassian expires it — reconnect from settings.
- Slack — org connections install a bot; personal connections authorize as you and can read what you can read. Slack messages are converted from Slack's markup to clean markdown on import.
- Google Drive — org-level via a service account with domain access to the target folders. Personal Drive is deliberately not offered (Google's restricted-scope review makes it impractical for now).
How a sync works
- Manual trigger — syncs run when you click “Sync now” (or call
trigger_syncover MCP /POST /v1/connectors/:id/sync). There is no background scheduler yet. - Incremental by content hash — unchanged documents are skipped; changed documents land as new draft versions on their existing node, never silently overwriting approved content.
- Import mode per connector —
importAs: draft(default: everything goes through the review queue) orimportAs: approvedfor a corpus an admin explicitly trusts (official policy documents, say). The admin who set the flag is recorded as the approver — the AI-write invariant holds because a human made the call. - Every run is recorded — a sync-run row with document counts, per-document errors, and a cursor; visible in settings, over MCP (
get_sync_status), and via the API. - Pause/resume and removal — pausing keeps everything; removing a connector deletes the connection and its run history but leaves imported memories in place.
Folder & classification mapping
Each connector carries a mapping config that routes documents into the tree and assigns sensitivity: a default destination path plus deterministic rules over source metadata — for example, “metadata department=HR → /departments/hr; level=Confidential → confidential.” Onboarding a whole corpus is a mapping config, not custom code. Personal connections skip this: their destination is always your private folder, enforced server-side.
Bulk upload
For corpora that live nowhere convenient: POST /v1/connectors (admin) accepts a zip plus a manifest.csv of per-file metadata, creates an upload connector, and starts the first sync. Same machinery — mapping rules, import mode, incremental re-upload by content hash. PDFs and DOCX are text-extracted, images OCR'd, audio transcribed before compilation.
PM webhooks are not connectors
Jira, GitHub, and Linear also appear on the push side: /api/webhooks/pm receives issue-closed and PR-merged events, creates tasks for routing, and proposes candidate captures (“this ticket's resolution looks like a lesson — file it?”). That's the Human-AgentOS loop, not corpus sync — you'll typically want both: a connector for history, the webhook for what happens next. Configure webhook signature verification with PM_WEBHOOK_SECRET (see API reference).