First-party app
SeaTable

SeaTable

Read and write SeaTable Cloud bases: rows, SQL, links, tables, columns, views and row comments.

stable DatabasesSpreadsheetsProductivity

About

SeaTable ships in the w6w first-party pack. It declares 23 actions, 2 health checks, and the host runs its code in a sandbox that never sees the credential.

App id
io.w6w.seatable
Version
0.1.0
Author
w6w
Licence
MIT
Categories
Databases · Spreadsheets · Productivity

Overview

SeaTable is a cloud spreadsheet-database: tables of typed columns, linked records and views, with an API for everything you can do in the grid.

This app connects to one SeaTable Cloud base with that base’s API token and lets a workflow list, fetch, append, update, delete and lock rows, run SQL against the base (SELECT, UPDATE and DELETE, with bound parameters), and read and change the structure around the data: tables, columns, views and the links between records.

It also reads and writes row comments and lists the base’s collaborators. SeaTable’s API uses a two-step credential: the long-lived API token is exchanged for a short-lived Base-Token, and this app does that exchange and the renewal for you, so a workflow only ever supplies the API token once.

Only SeaTable Cloud (cloud.seatable.io) is covered. A self-hosted SeaTable Server or Dedicated instance lives on a host of its own that a manifest cannot name in advance.

Build with SeaTable

Three routes to the same 23 actions. The Workflow tab is generated from SeaTable's own manifest and carries its real ids, so it is copy-pasteable; the Code and CLI examples are the same call for any action on any app, so every app-specific value in them is a blank you fill in.

Get Base Metadata

base-metadata-get

The structure of the connected base — every table with its columns and views, plus settings. Contains no row data. Use it to find table names, column names and the `link_id` / table `_id` values the link actions need.

List Collaborators

collaborator-list

The users who can see the base — the pool a collaborator column draws from. Each carries an `email` (an `…@auth.local` identifier), a display `name` and an avatar URL.

Delete Column

column-delete

Delete a column, by name or key, with all its data. Destructive.

Insert Column

column-insert

Add one column to a table. The vendor documents adding a single column at the end of the table. The response is the new column's definition including its `key`.

List Columns

column-list

