{
 "slug": "nocodb",
 "name": "NocoDB",
 "url": "https://nocodb.com",
 "domain": "nocodb.com",
 "category": "databases",
 "category_name": "Databases",
 "tested_at": "2026-10-03",
 "run": "20261003T204556Z",
 "draft": false,
 "reviewed": true,
 "owner_verified": null,
 "origin": "editorial",
 "history": [
  {
   "run": "20261002T141141Z",
   "date": "2026-10-02",
   "level": 4,
   "engine": {
    "runner": "omp",
    "model": "claude-opus-5-5",
    "driver": 2,
    "signed": true,
    "inbox": [
     "agentdrives.com"
    ],
    "robots": "start"
   },
   "drives": 2
  },
  {
   "run": "20261003T204556Z",
   "date": "2026-10-03",
   "level": 4,
   "engine": {
    "runner": "omp",
    "model": "claude-opus-5-5",
    "driver": 2,
    "signed": true,
    "inbox": [
     "agentdrives.com"
    ],
    "robots": "start"
   }
  }
 ],
 "level": 4,
 "level_name": "Runs on its own",
 "level_selfhost": null,
 "entry": "self-start",
 "door": {
  "passed": 3,
  "tries": 3,
  "self_start": true
 },
 "badges": [
  "agent-can-leave"
 ],
 "stages": [
  {
   "key": "in",
   "label": "Access",
   "state": "yes",
   "text": "Gets in on its own: sign-up in a browser"
  },
  {
   "key": "work",
   "label": "Use",
   "state": "yes",
   "text": "Work done: 100% of the core"
  },
  {
   "key": "pay",
   "label": "Pay",
   "state": "part",
   "text": "Reaches the checkout: stopped at the card form",
   "value": "ready",
   "route": "card_checkout"
  },
  {
   "key": "leave",
   "label": "Leave",
   "state": "yes",
   "text": "Leaves on its own: nothing to cancel, deletes its account",
   "left": "deleted"
  }
 ],
 "outcomes": [
  {
   "key": "find",
   "label": "Find",
   "state": "yes",
   "text": "Docs agents can read: llms.txt, an OpenAPI and an MCP server",
   "have": [
    "llms_txt",
    "openapi",
    "mcp"
   ]
  },
  {
   "key": "access",
   "label": "Access",
   "state": "yes",
   "text": "Gets in on its own: sign-up in a browser",
   "stage": "in"
  },
  {
   "key": "use",
   "label": "Use",
   "state": "yes",
   "text": "Work done: 100% of the core",
   "stage": "work"
  },
  {
   "key": "pay",
   "label": "Pay",
   "state": "part",
   "text": "Reaches the checkout: stopped at the card form",
   "value": "ready",
   "route": "card_checkout",
   "stage": "pay"
  },
  {
   "key": "leave",
   "label": "Leave",
   "state": "yes",
   "text": "Leaves on its own: nothing to cancel, deletes its account",
   "left": "deleted",
   "stage": "leave"
  }
 ],
 "access": [
  {
   "key": "browser_signup",
   "label": "Sign-up in a browser",
   "routes": [],
   "minutes": 6.6,
   "core": "10/10"
  }
 ],
 "minutes": 6.6,
 "next": {
  "to": 5,
  "text": "Next: pay without a person"
 },
 "stop": null,
 "core": "10/10",
 "scores": {
  "coverage": 78,
  "reliability": 69,
  "resilience": 49,
  "setup": 100,
  "surface_coverage": 57,
  "docs_accuracy": 60,
  "docs_completeness": 56
 },
 "parts": {
  "holds_up": 59,
  "docs_match": 59,
  "setup": 100,
  "security": "private",
  "standards": [
   {
    "standard": "MCP",
    "state": "behind",
    "behind": 1,
    "value": "2025-11-25"
   },
   {
    "standard": "MCP discovery",
    "state": "behind",
    "behind": null,
    "value": "legacy"
   },
   {
    "standard": "MCP client registration",
    "state": "behind",
    "behind": null,
    "value": "dcr"
   },
   {
    "standard": "OpenAPI",
    "state": "behind",
    "behind": 1,
    "value": "3.1.0"
   }
  ]
 },
 "reliability_method": "pass^k",
 "resilience": {
  "parts": {
   "error_legibility": 70,
   "recovery": 77,
   "idempotency": 0
  },
  "summary": {
   "error_legibility": "mixed",
   "recovery": "partial",
   "idempotency": "risky",
   "rate_limits": "none-seen",
   "notes": "Validation errors are clear JSON naming the field, but unknown record fields are silently dropped, a formula rename leaks a JS error and a wrong MCP key answers 404. A repeated create duplicates; 15 quick reads stayed inside the 60/min budget shown in x-ratelimit headers."
  }
 },
 "stress": [
  {
   "capability": "Create a table with fields",
   "probe": "create table without required title",
   "outcome": "400 application/json; charset=utf-8 {\"error\": \"ERR_INVALID_REQUEST_BODY\", \"message\": \"Validation failed: 'title' is required\", \"details\": [{\"instancePath\": \"\", \"schemaPath\": \"#/required\", \"keyword\": \"",
   "grade": "clear",
   "idempotent": null,
   "rate_limit": null
  },
  {
   "capability": "Add, edit and configure fields (30+ types incl. links, lookups, rollups, formulas)",
   "probe": "field with bad type enum",
   "outcome": "400 application/json; charset=utf-8 {\"error\": \"ERR_INVALID_REQUEST_BODY\", \"message\": \"Validation failed: 'type' must be one of: SingleLineText, LongText, PhoneNumber, URL, Email, Number, Decimal, Curr",
   "grade": "clear",
   "idempotent": null,
   "rate_limit": null
  },
  {
   "capability": "Create, update, delete records (CRUD)",
   "probe": "list records of a non-existent table id",
   "outcome": "422 application/json; charset=utf-8 {\"error\": \"ERR_TABLE_NOT_FOUND\", \"message\": \"Table 'mzzzzzzzzzzzzzz' not found\"}",
   "grade": "clear",
   "idempotent": null,
   "rate_limit": null
  },
  {
   "capability": "Create, update, delete records (CRUD)",
   "probe": "update a record id that does not exist",
   "outcome": "404 application/json; charset=utf-8 {\"error\": \"ERR_RECORD_NOT_FOUND\", \"message\": \"Record '99999' not found\"}",
   "grade": "clear",
   "idempotent": null,
   "rate_limit": null
  },
  {
   "capability": "Create, update, delete records (CRUD)",
   "probe": "bulk create with one invalid row (partial failure)",
   "outcome": "422 application/json; charset=utf-8 {\"error\": \"ERR_INVALID_VALUE_FOR_FIELD\", \"message\": \"Invalid value 'not-a-number' for type 'Number' on column 'Hours'\"}",
   "grade": "clear",
   "idempotent": null,
   "rate_limit": null
  },
  {
   "capability": "Create, update, delete records (CRUD)",
   "probe": "repeat a create with the same Idempotency-Key",
   "outcome": "200 then 200; list shows ids [6, 7]",
   "grade": "silent",
   "idempotent": "no",
   "rate_limit": null
  },
  {
   "capability": "The first call",
   "probe": "call with a wrong API token",
   "outcome": "401 application/json; charset=utf-8 {\"error\": \"ERR_AUTHENTICATION_REQUIRED\", \"message\": \"Authentication required - Invalid token\"}",
   "grade": "clear",
   "idempotent": null,
   "rate_limit": null
  },
  {
   "capability": "The first call",
   "probe": "MCP call with a wrong x-api-key",
   "outcome": "404 application/json; charset=utf-8 {\"msg\": \"MCP Token not found\"}",
   "grade": "vague",
   "idempotent": null,
   "rate_limit": null
  },
  {
   "capability": "Read and write data/meta via REST API (v3 data and meta endpoints)",
   "probe": "burst of 15 sequential GETs on one cheap read",
   "outcome": "15x 200; x-ratelimit-limit 60, x-ratelimit-remaining 57->43, x-ratelimit-reset counting down (seconds); no RateLimit/RateLimit-Policy (IETF draft) headers, no 429 reached",
   "grade": "clear",
   "idempotent": null,
   "rate_limit": "none-seen"
  }
 ],
 "surface_audit": {
  "totals": {
   "items": 405,
   "documented": 394,
   "safe": 386,
   "exercised": 354,
   "passed": 219,
   "skipped": 8,
   "blocked": 8,
   "not_run": 24,
   "match": 211,
   "drift": 136,
   "broken_doc": 7,
   "docs_complete": 49,
   "docs_partial": 344,
   "docs_missing": 1,
   "errors_clear": 145,
   "errors_vague": 5,
   "errors_silent": 5
  }
 },
 "coverage_core": 100,
 "after_wall": null,
 "coverage_source": "computed",
 "driver": {
  "version": 2,
  "model": "claude-opus-5-5",
  "profile": "full",
  "assisted": false,
  "handoff": null,
  "prompt_sha": "f9ae61c1d6ff",
  "kb_version": "2",
  "identity": null
 },
 "methodology": 15,
 "rules_date": "2026-10-15",
 "engine": {
  "runner": "omp",
  "model": "claude-opus-5-5",
  "driver": 2,
  "signed": true,
  "inbox": [
   "agentdrives.com"
  ],
  "robots": "start"
 },
 "same_level_drives": 3,
 "drives": 3,
 "works_assisted": null,
 "freshness": "fresh",
 "nothing_to_pay": false,
 "core_gated": false,
 "profiles": {},
 "agent_check": null,
 "agent_pass": null,
 "who_gets_in": {
  "server": {
   "state": "in"
  },
  "signed": {
   "state": "page",
   "kind": "signup",
   "at": "2026-10-13"
  },
  "browser": {
   "state": "in",
   "measured": false
  },
  "our_key": "pending",
  "robots": null,
  "tip": false
 },
 "ladder": {
  "docs": {
   "status": "headless",
   "note": "llms.txt and llms-full.txt, every docs page as Markdown (.md or Accept: text/markdown), OpenAPI 3.1.0 for v3 data+meta, MCP docs."
  },
  "signup": {
   "status": "browser",
   "note": "No sign-up API. Web form at app.nocodb.com/signup (email + password; Google; SSO), no CAPTCHA; done in our agent's browser."
  },
  "verify": {
   "status": "browser",
   "note": "6-digit code from noreply@nocodb.com arrived within ~30 s and was read headless from our inbox; the code is entered in the web app."
  },
  "credentials": {
   "status": "browser",
   "note": "API tokens and MCP keys are created only in Account settings (the tokens API answers 401 'not allowed with API token'). New tokens default to Records RW / Tables R / Fields R; a second token with Read & write all was needed to create bases. MCP OAuth (DCR + PKCE) needs a consent page.",
   "via": ""
  },
  "first_call": {
   "status": "headless",
   "note": "GET /api/v3/meta/workspaces with xc-token -> 200; MCP tools/list with x-api-key."
  },
  "first_action": {
   "status": "headless",
   "note": "POST /api/v3/meta/workspaces/{ws}/bases created a base, read back with GET."
  },
  "pay": {
   "status": "browser",
   "grade": "P2",
   "rails": [
    "Stripe embedded Checkout (card, Link)"
   ],
   "rail_ids": [
    "stripe-checkout"
   ],
   "first_party": false,
   "rail_scope": "none",
   "trial_path": "free tier",
   "note": "No 402 / x402 / MPP / UCP / L402 anywhere and no billing API. Billing > Upgrade Workspace > Choose Plus opens an embedded Stripe Checkout (EUR 266.11/year) with invisible hCaptcha and HUMAN Security; no trial offered there. Not paid (no card); on the evidence, untested whether its invisible checks pass an agent."
  },
  "cancel": {
   "status": "n/a",
   "note": "Nothing to cancel: our agent used the free plan.",
   "docs_note": "No plan started. Pricing FAQ: cancel or downgrade from account settings (web UI); no billing API.",
   "docs_grade": "",
   "nothing": "free_plan"
  },
  "delete": {
   "status": "browser",
   "note": "Account > Profile > Danger Zone > Delete Account (type email). Bases can be deleted over REST (soft delete to trash); the account only in the UI. Afterwards the token got 401 and the MCP key 404.",
   "left": "deleted",
   "account": true
  }
 },
 "routes": [],
 "checkout": null,
 "docs": null,
 "claims": null,
 "pay_options": {
  "checked": "2026-10-03",
  "source": "drive",
  "options": [
   {
    "id": "stripe-checkout",
    "name": "Stripe Checkout",
    "kind": "checkout",
    "first_party": false,
    "lead": false,
    "networks": [],
    "testnet": false
   }
  ],
  "agentic": [],
  "paid": null,
  "exercised": null,
  "detected_grade": null,
  "trial": {
   "no_card": null,
   "card_required": null,
   "free_plan": true
  },
  "owner_fixes": [
   {
    "title": "Accept x402 or MPP on your API",
    "how": "Answer an unpaid call with 402 and a payment challenge, so an agent pays per call or buys credits without an account or a card."
   },
   {
    "title": "List your plans on Stripe Projects",
    "how": "Agents buy a plan with `stripe projects add`, paid with a token under a spend cap the owner sets (projects.dev)."
   }
  ]
 },
 "surfaces": {
  "api": true,
  "openapi": true,
  "cli": true,
  "sdk": false,
  "mcp": "official",
  "llms_txt": true,
  "webhooks": true,
  "sandbox": false
 },
 "surface_notes": {
  "api": "REST v3, 112 operations; data and schema core works on Free, several groups plan- or scope-gated",
  "openapi": "3.1.0; most operations declare no auth",
  "mcp": "official, 202 tools (72 listed + 130 via listTools/callTool), the 25 Nov 2025 MCP spec",
  "cli": "bash CLI inside the downloadable Claude skill (71 commands)",
  "llms_txt": "llms.txt + llms-full.txt; Markdown for every docs page"
 },
 "can_do": [
  "Create bases, tables and fields (formula, links, lookup, rollup, selects) over REST",
  "Create, update, link and delete records over REST, MCP or the skill CLI",
  "Filter and sort views over REST and build kanban, calendar, form and gallery views over MCP",
  "Share a view behind a password link over MCP",
  "Import a CSV as a new table over MCP",
  "Build, test and publish a record-triggered workflow over MCP (a human switches it Live)",
  "Build an interface page and a dashboard widget over MCP",
  "Ask NocoAI in the web app to build a table from one sentence",
  "Invite a collaborator to a base and set their role over MCP"
 ],
 "cannot_do": [
  {
   "what": "Sign up, verify and get the first token without a browser",
   "why": "Web form and settings pages only; the tokens API refuses API tokens"
  },
  {
   "what": "Turn a workflow on",
   "why": "Enable and run-as are UI-only by design"
  },
  {
   "what": "Use views, webhooks, comments, dashboards or members over REST on Free",
   "why": "403 'Upgrade to a higher plan', although MCP covers most of it"
  },
  {
   "what": "Reach workflows, scripts, teams or workspace reads over REST",
   "why": "No API-token scope grants them"
  },
  {
   "what": "Update or delete one view filter or sort over REST",
   "why": "The documented routes 404 on Cloud"
  },
  {
   "what": "Pay or change plan",
   "why": "Embedded Stripe Checkout only; no billing API or agent payment rail"
  },
  {
   "what": "Delete the account",
   "why": "Web UI only"
  }
 ],
 "blockers": [
  "Sign-up, email-code entry and token creation need a browser",
  "Several REST groups are plan-gated or have no token scope"
 ],
 "tips_for_owner": [
  "Offer a headless sign-up and token path",
  "Align REST plan gates with MCP and pricing",
  "Fix filter and sort update/delete routes",
  "Add token scopes for automation and admin APIs",
  "Reject unknown fields on record writes",
  "Fix title-only rename of formula fields",
  "Support MCP (the 28 Jul 2026 spec) and server discovery",
  "Declare auth and errors in the OpenAPI",
  "Let the API enable a tested workflow",
  "Document how to verify webhook payloads",
  "Honour Idempotency-Key on record creates",
  "Fix the skill CLI upload and error output",
  "Offer account deletion over the API",
  "Add a billing API for plan changes"
 ],
 "tips_for_agents": [
  "Use the MCP server: on Free it covers far more than REST (views, sharing, dashboards, interfaces, comments, members, workflows). Call listTools(category) to reveal write tools, then callTool.",
  "Create the API token with 'Read & write all': the default token (Records RW, Tables R, Fields R) cannot create bases.",
  "Check field names on record writes: unknown fields are silently dropped with 200; read the record back.",
  "The sort query parameter must be JSON, e.g. [{\"field\":\"Hours\",\"direction\":\"desc\"}].",
  "Free plan: 1,000 API calls a month and 60 meta calls a minute (x-ratelimit-* headers); MCP tool calls count too.",
  "When renaming a Formula field, resend options.formula.",
  "Workflows: test every node with validateWorkflowNode before publishWorkflow, then ask a human to switch it Live."
 ],
 "selfhost": {
  "install": {
   "status": "skipped",
   "minutes": 0,
   "note": "no docker in the drive sandbox (NocoDB has a self-hosted Community Edition)"
  }
 },
 "summary": "Once it holds a token, an agent can run most of NocoDB on the free plan: bases, tables, fields, records, views, sharing, CSV import, workflows, interfaces and dashboards all worked, mostly over the official MCP server, and NocoAI built a table from one sentence in the web app. Getting in needs a browser (sign-up form, emailed code, token page), a workflow needs a human click to go live, and several REST groups are plan-gated or unreachable with any token.",
 "wall": "Sign-up and first API key need a browser",
 "plan_scope": "free plan",
 "robots_stop": null,
 "robots": null,
 "plain": {
  "summary": "NocoDB is a no-code database (an Airtable-style tool) that also offers an API and an AI assistant for building apps. Once an agent had a login and a key, it could build and run almost everything on the free plan by itself. The main thing stopping full automation was that signing up, confirming the emailed code, and creating the first API key all have to be done through NocoDB's website rather than by a program.",
  "can_do": [
   "Create databases, tables, and custom fields like formulas and lookups on its own",
   "Add, change, and delete records, and link records together",
   "Build different view types like kanban boards and calendars, and share a password-protected view",
   "Import a spreadsheet file into a new table",
   "Build and test an automated workflow, though a person has to flip the final switch to turn it on",
   "Build simple app pages and dashboards with charts",
   "Ask the built-in AI assistant to create a table just by describing it in plain English",
   "Invite another person to collaborate on a project"
  ],
  "cannot_do": [
   {
    "what": "Sign up and get its first access key without a browser",
    "why": "Only the web sign-up form and the account settings page offer this"
   },
   {
    "what": "Turn on a workflow it built",
    "why": "Switching a workflow live is only available in the website, by design"
   },
   {
    "what": "Use some features (sharing dashboards, member management) through its automated interface on the free plan",
    "why": "Those are blocked behind a paid plan when accessed that way, even though other routes to the same feature work"
   },
   {
    "what": "Pay for or cancel a paid plan on its own",
    "why": "Upgrading only works through a web checkout page; there is no automated payment option"
   },
   {
    "what": "Delete its own account",
    "why": "Account deletion is only available through the website"
   }
  ]
 },
 "plan_gated": [
  {
   "capability": "Scripts",
   "plan": "higher plan / Enterprise API",
   "evidence": "REST 403 no token permission createScript; MCP 'Upgrade to a higher plan to use script tools over MCP.'"
  },
  {
   "capability": "Webhooks",
   "plan": "higher plan",
   "evidence": "REST 403 'Upgrade to a higher plan to use webhook api.'; MCP 'Upgrade to a higher plan to use webhook tools over MCP.'"
  },
  {
   "capability": "NocoDocs",
   "plan": "higher plan",
   "evidence": "REST and MCP 'Upgrade to a higher plan to access Documents API.'"
  },
  {
   "capability": "Record-level security",
   "plan": "higher plan",
   "evidence": "MCP 'Upgrade to a higher plan to use row-level security.'"
  },
  {
   "capability": "Nested teams",
   "plan": "higher plan",
   "evidence": "MCP 'Upgrade to a higher plan to use team management.'"
  },
  {
   "capability": "Snapshots",
   "plan": "Plus",
   "evidence": "Base Settings > Snapshots shows 'Upgrade to Plus'"
  },
  {
   "capability": "Workspace audit log (record history works on Free)",
   "plan": "higher plan",
   "evidence": "MCP 'Upgrade to a higher plan to access workspace audit logs.'"
  },
  {
   "capability": "/ / over REST only (MCP works on Free)",
   "plan": "higher plan",
   "evidence": "403 'Upgrade to a higher plan to use view api.' / 'dashboard api.' / 'member management api.'"
  }
 ],
 "reply": null,
 "capabilities": [
  {
   "id": "cap-01",
   "group": "Database building",
   "capability": "Create a base (database)",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": "POST /api/v3/meta/workspaces/{workspaceId}/bases",
    "mcp": "base management tools (149-tool MCP server)",
    "cli": null,
    "ui": "Workspace > New base"
   },
   "check": "GET /api/v3/meta/bases/{baseId} returns the created base",
   "source": "https://nocodb.com/docs/product/bases; https://nocodb.com/docs/apis-and-mcp/mcp"
  },
  {
   "id": "cap-02",
   "group": "Database building",
   "capability": "Create a table with fields",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": "POST /api/v3/meta/bases/{baseId}/tables",
    "mcp": "table/field tools",
    "cli": null,
    "ui": "Base > + New Table"
   },
   "check": "GET /api/v3/meta/tables/{tableId} shows new table and its fields",
   "source": "https://nocodb.com/docs/product/tables; https://nocodb.com/docs/product/tables/fields"
  },
  {
   "id": "cap-03",
   "group": "Database building",
   "capability": "Add, edit and configure fields (30+ types incl. links, lookups, rollups, formulas)",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": "POST/PATCH /api/v3/meta/tables/{tableId}/fields",
    "mcp": "field tools",
    "cli": null,
    "ui": "Grid view > + field / field menu"
   },
   "check": "GET table fields shows field with configured type/options",
   "source": "https://nocodb.com/docs/product/tables/fields"
  },
  {
   "id": "cap-04",
   "group": "Database building",
   "capability": "Create, update, delete records (CRUD)",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": "POST/PATCH/DELETE /api/v3/data/{baseId}/{tableId}/records",
    "mcp": "record CRUD tools",
    "cli": null,
    "ui": "Grid/expanded record form"
   },
   "check": "GET /api/v3/data/{baseId}/{tableId}/records/{id} reflects the change",
   "source": "https://nocodb.com/docs/product; https://nocodb.com/docs/apis-and-mcp"
  },
  {
   "id": "cap-05",
   "group": "Views",
   "capability": "Build multiple view types (Grid, Form, Gallery, Kanban, Calendar, Timeline, Gantt, List, Map)",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": "POST /api/v3/meta/tables/{tableId}/views",
    "mcp": "view tools",
    "cli": null,
    "ui": "Table sidebar > + View"
   },
   "check": "GET views list shows new view with its type",
   "source": "https://nocodb.com/docs/product/tables/views"
  },
  {
   "id": "cap-06",
   "group": "Views",
   "capability": "Sort, filter, group and search records in a view",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": "view/filter and sort meta endpoints",
    "mcp": "filter/sort tools",
    "cli": null,
    "ui": "Grid toolbar"
   },
   "check": "GET view filters/sorts config matches applied settings",
   "source": "https://nocodb.com/docs/product"
  },
  {
   "id": "cap-07",
   "group": "Views",
   "capability": "Share a base or view publicly or privately (password protected)",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": "POST /api/v3/meta/views/{viewId}/share",
    "mcp": "share tools",
    "cli": null,
    "ui": "Share button on base/view"
   },
   "check": "GET shared view link is reachable and reflects password setting",
   "source": "https://nocodb.com/docs/product"
  },
  {
   "id": "cap-08",
   "group": "AI assistant",
   "capability": "Ask NocoAI to build/change bases, tables, views, dashboards, workflows, interfaces from plain language",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "AskNocoAI panel in base"
   },
   "check": "Resulting table/view/workflow appears in base meta after prompt execution",
   "source": "https://nocodb.com/docs/product/noco-ai; https://nocodb.com/docs/product/noco-ai/capabilities"
  },
  {
   "id": "cap-09",
   "group": "Automation",
   "capability": "Build a workflow (triggers, actions, conditions, loops) on records",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": "workflow tools",
    "cli": null,
    "ui": "Workflows visual builder"
   },
   "check": "Triggering the record/form/schedule/button event produces the configured action's effect (e.g. email sent, record updated)",
   "source": "https://nocodb.com/docs/workflows; https://nocodb.com/llms.txt"
  },
  {
   "id": "cap-10",
   "group": "Import/Export",
   "capability": "Import a base from Airtable, CSV or Excel",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": "import meta endpoints",
    "mcp": "import tool",
    "cli": null,
    "ui": "Base > Import"
   },
   "check": "GET base tables shows imported tables/records matching source file",
   "source": "https://nocodb.com/docs/product/bases/import-base-from-airtable"
  },
  {
   "id": "cap-11",
   "group": "Apps & dashboards",
   "capability": "Build an Interface (focused app with dashboard/form/table/record pages) on base data",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": "interface tools",
    "cli": null,
    "ui": "Interfaces tab"
   },
   "check": "Published interface URL renders configured pages reading live base data",
   "source": "https://nocodb.com/docs/interfaces"
  },
  {
   "id": "cap-12",
   "group": "Apps & dashboards",
   "capability": "Build a dashboard with chart widgets (bar, line, pie, donut, numbers, text, iframe)",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": "dashboard tools",
    "cli": null,
    "ui": "Dashboards tab"
   },
   "check": "Dashboard widget renders values matching underlying table data",
   "source": "https://nocodb.com/docs/product/dashboards"
  },
  {
   "id": "cap-13",
   "group": "Automation",
   "capability": "Write and run JavaScript Scripts with API access to base/table/field/record objects",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "Scripts editor"
   },
   "check": "Script run log shows executed output and resulting record changes",
   "source": "https://nocodb.com/docs/workflows/scripts"
  },
  {
   "id": "cap-14",
   "group": "Automation",
   "capability": "Configure webhooks on record create/update/delete",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": "POST /api/v2/meta/tables/{tableId}/hooks",
    "mcp": "webhook tools",
    "cli": null,
    "ui": "Table > Webhooks"
   },
   "check": "Triggering the record event delivers a payload to the configured webhook URL",
   "source": "https://nocodb.com/docs/product/tables/table-operations/webhook"
  },
  {
   "id": "cap-15",
   "group": "Collaboration",
   "capability": "Write and collaborate on NocoDocs (rich text docs with comments and version history)",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": "docs tools",
    "cli": null,
    "ui": "Docs tab"
   },
   "check": "GET doc version history shows saved revisions and comments",
   "source": "https://nocodb.com/docs/product/docs"
  },
  {
   "id": "cap-16",
   "group": "Collaboration",
   "capability": "Organize tables, docs, dashboards into sidebar folders",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "Base sidebar"
   },
   "check": "Sidebar reflects items grouped inside the created folder",
   "source": "https://nocodb.com/docs/product"
  },
  {
   "id": "cap-17",
   "group": "Collaboration",
   "capability": "Invite collaborators and assign roles at workspace/base/table/field/record level",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": "POST /api/v3/meta/bases/{baseId}/users",
    "mcp": "collaborator tools",
    "cli": null,
    "ui": "Team & Settings"
   },
   "check": "GET base users list shows invited user with assigned role",
   "source": "https://nocodb.com/docs/product/collaboration/roles-and-permissions"
  },
  {
   "id": "cap-18",
   "group": "Collaboration",
   "capability": "Define record-level security policies restricting which records a role/team/user sees",
   "weight": "secondary",
   "plan": "paid",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "Base Settings > Record Level Security"
   },
   "check": "Logging in as restricted role returns only the scoped subset of records",
   "source": "https://nocodb.com/docs/product/collaboration/record-level-security; https://nocodb.com/pricing"
  },
  {
   "id": "cap-19",
   "group": "Collaboration",
   "capability": "Create nested teams (up to 4 levels) with permissions flowing down hierarchy",
   "weight": "secondary",
   "plan": "paid",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "Workspace Settings > Teams"
   },
   "check": "Sub-team member inherits parent team's table/field permissions",
   "source": "https://nocodb.com/docs/product/collaboration/teams/sub-teams"
  },
  {
   "id": "cap-20",
   "group": "Data management",
   "capability": "Take on-demand or scheduled snapshots of a base",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": "snapshot meta endpoints",
    "mcp": "snapshot tools",
    "cli": null,
    "ui": "Base Settings > Snapshots"
   },
   "check": "GET snapshots list shows the created snapshot with timestamp",
   "source": "https://nocodb.com/docs/product/bases/snapshots"
  },
  {
   "id": "cap-21",
   "group": "Data management",
   "capability": "Sync data from external apps (GitHub, GitLab, Linear, calendars, CRM, HRIS, ATS)",
   "weight": "secondary",
   "plan": "paid",
   "surfaces": {
    "api": null,
    "mcp": "sync tools",
    "cli": null,
    "ui": "Base > Sync"
   },
   "check": "Table populated with records matching the connected external source",
   "source": "https://nocodb.com/docs/product/sync"
  },
  {
   "id": "cap-22",
   "group": "Data management",
   "capability": "Mirror a view from another base as a continuously updated read-only table (NocoDB Sync)",
   "weight": "secondary",
   "plan": "paid",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "Base > Sync > NocoDB Sync"
   },
   "check": "Mirrored table updates automatically when source view data changes",
   "source": "https://nocodb.com/docs/product/sync/nocodb-sync"
  },
  {
   "id": "cap-23",
   "group": "Data management",
   "capability": "Connect an external PostgreSQL/MySQL (or SQL Server/Oracle on Enterprise) database as a data source",
   "weight": "secondary",
   "plan": "paid",
   "surfaces": {
    "api": null,
    "mcp": "integration tools",
    "cli": null,
    "ui": "Base > Integrations"
   },
   "check": "Base lists tables sourced live from the connected external database",
   "source": "https://nocodb.com/docs/product/integrations; https://nocodb.com/pricing"
  },
  {
   "id": "cap-24",
   "group": "Extensions",
   "capability": "Use extensions (Bulk Update, Data Exporter, Dedupe, Org Chart, Page Designer, URL Preview)",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "Base > Extensions"
   },
   "check": "Extension action (e.g. export) produces a downloadable file matching table data",
   "source": "https://nocodb.com/docs/product/extensions"
  },
  {
   "id": "cap-25",
   "group": "Programmatic access",
   "capability": "Read and write data/meta via REST API (v3 data and meta endpoints)",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": "GET/POST/PATCH/DELETE /api/v3/data and /api/v3/meta",
    "mcp": null,
    "cli": null,
    "ui": null
   },
   "check": "API response matches the underlying record/meta state",
   "source": "https://nocodb.com/docs/apis-and-mcp; https://nocodb.com/apis/v3/data; https://nocodb.com/apis/v3/meta"
  },
  {
   "id": "cap-28",
   "group": "Security & governance",
   "capability": "View audit logs of workspace and record-level changes",
   "weight": "secondary",
   "plan": "paid",
   "surfaces": {
    "api": null,
    "mcp": "audit log tools",
    "cli": null,
    "ui": "Workspace Settings > Audit"
   },
   "check": "Audit log lists the performed action with actor and timestamp",
   "source": "https://nocodb.com/docs/product/workspaces/workspace-audit; https://nocodb.com/pricing"
  },
  {
   "id": "cap-27",
   "group": "Programmatic access",
   "capability": "Use the NocoDB Claude agent skill to manage bases via natural language",
   "weight": "peripheral",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": null
   },
   "check": "Installed skill performs described base-management actions in a Claude session",
   "source": "https://nocodb.com/docs/apis-and-mcp/skills"
  },
  {
   "id": "cap-29",
   "group": "Security & governance",
   "capability": "Configure SSO (SAML/OIDC) and SCIM provisioning",
   "weight": "peripheral",
   "plan": "paid",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "Workspace Settings > Authentication"
   },
   "check": "Login via configured SSO provider succeeds and provisions the user per SCIM mapping",
   "source": "https://nocodb.com/docs/product/account-settings/authentication"
  },
  {
   "id": "cap-30",
   "group": "Security & governance",
   "capability": "Enable two-factor authentication",
   "weight": "peripheral",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "Account Settings > Security"
   },
   "check": "Subsequent login prompts for the second factor",
   "source": "https://nocodb.com/docs/product/account-settings/authentication"
  },
  {
   "id": "cap-31",
   "group": "Self-hosting & deployment",
   "capability": "Self-host NocoDB on own infrastructure (quickstart / single-server install)",
   "weight": "peripheral",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": "docker run / npx create-nocodb-app (quickstart command)",
    "ui": null
   },
   "check": "Self-hosted instance responds on configured host with the NocoDB UI",
   "source": "https://nocodb.com/docs/self-hosting; https://nocodb.com/docs/self-hosting/installation/quickstart"
  },
  {
   "id": "cap-32",
   "group": "Branding",
   "capability": "Apply white-label custom branding (self-hosted Enterprise)",
   "weight": "peripheral",
   "plan": "paid",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "Enterprise admin settings"
   },
   "check": "Deployed instance UI shows custom logo/branding instead of NocoDB default",
   "source": "https://nocodb.com/docs/self-hosting/white-label"
  }
 ],
 "attempts": [
  {
   "t": "01:27",
   "cap": "discovery",
   "capability": "robots/aipref",
   "task": "robots.txt and Content-Usage",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "https://nocodb.com/robots.txt 200: User-agent: * / Allow: / / Sitemap. No Content-Usage or Content-signal line; no Content-Usage response header on nocodb.com"
  },
  {
   "t": "01:27",
   "cap": "discovery",
   "capability": "llms.txt",
   "task": "fetch /llms.txt",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "https://nocodb.com/llms.txt 200 text/plain 209847 bytes, H1 # NocoDB; /llms-full.txt 200 1.97 MB"
  },
  {
   "t": "01:27",
   "cap": "discovery",
   "capability": "markdown docs",
   "task": "Accept: text/markdown and .md URL",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "GET /docs/apis-and-mcp/mcp with Accept: text/markdown -> content-type: text/markdown, vary: Accept; /docs/apis-and-mcp/mcp.md -> 200 text/markdown"
  },
  {
   "t": "01:27",
   "cap": "discovery",
   "capability": "mcp server/discover",
   "task": "POST server/discover 2026-07-28 to https://app.nocodb.com/mcp",
   "route": "mcp",
   "documented": true,
   "result": "blocked",
   "verified": true,
   "evidence": "401 application/json {\"error\":\"ERR_AUTHENTICATION_REQUIRED\",\"message\":\"Authentication required - Authentication required\"}; no WWW-Authenticate header (no resource_metadata pointer). Retry with credentials pending"
  },
  {
   "t": "05:32",
   "cap": "docs",
   "capability": "find docs",
   "task": "find API, MCP and agent docs",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "llms.txt, /docs/apis-and-mcp(.md), OpenAPI 3.1.0 at https://nocodb.com/apis/v3/swagger-v3.json (132 operations), MCP doc with OAuth + token config",
   "quality": {
    "docs_match": "match"
   }
  },
  {
   "t": "05:32",
   "cap": "signup",
   "capability": "sign up",
   "task": "create account",
   "route": "browser",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "No signup operation in OpenAPI or docs; web form app.nocodb.com/signup (email+password, Google, SSO). No CAPTCHA signals (turnstile/hcaptcha/recaptcha all false). Create Account -> We Emailed You code screen",
   "notes": "browser; Amplify-style authenticator"
  },
  {
   "t": "05:32",
   "cap": "verify",
   "capability": "verify email",
   "task": "enter 6-digit code",
   "route": "browser",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "Mail from noreply@nocodb.com Your verification code for nocodb cloud arrived within ~30s; code entered on sign-in confirm screen; landed on app.nocodb.com onboarding (What do you plan on using NocoDB for?)",
   "notes": "confirm screen lost on page reload; signing in again re-prompted for the code"
  },
  {
   "t": "06:38",
   "cap": "credentials",
   "capability": "API token",
   "task": "create personal API token",
   "route": "browser",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "Account > API Tokens > Create New API Token in web UI -> nc_pat_•••• shown once. POST /api/v3/meta/tokens exists in OpenAPI but itself needs a token, so the first credential needs the web UI",
   "notes": "OAuth (DCR + auth code + PKCE) exists for MCP but needs browser consent; no device flow"
  },
  {
   "t": "06:38",
   "cap": "first_call",
   "capability": "first API call",
   "task": "GET /api/v3/meta/workspaces",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "200 {\"list\":[{\"id\":\"[redacted]\",\"title\":\"an inbox\"}]}; headers x-ratelimit-limit: 60, x-ratelimit-remaining: 59, x-ratelimit-reset: 60",
   "quality": {
    "docs_match": "match"
   }
  },
  {
   "t": "07:58",
   "cap": "cap-01",
   "capability": "Create a base",
   "task": "POST create base with default-scope token",
   "route": "api",
   "documented": true,
   "result": "failed",
   "verified": true,
   "evidence": "POST /api/v3/meta/workspaces/[redacted]/bases {\"title\":\"AD Drive Base 1\"} -> 403 {\"error\":\"ERR_FORBIDDEN\",\"message\":\"Forbidden - API token does not have permission to baseCreate. Required permission not granted.\"}",
   "notes": "New tokens default to Records RW, Tables R, Fields R (documented). Error names the missing permission. Created a second token with Read & write all in the UI.",
   "quality": {
    "error_legibility": "clear",
    "recoverable": "yes",
    "docs_match": "match"
   }
  },
  {
   "t": "08:04",
   "cap": "cap-01",
   "capability": "Create a base",
   "task": "Create base \"AD Drive Base 1\" and read it back",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "POST /api/v3/meta/workspaces/[redacted]/bases -> 200 id pwv7v3b8v82110j; GET /api/v3/meta/bases/pwv7v3b8v82110j -> 200 title AD Drive Base 1",
   "quality": {
    "verify_route": "yes",
    "docs_match": "match"
   }
  },
  {
   "t": "08:21",
   "cap": "cap-02",
   "capability": "Create a table with fields",
   "task": "Create table Tasks with Name, Status (select), Hours, Due",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "POST /api/v3/meta/bases/pwv7v3b8v82110j/tables -> 200 id malamliwjxt0fwf; GET table schema -> fields [('Id', 'ID'), ('Name', 'SingleLineText'), ('Status', 'SingleSelect'), ('Hours', 'Number'), ('Due', 'Date')]",
   "quality": {
    "verify_route": "yes",
    "docs_match": "match"
   }
  },
  {
   "t": "08:52",
   "cap": "cap-03",
   "capability": "Add, edit and configure fields",
   "task": "Add Formula, Links (mo), Lookup, Rollup fields; rename and add option to a SingleSelect",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "POST /fields Cost Formula {Hours}*50, Project Links mo->Projects, Project Title Lookup, Projects.Total Hours Rollup sum -> 200 each; PATCH /fields/{id} Status->State + Blocked choice -> 200; GET table/field shows them",
   "notes": "PATCH with a choices list replaces all choices: existing choice ids were regenerated and colours set to null when not resent",
   "quality": {
    "verify_route": "yes",
    "docs_match": "match"
   }
  },
  {
   "t": "09:17",
   "cap": "cap-04",
   "capability": "Create, update, delete records",
   "task": "Create 2 tasks, update one, read back, delete the other, link task to project",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "POST records -> ids 1,2; PATCH id1 State=Done Hours=5 -> GET /records/1 shows Done, 5, Cost 250 (formula); DELETE id2 -> {deleted:true}, GET /records/2 -> 404 ERR_RECORD_NOT_FOUND; link POST -> 200; Projects/1 Total Hours rollup = 5",
   "quality": {
    "verify_route": "yes",
    "docs_match": "match"
   }
  },
  {
   "t": "10:20",
   "cap": "cap-06",
   "capability": "Sort, filter, group and search records in a view",
   "task": "Add filter State=Done and sort Hours desc to the default grid view; read config and filtered records back; ad-hoc where+sort query",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "POST /views/vwtd0irm5m4eq1qx/filters -> 200 filter eq Done; POST /sorts -> 200 desc; GET filters/sorts list them; GET records?viewId=vwtd0irm5m4eq1qx returns only the Done record; GET records?where=(Hours,gt,1)&sort=[...] -> 200",
   "notes": "GET filters returns {} when empty but {\"list\": {...}} once set; POST returns the group without list wrapper. sort query param must be JSON (a plain -Hours gives a clear 400). Group-by not exercised (no API op for it).",
   "quality": {
    "verify_route": "yes",
    "docs_match": "drift",
    "error_legibility": "clear"
   }
  },
  {
   "t": "10:20",
   "cap": "cap-05",
   "capability": "Build multiple view types",
   "task": "Create kanban, calendar, form, gallery, grid views on Tasks via REST",
   "route": "api",
   "documented": true,
   "result": "plan_gated",
   "verified": true,
   "evidence": "POST /api/v3/meta/bases/{base}/tables/{table}/views (each type) -> 403 {\"error\":\"ERR_FEATURE_NOT_SUPPORTED\",\"message\":\"Upgrade to a higher plan to use view api.\"}; GET views list and GET view also 403 on Free plan",
   "notes": "Pricing page says Free includes all view types and Rest API; does not say the view API is paid. Filters and sorts endpoints work on Free.",
   "quality": {
    "error_legibility": "vague",
    "recoverable": "no"
   }
  },
  {
   "t": "12:26",
   "cap": "discovery",
   "capability": "mcp server/discover with key",
   "task": "server/discover 2026-07-28 then initialize fallback on https://app.nocodb.com/mcp/<ncId>",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "server/discover -> 400 {\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"Bad Request: Unsupported protocol version: 2026-07-28 (supported versions: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07)\"}}; initialize offering 2026-07-28 -> 200 SSE protocolVersion 2025-11-25, serverInfo NocoDB MCP Server 1.0.0, no Mcp-Session-Id; tools/list -> 72 tools listed + listTools/callTool reveal write tools by category",
   "notes": "Legacy server (error code -32000, not -32022). Auth: x-api-key header (or xc-mcp-token); OAuth at https://app.nocodb.com/mcp with PRM + DCR"
  },
  {
   "t": "13:11",
   "cap": "cap-05",
   "capability": "Build multiple view types",
   "task": "Create kanban, calendar, form and gallery views on Tasks via MCP createView; read back with listViews",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "callTool createView kanban vwuqcy90xriglf5n, then {'kanban': 'vwg6x741lx8a71fz', 'calendar': 'vwjhp0srzqr43mwb', 'form': 'vwsbgtm6tlpvkuga', 'gallery': 'vwc472oxabogs4fd'}; listViews returns all with their type",
   "notes": "Same views REST endpoint returns 403 Upgrade to a higher plan to use view api on Free; MCP createView works on Free. Calendar created without date range (no options) still succeeded.",
   "quality": {
    "verify_route": "yes",
    "docs_match": "match"
   }
  },
  {
   "t": "14:59",
   "cap": "cap-07",
   "capability": "Share a view publicly or with a password",
   "task": "Share the Tasks grid view with a password via MCP shareView; open the public link",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "callTool shareView password -> public_url https://app.nocodb.com/nc/view/<uuid>, password_protected true; listSharedViews lists it; opening the link in a browser shows \"This shared view is protected\" and the password unlocks the Tasks grid (Download/Fields/Filter/Group/Sort toolbar)",
   "notes": "REST v3 has no share operation in the OpenAPI; MCP only. Verification of the password gate used a browser.",
   "quality": {
    "verify_route": "yes",
    "docs_match": "match"
   }
  },
  {
   "t": "16:32",
   "cap": "cap-09",
   "capability": "Build a workflow",
   "task": "Workflow: when a Task is created, create a Project titled from it. Build via MCP createWorkflow, validate both nodes, publish, then insert a task",
   "route": "mcp",
   "documented": true,
   "result": "partial",
   "verified": true,
   "evidence": "createWorkflow aut4cxep6qpq026yn -> ok; validateWorkflowNode trigger/mk -> success (simulated); publishWorkflow -> ok but \"enabled\": false; POST record \"WF trigger 1\" -> no new Project after 15 s; listExecutions -> []; REST POST /workflows/{id}/execute with full-scope token -> 403 permission workflowExecute not granted",
   "notes": "Documented: enabling and run_as are deliberately not exposed over MCP - a human sets those in the UI. API token scopes have no Automation category, so workflow list/execute REST calls are forbidden for any token.",
   "quality": {
    "error_legibility": "clear",
    "docs_match": "match",
    "recoverable": "no"
   }
  },
  {
   "t": "17:38",
   "cap": "cap-09",
   "capability": "Build a workflow",
   "task": "Enable the MCP-built workflow in the web UI (the one step MCP does not expose), insert a task, check the effect",
   "route": "browser",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "Workflow editor toggle Paused -> Live; POST record \"WF trigger 2\" -> Projects now has \"WF A: WF trigger 2\"; MCP listExecutions -> 1 execution status completed, node_count 2",
   "notes": "Hybrid: graph built, tested and published over MCP; only the enable toggle needs the browser (documented).",
   "quality": {
    "verify_route": "yes",
    "docs_match": "match"
   }
  },
  {
   "t": "18:02",
   "cap": "cap-10",
   "capability": "Import a base from Airtable, CSV or Excel",
   "task": "Import a 3-row CSV as a new table via MCP importCsv, read rows back over REST",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "importCsv -> table m3qg7nwn548l5fe, rows_inserted 3, rows_failed 0; GET /api/v3/data/pwv7v3b8v82110j/m3qg7nwn548l5fe/records -> [('Ada', 'London', '9'), ('Grace', 'Arlington', '8'), ('Linus', 'Helsinki', '7')]",
   "notes": "CSV only over MCP (all columns created as SingleLineText). Airtable and Excel import are UI-only (no REST/MCP route found).",
   "quality": {
    "verify_route": "yes",
    "docs_match": "match"
   }
  },
  {
   "t": "20:41",
   "cap": "cap-01",
   "trial": 2,
   "capability": "Create a base",
   "task": "Create base AD Trial 2, read back",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "POST bases -> 200 plbijwi8hmn1qlh; GET -> 200"
  },
  {
   "t": "20:43",
   "cap": "cap-02",
   "trial": 2,
   "capability": "Create a table with fields",
   "task": "Create Tasks table with 4 fields, read back",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "POST tables -> 200 m765btvbjd9h1hl; GET -> 200 fields ['Id', 'Name', 'Status', 'Hours', 'Due']"
  },
  {
   "t": "20:47",
   "cap": "cap-03",
   "trial": 2,
   "capability": "Add, edit and configure fields",
   "task": "Add Formula field, rename it, read back",
   "route": "api",
   "documented": true,
   "result": "failed",
   "verified": true,
   "evidence": "POST field -> 200; PATCH -> 400; GET field title Cost, formula {'formula': '{Hours} * 50'}",
   "notes": "Renaming a Formula field with PATCH {\"title\":\"Cost EUR\"} -> 400 ERR_INVALID_REQUEST_BODY \"Invalid formula: Cannot read properties of undefined (reading 'length')\" - server-side error leaks; a title-only rename should not need the formula resent.",
   "quality": {
    "error_legibility": "vague",
    "recoverable": "yes",
    "docs_match": "drift"
   }
  },
  {
   "t": "20:50",
   "cap": "cap-04",
   "trial": 2,
   "capability": "Create, update, delete records",
   "task": "Create 2, update 1, read back, delete 1",
   "route": "api",
   "documented": true,
   "result": "failed",
   "verified": true,
   "evidence": "create 200, update 200, read 200 state ok=False, delete 200, read deleted 404",
   "notes": "Our script sent field \"State\" (renamed only in trial 1; this table has \"Status\"). The API accepted the unknown field with 200 and silently dropped it (also confirmed with a probe field \"Statuz\"), so the update looked successful but State was never set.",
   "quality": {
    "error_legibility": "silent",
    "recoverable": "no"
   }
  },
  {
   "t": "20:54",
   "cap": "cap-05",
   "trial": 2,
   "capability": "Build multiple view types",
   "task": "Create kanban, calendar, form, gallery via MCP; listViews",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "createView -> {'kanban': 'vw1d2b05po4ckclm', 'calendar': 'vwntrzgqhgxw4lts', 'form': 'vwpkr30y5gl3ypsi', 'gallery': 'vwzeo6wszgfzwrea'}; listViews types ['calendar', 'form', 'gallery', 'grid', 'kanban']"
  },
  {
   "t": "20:56",
   "cap": "cap-06",
   "trial": 2,
   "capability": "Sort, filter, group and search records in a view",
   "task": "Filter Status=Done, sort Hours desc on grid; read records through view",
   "route": "api",
   "documented": true,
   "result": "failed",
   "verified": true,
   "evidence": "filter 200, sort 200, records via view []",
   "notes": "Consequence of the silent drop in trial 2: no record had Status=Done, so the filtered view returned []. Filter and sort writes themselves returned 200."
  },
  {
   "t": "20:58",
   "cap": "cap-07",
   "trial": 2,
   "capability": "Share a view publicly or with a password",
   "task": "shareView with password via MCP; listSharedViews; fetch link",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "shareView password_protected True, listed True, public_url HTTP 404",
   "notes": "Plain HTTP GET of the returned public_url (https://app.nocodb.com/nc/view/<uuid>) gives 404 {\"msg\":\"Cannot GET /nc/view/...\"}; the same URL renders the password gate in a browser. Share itself verified via listSharedViews."
  },
  {
   "t": "21:04",
   "cap": "cap-10",
   "trial": 2,
   "capability": "Import CSV",
   "task": "importCsv 3 rows as new table; read back",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "importCsv {'table_id': 'mqkh8l3hipao35d', 'table_name': 'Imported People T2', 'created_table': True, 'rows_inserted': 3, 'rows_failed': 0, 'links_created': 0, 'links_unmatched': 0}; GET records count 3"
  },
  {
   "t": "21:56",
   "cap": "cap-01",
   "trial": 3,
   "capability": "Create a base",
   "task": "Create base AD Trial 3, read back",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "POST bases -> 200 pxm2v5c5nt93p1a; GET -> 200"
  },
  {
   "t": "21:58",
   "cap": "cap-02",
   "trial": 3,
   "capability": "Create a table with fields",
   "task": "Create Tasks table with 4 fields, read back",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "POST tables -> 200 momc5rd5z9ibwdd; GET -> 200 fields ['Id', 'Name', 'Status', 'Hours', 'Due']"
  },
  {
   "t": "22:00",
   "cap": "cap-03",
   "trial": 3,
   "capability": "Add, edit and configure fields",
   "task": "Add Formula field, rename it, read back",
   "route": "api",
   "documented": true,
   "result": "failed",
   "verified": true,
   "evidence": "POST field -> 200; PATCH -> 400; GET field title Cost, formula {'formula': '{Hours} * 50'}",
   "notes": "Same as trial 2: title-only PATCH of a Formula field -> 400 \"Invalid formula: Cannot read properties of undefined (reading 'length')\". Reproducible.",
   "quality": {
    "error_legibility": "vague",
    "recoverable": "yes",
    "docs_match": "drift"
   }
  },
  {
   "t": "22:03",
   "cap": "cap-04",
   "trial": 3,
   "capability": "Create, update, delete records",
   "task": "Create 2, update 1, read back, delete 1",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "create 200, update 200, read 200 state ok=True, delete 200, read deleted 404"
  },
  {
   "t": "22:07",
   "cap": "cap-05",
   "trial": 3,
   "capability": "Build multiple view types",
   "task": "Create kanban, calendar, form, gallery via MCP; listViews",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "createView -> {'kanban': 'vwhps7yxndqfmvcm', 'calendar': 'vwi8k1esogp58eub', 'form': 'vwxxy6u4mvjvqb22', 'gallery': 'vw86uiopt0xgiven'}; listViews types ['calendar', 'form', 'gallery', 'grid', 'kanban']"
  },
  {
   "t": "22:09",
   "cap": "cap-06",
   "trial": 3,
   "capability": "Sort, filter, group and search records in a view",
   "task": "Filter Status=Done, sort Hours desc on grid; read records through view",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "filter 200, sort 200, records via view ['Write spec T3']"
  },
  {
   "t": "22:11",
   "cap": "cap-07",
   "trial": 3,
   "capability": "Share a view publicly or with a password",
   "task": "shareView with password via MCP; listSharedViews; fetch link",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "shareView password_protected True, listed True, public_url HTTP 404",
   "notes": "Plain HTTP GET of public_url returns 404 JSON; renders in a browser."
  },
  {
   "t": "22:16",
   "cap": "cap-10",
   "trial": 3,
   "capability": "Import CSV",
   "task": "importCsv 3 rows as new table; read back",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "importCsv {'table_id': 'mneexd1if4pq7qh', 'table_name': 'Imported People T3', 'created_table': True, 'rows_inserted': 3, 'rows_failed': 0, 'links_created': 0, 'links_unmatched': 0}; GET records count 3"
  },
  {
   "t": "22:27",
   "cap": "cap-08",
   "capability": "Ask NocoAI to build from plain language",
   "task": "Ask NocoAI (base home prompt) to create a Vendors table with Name, Email, Rating",
   "route": "browser",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "Typed prompt in base home NocoAI box -> \"Done - Vendors, Created 1 table\" in ~75 s; GET /api/v3/meta/bases/{B1}/tables/mwte0524y94il49 -> fields Name SingleLineText, Email Email, Rating Rating, description \"Vendor directory with contact details and rating.\"",
   "notes": "No API or MCP route to NocoAI (browser only). Worked on the Free plan with no own LLM key.",
   "quality": {
    "verify_route": "yes"
   }
  },
  {
   "t": "23:38",
   "cap": "cap-09",
   "trial": 2,
   "capability": "Build a workflow",
   "task": "Build after-insert -> create-record workflow via MCP, validate, publish; enable in UI; insert a record",
   "route": "browser",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "workflow aute5jst9zkfhqp5k: target table rows ['Ada', 'Grace', 'Linus', 'WF T2: WF fire T2']; executions ['completed']",
   "notes": "MCP for build/test/publish, browser only for the Live toggle"
  },
  {
   "t": "23:39",
   "cap": "cap-09",
   "trial": 3,
   "capability": "Build a workflow",
   "task": "Build after-insert -> create-record workflow via MCP, validate, publish; enable in UI; insert a record",
   "route": "browser",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "workflow autwd0in7ee0wk1yf: target table rows ['Ada', 'Grace', 'Linus', 'WF T3: WF fire T3']; executions ['completed']",
   "notes": "MCP for build/test/publish, browser only for the Live toggle"
  },
  {
   "t": "24:14",
   "cap": "cap-12",
   "capability": "Build a dashboard with chart widgets",
   "task": "Create dashboard via REST",
   "route": "api",
   "documented": true,
   "result": "plan_gated",
   "verified": true,
   "evidence": "POST /api/v3/meta/bases/{B1}/dashboards {\"title\":\"Ops dashboard\"} -> 403 {\"error\":\"ERR_FEATURE_NOT_SUPPORTED\",\"message\":\"Upgrade to a higher plan to use dashboard api.\"}",
   "quality": {
    "error_legibility": "vague"
   }
  },
  {
   "t": "24:37",
   "cap": "cap-12",
   "capability": "Build a dashboard with chart widgets",
   "task": "Create dashboard + metric widget (sum of Hours) via MCP; compare widget data to table",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "createDashboard mtppcjopgew19fx; createWidget metric sum Hours -> wgt9rlyzy1dbzmxxa; getWidgetData -> {\"data\": 7}; REST records Hours [5,1,1] sum 7",
   "notes": "REST dashboard API 403 on Free; MCP works.",
   "quality": {
    "verify_route": "yes",
    "docs_match": "match"
   }
  },
  {
   "t": "25:07",
   "cap": "cap-14",
   "capability": "Configure webhooks",
   "task": "Register a record-insert webhook via REST",
   "route": "api",
   "documented": true,
   "result": "plan_gated",
   "verified": true,
   "evidence": "POST /api/v3/meta/bases/{B1}/tables/{T1}/hooks -> 403 {\"error\":\"ERR_FEATURE_NOT_SUPPORTED\",\"message\":\"Upgrade to a higher plan to use webhook api.\"}; GET hooks list also 403",
   "quality": {
    "error_legibility": "vague"
   }
  },
  {
   "t": "25:21",
   "cap": "cap-14",
   "capability": "Configure webhooks",
   "task": "createHook / listHooks over MCP",
   "route": "mcp",
   "documented": true,
   "result": "plan_gated",
   "verified": true,
   "evidence": "callTool createHook -> \"Error: Upgrade to a higher plan to use webhook tools over MCP.\"; listHooks same",
   "notes": "Pricing FAQ says the Free plan includes webhooks; delivery could not be exercised anyway (no receiver of ours in the sandbox; the workflow webhook trigger node is Plus+: \"The workflow contains a node that requires the Plus plan or higher\").",
   "quality": {
    "error_legibility": "clear"
   }
  },
  {
   "t": "25:28",
   "cap": "cap-13",
   "capability": "Write and run JavaScript Scripts",
   "task": "Create a script via REST and MCP",
   "route": "api",
   "documented": true,
   "result": "plan_gated",
   "verified": true,
   "evidence": "POST /api/v3/meta/bases/{B1}/scripts with Read&write-all token -> 403 \"API token does not have permission to createScript\"; MCP createScript -> \"Upgrade to a higher plan to use script tools over MCP.\"",
   "notes": "Pricing: \"Certain APIs are Enterprise-only, including Workspace, Script, and User Management (Collaboration) APIs.\" Token scope picker has no Scripts category. Running a script is UI-only per docs.",
   "quality": {
    "error_legibility": "clear"
   }
  },
  {
   "t": "25:43",
   "cap": "cap-15",
   "capability": "Write NocoDocs",
   "task": "Create a document via REST and MCP",
   "route": "api",
   "documented": true,
   "result": "plan_gated",
   "verified": true,
   "evidence": "POST /api/v3/docs/{B1} -> 403 {\"error\":\"ERR_FEATURE_NOT_SUPPORTED\",\"message\":\"Upgrade to a higher plan to access Documents API.\"}; MCP createDocument -> same message",
   "notes": "Bad argument name gave a clear zod error (unrecognized key markdown; schema says contentMarkdown).",
   "quality": {
    "error_legibility": "vague"
   }
  },
  {
   "t": "26:41",
   "cap": "cap-16",
   "capability": "Organize items into sidebar folders",
   "task": "Create folder Planning and move Projects table into it via MCP; listFolders",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "createFolder secwaqwd5u2s2xfmi; moveTableToFolder Projects -> fk_base_section_id set; listFolders shows Planning with child table maa8g6hv1zn2sop",
   "quality": {
    "verify_route": "yes",
    "docs_match": "match"
   }
  },
  {
   "t": "26:57",
   "cap": "cap-08",
   "trial": 2,
   "capability": "Ask NocoAI to build from plain language",
   "task": "Ask NocoAI to create Vendors 2 with Name, Email, Rating",
   "route": "browser",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "NocoAI: \"Done - Vendors 2 was created\"; REST table fields [('Id', 'ID'), ('Name', 'SingleLineText'), ('Email', 'Email'), ('Rating', 'Rating')]"
  },
  {
   "t": "26:58",
   "cap": "cap-08",
   "trial": 3,
   "capability": "Ask NocoAI to build from plain language",
   "task": "Ask NocoAI to create Vendors 3 with Name, Email, Rating",
   "route": "browser",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "NocoAI: \"Done - Vendors 3 was created\"; REST table fields [('Id', 'ID'), ('Name', 'SingleLineText'), ('Email', 'Email'), ('Rating', 'Rating')]"
  },
  {
   "t": "27:14",
   "cap": "cap-17",
   "capability": "Invite collaborators and assign roles",
   "task": "Invite our second inbox as base editor (REST then MCP)",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "REST POST /bases/pwv7v3b8v82110j/members -> 403 \"Upgrade to a higher plan to use member management api.\"; MCP addBaseMembers emails=[the agent's inbox] editor -> member us742qlwk790okep; listBaseMembers shows editor; invite mail \"You've been invited to a Workspace\" from noreply@nocodb.com arrived in our inbox",
   "notes": "Invitee is inbox. addBaseMembers supports an idempotency_key.",
   "quality": {
    "verify_route": "yes",
    "docs_match": "match"
   }
  },
  {
   "t": "27:14",
   "cap": "cap-17",
   "capability": "Invite collaborators",
   "task": "REST invite",
   "route": "api",
   "documented": true,
   "result": "plan_gated",
   "verified": true,
   "evidence": "POST /api/v3/meta/bases/{base}/members -> 403 {\"error\":\"ERR_FEATURE_NOT_SUPPORTED\",\"message\":\"Upgrade to a higher plan to use member management api.\"}"
  },
  {
   "t": "27:37",
   "cap": "cap-28",
   "capability": "View audit logs",
   "task": "Read record history and base audit log via MCP",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "listRecordAudits Tasks row 1 -> entries incl. op_type DATA_LINK by the agent's inbox with details (Tasks->Projects link we made)",
   "notes": "Record-level history works on Free; base/workspace audit log gated (next line).",
   "quality": {
    "verify_route": "yes"
   }
  },
  {
   "t": "27:37",
   "cap": "cap-28",
   "capability": "View audit logs (workspace)",
   "task": "listBaseAudits",
   "route": "mcp",
   "documented": true,
   "result": "plan_gated",
   "verified": true,
   "evidence": "callTool listBaseAudits -> \"Error: Upgrade to a higher plan to access workspace audit logs.\""
  },
  {
   "t": "27:37",
   "cap": "cap-18",
   "capability": "Record-level security policies",
   "task": "listRlsPolicies / createRlsPolicy via MCP",
   "route": "mcp",
   "documented": true,
   "result": "plan_gated",
   "verified": true,
   "evidence": "listRlsPolicies -> \"Error: Upgrade to a higher plan to use row-level security.\""
  },
  {
   "t": "29:12",
   "cap": "cap-11",
   "capability": "Build an Interface",
   "task": "Create interface Task desk with a table page (grid of Name, Hours) via MCP, publish, open it",
   "route": "mcp",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "createInterface itfbky1w5sq7o2fx2; createInterfacePage table; updateInterfacePage visualizations grid; publishInterface -> published true; interface URL in browser renders live rows Write spec A 5, WF trigger 1 1, WF trigger 2 1 (\"3 records\")",
   "notes": "First publish with an empty visualizations list rendered a blank page with no warning. buildInterfacePageConfigFromView is plan-gated (\"Upgrade to a higher plan to copy view configuration from another view\"). Share-to-web is UI-only.",
   "quality": {
    "verify_route": "yes"
   }
  },
  {
   "t": "29:12",
   "cap": "cap-19",
   "capability": "Nested teams",
   "task": "List/create teams via REST and MCP",
   "route": "mcp",
   "documented": true,
   "result": "plan_gated",
   "verified": true,
   "evidence": "GET /api/v3/meta/workspaces/[redacted]/teams -> 200 {\"list\": []}; MCP listWorkspaceTeams -> \"Error: Upgrade to a higher plan to use team management.\""
  },
  {
   "t": "31:18",
   "cap": "cap-27",
   "capability": "NocoDB Claude agent skill",
   "task": "Download nocodb-skills.zip, check SKILL.md, run its noco.sh CLI (workspace:list, base:list, record:create, record:list, view:list)",
   "route": "cli",
   "documented": true,
   "result": "partial",
   "verified": true,
   "evidence": "https://nocodb.com/nocodb-skills.zip 200 application/zip 10012 bytes: SKILL.md (frontmatter name: nocodb, description) + scripts/noco.sh (942 lines, ~70 subcommands). workspace:list -> an inbox [redacted]; base:list -> 4 bases; record:create -> id 5 \"From skill CLI\"; record:list ok; view:list -> \"jq: error (at <stdin>:0): Cannot iterate over null\" (the 403 plan-gate message is swallowed)",
   "notes": "Not run inside a Claude session (no Claude client in the sandbox); the skill CLI itself works on the free plan except plan-gated groups, where it hides the API error. SKILL.md says get the token at \"Team & Settings > API Tokens > Add New Token\" but the UI is Account > API Tokens > Create New API Token.",
   "quality": {
    "error_legibility": "silent",
    "docs_match": "drift"
   }
  },
  {
   "t": "31:18",
   "cap": "cap-25",
   "capability": "Read and write data/meta via REST API",
   "task": "Use v3 data and meta endpoints end to end (bases, tables, fields, records, links, filters, sorts)",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "See ..04, v3 meta+data calls all 200 and read back; views, dashboards, docs, hooks, members, scripts endpoints 403 on Free (plan or token-scope)",
   "quality": {
    "verify_route": "yes",
    "docs_match": "match"
   }
  },
  {
   "t": "33:07",
   "cap": "cap-20",
   "capability": "Snapshots of a base",
   "task": "Open Base Settings > Snapshots (no API or MCP tool for snapshots)",
   "route": "browser",
   "documented": true,
   "result": "plan_gated",
   "verified": true,
   "evidence": "Base Settings > Snapshots shows \"Save a restorable copy of this base at a point in time.\" with an \"Upgrade to Plus\" button; no snapshot operation in OpenAPI or MCP tools/list (202 tools)"
  },
  {
   "t": "33:07",
   "cap": "cap-21",
   "capability": "Sync data from external apps",
   "task": "not attempted",
   "route": "none",
   "documented": true,
   "result": "skipped",
   "verified": false,
   "evidence": "Needs accounts at external apps (GitHub, CRM, ...) we do not hold; Base Settings shows Sync with an info badge; map marks it paid"
  },
  {
   "t": "33:07",
   "cap": "cap-22",
   "capability": "NocoDB Sync between bases",
   "task": "not attempted",
   "route": "none",
   "documented": true,
   "result": "skipped",
   "verified": false,
   "evidence": "Map marks paid; not attempted for time"
  },
  {
   "t": "33:07",
   "cap": "cap-23",
   "capability": "Connect external PostgreSQL/MySQL",
   "task": "not attempted",
   "route": "none",
   "documented": true,
   "result": "skipped",
   "verified": false,
   "evidence": "Needs a reachable database of ours; none in the sandbox"
  },
  {
   "t": "33:07",
   "cap": "cap-24",
   "capability": "Use extensions",
   "task": "not attempted",
   "route": "none",
   "documented": true,
   "result": "skipped",
   "verified": false,
   "evidence": "UI-only, no API/MCP route; pricing FAQ says extensions are cloud/enterprise premium; not attempted for time"
  },
  {
   "t": "33:07",
   "cap": "cap-29",
   "capability": "SSO and SCIM",
   "task": "not attempted",
   "route": "none",
   "documented": true,
   "result": "skipped",
   "verified": false,
   "evidence": "Needs an identity provider of ours; pricing: SSO on Plus and above"
  },
  {
   "t": "33:07",
   "cap": "cap-30",
   "capability": "Enable 2FA",
   "task": "not attempted",
   "route": "none",
   "documented": true,
   "result": "skipped",
   "verified": false,
   "evidence": "UI-only (Account > Security); not enabled to avoid locking the headless account behind a TOTP device"
  },
  {
   "t": "33:07",
   "cap": "cap-31",
   "capability": "Self-host",
   "task": "not installed",
   "route": "none",
   "documented": true,
   "result": "skipped",
   "verified": false,
   "evidence": "No Docker in the drive sandbox (brief: do not install)"
  },
  {
   "t": "33:07",
   "cap": "cap-32",
   "capability": "White-label branding",
   "task": "not attempted",
   "route": "none",
   "documented": true,
   "result": "skipped",
   "verified": false,
   "evidence": "Self-hosted Enterprise only"
  },
  {
   "t": "38:07",
   "cap": "pay",
   "capability": "buy the product",
   "task": "Probe 402 rails, discovery files, registries; follow the in-app upgrade to the checkout (no card entered)",
   "route": "browser",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "Unauthenticated API -> 401 JSON (no 402, no PAYMENT-REQUIRED, no WWW-Authenticate Payment/L402); x402./mpp./agents.nocodb.com -> 302 to https://nocodb.com/; /.well-known/ucp 404; no x-payment-info (OpenAPI has none); not in x402 Bazaar or mpp.dev/api/services; no x402/MPP/402/Stripe Projects mentions in llms-full.txt. Billing page (workspace settings) -> Upgrade Workspace -> pricing iframe (nocodb.com, invisible reCAPTCHA) -> Choose Plus -> app.nocodb.com/<ws>/checkout/<id> with embedded Stripe Checkout: \"Subscribe to Plus EUR 266.11 per year\", Link or card, frames include Stripe invisible hCaptcha and HUMAN Security. No trial offered at checkout; stopped before entering anything.",
   "notes": "Free plan needs no card. No billing API/CLI/MCP tool. Pricing FAQ mentions a \"free trial\" but none was offered in the checkout."
  },
  {
   "t": "38:07",
   "cap": "cancel",
   "capability": "cancel plan",
   "task": "Find how to cancel/downgrade",
   "route": "none",
   "documented": true,
   "result": "skipped",
   "verified": false,
   "evidence": "No plan was started. Pricing FAQ: \"you can upgrade, downgrade, or cancel your plan at any time from your account settings\" (web UI). No billing API or MCP tool found."
  },
  {
   "t": "54:53",
   "cap": "cleanup",
   "capability": "delete created data",
   "task": "DELETE every base in the workspace via REST, list again",
   "route": "api",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "DELETE /api/v3/meta/bases/{id} for 7 bases -> 200; GET bases -> {\"list\": []}"
  },
  {
   "t": "55:57",
   "cap": "delete",
   "capability": "delete account and data",
   "task": "Delete the account (Account > Profile > Danger Zone > Delete Account, type email)",
   "route": "browser",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "Dialog listed workspace an inbox, all bases (including ones already deleted via API, still in trash) and both API tokens; after confirming -> redirected to /signin; API token now 401 \"Invalid token\"; MCP endpoint 404 \"MCPToken ... not found\"",
   "notes": "No API, CLI or MCP route to delete the account (MCP cannot remove you from a workspace, documented). Bases deleted over REST stayed listed for deletion: REST delete is a soft delete into trash.",
   "quality": {
    "verify_route": "yes"
   }
  },
  {
   "t": "55:57",
   "cap": "discovery",
   "capability": "bot checks",
   "task": "Record bot checks met",
   "route": "browser",
   "documented": true,
   "result": "done",
   "verified": true,
   "evidence": "Sign-up, verify, login: no CAPTCHA signals (pw: turnstile/hcaptcha/recaptcha false). Pricing iframe (nocodb.com) loads invisible reCAPTCHA (anchor size=invisible); embedded Stripe Checkout loads invisible hCaptcha and HUMAN Security frames. No visible challenge appeared; nothing was submitted at checkout."
  }
 ],
 "stale": false,
 "icon": "/logos/nocodb.png",
 "monitored": false,
 "verdict": "L4 · Runs on its own: our agent signed up and confirmed through a browser form and an emailed code, then worked headless from a token. No checkpoint stopped it: tokens and MCP keys needed a settings page, not an API, and some REST groups stayed plan-gated or unreachable with any token. Through the official MCP server and the REST API it created bases, tables, fields, records, views, sharing, CSV import, workflows, interfaces and dashboards, and NocoAI built a table from one sentence in the web app. Upgrading opens an embedded Stripe checkout with an invisible hCaptcha and HUMAN Security our agent never tried; it deleted its account cleanly from Account settings, and its token and MCP key stopped working right after.",
 "page": "https://agentdrives.com/tools/nocodb?via=api"
}