Give each end user their own tool access
A user connection is one end user’s own account (mailbox, calendar, drive). A task uses its owner’s connection, else the connector’s org-owned one.
You need: a deployed runtime (here support-agent), tasks owned by the end
user, and a Pipedream Connect project.
1. Create the Pipedream connector
Put the request in a file, so the secret stays off the command line:
{ "name": "Pipedream", "slug": "pipedream", "provider": "pipedream",
"auth_mode": "client_credentials", "environment": "production",
"client_id": "<pipedream-client-id>", "client_secret": "<pipedream-client-secret>",
"metadata": { "provider_workspace_id": "proj_abc123" } }introspection connectors create @pipedream.jsonDelete pipedream.json afterwards.
2. Declare the app in the recipe
The MCP server id is the app’s slug from
Pipedream’s app directory , such as gmail.
{ "pi": { "mcp": { "servers": [{ "id": "<app>", "tools": { "include": ["*"] } }] } } }Select it under each agent’s mcp: (Connect an MCP server).
3. Mint a link for the end user
Your backend mints it with an API key and sends it to the user. The link lasts
10 minutes unless you set expires_in (Pipedream caps it at 4 hours).
const { authorize_url } = await client.connectors.authorize("<connector-id>", {
app: "<app>",
runtime: "support-agent",
identity: { user_id: "user-4821" },
expires_in: 3600,
});By hand: introspection connectors authorize-url pipedream --runtime support-agent --app <app> --user-id user-4821.
On approval, Introspection binds the app’s MCP endpoint for the runtime.
4. Run a task as that user
The task must belong to that end user, so start it with an API key and --subject:
introspection tasks create -r support-agent -e production \
--subject user-4821 --prompt "List what changed in my inbox this week."Verify
introspection connectors connections list --connector pipedream -o json
introspection bindings mcp list -r support-agent -e productionExpect a connection for user:user-4821 and an <app> endpoint.
Or ask your agent: “Set up per-user Gmail access for support-agent.”
Signed-in users, a Connect button, and revoking
Two kinds of member. A user_id your backend passes is the member
user:<id>: its tasks use links minted for it, including tasks your scheduler
starts with --subject <id>. A user signed in through an
application is another member. Neither sees the
other’s connections, so pick one per person. An automation that starts a new
task runs as the platform, with shared connections only.
Connect button for signed-in users. Declare each app with
"required": false (without the account, its tools return “not connected”).
The application’s --allowed-scope must include connections:read and
connections:write.
const mine = await client.connections.list({ app: "<app>" });
const { authorize_url } = await client.connections.create({ app: "<app>", runtime: "support-agent" });Revoke a connection with its ID from connections list; the user must
reconnect through a new link:
introspection connectors connections revoke <connection-id> --connector pipedreamLimits
| Not supported | Do this instead |
|---|---|
| Per-user connections on other connectors | A connector per tenant, each authorized once. |
| A tool Pipedream lacks, per user | Your own API bound with --authorized-application; pick the account from the JWT sub (claims). |
| A person’s own connection in Slack | Use your app with sign-in. |
| Testing one user’s connection | connectors test checks only the org connection; run a task as that user. |