Getting Started with AI Coding Agents
What is the MCP Server?
Section titled “What is the MCP Server?”The Model Context Protocol is an open standard for letting AI agents talk to external tools and data. PlaidCloud runs an MCP server on every workspace that wraps the same core helpers the REST API uses — grouped by intent (find, describe, upsert, run, organize) so an agent can navigate the surface without loading 1,000+ low-level RPC method names.
The server lives at:
https://<your-workspace>.plaid.cloud/mcpReplace <your-workspace> with your workspace subdomain (whatever you use to log into the PlaidCloud UI).
What It Exposes
Section titled “What It Exposes”The catalog covers most of the day-to-day surface an agent needs:
- Projects, workflows, steps — find/describe/upsert/run/organize, including step-level rerun and version history.
- Tables, views, queries — schema introspection, query execution, exports, snapshots, branches.
- Dimensions — describe, find, upsert, version, manage nodes/aliases/properties.
- Connections — find/upsert/test connections to external systems.
- Lakehouse — branches, snapshots, optimize/vacuum operations.
- Identity — members, groups, sessions, distros.
- Documents, dashboards, UDFs, editors, agents, publishes — domain-specific tools.
- Alteryx migration — convert Alteryx workflows staged in Document and coordinate portfolio migration work.
- Workflow logs and run tracking —
workflow_logs,workflow_run_status,workflow_job_track.
Every tool returns a uniform envelope {ok, data, next_cursor?, total?}; failures use {ok: false, error: {code, retryable, message, hint?}}. Mutations accept dry_run=True for plan-without-write validation.
Keeping Results Small
Section titled “Keeping Results Small”Tool results are the largest single consumer of an agent’s context, so the find and describe tools default to a modest slice and let you widen it:
- Rows. A find returns 25 matches per page (
step_findreturns 50). A capped page setsnext_cursor, and the find tools additionally name the clipped list intruncated— either one means “there is more”, not “that is all of them”.totalalways reports the full count. Raiselimitor page with the cursor. - Columns. Pass
fields=['id', 'name', 'update_time']to get only those columns back. A field name that appears on no record is an error listing the available fields, not a silent omission — so a typo fails loudly instead of quietly returning less than you asked for. Tools that offer curated sets also takefield_set='minimal' | 'default' | 'full'; callmcp_introspectto see which parameters a given tool accepts. - Counts.
count_only=Truesizes a result set without fetching it.
Batching Requests
Section titled “Batching Requests”mcp_batch bundles several tool calls into one request. It takes at most 100 calls, runs a bounded number of them at a time, and cannot be nested inside another mcp_batch or a recipe — list the calls in one flat batch instead, which costs no more to send. A batch over the limit is refused with a message naming it rather than being quietly trimmed; the limit bounds the work a single request may start, not the total you may do, so split a larger job across several batches.
The paginate_through_listing recipe stops after 200 pages however high a max_pages you pass it, and reports partial: true when it stops early. Between that and its max_items limit, a single paginate call always terminates.
A recipe refuses a params key it does not recognise, and the message lists the keys that recipe accepts — so a misspelled optional parameter fails loudly instead of being dropped, which would leave the call quietly answering a different question than the one you asked. Call mcp_recipes(name=...) for the keys a given recipe takes.
Column-Oriented Results
Section titled “Column-Oriented Results”A large result whose rows all carry the same fields comes back column-oriented rather than as a list of objects, so the field names are sent once instead of once per row:
{"_fmt": "cols", "cols": ["id", "name"], "rows": [["a1", "Sales"], ["b2", "Costs"]]}Row i is dict(zip(cols, rows[i])). Small results, and any result whose rows don’t share an identical set of fields, stay as ordinary arrays of objects — so both shapes appear, and code reading these responses directly should handle each. The envelope around it is unchanged, and no value is converted or rounded on the way. Agents are told about this shape when they connect and read it without any prompting from you; the saving is around 30% of the characters and around 15% of an agent’s reading budget on typical listing traffic, which is context left over for your actual question. (The two figures differ because repeated field names are cheap for a model to read — the character saving is always the larger of the two.)
For the live catalog, point your agent at the server and call mcp_introspect (no arguments) — that returns the current tool count, per-domain summaries, and parameter signatures. Use mcp_recipes for common multi-tool playbooks (paginating large lists, snapshot-then-modify, rerun a failed step, etc.).
Task Starters
Section titled “Task Starters”The server ships a small set of starters for the tasks people ask for by name. A client that supports MCP prompts lists them and offers them as a menu — check your client’s documentation for where it puts them — so you pick the task rather than describe the sequence of tool calls it takes:
| Starter | What you give it |
|---|---|
| Import a CSV file into a table | The file, and optionally the project, the folder holding it, and a name for the new table |
| Explain a cost change | The results table, and optionally the project and the two periods |
| Debug a failed workflow | The workflow, and optionally the project |
| Explore project data | What you are looking for, and optionally the project |
Each one is a starting message, not a command: your agent reads it and then drives the tools itself, so you can edit it or carry the conversation on from there.
Importing a File Without Knowing the Object Model
Section titled “Importing a File Without Knowing the Object Model”The import starter saves the most work, because the naive route needs four tools in the right order — find the document account, browse to the file, create the target table, then run the import — and a wrong guess at any of them ends the flow several calls in.
It reads delimited text — CSV, TSV and the like. An Excel workbook or a Parquet file is rejected rather than misread; bring those in with the matching import step in a workflow instead.
Instead, the bulk_import_csv playbook takes the account by name and the file by name or path:
mcp_recipe_run(name='bulk_import_csv', params={ 'project_id': '<project>', 'document_path': 'sales_2026.csv', 'document_account': 'Demo Data',})It resolves the account to its identifier, locates the file, creates the table with the columns and types read from the file itself, and loads it — so you supply neither an account id nor a column specification. table_name defaults to the file name without its extension, and table_path to the project root.
Give the folder when you know it — 'document_path': 'raw/sales_2026.csv' — and the search is confined to it. A file named in a folder is only matched in that folder: a same-named file further down is offered as a choice rather than imported in its place.
Where an argument is ambiguous, the result asks instead of guessing:
{ "needs_choice": "document_account", "question": "More than one document account is named 'Archive'. Which one?", "candidates": [{"id": "...", "name": "Archive"}, {"id": "...", "name": "Archive"}]}Show the candidates to the person you are helping, then call the playbook again with their answer, passing the candidate back exactly as it was given. When the file cannot be found, the reply lists the nearest names instead and reports how many files it searched, so “not there” can be told apart from “not where I looked”.
Authentication
Section titled “Authentication”PlaidCloud’s MCP server accepts two authentication paths:
- OAuth 2.1 + PKCE via Dynamic Client Registration (DCR). This is what Claude.ai’s custom-connector UI uses, and it’s also the default for Claude Code’s MCP bridge. The client registers itself, redirects you to PlaidCloud’s Keycloak login, and gets back a token transparently. You don’t need to do anything other than pick “OAuth” in the client and approve the login.
- Static Bearer token in an
Authorizationheader. For agent runtimes that don’t have a usable browser redirect or that want a long-lived token in a config file. PlaidCloud exposes a helper page to mint one for you (see below).
Getting a Static Bearer Token
Section titled “Getting a Static Bearer Token”Open this URL in a browser tab where you’re already signed into PlaidCloud:
https://<your-workspace>.plaid.cloud/mcp/setup/tokenThe page returns a JSON snippet ready to paste into your agent’s MCP config. Each workspace has its own snippet.
The token’s lifespan is governed by your Keycloak realm’s access-token-lifespan policy (typically a few hours to a day). To refresh, reload the same URL — your browser session re-mints the token automatically.
Pick a Client
Section titled “Pick a Client”The rest of this section walks through setup for specific AI agent clients:
- Claude Code — Anthropic’s coding agent (CLI, VSCode extension, JetBrains plugin).
- Claude Desktop and Claude.ai — the consumer Claude app (desktop) and web (
claude.ai) using “Custom Connectors.” - Cursor — the AI-native code editor.
- GitHub Copilot — Copilot agent mode in VSCode.
- Google Gemini CLI —
gemini-cliand Gemini Code Assist. - ChatGPT — current support status and recommended workaround.
- Troubleshooting — common errors and how to fix them.