The columns of a table (or only a view's visible ones) with their key, name, type and type-specific `data`. Link columns carry the `link_id` and linked table the link actions need.

Append Rows

row-append

Add one or more rows (up to 1,000 per call) to a table. Row objects are keyed by column NAME — internal column keys are not accepted here, and a name that matches no column is silently ignored rather than rejected, so check the result.

Create Row Comment

row-comment-create

Add a comment to a row. This endpoint takes the table's `_id` (e.g. 0000), not its name — get it from Get Base Metadata. The vendor's success answer is a plain string, so the response here is `{success: true}`.

List Row Comments

row-comment-list

All comments on one row. The answer is a bare array; each comment has an `id`.

Delete Rows

row-delete

Delete rows by ID (up to 10,000 per call), from the normal or the big-data backend. Destructive: there is no undo in this API.

Get Row

row-get

One row with all its columns, by row ID. The row object is the whole response.

Create Row Links

row-link-create

Create links between rows through a link column: the map says, for each row of the source table, which rows of the other table to link it to. Creating a link that already exists is an error, so this is not retry-safe.

Delete Row Links

row-link-delete

Delete the links named in the mapping. Other links are left untouched.

List Row Links

row-link-list

The records linked to each of the given rows through one link column. The answer is an object keyed by row ID, each holding `{row_id, display_value}` entries. Up to 10 linked records per row are returned unless a Limit is given.

Update Row Links

row-link-update

Replace links through a link column: existing links are removed and replaced with the mapping given.

List Rows

row-list

Rows of a table, or of one view of it. Without a view every column is returned, hidden ones included; with a view only that view's visible columns. Link columns return at most 50 linked records per row. Page with Start and Limit.

Lock Rows

row-lock

Lock rows so they cannot be edited. Already-locked rows may be included. An advanced feature of SeaTable's enterprise subscriptions; rows in the big-data backend cannot be locked.

Unlock Rows

row-unlock

Unlock rows that were locked. An advanced feature of the enterprise subscriptions.

Update Rows

row-update

Change values in one or more existing rows (up to 1,000 per call). Only the columns named in each `row` object change. Keyed by column NAME; an unknown name is silently ignored.

Run SQL Query

sql-query

Run a SQL statement against the base. SELECT returns up to 10,000 rows (100 unless the statement has a LIMIT); UPDATE and DELETE change rows and are not retry-safe in general. INSERT only works on bases with the big-data backend. Bind values with `?` placeholders and the Parameters list rather than building them into the statement.

Create Table

table-create

Create a table, optionally with columns. The first column can only be of type text, number, date, single-select, formula or auto-number. The response is the new table's full definition, including its `_id`.

Delete Table

table-delete

Delete a table and all its rows, identified by name. Destructive.

Rename Table

table-rename

Rename a table. Later calls must use the new name, so a workflow that renames and then reads should pass the new name on.

List Views

view-list

All views of a table with their settings: filters, sorts, groupings, hidden columns.

A workflow step names the app and the action, and the editor fills in the connection when you pick one. This is the Step shape from the workflow spec, carrying SeaTable's real ids.

{
  "manifestVersion": "2",
  "name": "seatable-example",
  "steps": [
    {
      "id": "column-insert",
      "uses": {
        "app": "io.w6w.seatable",
        "action": "column-insert",
        "connection": "conn_YOUR_CONNECTION_ID"
      },
      "with": {
        "tableName": "<tableName>",
        "columnName": "<columnName>",
        "columnType": "<columnType>"
      }
    }
  ]
}

Here are some of the things you can do

  • Insert Column

    perform
    column-insert
  • Get Base Metadata

    read
    base-metadata-get
  • List Collaborators

    read
    collaborator-list
  • List Columns

    read
    column-list
  • Append Rows

    perform
    row-append

+18 more actions available

Every app-specific value here is a blank you have to fill in. An app action is reached through the connection that authenticates it, so the address is a connection id, not the app id — and connections belong to your account, so a public page cannot know yours. Create one for SeaTable, then fill in the three blanks: conn_YOUR_CONNECTION_ID, the action key, and the parameters that action declares. The call itself is real — the shape is transcribed from the studio's own snippet builder, which prints the same kind of blanks — but nothing in it is specific to SeaTable. The Workflow tab is where this app's real ids are.

Install
npm install @w6w/sdk
yarn add @w6w/sdk
pnpm add @w6w/sdk
deno add npm:@w6w/sdk
Code
import { W6wClient, isActionRun } from "@w6w/sdk";

// Reads W6W_BASE_URL and W6W_TOKEN from the environment when omitted.
const client = new W6wClient();

const envelope = await client.run({
  urn: "conn_YOUR_CONNECTION_ID",
  action: "column-insert",
  payload: {
    tableName: "<value>",
    columnName: "<value>",
    columnType: "<value>",
    // anchorColumn: "<value>",
    // columnData: "<value>",
  },
});

if (isActionRun(envelope)) console.log(envelope.value);
Install the CLI
npm install -g @w6w/cli
CLI
w6w run conn_YOUR_CONNECTION_ID --action column-insert --payload '{"tableName":"<value>","columnName":"<value>","columnType":"<value>"}'

Give an AI agent SeaTable — without giving it SeaTable's credentials. One MCP endpoint exposes every app, function and workflow the caller is entitled to, as tools it can discover and run. Access is granted per team while we onboard.

One tool call
{
  "name": "w6w_invoke",
  "arguments": {
    "ref": "app:io.w6w.seatable#column-insert",
    "input": {
      "tableName": "<tableName>",
      "columnName": "<columnName>",
      "columnType": "<columnType>"
    }
  }
}

Every tool names its target with a single ref. The app: form above doesn't name a connection at all — the host resolves which of the caller's SeaTable connections to sign with, and refuses rather than guesses when the answer is ambiguous.

What the agent gets

Credentials it can't read

The token is attached host-side, at the moment of the call. It is never a tool argument, never in the model's context, and never in a transcript — so a prompt injection has nothing to exfiltrate.

A tool surface scoped to the caller

Tools are derived per end user from what that person has actually connected and is entitled to — not one shared bot identity carrying the union of everyone's access.

A durable workflow in one call

Multi-step work runs on the workflow engine and returns a run handle the agent can poll — retries, branching and state survive the conversation that started them.

Health-aware discovery

SeaTable's declared health checks are on the surface too, so an agent can tell "the vendor is down" from "your credential expired" before it burns a retry on either.

The MCP surface is part of the hosted platform. SeaTable itself is MIT, and the runtime that executes it is source-available (FSL).

Request MCP access

Health checks

SeaTable declares its own checks, so its health is a property of the app rather than something the host guesses at.

service

SeaTable Cloud base API status

Latest probe of the `Cloud API (Base Operations)` component on status.seatable.com — the /api-gateway surface this app calls.

quota

API request headroom