> Source: https://wexa.ai/docs/data-tables/list-tables

# list-tables

List the Data Tables in this project. Each `table_id` is accepted unchanged by `get-table`, `query-table-rows` and the row and column tools. Needs the `fabric:table.read` grant.

**List tables**

**Wexa MCP server**

```bash
curl -sS -X POST https://fabric.wexa.ai/mcp/$FABRIC_PROJECT_ID \
  -H "authorization: Bearer $FABRIC_API_KEY" \
  -H "Mcp-Session-Id: $MCP_SESSION_ID" \
  -H "content-type: application/json" -H "accept: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"list-tables","arguments":{"limit":5}}}'
```

```json
{
  "content": [
    {
      "type": "text",
      "text": "{\"lifecycle_id\":\"qlc_000194\",\"result\":{\"limit\":5,\"tables\":[{\"table_id\":\"6ab1944e7566f41b5c28e2eb\",\"table_name\":\"docs_fixture_orders\"}]}}"
    }
  ],
  "isError": false
}
```

**REST API**

```bash
curl -sS https://fabric.wexa.ai/v1/list-tables \
  -H "authorization: Bearer $FABRIC_API_KEY" \
  -H "content-type: application/json" \
  -d '{"limit":5}'
```

```json
{
  "lifecycle_id": "qlc_000194",
  "result": {
    "limit": 5,
    "tables": [
      {
        "table_id": "6ab1944e7566f41b5c28e2eb",
        "table_name": "docs_fixture_orders"
      }
    ]
  }
}
```

**TypeScript SDK**

```ts
import { Fabric } from '@wexa-fabric/sdk'

const fabric = new Fabric()
const result = await fabric.listTables({
  limit: 5
})
```

```ts
// result is the payload itself, with no `.result` to read
{
  limit: 5,
  tables: [
    {
      table_id: '6ab1944e7566f41b5c28e2eb',
      table_name: 'docs_fixture_orders'
    }
  ]
}
```

**Python SDK**

```python
from wexa import Fabric

fabric = Fabric()
out = fabric.list_tables(limit=5)
```

```python
# out is the result, already unwrapped
{
    "limit": 5,
    "tables": [
        {
            "table_id": "6ab1944e7566f41b5c28e2eb",
            "table_name": "docs_fixture_orders"
        }
    ]
}
```

## Parameters

| Parameter | Type | Required | Notes |
| --- | --- | --- | --- |
| `limit` | integer | Optional | Tables per page. Default 50. A full page returns `next_after_id`. |
| `after_id` | string | Optional | The `next_after_id` of the previous page. It must be a `table_id` from a previous page; any other string is refused (a literal placeholder never gets through). |

**Show full response**

A real response, captured from a live call to `list-tables`:

**Result of list-tables**

**REST API**

```json
{
  "lifecycle_id": "qlc_000194",
  "result": {
    "limit": 5,
    "tables": [
      {
        "table_id": "6ab1944e7566f41b5c28e2eb",
        "table_name": "docs_fixture_orders"
      }
    ]
  }
}
```

**TypeScript SDK**

```ts
// the object you get back IS the result — there is no `.result` to read
{
  limit: 5,
  tables: [
    {
      table_id: '6ab1944e7566f41b5c28e2eb',
      table_name: 'docs_fixture_orders'
    }
  ]
}

// The TS SDK names these camelCase — lifecycleId, traceId — where Python uses
// lifecycle_id and trace_id. Both are non-enumerable: readable, but omitted by
// Object.keys() and JSON.stringify(). `result.lifecycleId` here is undefined.
result.lifecycleId // 'qlc_000194'
```

**Python SDK**

```python
# a dict subclass; `result` is already unwrapped
{
 "limit": 5,
 "tables": [
  {
   "table_id": "6ab1944e7566f41b5c28e2eb",
   "table_name": "docs_fixture_orders"
  }
 ]
}

out.lifecycle_id  # 'qlc_000194' — an attribute, not a key
```

**More details**

Every argument is optional: `list-tables` answers a bare call. It is cursor-paged. A page shorter than `limit` is the last, and carries no `next_after_id`.

```python
from wexa import Fabric

fabric = Fabric()
page = fabric.list_tables(limit=50)
while page.get("next_after_id"):
    page = fabric.list_tables(after_id=page["next_after_id"], limit=50)
```

Not marked consequential: it is audited lightly and the project's write gate never holds it.

Every tool call works the same way: [How every tool call works](/docs/sdks-and-apis/how-every-tool-call-works).
