softr-vibe-coding 1.12.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/README.md +28 -20
- package/SKILL.md +32 -31
- package/datasources/fields.md +4 -4
- package/datasources/monday.md +8 -1
- package/datasources/multi-datasource.md +4 -2
- package/datasources/notion.md +2 -2
- package/datasources/overview.md +1 -1
- package/datasources/reading.md +26 -6
- package/datasources/rest-api.md +20 -1
- package/datasources/shared-patterns.md +1 -1
- package/datasources/softr-database.md +6 -6
- package/datasources/writing.md +195 -62
- package/package.json +1 -1
- package/references/airtable-automations.md +1 -1
- package/references/anti-patterns.md +11 -7
- package/references/common-patterns.md +1 -1
- package/references/helper-blocks.md +4 -2
- package/references/native-block-filters.md +1 -1
- package/references/quick-reference.md +41 -12
- package/references/softr-mcp.md +144 -0
- package/references/softr-database-mcp.md +0 -59
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Fast lookup for imports, hook signatures, field mapping syntax, and common patterns. Use when you already know what you need and just want the shape.
|
|
4
4
|
|
|
5
|
+
The current platform compiles TypeScript with modern syntax (`?.`, `??`, arrows, `const`, generics) — verified live 2026-08-25. Snippets below in `var` style predate that and remain valid; both styles compile.
|
|
6
|
+
|
|
5
7
|
## Imports
|
|
6
8
|
|
|
7
9
|
```jsx
|
|
8
10
|
// DATASOURCE (add `datasource` when the block connects to more than one source)
|
|
9
11
|
import { datasource, useRecords, useRecord, useRecordCreate, useRecordUpdate, useRecordDelete,
|
|
10
|
-
useCurrentRecordId, useLinkedRecords, useUpload, useMetric, useChartData,
|
|
12
|
+
useCurrentRecordId, useLinkedRecords, useFieldOptions, useUpload, useMetric, useChartData,
|
|
11
13
|
q, metric } from "@/lib/datasource";
|
|
12
14
|
|
|
13
15
|
// USER
|
|
@@ -50,6 +52,7 @@ var ds = datasource.define({ // values MUST be inline string literals
|
|
|
50
52
|
});
|
|
51
53
|
|
|
52
54
|
useRecords({ from: ds.people, select: select }); // `from:` required once >1 source
|
|
55
|
+
var proxyFetch = useProxyFetch(ds.people); // REST API source: alias is the ARGUMENT, not a from: option
|
|
53
56
|
```
|
|
54
57
|
|
|
55
58
|
Ids are plain UUIDs. Get them by asking Studio's AI chat to **write code**, never to recite a
|
|
@@ -59,9 +62,13 @@ value — it fabricates them in prose. Full detail: [../datasources/multi-dataso
|
|
|
59
62
|
|
|
60
63
|
```jsx
|
|
61
64
|
var result = useRecords({ select: select, count: 100 });
|
|
62
|
-
var records =
|
|
65
|
+
var records = result.data?.pages.flatMap(p => p.items) ?? [];
|
|
63
66
|
```
|
|
64
67
|
|
|
68
|
+
⚠ The options object MUST be an inline literal — `useRecords(opts)` with `opts` built in a
|
|
69
|
+
variable or returned by a wrapper function **fails to compile** (verified live 2026-08-25).
|
|
70
|
+
Share `q.select` mappings, not options objects.
|
|
71
|
+
|
|
65
72
|
## Filter + Sort
|
|
66
73
|
|
|
67
74
|
```jsx
|
|
@@ -84,8 +91,9 @@ var result = useRecord({ recordId: recordId, select: select });
|
|
|
84
91
|
## Current User
|
|
85
92
|
|
|
86
93
|
```jsx
|
|
87
|
-
var currentUser = useCurrentUser(); // { id, fullName, email, avatar }
|
|
88
|
-
var
|
|
94
|
+
var currentUser = useCurrentUser(); // { id, fullName, firstName, lastName, email, avatar } | null; id only with user sync
|
|
95
|
+
var withProps = useCurrentUser({ properties: { plan: "FIELD_ID" } }); // custom user fields → withProps.properties.plan
|
|
96
|
+
var softrUser = window.__softr_current_user; // userGroups/role ONLY — not exposed by the hook
|
|
89
97
|
```
|
|
90
98
|
|
|
91
99
|
## Create
|
|
@@ -96,7 +104,7 @@ var createRecord = useRecordCreate({
|
|
|
96
104
|
onSuccess: function(newRecord) { refetch(); },
|
|
97
105
|
onError: function(err) { toast.error(err.message); },
|
|
98
106
|
});
|
|
99
|
-
createRecord.mutate({ name: "Jane", email: "jane@example.com" });
|
|
107
|
+
createRecord.mutate({ name: "Jane", email: "jane@example.com" }); // FLAT — no { fields } wrapper
|
|
100
108
|
```
|
|
101
109
|
|
|
102
110
|
## Update (THE CORRECT PATTERN)
|
|
@@ -108,7 +116,7 @@ var updateRecord = useRecordUpdate({
|
|
|
108
116
|
onError: function(err) { toast.error(err.message); },
|
|
109
117
|
});
|
|
110
118
|
|
|
111
|
-
//
|
|
119
|
+
// Payload is the nested {recordId, fields:{}} shape (create is flat — the asymmetry is by design).
|
|
112
120
|
// Per-call onSuccess/onError go in the second argument.
|
|
113
121
|
updateRecord.mutate(
|
|
114
122
|
{ recordId: record.id, fields: { name: "New" } },
|
|
@@ -119,11 +127,26 @@ updateRecord.mutate(
|
|
|
119
127
|
);
|
|
120
128
|
```
|
|
121
129
|
|
|
122
|
-
**
|
|
123
|
-
1.
|
|
124
|
-
2.
|
|
130
|
+
**Payload shapes or `enabled` stays `false`:**
|
|
131
|
+
1. Update payload is `{ recordId, fields: {...} }` — NOT flat `{ recordId, status: "..." }`
|
|
132
|
+
2. Create payload is FLAT — `{ name: "..." }`, no `fields` wrapper
|
|
133
|
+
|
|
134
|
+
See [datasources/writing.md](../datasources/writing.md#critical-the-userecordupdate-payload-shape-and-the-retired-mutate-only-rule) for the full debugging path.
|
|
125
135
|
|
|
126
|
-
|
|
136
|
+
## Sequential Multi-Row Saves (mutateAsync)
|
|
137
|
+
|
|
138
|
+
`mutateAsync` is fully supported (verified live 2026-08-25 — the old ".mutate() only" parser
|
|
139
|
+
rule is retired). It's the tool whenever writes must happen in order:
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
const header = await createHeader.mutateAsync({ name, date }); // header first
|
|
143
|
+
for (const line of lines) {
|
|
144
|
+
await createLine.mutateAsync({ header: [header.id], ...line }); // then lines, in order
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Stop on the first failure, render it with a Retry, never re-issue completed writes. Full queue
|
|
149
|
+
pattern: [datasources/writing.md](../datasources/writing.md#sequential-multi-row-writes-mutateasync).
|
|
127
150
|
|
|
128
151
|
## Delete
|
|
129
152
|
|
|
@@ -138,7 +161,10 @@ deleteRecord.mutate(record.id); // Just the ID string
|
|
|
138
161
|
|
|
139
162
|
`.enabled`, `.status`, `.error`, `.mutate()`, `.mutateAsync()`, `.reset()`
|
|
140
163
|
|
|
141
|
-
|
|
164
|
+
Both `.mutate(payload, { onSuccess, onError })` and `await .mutateAsync(payload)` derive
|
|
165
|
+
Actions correctly on the current platform (verified 2026-08-25). Use `.mutate` for
|
|
166
|
+
fire-and-forget single writes, `mutateAsync` for sequenced flows. (Pre-2026-08 platforms only
|
|
167
|
+
recognized the literal `.mutate(` token — relevant only when maintaining old apps.)
|
|
142
168
|
|
|
143
169
|
## Linked Records Picker
|
|
144
170
|
|
|
@@ -152,9 +178,12 @@ var options = (result.data && result.data.pages) ? result.data.pages.flatMap(fun
|
|
|
152
178
|
## Linked Records in Mutations
|
|
153
179
|
|
|
154
180
|
```jsx
|
|
155
|
-
teamMembers: [
|
|
181
|
+
teamMembers: ["MEMBER_ID_1", "MEMBER_ID_2"] // array of record-id STRINGS (verified Softr DB, 2026-08-25)
|
|
156
182
|
```
|
|
157
183
|
|
|
184
|
+
Legacy/Airtable: the `[{ id: "..." }]` object shape was the verified form on Airtable-backed
|
|
185
|
+
blocks (May 2026) — try it if a string-array write fails there.
|
|
186
|
+
|
|
158
187
|
## Formula Booleans
|
|
159
188
|
|
|
160
189
|
```jsx
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Softr MCP Server
|
|
2
|
+
|
|
3
|
+
The official Softr MCP server (`https://mcp.softr.io/mcp`) gives an AI assistant (Claude Code, Claude Desktop, claude.ai, Cursor, ChatGPT, Mistral) direct access to a Softr **workspace**: databases, applications, vibe coding blocks, integrations (external data sources), and workflows. Everything the assistant does happens as the connected user, with their permissions, and shows up in Studio like any other change.
|
|
4
|
+
|
|
5
|
+
**This file is a sibling concern to the [../datasources/](../datasources/) guides, which cover in-block data fetching (`useRecords` + `q.select()`).** The MCP runs at chat-build time, not inside the block. For Vibe Coding work it matters twice: it answers "what fields does this table have?" without any paste-ins, and it can create and deploy the block itself — no copy-paste into Studio.
|
|
6
|
+
|
|
7
|
+
> Historical note: this file was previously named `softr-database-mcp.md` and described a databases-only server with granular scopes. That server has since grown into the workspace-wide MCP documented here; the old "does NOT cover external sources" limitation is gone (see [Integrations](#browsing-integrations-external-data-sources)).
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
|
|
11
|
+
- [What it covers](#what-it-covers)
|
|
12
|
+
- [Connection and auth](#connection-and-auth)
|
|
13
|
+
- [Permissions model](#permissions-model)
|
|
14
|
+
- [Vibe coding block tools](#vibe-coding-block-tools)
|
|
15
|
+
- [Vibe coding gotchas (official)](#vibe-coding-gotchas-official)
|
|
16
|
+
- [Browsing integrations (external data sources)](#browsing-integrations-external-data-sources)
|
|
17
|
+
- [Softr Database tools](#softr-database-tools)
|
|
18
|
+
- [Two delivery paths for this skill](#two-delivery-paths-for-this-skill)
|
|
19
|
+
- [When the MCP is not installed](#when-the-mcp-is-not-installed)
|
|
20
|
+
|
|
21
|
+
## What it covers
|
|
22
|
+
|
|
23
|
+
| Area | What the assistant can do | Official docs |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| Databases | Query, filter, aggregate; create/update records; build tables and fields | https://docs.softr.io/mcp/databases |
|
|
26
|
+
| Applications | Read apps, pages, blocks, permissions; preview; publish | https://docs.softr.io/mcp/apps |
|
|
27
|
+
| Vibe coding blocks | Create and edit blocks, manage settings, visibility, versions, data source connections | https://docs.softr.io/mcp/vibe-coding |
|
|
28
|
+
| Integrations | Browse external data sources connected to the workspace, down to field level | https://docs.softr.io/mcp/integrations |
|
|
29
|
+
| Workflows | Build, test, and publish workflows | https://docs.softr.io/mcp/workflows |
|
|
30
|
+
|
|
31
|
+
`list_workspaces` is often the first call — it turns "my Sales workspace" into the workspace ID every other tool needs.
|
|
32
|
+
|
|
33
|
+
## Connection and auth
|
|
34
|
+
|
|
35
|
+
- **Server URL:** `https://mcp.softr.io/mcp` (streamable HTTP)
|
|
36
|
+
- **Official docs:** https://docs.softr.io/mcp/overview
|
|
37
|
+
|
|
38
|
+
Install in Claude Code:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
claude mcp add --transport http softr https://mcp.softr.io/mcp
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Then start a new session and run `/mcp` to complete OAuth in the browser.
|
|
45
|
+
|
|
46
|
+
Two auth methods:
|
|
47
|
+
|
|
48
|
+
1. **OAuth (recommended)** — pre-built clients exist for Claude (claude.ai), Cursor, ChatGPT, and Mistral. If a Client ID is requested, use the value from the [overview docs](https://docs.softr.io/mcp/overview); leave Client Secret blank (Softr's OAuth clients are public). The assistant cannot request permissions — the user always picks them on Softr's authorization screen.
|
|
49
|
+
2. **Personal access token** — for custom clients. Created in Softr under **Settings → API tokens** (name, expiry, workspace + permission scoping), then used as a Bearer token.
|
|
50
|
+
|
|
51
|
+
Revoke or edit access anytime in **Settings → API tokens** (Authorized apps section for OAuth, token list for PATs).
|
|
52
|
+
|
|
53
|
+
## Permissions model
|
|
54
|
+
|
|
55
|
+
Permissions are chosen per workspace across **three areas with bundled levels** — not granular per-tool scopes. Each level includes everything below it (no "write without read").
|
|
56
|
+
|
|
57
|
+
| Area | Levels | Highest level adds |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| Applications & Forms | Full access · Read only · None | Creating/editing vibe coding blocks, previewing, publishing |
|
|
60
|
+
| Databases | Full access · Edit data · View only · None | Schema changes (tables/fields); Edit data adds record writes |
|
|
61
|
+
| Workflows | Full access · Read only · None | Building, testing, publishing workflows |
|
|
62
|
+
|
|
63
|
+
For block-building work you need **Applications & Forms: Full access** (to create/edit blocks) plus at least **Databases: View only** (schema discovery). Integrations browsing rides on Applications & Forms read access.
|
|
64
|
+
|
|
65
|
+
## Vibe coding block tools
|
|
66
|
+
|
|
67
|
+
Before writing any block code through the MCP, call `get_vibe_coding_docs` — it returns the current version of the [Vibe Coding Developer Guide](https://docs.softr.io/vibe-coding-developer-guide), which is the authority on hook signatures if it and this skill ever disagree.
|
|
68
|
+
|
|
69
|
+
| Group | Tools |
|
|
70
|
+
|---|---|
|
|
71
|
+
| Create / read | `get_vibe_coding_docs`, `create_vibe_coding_block`, `get_vibe_coding_block_code`, `get_vibe_coding_block_settings` |
|
|
72
|
+
| Edit code | `update_vibe_coding_block_code` (full replace), `update_vibe_coding_block_code_search_replace` (targeted edit) |
|
|
73
|
+
| Settings / visibility | `update_vibe_coding_block_settings`, `set_vibe_coding_block_visibility`, `set_vibe_coding_block_action_visibility` |
|
|
74
|
+
| Versions | `list_vibe_coding_block_versions`, `restore_vibe_coding_block_version`, `duplicate_vibe_coding_block_from_version` |
|
|
75
|
+
| Data sources | `connect_vibe_coding_block_data_source`, `disconnect_vibe_coding_block_data_source`, `set_vibe_coding_block_data_source_sort`, `set_vibe_coding_block_data_source_record_filters` |
|
|
76
|
+
|
|
77
|
+
Editable settings via MCP are the same fields as the block's **Content → Settings** panel; sort and record filters are the same as the **Source** tab. Duplicating from a version is the safe way to try an alternative — the original keeps working while you experiment on the copy.
|
|
78
|
+
|
|
79
|
+
## Vibe coding gotchas (official)
|
|
80
|
+
|
|
81
|
+
From the official MCP docs — these hold for MCP-driven and Studio-driven edits alike:
|
|
82
|
+
|
|
83
|
+
- **A broken block can't be saved.** Code is validated before storage; on failure the block keeps its last working state and nothing is lost.
|
|
84
|
+
- **A version is a snapshot of the whole block** — code, settings, visibility, AND data source connections. Setting-only changes don't create a version.
|
|
85
|
+
- **Rolling back reverts more than the code.** Restoring a version also restores settings, visibility, and data source connections as they were at that point.
|
|
86
|
+
- **Changing the code resets action permissions.** Any code change rebuilds the block's record actions at default visibility — restrictions to user groups must be re-applied. (This is Hard Constraint 21 in SKILL.md, now officially documented: tighten Action permissions only after the LAST redeploy.)
|
|
87
|
+
- **A block with an unconnected data source saves without complaint**, then errors when the page loads. If a freshly created block looks broken but the code seems right, check its data source connection first.
|
|
88
|
+
|
|
89
|
+
## Browsing integrations (external data sources)
|
|
90
|
+
|
|
91
|
+
An integration is an external data source connected once per workspace (the builder says "integrations", the tools say "data sources" — same thing). Five read-only tools drill down from workspace to fields; each level needs an ID from the level above:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
list_data_sources workspace's integrations
|
|
95
|
+
└── list_data_source_databases a base, spreadsheet, or database
|
|
96
|
+
└── list_data_source_schemas SQL schemas — Supabase only (usually just `postgres`)
|
|
97
|
+
└── list_data_source_tables tables or sheets
|
|
98
|
+
└── list_data_source_table_fields fields, types, options, primary field
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Only five integration types are browsable/connectable through MCP today:** Softr Databases, Airtable, Google Sheets, Notion, and Supabase. Anything else still appears in `list_data_sources` but must be connected through the block's **Source** tab in Studio, with schema discovery via the manual workflows in [../datasources/fields.md](../datasources/fields.md#field-inspector-block).
|
|
102
|
+
|
|
103
|
+
`list_data_source_table_fields` also tells you **how fields must be referenced in `q.select()`**:
|
|
104
|
+
|
|
105
|
+
| Integration | Reference fields by |
|
|
106
|
+
|---|---|
|
|
107
|
+
| Airtable, Google Sheets, Notion | Name |
|
|
108
|
+
| Softr Databases, Supabase | ID (for Supabase, the SQL column name) |
|
|
109
|
+
|
|
110
|
+
Getting this wrong **fails silently** — the code compiles, saves, and looks right in the builder, then returns nothing at page load. If a block renders but its data is empty, check this first.
|
|
111
|
+
|
|
112
|
+
## Softr Database tools
|
|
113
|
+
|
|
114
|
+
For Softr's native databases the MCP goes far beyond browsing: `get_schema` (authoritative field-type + filter-operator reference — call it before building tables or filters), database/table/field CRUD, `list_views`, record reads (`list_records`, `search_records`, `get_record`), record writes (`create_record`, `create_records` batch, `update_record`), and `aggregate_data` for grouped summaries.
|
|
115
|
+
|
|
116
|
+
Known limits and behaviors (per official docs):
|
|
117
|
+
|
|
118
|
+
- Record field keys are **field IDs**, not labels — `list_fields` maps between them.
|
|
119
|
+
- Computed fields (formula, lookup, rollup, count) and system fields (created/updated time and by, autonumber, record ID) are read-only; a field's type cannot be changed after creation.
|
|
120
|
+
- **Nothing can be deleted through the MCP yet** — no record/table/field/database delete tools (docs say deletion is coming). Deletions happen in the builder.
|
|
121
|
+
- **Attachment writes take a URL and copy the file.** `create_record` / `update_record` accept
|
|
122
|
+
`{ filename, url }` on an ATTACHMENT field with any publicly reachable URL; Softr fetches it, stores its
|
|
123
|
+
own copy and generates thumbnails, so backfilling images from another system is one write per record
|
|
124
|
+
with no upload step. Verified 2026-08-26 — see [../datasources/writing.md](../datasources/writing.md#attachment).
|
|
125
|
+
- Limits: 100 records per `create_records` call, 200 records per read (silently capped, not an error), 2 group-by fields in `aggregate_data`. For big tables prefer a filter or aggregate over paging.
|
|
126
|
+
|
|
127
|
+
Typical Vibe Coding uses: "list every field on `Wigs` with id, name, type, and dropdown options", "what's the option id for `Payment status` = 'Partially paid'?", "show 3 sample records so we know value shapes", "verify the field id in my `q.select()` exists". This eliminates the field-id-typo / wrong-option-uuid class of bugs entirely.
|
|
128
|
+
|
|
129
|
+
## Two delivery paths for this skill
|
|
130
|
+
|
|
131
|
+
When generating a block, pick the delivery path by what's connected:
|
|
132
|
+
|
|
133
|
+
1. **MCP connected with Applications & Forms full access** — write the `.tsx` file locally first (it remains the source of truth and the reviewable artifact), then offer to deploy it directly: `create_vibe_coding_block` (or `update_vibe_coding_block_code` for edits), then `connect_vibe_coding_block_data_source` to wire up the data. Remember the action-permissions reset gotcha after every code push.
|
|
134
|
+
2. **No MCP (or read-only access)** — classic path: write the `.tsx` file and have the user paste it into Studio's Vibe Coding editor, then connect the data source in the **Source** tab themselves.
|
|
135
|
+
|
|
136
|
+
Either way, never deliver code inline in chat (JSX character corruption — see SKILL.md workflow step 5).
|
|
137
|
+
|
|
138
|
+
## When the MCP is not installed
|
|
139
|
+
|
|
140
|
+
If the user hasn't installed the MCP (and doesn't want to right now), fall back to the schema-discovery methods documented per source:
|
|
141
|
+
|
|
142
|
+
- **Softr Database:** bundled CLI script — see [../datasources/softr-database.md](../datasources/softr-database.md#bundled-cli-script-get-softr-database); or the `tablespace-with-tables` network paste — see [../datasources/fields.md](../datasources/fields.md#field-inspector-block).
|
|
143
|
+
- **Airtable:** bundled `get-airtable-base` script — see [../datasources/airtable.md](../datasources/airtable.md#bundled-cli-script-get-airtable-base).
|
|
144
|
+
- **Other sources:** Field Inspector block and vendor workflows in [../datasources/fields.md](../datasources/fields.md#field-inspector-block).
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# Softr Database MCP Server
|
|
2
|
-
|
|
3
|
-
Out-of-band integration for AI-assisted Vibe Coding workflows. The MCP server lets the AI assistant (Claude Code, Claude Desktop, Cursor, ChatGPT, Mistral) read schema, list field IDs, query records, and write data directly into Softr Databases — eliminating the manual "paste `tablespace-with-tables` JSON" step and removing transcription errors on field IDs and dropdown option UUIDs.
|
|
4
|
-
|
|
5
|
-
**This file is a sibling concern to [../datasources/softr-database.md](../datasources/softr-database.md), which covers in-block data fetching (`useRecords` + `q.select()`).** The MCP runs at chat-build time, not inside the block. Same parallel as [airtable-automations.md](airtable-automations.md) sits next to [../datasources/airtable.md](../datasources/airtable.md).
|
|
6
|
-
|
|
7
|
-
## Connection
|
|
8
|
-
|
|
9
|
-
- **Server URL:** `https://mcp.softr.io/mcp`
|
|
10
|
-
- **Transport:** streamable HTTP
|
|
11
|
-
- **Auth:** OAuth (pre-configured for Claude / Cursor / ChatGPT / Mistral) or Personal API Token (`Settings → API Tokens` in Softr)
|
|
12
|
-
- **Official docs:** https://docs.softr.io/mcp-server
|
|
13
|
-
|
|
14
|
-
## Install (Claude Code)
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
claude mcp add --transport http softr https://mcp.softr.io/mcp
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Then start a new Claude Code session and run `/mcp` to complete the OAuth authorization in the browser. See [the Softr docs](https://docs.softr.io/mcp-server) for Cursor / ChatGPT / Mistral / custom client setup.
|
|
21
|
-
|
|
22
|
-
## Permissions (three granular scopes)
|
|
23
|
-
|
|
24
|
-
Grant only what you need:
|
|
25
|
-
|
|
26
|
-
| Scope | Use case for Vibe Coding |
|
|
27
|
-
|-----------------------------|-----------------------------------------------------------------------|
|
|
28
|
-
| `databases.records:read` | AI discovers field IDs, dropdown UUIDs, verifies value shapes |
|
|
29
|
-
| `databases.records:write` | AI mutates live data (e.g. seeding test records, bulk updates) |
|
|
30
|
-
| `databases.schema:write` | AI provisions databases / tables / fields for you |
|
|
31
|
-
|
|
32
|
-
For block-writing workflows, **read scopes are the most valuable** — they cover the AI's schema-discovery needs (the bottleneck the MCP solves) without any blast-radius into live data. Add write scopes only when you want the AI to mutate records; schema-write only when you want it to provision tables.
|
|
33
|
-
|
|
34
|
-
## Tools available (20 total)
|
|
35
|
-
|
|
36
|
-
- **Databases (4):** list / get / create / update
|
|
37
|
-
- **Tables (8):** list tables, list fields, list views, get table schema, create / update tables, create / update fields
|
|
38
|
-
- **Records (8):** list / get / create (batch ≤ 100) / update / delete + filter-based and view-filtered search
|
|
39
|
-
|
|
40
|
-
## Why this changes Vibe Coding workflows
|
|
41
|
-
|
|
42
|
-
Without the MCP, the AI needs schema shared manually — either paste `tablespace-with-tables` network JSON or describe fields by name. Both are slow, and verbal-name approaches lose dropdown option UUIDs entirely without a second copy step.
|
|
43
|
-
|
|
44
|
-
With the MCP installed, you can ask things like:
|
|
45
|
-
|
|
46
|
-
- "List every field on the `Wigs` table with id, name, type, and dropdown options."
|
|
47
|
-
- "What's the option id for `Wigs.Payment status` = 'Partially paid'?"
|
|
48
|
-
- "Show me 3 sample records from `Wig Services` so we know the value shapes."
|
|
49
|
-
- "Verify the field id I used for `q.select({ status: 'sel...' })` exists on this table."
|
|
50
|
-
|
|
51
|
-
The AI then writes `q.select()` keys and write payloads against the live schema, eliminating an entire class of "field id typo" / "wrong option uuid" bugs.
|
|
52
|
-
|
|
53
|
-
## Scope: Softr Database only
|
|
54
|
-
|
|
55
|
-
The MCP server exposes Softr's **native** databases only. It does NOT proxy external sources (Airtable, Google Sheets, HubSpot, Notion, Xano, etc.) — those still need the schema-discovery workflows documented in [../datasources/fields.md](../datasources/fields.md#field-inspector-block) (Field Inspector block, vendor APIs, network inspector paste, etc.). If your Softr app blends Softr DB with external sources, the MCP helps only with the Softr DB tables.
|
|
56
|
-
|
|
57
|
-
## When the MCP is not installed
|
|
58
|
-
|
|
59
|
-
If the user hasn't installed the MCP (and doesn't want to right now), fall back to the schema-sharing methods documented in [../datasources/fields.md](../datasources/fields.md#field-inspector-block) — primarily the `tablespace-with-tables` network paste, which gives the AI everything it needs in one shot.
|