Skip to content

Commit 7fb7e2c

Browse files
Danny/docs/mcp tool mode (#16890)
* Update developers.mdx * Update developers.mdx * Tools Mode * Update developers.mdx * Update pnpm-lock.yaml * Update developers.mdx
1 parent b1d1018 commit 7fb7e2c

File tree

2 files changed

+148
-12
lines changed

2 files changed

+148
-12
lines changed

docs-v2/pages/connect/mcp/developers.mdx

Lines changed: 138 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import { Callout, Steps, Tabs } from 'nextra/components'
44

55
Add Pipedream's MCP server to your application or agent to make tool calls on behalf of your users to {process.env.PUBLIC_APPS}+ APIs and 10,000+ tools.
66

7+
<Callout type="info">
8+
Pipedream Connect includes built-in user authentication for [every MCP server](https://mcp.pipedream.com), which means you don't need to build any authorization flows or deal with token storage and refresh in order to make authenticated requests on behalf of your users. [Learn more here](/connect/mcp/developers/#user-account-connections).
9+
</Callout>
10+
711
## Overview
812

913
Pipedream's MCP server code is [publicly available on GitHub](https://github.com/PipedreamHQ/pipedream/blob/master/modelcontextprotocol/README.md), and you have two options for using Pipedream's MCP server in your app:
@@ -126,6 +130,7 @@ const slackApps = await pd.getApps({ q: "slack" });
126130
</Tabs.Tab>
127131
</Tabs>
128132

133+
129134
### Use Pipedream's remote MCP server
130135

131136
<Callout type="info">
@@ -136,6 +141,120 @@ The remote MCP server is in beta, and we're looking for feedback. During the bet
136141

137142
The Pipedream MCP server supports both SSE and streamable HTTP transport types dynamically, with no configuration required by the developer or MCP client.
138143

144+
#### Tool modes
145+
146+
Pipedream MCP supports two methods for interacting with tools:
147+
148+
1. [Sub-agent](#sub-agent-mode) (default)
149+
2. [Tools only](#tools-only-mode)
150+
151+
##### Sub-agent mode
152+
153+
When using Pipedream MCP in sub-agent mode, all tools you expose to your LLM take a single input: **`instruction`**.
154+
155+
The Pipedream MCP server passes the **`instruction`** to an LLM to handle the configuration of the main tool using a set of agents with narrowly scoped sets of instructions and additional tools to aid in the configuration and execution of the top-level tool.
156+
157+
- The benefit with this approach is that sub-agent mode abstracts a lot of the complexity with handling things like [remote options](/connect/components/#configure-the-component) and [dynamic props](/connect/components/#configure-dynamic-props), especially for MCP clients that don't automatically [reload tools](https://modelcontextprotocol.io/docs/concepts/tools#tool-discovery-and-updates).
158+
- However, one downside is that you hand over some of the control and observability to Pipedream in this model.
159+
160+
<Callout type="warning">
161+
While in Beta, Pipedream eats the costs of the LLM tokens in sub-agent mode. We'll likely pass these costs on to the developer in the future.
162+
</Callout>
163+
164+
<details>
165+
<summary>View the schema for the `google_sheets-add-single-row` tool in **sub-agent mode**</summary>
166+
167+
```javascript
168+
{
169+
"name": "GOOGLE_SHEETS-ADD-SINGLE-ROW",
170+
"description": "Add a single row of data to Google Sheets. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append)",
171+
"inputSchema": {
172+
"type": "object",
173+
"properties": {
174+
"instruction": {
175+
"type": "string"
176+
}
177+
},
178+
"required": [
179+
"instruction"
180+
],
181+
"additionalProperties": false,
182+
"$schema": "http://json-schema.org/draft-07/schema#"
183+
}
184+
}
185+
```
186+
187+
</details>
188+
189+
##### Tools-only mode
190+
191+
To handle all tool configuration and calling yourself, you should use `tools-only` mode.
192+
193+
###### Configuring dynamic props
194+
195+
- Tools that use [dynamic props](/connect/api/#reload-component-props) can't be configured in one shot, as the full prop definition isn’t known until certain inputs are defined.
196+
- For example, the full set of props for `google_sheets-add-single-row` aren't known until you configure the `hasHeaders` prop. Once we know if there's a header row, we can retrieve the column names from the header row and make them available as props that can be configured.
197+
- As you call each tool, you should reload the available tools for the server, and we'll expose meta tools for configuration, such as `begin_configuration_google_sheets-add-single-row`, which causes the rest of the tools to be removed and only tools relevant to the configuration are exposed.
198+
199+
{/* Need to add info for devs to step through async options */}
200+
{/* Need to add more detailed info for devs to step through dynamic props */}
201+
202+
<details>
203+
<summary>View the schema for the `google_sheets-add-single-row` tool in **tools-only mode**</summary>
204+
205+
```javascript
206+
{
207+
"name": "google_sheets-add-single-row",
208+
"description": "Add a single row of data to Google Sheets. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append)",
209+
"inputSchema": {
210+
"type": "object",
211+
"properties": {
212+
"drive": {
213+
"anyOf": [
214+
{
215+
"anyOf": [
216+
{
217+
"not": {}
218+
},
219+
{
220+
"type": "string"
221+
}
222+
]
223+
},
224+
{
225+
"type": "null"
226+
}
227+
],
228+
"description": "Defaults to `My Drive`. To select a [Shared Drive](https://support.google.com/a/users/answer/9310351) instead, select it from this list.\n\nYou can use the \"CONFIGURE_COMPONENT\" tool using these parameters to get the values. key: google_sheets-add-single-row, propName: drive"
229+
},
230+
"sheetId": {
231+
"type": "string",
232+
"description": "Select a spreadsheet or provide a spreadsheet ID\n\nYou can use the \"CONFIGURE_COMPONENT\" tool using these parameters to get the values. key: google_sheets-add-single-row, propName: sheetId"
233+
},
234+
"worksheetId": {
235+
"type": "string",
236+
"description": "Select a worksheet or enter a custom expression. When referencing a spreadsheet dynamically, you must provide a custom expression for the worksheet.\n\nYou can use the \"CONFIGURE_COMPONENT\" tool using these parameters to get the values. key: google_sheets-add-single-row, propName: worksheetId"
237+
},
238+
"hasHeaders": {
239+
"type": "boolean",
240+
"description": "If the first row of your document has headers, we'll retrieve them to make it easy to enter the value for each column. Note: When using a dynamic reference for the worksheet ID (e.g. `{{steps.foo.$return_value}}`), this setting is ignored."
241+
}
242+
},
243+
"required": [
244+
"sheetId",
245+
"worksheetId",
246+
"hasHeaders"
247+
],
248+
"additionalProperties": false,
249+
"$schema": "http://json-schema.org/draft-07/schema#"
250+
}
251+
}
252+
```
253+
254+
</details>
255+
256+
{/* ![Tools-only mode](https://res.cloudinary.com/pipedreamin/image/upload/v1748583198/slack-mcp-tools-only_d1veqw.png) */}
257+
139258
#### Base URL
140259

141260
```
@@ -180,19 +299,24 @@ curl -s -X POST https://api.pipedream.com/v1/oauth/token \
180299
</Tabs.Tab>
181300
</Tabs>
182301

183-
#### Required headers
302+
#### Params
184303

185-
Include these headers in every HTTP request:
304+
- Below are params that you should send with every HTTP request to Pipedream's MCP server.
305+
- To enable broad support for various MCP clients, you can pass these params via HTTP headers **or** as query params on the URL.
186306

187-
```javascript
188-
{
189-
"Authorization": `Bearer ${accessToken}`,
190-
"x-pd-project-id": PIPEDREAM_PROJECT_ID, // proj_xxxxxxx
191-
"x-pd-environment": PIPEDREAM_ENVIRONMENT // development | production
192-
}
193-
```
307+
<br />
308+
309+
<div className="highlightHeaderRowTable">
310+
| Header | Query Param | Value | Required? |
311+
|--------|---------|------------------------------|--------|
312+
| `x-pd-project-id` | `projectId` | `proj_xxxxxxx` | Yes |
313+
| `x-pd-environment` | `environment` | `development`, `production` | Yes |
314+
| `x-pd-external-user-id` | `externalUserId` | `<your-users-id>` | Yes |
315+
| `x-pd-app-slug` | `app` | `linear`, `notion`, etc | Yes |
316+
| `x-pd-tool-mode` | `toolMode` | `sub-agent`, `tools-only` | No <br /> Defaults to `sub-agent` |
317+
</div>
194318

195-
Example request:
319+
#### Example request
196320

197321
```javascript
198322
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
@@ -210,14 +334,16 @@ const pd = createBackendClient({
210334

211335
// Retrieve your developer access token via the Pipedream SDK
212336
const accessToken = await pd.rawAccessToken();
213-
const serverUrl = MCP_SERVER_URL || `https://remote.mcp.pipedream.net/${externalUserId}/${appSlug}`;
337+
const serverUrl = MCP_SERVER_URL || `https://remote.mcp.pipedream.net`;
214338

215339
const transport = new StreamableHTTPClientTransport(new URL(serverUrl), {
216340
requestInit: {
217341
headers: {
218342
"Authorization": `Bearer ${accessToken}`,
219343
"x-pd-project-id": PIPEDREAM_PROJECT_ID, // proj_xxxxxxx
220-
"x-pd-environment": PIPEDREAM_ENVIRONMENT // development | production
344+
"x-pd-environment": PIPEDREAM_ENVIRONMENT, // development | production
345+
"x-pd-external-user-id": EXTERNAL_USER_ID, // the user's ID from your system
346+
"x-pd-app-slug": APP_SLUG, // notion, linear, gmail, etc
221347
}
222348
}
223349
});

pnpm-lock.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)