Beyond Shopify, five providers connect by OAuth:
| Provider | Used for | |---|---| | Google | GTM containers, GA4 properties and data streams | | Meta | Ad accounts, pixels, datasets | | Klaviyo | Lists, flows, metrics | | Notion | Knowledge search and user instructions | | Figma | Brand kit extraction — read-only on file content |
A sixth provider, Shopify Partners, backs the store-provisioning pool rather than a merchant-facing connection.
The state parameter is bound to your browser
Worth documenting because the failure mode is not obvious.
All four original connectors built their OAuth state the same way: a
base64 envelope of the store id and a return path. Unsigned, unbound,
and forgeable by anyone who could read it.
The callbacks did check that the person arriving could reach the store — which is a different question, and answering it is what made the gap look closed. It proves the arriving user has access; it never proves the authorization code belongs to them.
The attack was textbook: start the flow with your Google account against the victim's store id, capture the callback URL, get a member of that organization to open it. Their store is now linked to your account, and the tracking scan reads your containers and pixels.
The state is now signed and bound to a nonce in the browser that started the flow, so a callback opened in a different browser is refused.
Tokens
Access and refresh tokens are stored encrypted, with expiry carried alongside. Google and Meta tokens are refreshed automatically before expiry; a refresh failure marks the connection rather than failing silently in whatever feature next reads it.
Revoking on the provider's side is honoured: the connection stops working, and reconnecting is an explicit action.
Figma is read-only, and why
The Figma REST API cannot write file content: writing goes through a plugin inside the editor, and the write-side Variables API is Enterprise-only. So the brand wizard verifies that a copy is in your account, reads its paint and text styles, and exports a W3C design-tokens JSON you import back through a tokens plugin.
It is not a limitation we chose, and pretending otherwise would promise a sync that cannot exist.
What was removed
There is no MCP bridge in the connector layer. A registry, a phantom MCP server and a Shopify provider holding a token on disk once lived here; all three had no callers and were deleted. If you are reading an older note that mentions them, it describes code that is gone.