Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Connect AI agents to the NocoDB MCP server

Vendor MCP
Open markdown

The NocoDB MCP connector routes your AI agent's tool calls to NocoDB's own MCP server through Scalekit. Each user signs in to NocoDB once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 147 tools.

Tools
147
What they doRead · write · destructive
9 · 118 · 209 read118 write20 destructive
Users sign in with
OAuth app
Scalekit's or your own

Setup

  1. Install the SDK

    Terminal window
    npm install @scalekit-sdk/node dotenv
  2. Set your credentials

    Add your Scalekit credentials to your .env file. Find values in app.scalekit.com > Developers > API Credentials.

    .env
    SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
    SCALEKIT_CLIENT_ID=<your-client-id>
    SCALEKIT_CLIENT_SECRET=<your-client-secret>
  3. Create the NocoDB MCP connection

    In AgentKit > Connections, create a NocoDB MCP connection. The name you give it is the connection_name your code passes. See Configure connections.

    Scalekit credentials are available for NocoDB MCP server, so you don't need to register an OAuth app.

  4. Authorize a user and make your first call

    quickstart.mts
    import { ScalekitClient } from '@scalekit-sdk/node'
    import 'dotenv/config'
    import { createInterface } from 'node:readline/promises'
    const scalekit = new ScalekitClient(
    process.env.SCALEKIT_ENVIRONMENT_URL,
    process.env.SCALEKIT_CLIENT_ID,
    process.env.SCALEKIT_CLIENT_SECRET,
    )
    const actions = scalekit.actions
    const connector = 'nocodbmcp'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize NocoDB MCP:', link)
    const rl = createInterface({ input: process.stdin, output: process.stdout })
    await rl.question('Press Enter after authorizing...')
    rl.close()
    // Make your first call
    const result = await actions.executeTool({
    connector,
    identifier,
    toolName: 'nocodbmcp_getbaseinfo',
    toolInput: {},
    })
    console.log(result)
    Terminal window
    npx tsx quickstart.mts

    Each user signs in once. See Authorize a user for the full flow and statuses.

Tools

