Problem
The PDF importer works because we hold one Datalab key for everybody (PDF Importer). Salesforce is the opposite. Every company has its own account, every user has its own login, and nobody is going to paste a token into an agent. Same with a company database. And we can't ship one builtin per service, there are thousands.
Horacio wants the same for GitHub, "connect from my agent to GitHub", one click (Github Connector proposal). So this is not a Salesforce thing, it is a connector thing. This note is my take on how connectors should work.
What a connector is
In the shape-up meeting someone said "an API key is not a tool" (meeting notes). I think that is the whole design. A connector is three objects with three different owners.
The template. Public, anyone can publish one, it is a Seed document. It says which executor to use (an MCP server, SQL, later plain HTTP), where the service is, how to log in, which kind of secrets it needs (not the secrets, just "needs an OAuth login" or "needs a connection string"), and a guide so the agent knows how to use the thing.
The credential. Private, belongs to one space, encrypted in the agents server. Never in the template, never in memory, never in the model.
The executor. Code inside the agents server binary. Same code in our hosted server, in the local server the desktop starts, in a self hosted docker. It takes the template, the credential and the arguments the model wrote, makes the call, gives back a bounded result.
Anyone with the template gets the functionality the moment they add their own credential. That is the "we kinda have that" part, and we almost do.
Where a connector lives
In the gateway a custom domain (example.com) and a subdomain (example.hyper.media) resolve to the same thing: the space registered on that site (Sites). I want the same unit in the agents server. A connector is installed in a space.
The agents server never sees a hostname, only the signed envelope with the account and the capability. That is enough. Installing a connector is a signed action on the space, so only the owner or a writer of that space can do it. The install record, the credential and the list of agents that can use it all hang from the space.
Visibility rule is simple. Builtins are visible to every agent. A space's connectors are visible only to agents attached to that space (they hold a capability for it, the same chain Eric describes in Agent Permissions) and only if a writer of the space enabled them for that agent. Nothing from another space on the same server is visible, not even to the same person.
Visibility of a template is the visibility of the document, nothing new. A public template anyone can install. A private template in your space is visible only to the people who can read your private documents, so only they can install it. One catch: the agents server reads documents anonymously today, so to install a private template it has to read as the agent key with a capability, which is what Eric's note asks for anyway.
If you want total control, self host. A site can already say which agents server it uses (agentServerUrl in the home document), so a self hosted site with a self hosted agents server keeps every connector and credential in a process nobody else shares.
Can a connector just be a document the agent reads?
Half. Today every tool is already a content addressed document in the agent's tools folder (Tool document), three kinds: builtin, lambda (code the agent wrote, runs in the sandbox) and MCP (one tool of a remote MCP server, MCP servers). The code even says that publishing a tool to the network later is just publishing bytes that already exist.
But reading a document gives the agent knowledge, not capability. If the agent reads "here is the Salesforce API, call it like this", it still needs code that runs with a key. So the template is an install manifest plus a guide. Install is a signed action: the server fetches the document, pins its version, creates the same records we have today (an MCP server record, or a SQL source) and the grant. No new tool kind. From there the existing machinery does the rest, discovery projects the tools, the agent sees them in its index, call runs them.
What is missing: install from an hm:// address, OAuth on MCP servers (today only static headers, MCP servers), and a SQL executor.
Who executes the code
The agents server where the agent lives. The model only returns text and tool calls. The server makes the call with the credential and returns the result. The LLM provider sees the arguments and the data that comes back, never the key. So the question is not "do I trust OpenAI with my key", it is "do I trust the agents server", same question we have today with model provider keys. For most users that server is their laptop.
Lambdas stay out. The model writes that code, so if a lambda could read a secret the model could print it. Connectors that need code run as an MCP server (someone hosts it) or as a declarative HTTP contract where the server adds the auth header itself.
One exception to "no relay". Some services still want a client secret when exchanging the OAuth code, GitHub does. A laptop can't hold that secret. So for those, that one step goes through a broker in our hosted server, the same relay pattern as convert. Salesforce doesn't need it.
How the key stays secret
Same as MCP headers and provider keys today: secrets by reference, decrypted only inside the executor, redacted everywhere else.
Two rules on top. One, the template declares roles ("oauth", "dsn"), never secret names. Install creates the secrets in a namespace that belongs to that install, and the executor only resolves inside it. Otherwise a bad template could say "my secret is called openai-subscription-oauth" and get your ChatGPT token posted to its URL. Two, the credential remembers the host it was created for. A template update that changes the host doesn't inherit the credential, you sign in again.
What we can't hide is the data. Whatever Salesforce returns goes to the model, so to the provider. That is the point of the connector, and people should know it.
Can we do SSO?
Yes, and it is the best part. What you call SSO is OAuth authorization code with PKCE: the user logs in at Salesforce in the browser, Salesforce sends us a code, we exchange it for a token. We never see the password. We hold a refresh token with a small scope that the user can revoke from Salesforce any day. We already run exactly this flow for "Sign in with ChatGPT" (Model providers), it just needs to be generalized to MCP servers.
Salesforce made this easy. Since April 2026 they have hosted MCP servers (Enterprise Edition and up). The org admin enables them and creates an External Client App with scopes mcp_api and refresh_token, PKCE, no client secret. Every call runs as the logged in user with their own Salesforce permissions, so we don't have to invent permissions for Salesforce data.
So the Salesforce connector is an MCP connector plus OAuth. The org URL and the client id are install parameters, they are per org, not per template. The callback is a fixed localhost port in the desktop and a real endpoint in the hosted server, both registered in the same External Client App. For discovery we should follow the MCP authorization spec, the SDK we use already supports it, so GitHub, Linear and any other MCP server with OAuth get the same "Sign in" button for free.
The SQL connector
Not easier, different. There is no hosted MCP for a MySQL that sits in a private network, so we are the client. A small sql executor in the agents server process (MySQL first, Postgres is the same code), the connection string is the credential, the template has the dialect and some notes about the schema so the agent knows what to query.
Read only has to come from the database, not from us parsing SQL. A read only database user and a read only transaction, plus a statement timeout and limits on rows and bytes. Running in the server process, not in the sandbox, is what lets the laptop server reach a database in the office network. The hosted server only reaches what is public, fine.
If someone doesn't want to give us a connection string, they run one of the existing MySQL MCP servers next to the database and install it as an MCP connector.
Grants and injection
Enabling a connector is as strong as execute, the remote server decides what its tools do (MCP servers). Two things for the first version. Connectors get a mode, read or all, taken from the tool annotations MCP already has, and destructive tools ask the user before running. And OAuth connectors run only in sessions of the space owner and writers, because a Salesforce record can contain instructions for the agent, and now the agent has your Salesforce authority (Security). Per user sign in for chatters comes later.
The marketplace
A template is a Seed document of a known type, "Connector template", published in the author's space, like hm://<author>/tools/salesforce. Any site with a query over that type is a marketplace. We can run a curated one in hyper.media, a community can run its own. The author's signature is the trust, the comments are the reviews, the document version is the release. I wrote one, the Sales database template, so we see what a template actually is.
Installing. The template page has an Install button. You pick the space, the agents, fill the parameters the template asks for (org URL, client id), confirm. One signed action from a writer of the space, pinned to that version of the template. The agent can also propose it from the chat after reading a template, but the user clicks. And the CLI for scripted setups.
Seeing what is ready. The Tools tab lists every connector of the space with a state: Ready, Needs sign in, Needs secret, Unreachable, Update available. Today the MCP rows already have an Unreachable chip and an Auth chip, this extends them. Only Ready tools go to the agent's index, so the model never calls what cannot run. Update is explicit, and if the new version changes the host the credential is dropped.
Creating your own. Write the tool in an agent (a lambda, or point it to your MCP server), try it, then "Publish as template" into your space. The server writes a Seed document from the tool bytes, minus the credential, plus the secret roles and the guide. Anyone who can read your space can install it, in their space, with their credential.
Do you like what you are reading? Subscribe to receive updates.
Unsubscribe anytime