v0.1.0
Protocol Spec

Connector Ecosystem

Reference runtime notes for connectors: browser abstraction decisions and third-party source integration.

Date: 2026-07-07 (revised from 2026-03-30)

Scope: Survey of connector types and the browser-abstraction decision behind the Collection Profile.

Browser abstraction decision

Two models were considered in March 2026 for how connectors interact with browsers:

  • Model A: the runtime owns the browser and hands connectors a live automation handle. Simple, powerful, debuggable.
  • Model B: the runtime exposes the browser through custom JSONL messages (BROWSER/BROWSER_RESULT). Connectors never touch the browser API. Enables process isolation and language independence, but adds a fragile proxy layer.

Decision: no custom BROWSER message protocol. Connectors need real browser power (bot challenges, SPA navigation, network interception, cookie extraction). A message protocol either reimplements the automation API or falls back to evaluate for everything hard. The JSONL protocol stays reserved for RECORD/STATE/INTERACTION/DONE; browser automation is a runtime capability declared in the manifest, not a protocol concern.

The isolation path chosen instead was a standard browser endpoint: the Collection Profile now specifies the browser_automation binding as a CDP WebSocket ({ interface: "cdp", ws_url }) that the runtime provides to the connector process. This gives process isolation and language independence without a bespoke proxy protocol.

Connector strategies

How connectors get data from sources:

StrategyExamplesRuntime needsLanguage
API clientPlaid, Terra API, Spotify API, GitHub APIHTTP onlyAny
Browser automationChatGPT, LinkedIn, H-E-Bbrowser_automation binding (CDP)Any that speaks CDP
Session cookie extractionslackdump, DiscordChatExporterCookies from browser profile, no live browserAny
Archive/export parserTimelinize, WhatsApp export, Facebook DYI, Google Takeoutfilesystem bindingAny
Browser extensionLinkedIn scrapers, Amazon purchase historyRuns in user's browser, sends to local connectorJS (extension) + any (receiver)
Aggregator wrapperPlaid (many banks), Terra (Fitbit/Oura/Garmin/Apple Health)Just API callsAny

Third-party tools that could become PDPP connectors

Go-based

ToolDataAuth methodLicenseWrap difficulty
slackdump (rusq/slackdump)Slack messages, threads, files, users, emojisBrowser session cookie (d cookie) or export tokenGPL-3.0Easy: already outputs JSON/SQLite
Timelinize (timelinize/timelinize)10+ sources: photos, Facebook, Instagram, Twitter, Google, iCloud, Strava, SMS, email, contactsPer-source (OAuth, file import, API keys)Apache-2.0Medium: need Go wrapper per data source

C# / .NET

ToolDataAuth methodLicenseWrap difficulty
DiscordChatExporter (Tyrrrz/DiscordChatExporter)Discord messages, DMs, servers, attachmentsUser tokenGPL-3.0Easy: supports JSON export, CLI invokable

Python

ToolDataAuth methodLicenseWrap difficulty
tg-archive (knadh/tg-archive)Telegram groups, private messages, mediaTelegram API credentials (api_id, api_hash, phone)MITEasy: syncs to SQLite, read and emit
rexport (karlicoss/rexport)Reddit comments, submissions, upvotes, savedReddit API (client_id, client_secret, username/password)MITEasy: outputs JSON arrays

Aggregator services (one connector = many sources)

ServiceData domainSources coveredAuthWrap difficulty
PlaidFinancial (transactions, accounts, balances, investments)US/EU financial institutions via Plaid's aggregation coveragePlaid Link OAuth flow → access_tokenEasy: structured JSON API
Terra APIHealth/fitness (workouts, sleep, heart rate, steps)Fitbit, Oura, Garmin, Apple Health, Whoop, Peloton, etc.Terra OAuth → API callsEasy: structured JSON API
CommonHealthHealth records (Android)400+ data sourcesOn-device consentMedium: Android-specific

Archive parsers (user provides exported data)

SourceExport formatParser exists?Notes
WhatsApp.txt/.zip from phone exportPython parsers existE2E encrypted, no API access possible
Facebook DYI.zip archive (HTML or JSON)Timelinize parses itLarge archives, complex structure
Google Takeout.zip per-productTimelinize parses some51-54 data types
Apple Data & Privacy.zip archiveNo standard parser15 categories, 1-7 day fulfillment
Instagram data export.zip archiveTimelinize parses itDifferent format eras

Runtime requirements summary

The connector run protocol (JSONL over stdin/stdout) is universal. What varies is which bindings a connector declares in runtime_requirements.bindings and whether the runtime can satisfy them. The Collection Profile defines the standard bindings: browser_automation (CDP WebSocket), browser_profile, filesystem, network, interactive, and loopback_listen; extension bindings use namespaced identifiers. Binding matching happens before the connector process is spawned: if the runtime cannot satisfy a required binding, the run fails with a clear error. See Collection Profile Section 1 for descriptors and matching rules.

Implications for the spec

  1. The JSONL protocol is correct. Every connector type (Go binary, Python script, Node.js process, aggregator wrapper) can write JSONL to stdout.
  2. Browser access is a binding, not a protocol message. Connectors that need a browser declare browser_automation and receive a CDP WebSocket descriptor at START. The run protocol itself stays browser-free.
  3. Aggregator connectors (Plaid, Terra) cover many sources at once. One Plaid connector reaches the financial institutions Plaid aggregates; one Terra connector reaches the health/fitness platforms Terra supports.
  4. Archive parsers are served by the filesystem binding, which the Collection Profile now defines as a standard binding.
  5. Go/Python/C# connectors work today via the JSONL protocol. No Node.js required. The runtime just spawns a process.

Sources