Pass the exact name to execute_tool
Try in PlaygroundRequest a tool
  • nocodbmcp_aggregatePerform aggregations (sum, count, avg, etc.) on table data with filtering and groupingRead-only

    Aggregate

    Perform aggregations (sum, count, avg, etc.) on table data with filtering and grouping

    Inputs

    aggregationsarrayrequired
    Aggregations to perform — at least one
    filterGroupsarrayrequired
    Filter groups, each producing its own result under its alias. Omit (or pass []) for one unfiltered result keyed "all"
    tableIdstringrequired
    Table ID
    viewIdstring
    Optional view ID to use view-specific configurations — the view filters, sorts and field visibility are applied. Obtain one from getTableSchema.
  • nocodbmcp_countrecordsCount Records in a TableRead-only

    CountRecords

    Count Records in a Table

    Inputs

    tableIdstringrequired
    Table ID
    filterstring
    Structured filter — the same shape as createFilter: a single condition { field, operator, value }, or a group { group_operator: "AND"|"OR", filters: [...] } whose members may themselves be groups. Field names and values are quoted for you, so commas, parentheses and quotes in either are safe. Prefer this over `where`; pass only one of the two.
    viewIdstring
    Optional view ID to use view-specific configurations — the view filters, sorts and field visibility are applied. Obtain one from getTableSchema.
    wherestring
    Filter records using NocoDB query syntax, e.g. (status,eq,active)~and(amount,gte,100). For the complete operator list, date sub-operators, quoting rules and examples, see the `where` parameter of the `queryRecords` tool — the syntax is identical.
  • nocodbmcp_createrecordsCreate records in a tableRead-only

    CreateRecords

    Create records in a table

    Inputs

    recordsarrayrequired
    Array of records with fields as key-value pairs. At most 100 per call — a longer array is rejected outright, so split larger writes into batches.
    tableIdstringrequired
    Table ID
    returnFieldsstring
    Fields to return for each record — an array of field names or ids, or a comma-separated list. Omit to get every field; pass only what you need to keep large writes readable.
  • nocodbmcp_getbaseinfoFetch information about current baseRead-only

    GetBaseInfo

    Fetch information about current base

    Inputs

    This tool takes no inputs.

  • nocodbmcp_getrecordFetch a record by IDRead-only

    GetRecord

    Fetch a record by ID

    Inputs

    recordIdstringrequired
    Record ID or primary key value
    tableIdstringrequired
    Table ID
    fieldsstring
    Fields to return — an array of field names, or a comma-separated list. Linked-record fields returned with this option omit their display values.
    viewIdstring
    Optional view ID to use view-specific configurations — the view filters, sorts and field visibility are applied. Obtain one from getTableSchema.
  • nocodbmcp_gettableschemaGet the table schema including fields and views informationRead-only

    GetTableSchema

    Get the table schema including fields and views information

    Inputs

    tableIdstringrequired
    Table Id
    includeSystemboolean
    Also return the system CreatedAt, UpdatedAt, CreatedBy and UpdatedBy fields the table has, marked `system: true` — e.g. to sort or filter an interface page by them. Default false.
  • nocodbmcp_gettableslistList tables accessible by userRead-only

    GetTablesList

    List tables accessible by user

    Inputs

    This tool takes no inputs.

  • nocodbmcp_queryrecordsQuery Records from a TableRead-only

    QueryRecords

    Query Records from a Table

    Inputs

    tableIdstringrequired
    Table ID
    fieldsstring
    Fields to return — an array of field names, or a comma-separated list. Linked-record fields returned with this option omit their display values.
    filterstring
    Structured filter — the same shape as createFilter: a single condition { field, operator, value }, or a group { group_operator: "AND"|"OR", filters: [...] } whose members may themselves be groups. Field names and values are quoted for you, so commas, parentheses and quotes in either are safe. Prefer this over `where`; pass only one of the two.
    pageinteger
    Page number for pagination (default: 1). Use `next_page` / `prev_page` from the response. A page past the end returns an empty `records` list whose `prev_page` is the last page with records (1 if there are none).
    pageSizeinteger
    Number of records to fetch (default: 50, minimum 1). Capped at 200 here, and further by the deployment limit — the response reports the `page_size` actually applied.
    sortarray
    Sort order, applied in array order, e.g. [{"field":"Amount","direction":"desc"}]
    viewIdstring
    Optional view ID to use view-specific configurations — the view filters, sorts and field visibility are applied. Obtain one from getTableSchema.
    wherestring
    Filter records using NocoDB query syntax. SYNTAX: Basic: (field,operator,value) No-value ops: (field,operator) Date with sub: (field,operator,sub_operator) or (field,operator,sub_operator,value) Multiple values: (field,operator,value1,value2,value3) OPERATORS: Text/General: eq Equal to (name,eq,John) neq Not equal to (status,neq,archived) like Contains (use % wildcard) (name,like,%john%) nlike Does not contain (name,nlike,%test%) in In list of values (status,in,active,pending,review) Numeric: gt Greater than (>) (price,gt,100) lt Less than (<) (stock,lt,10) gte Greater than or equal (>=) (rating,gte,4) lte Less than or equal (<=) (age,lte,65) Range: btw/nbtw take two bounds on Number, Decimal, Currency, Percent, Rating, Duration, Time and text fields. They are REJECTED on Date/DateTime and Checkbox; use two bounds there. Between (inclusive) (price,btw,10,100) Not between (score,nbtw,0,50) Null/Empty (no value needed): blank Is blank (null or empty) (notes,blank) notblank Is not blank (email,notblank) null Is null (deleted_at,null) notnull Is not null (created_by,notnull) empty Is empty string (description,empty) notempty Is not empty string (title,notempty) Boolean/Checkbox (no value needed): checked Is checked/true (is_active,checked) notchecked Is not checked/false (is_archived,notchecked) Multi-Select/Tags: allof Contains all of (tags,allof,urgent,important) anyof Contains any of (tags,anyof,bug,feature) nallof Does not contain all of (tags,nallof,spam,junk) nanyof Does not contain any of (categories,nanyof,draft,deleted) DATE/TIME FILTERING (for Date, DateTime, CreatedTime, LastModifiedTime fields): Date fields require a sub-operator. Syntax: (field,operator,sub_operator) or (field,operator,sub_operator,value) CRITICAL: To filter by a specific calendar date you MUST use the "exactDate" sub-operator and put the date in the value slot — NEVER place a YYYY-MM-DD date directly after the operator. CORRECT: (due_date,eq,exactDate,2026-06-01) WRONG: (due_date,eq,2026-06-01) CORRECT: (due_date,gt,exactDate,2026-06-01) WRONG: (due_date,gt,2026-06-01) A bare date with no sub-operator is read as the sub-operator and rejected ("'2026-06-01' is not supported"). isWithin - Check if date falls within a time range: Sub-operators (no value): pastWeek, pastMonth, pastYear, nextWeek, nextMonth, nextYear Sub-operators (value = days): pastNumberOfDays, nextNumberOfDays Examples: (created_at,isWithin,pastWeek) Last 7 days (created_at,isWithin,pastMonth) Last 30 days (due_date,isWithin,pastNumberOfDays,14) Last 14 days (due_date,isWithin,nextNumberOfDays,30) Next 30 days eq, neq, gt, lt, gte, lte - Date comparisons (gt=after, lt=before, gte=on or after, lte=on or before): Sub-operators (no value): today, tomorrow, yesterday, oneWeekAgo, oneWeekFromNow, oneMonthAgo, oneMonthFromNow Sub-operators (value = days): daysAgo, daysFromNow Sub-operator (value = YYYY-MM-DD): exactDate Examples: (created_at,eq,today) Created today (due_date,lt,today) Overdue (before today) (updated_at,gt,oneWeekAgo) Updated after one week ago (event_date,eq,exactDate,2024-06-15) On exact date (deadline,lt,exactDate,2024-12-31) Before Dec 31, 2024 (created_at,gte,daysAgo,7) Created within last 7 days Date ranges - btw/nbtw are NOT supported on date fields. Use two bounds: (event_date,gte,exactDate,2024-01-01)~and(event_date,lte,exactDate,2024-12-31) in - Match any of several exact dates (sub-operator required): (due_date,in,exactDate,2024-06-15,2024-07-01) Null checks for dates (no sub-operator): (due_date,blank) Date is not set (due_date,notblank) Date is set LOGICAL OPERATIONS: IMPORTANT: Use ~and, ~or, ~not (with tilde). Plain "and"/"or" will error, and so does "~AND"/"~OR" — the operators are lowercase. AND: (filter1)~and(filter2) Example: (name,eq,John)~and(age,gte,18) OR: (filter1)~or(filter2) Example: (status,eq,active)~or(status,eq,pending) NOT: ~not(filter) Example: ~not(is_deleted,checked) CRITICAL — never put whitespace after ~and/~or/~not. A space or newline before them is fine; one after them is a parse error. Write the whole clause on one line. CORRECT: (a,eq,1)~and(b,eq,2) WRONG: (a,eq,1)~and (b,eq,2) ~not only starts an expression or a group. To negate a later term, wrap it: CORRECT: (a,eq,1)~and(~not(b,checked)) WRONG: (a,eq,1)~and~not(b,checked) Nested grouping works: ((status,eq,active)~or(status,eq,pending))~and(country,eq,USA) For a single field, 'in' is shorter: (status,in,active,pending)~and(country,eq,USA) SPECIAL VALUES: NULL value: (field,eq,null) Empty string: (field,eq,'') or (field,eq,"") Value with comma: (field,eq,"hello, world") Value with quotes: (field,eq,"it's here") or (field,eq,'say "hello"') Field with spaces: (Full Name,eq,John) Quotes optional: ("Full Name",eq,John) NOTE: a field name must not carry a trailing space — (name ,eq,John) reports "field 'name ' not found". A trailing space in a VALUE is kept, so (name,eq,John ) filters on "John " and silently matches nothing. EXAMPLES: Active users this month: (status,eq,active)~and(created_at,isWithin,pastMonth) Overdue high-priority: (due_date,lt,today)~and(priority,eq,high)~and(completed,notchecked) Orders $100-$500 pending: (amount,gte,100)~and(amount,lte,500)~and(status,in,pending,processing) Updated recently, not archived: (updated_at,isWithin,pastNumberOfDays,14)~and(is_archived,notchecked) Multiple segments & countries: (Segment,in,Government,Enterprise)~and(Country,in,Germany,France)