Your workspace, from inside your assistant.
RowFold is an MCP server. Point Claude Code, Claude Desktop, Cursor, Gemini CLI or the OpenAI API at it and ask about your data in the tool you already have open — no export, no copied spreadsheet, no second permissions model to configure.
/mcp · streamable HTTP · JSON-RPC 2.0The totals are real
This is probably the part worth understanding first, because it is where most "AI on your data" integrations quietly fail. Ask a chatbot for the total value of your open deals and it will usually fetch a page of rows and add them up. If the filter matched 3,000 records and the page held 50, the number it hands you is confidently wrong, and nothing on screen says so.
RowFold's MCP tools are the same tools its own Ask panel uses — not a thinner API written for outsiders. Aggregates are computed in Postgres, over every matching row. Filters can travel a relationship, so "deals whose company's region is EMEA" is one query rather than two round trips and an intersection done by hand. When a filter cannot be compiled, the result says which term was dropped and whether the answer is exact.
About two minutes to connect
The Bearer token in the blocks below is an MCP key, and there is one place it comes from:
- Sign in to RowFold and open Developers. You need to be an admin of the workspace you want the agent to reach.
- Under AI agents (MCP), create a connection: give it a name, choose the member it acts as, and tick allow record writes only if you want the agent able to change things.
- Copy the key it shows you — it starts
rfmcp_. This is the only time you see it: RowFold stores a hash, so it cannot show you the key again later. Lose it and you revoke that connection and make another. - Paste it into your client as the
Authorization: Bearerheader, below.
In Claude Code, that is one command:
claude mcp add rowfold --transport http https://www.rowfold.com/mcp \
--header "Authorization: Bearer rfmcp_…"
Claude Desktop, Cursor and most other clients take a block of JSON in their settings file:
{
"mcpServers": {
"rowfold": {
"type": "http",
"url": "https://www.rowfold.com/mcp",
"headers": { "Authorization": "Bearer rfmcp_…" }
}
}
}
That is the real address — there is no per-account host to look up. The Developers page prints both blocks with your own key already in them, so it is a copy and a paste.
Gemini CLI
One command, or the same thing in settings.json:
gemini mcp add rowfold https://www.rowfold.com/mcp \
--transport http --header "Authorization: Bearer rfmcp_…"
{
"mcpServers": {
"rowfold": {
"httpUrl": "https://www.rowfold.com/mcp",
"headers": { "Authorization": "Bearer rfmcp_…" }
}
}
}
Use httpUrl, not url. Gemini CLI defaults to a stdio transport, and a stdio server ignores the headers block entirely — the connection then fails as unauthorised with nothing obviously wrong in the file.
OpenAI API
The Responses API takes a remote MCP server as a tool, and forwards your headers on every call:
{
"type": "mcp",
"server_label": "rowfold",
"server_url": "https://www.rowfold.com/mcp",
"headers": { "Authorization": "Bearer rfmcp_…" },
"require_approval": "never"
}
Send the header with every request: OpenAI deliberately does not store header values, so there is nothing to configure once and forget. Consider leaving require_approval at its default on a write-enabled key.
ChatGPT (the app) — not yet
You cannot connect RowFold to ChatGPT itself today, and the reason is on their side rather than ours. ChatGPT's custom connectors accept OAuth or no authentication; the setup UI has no field for a bearer token or a custom header, so there is nowhere to put an MCP key. The OpenAI API above is unaffected — it takes headers happily. If you want RowFold inside ChatGPT, the thing that unblocks it is us adding an OAuth flow to /mcp, not a setting either of us has missed.
However you connect, you then just talk to it: what's in my workspace?, total open pipeline by owner, who changed the price on the Meridian deal?
What it can do
Nineteen read tools. These are the names your client will show you:
list_tables— every table this member can seeget_table_schema— a table's fields, types and keysquery_records— filtered and sorted in the database, including filters that travel a linksearch_records— keyword search across a tableget_record— one record with everything it links toaggregate_records— count, sum, average, min, max; filtered and grouped, computed in Postgresfind_nearby— records near a placefind_free_time— when somebody is free: the rota, existing bookings and connected calendars, with anything it could not reach namedget_record_history— who changed what, and whenget_comments— the discussion on a recordget_conversation— a support ticket's message threadget_ticket_stats— response times and satisfaction, from the SLA ledgerget_automation_runs— why an automation did or didn't fire (admins only)read_attachment— text out of an attached fileexport_records— prepare a CSV of exactly the records in the answersearch_help— RowFold's own documentation, so the agent can answer "how do I…"list_views— the saved views on a table: the slices this team has already namedlist_reports— the saved reports in the workspacerun_report— run one and get its rows and totals, exactly as the report page computes them
Four write tools, off unless you tick allow record writes when the connection is made:
create_records— up to 40 in one table per call, with relation links inside the batch or to records that already existupdate_records— per-record skips with reasons; the result carries each record's previous valuestrash_records— the restorable soft deleterestore_records— bring them back out again, which is what makes the line above true
The write tools run the same checks as RowFold's own AI edits: field-level permissions, the posting seal, lifecycle rules, applied per record, with refusals skipped and the reason named rather than the batch failing. Every one takes a dry run that reports exactly what would happen and writes nothing. An update hands back each record's previous values, so posting those back is the undo. Trash is the restorable soft delete; nothing here destroys a record.
Writes appear in the audit trail as MCP · connection (as person) and fire automations like any other save.
It logs in as somebody
A connection is bound to one member of one workspace, and the agent sees exactly what that person sees. Fields hidden from them stay hidden. Tables they cannot open stay invisible. There is no integration-permissions screen, because there is no second set of rules — the ones you already set up are the ones that apply.
That is also the safest way to scope an agent. Bind it to a client-facing teammate and it cannot read the columns you hid from that teammate, whatever it is asked. Revoking on the Developers page stops the key answering, and removing the member from the workspace kills their connections with them. Requests are rate-limited per key, exports are written to the audit trail, and a workspace whose trial has ended gets a payment-required error, the same as the REST API.
Things worth knowing before you rely on it
The key is the credential. Anyone holding it reads the workspace as that member, and assistant config files store it in plain text on the machine — so a synced or shared config shares the key, and a write-enabled key in a shared config is an editor's pen in everyone's hands. Name each connection after the tool and the laptop it lives on, because that name is how you know which one to revoke.
Revocation is not quite instant. A revoked key can keep answering for up to a minute or so on other servers, while the auth caches expire.
A CSV export hands back a short-lived link that only opens in a browser already signed in as the acts-as person, and re-checks their permissions at click time. Relative dates resolve in the workspace's timezone, not the agent's.
Try it
There is one plan, and this is in it — not an add-on, not an enterprise tier. The 30-day trial has it on from the first minute.