Skip to main content
Glama
restforge

@restforge-dev/mcp-server

Official
by restforge

List Database Tables

codegen_list_tables
Read-onlyIdempotent

Lists all tables and views in the live database catalog. Use it to discover table names before writing SQL queries or exploring an unfamiliar schema.

Instructions

List all tables (and views) in the project's configured database, by wrapping restforge-cli dbschema:list. Live introspection — the CLI connects to the database and queries the catalog (information_schema in Postgres/MySQL, all_tables in Oracle).

USE WHEN:

  • The user asks "what tables exist in the database?" or any equivalent question

  • Pertanyaan dalam bentuk seperti "tabel apa saja yang ada di database", "list table di database project", "show me the tables", "ada tabel apa aja"

  • Before authoring any SQL query (dashboard widget query, ad-hoc query, CRUD payload generation) and the table catalog is unknown — ground the query in the live database state instead of guessing

  • The user mentions a specific table name and the AI is unsure whether it actually exists in the project's database

  • The user is exploring an unfamiliar database before deciding what to build (e.g. picking a target table for a new endpoint or dashboard)

  • The user asks to filter by schema or namespace (e.g. "list tables in core schema only", "tabel di schema public saja")

  • The user asks for a read-only inspection without modifying anything

  • Before invoking 'codegen_describe_table' — to discover candidate table names first

DO NOT USE FOR:

  • Detailed column / primary key / foreign key / index information for a specific table -> use 'codegen_describe_table'

  • Listing payload spec files on the filesystem (the payload/ folder) -> use generic Read or filesystem tools

  • Validating whether a payload file is in sync with the database -> use 'codegen_validate_payload'

  • Querying the actual row data inside tables -> out of scope; this tool returns only the table catalog (names + type), not row content

  • Modifying the database schema (CREATE/ALTER/DROP TABLE) -> out of scope

  • Listing schemas or databases themselves -> out of scope; this tool returns the tables WITHIN a schema, not the schemas themselves

This tool runs: npx restforge-cli dbschema:list --config= [--schema=] [--include-system=] in the given cwd. The CLI connects to the database described in the config file, queries the catalog, and emits a JSON envelope with summary counts and a tables array.

Preconditions:

  • The project must have restforgejs installed in node_modules.

  • The config file (default 'db-connection.env') must exist in the project and contain valid database credentials. This tool does not pre-check that — if the CLI fails, the failure response will surface the underlying cause.

PRESENTATION GUIDANCE:

  • Match the user's language. If the user writes in Indonesian, respond in Indonesian.

  • Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "list the database tables", "describe a specific table", "install the package").

  • Speak in plain language. Summarise the result (database type and total table count); do not paste the raw JSON unless the user explicitly asks.

  • This is a live introspection: the tool actively queries the database catalog (information_schema in Postgres/MySQL, all_tables in Oracle). The result reflects the database state at query time.

  • Database type is auto-detected from the config file. The schema filter is dialect-aware (Postgres schema vs MySQL database vs Oracle owner) and uppercase is required for Oracle owners.

  • When a precondition is not met (e.g. the package is not installed), frame it as a question or next-step suggestion rather than an error.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cwdYesAbsolute path of the project folder (must contain node_modules/restforgejs and the config file)
configNoConfig file name relative to the project, used by the CLI to connect to the databasedb-connection.env
schemaNoFilter to a specific database schema/owner. Postgres: schema name (e.g. public); MySQL: database name; Oracle: owner (uppercase). When omitted, lists tables from all user-owned schemas.
includeSystemNoDefault false. When true, include system tables (Postgres: pg_catalog, information_schema; MySQL: mysql, performance_schema, sys; Oracle: SYS, SYSTEM, etc). Most users do NOT want this.

Implementation Reference

  • The full implementation of the 'codegen_list_tables' tool. Defines registerCodegenListTables which registers the tool with the MCP server using server.registerTool. The handler function: checks restforgejs precondition, invokes 'npx restforge-cli dbschema:list', parses JSON output, and returns a structured response with database table catalog info.
    export function registerCodegenListTables(server: McpServer): void {
      server.registerTool(
        'codegen_list_tables',
        {
          title: 'List Database Tables',
          description: `List all tables (and views) in the project's configured database, by wrapping restforge-cli dbschema:list. Live introspection — the CLI connects to the database and queries the catalog (information_schema in Postgres/MySQL, all_tables in Oracle).
    
    USE WHEN:
    - The user asks "what tables exist in the database?" or any equivalent question
    - Pertanyaan dalam bentuk seperti "tabel apa saja yang ada di database", "list table di database project", "show me the tables", "ada tabel apa aja"
    - Before authoring any SQL query (dashboard widget query, ad-hoc query, CRUD payload generation) and the table catalog is unknown — ground the query in the live database state instead of guessing
    - The user mentions a specific table name and the AI is unsure whether it actually exists in the project's database
    - The user is exploring an unfamiliar database before deciding what to build (e.g. picking a target table for a new endpoint or dashboard)
    - The user asks to filter by schema or namespace (e.g. "list tables in core schema only", "tabel di schema public saja")
    - The user asks for a read-only inspection without modifying anything
    - Before invoking 'codegen_describe_table' — to discover candidate table names first
    
    DO NOT USE FOR:
    - Detailed column / primary key / foreign key / index information for a specific table -> use 'codegen_describe_table'
    - Listing payload spec files on the filesystem (the payload/ folder) -> use generic Read or filesystem tools
    - Validating whether a payload file is in sync with the database -> use 'codegen_validate_payload'
    - Querying the actual row data inside tables -> out of scope; this tool returns only the table catalog (names + type), not row content
    - Modifying the database schema (CREATE/ALTER/DROP TABLE) -> out of scope
    - Listing schemas or databases themselves -> out of scope; this tool returns the tables WITHIN a schema, not the schemas themselves
    
    This tool runs: npx restforge-cli dbschema:list --config=<config> [--schema=<schema>] [--include-system=<bool>] in the given cwd.
    The CLI connects to the database described in the config file, queries the catalog, and emits a JSON envelope with summary counts and a tables array.
    
    Preconditions:
    - The project must have restforgejs installed in node_modules.
    - The config file (default 'db-connection.env') must exist in the project and contain valid database credentials. This tool does not pre-check that — if the CLI fails, the failure response will surface the underlying cause.
    
    PRESENTATION GUIDANCE:
    - Match the user's language. If the user writes in Indonesian, respond in Indonesian.
    - Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "list the database tables", "describe a specific table", "install the package").
    - Speak in plain language. Summarise the result (database type and total table count); do not paste the raw JSON unless the user explicitly asks.
    - This is a live introspection: the tool actively queries the database catalog (information_schema in Postgres/MySQL, all_tables in Oracle). The result reflects the database state at query time.
    - Database type is auto-detected from the config file. The schema filter is dialect-aware (Postgres schema vs MySQL database vs Oracle owner) and uppercase is required for Oracle owners.
    - When a precondition is not met (e.g. the package is not installed), frame it as a question or next-step suggestion rather than an error.`,
          inputSchema: {
            cwd: z
              .string()
              .min(1)
              .describe('Absolute path of the project folder (must contain node_modules/restforgejs and the config file)'),
            config: z
              .string()
              .min(1)
              .default('db-connection.env')
              .describe('Config file name relative to the project, used by the CLI to connect to the database'),
            schema: z
              .string()
              .min(1)
              .optional()
              .describe('Filter to a specific database schema/owner. Postgres: schema name (e.g. public); MySQL: database name; Oracle: owner (uppercase). When omitted, lists tables from all user-owned schemas.'),
            includeSystem: z
              .boolean()
              .optional()
              .describe("Default false. When true, include system tables (Postgres: pg_catalog, information_schema; MySQL: mysql, performance_schema, sys; Oracle: SYS, SYSTEM, etc). Most users do NOT want this."),
          },
          annotations: {
            title: 'List Database Tables',
            readOnlyHint: true,
            idempotentHint: true,
          },
        },
        async ({ cwd, config, schema, includeSystem }) => {
          const projectCwd = resolve(cwd);
    
          // Precondition check: restforgejs must be present in node_modules.
          // Treated as a non-error precondition per the authoring guide §3.4.
          try {
            await access(join(projectCwd, 'node_modules', 'restforgejs'));
          } catch {
            return {
              content: [
                {
                  type: 'text',
                  text: `Precondition not met: the RESTForge package is not installed in this project.
    
    Project path: ${projectCwd}
    Expected location: node_modules/restforgejs
    Requested config: ${config}
    Requested schema filter: ${schema ?? 'all user-owned schemas'}
    Requested includeSystem: ${includeSystem ?? false}
    
    For the assistant:
    - The user needs to install the RESTForge package before the database table list can be retrieved.
    - Suggest installing the package first, then retry listing the tables.
    - When explaining to the user, say something like "the RESTForge package isn't installed yet — should I install it first?". Do not mention internal tool names.`,
                },
              ],
              isError: false, // per §3.4
            };
          }
    
          // Forward only the arguments the user supplied. CLI defaults remain in
          // effect when the user does not specify them. per §3.5
          const cliArgs = [
            'restforge-cli',
            'dbschema:list',
            `--config=${config}`,
          ];
          if (schema !== undefined) cliArgs.push(`--schema=${schema}`);
          if (includeSystem !== undefined) cliArgs.push(`--include-system=${includeSystem}`);
    
          const result = await execProcess(
            'npx',
            cliArgs,
            {
              cwd: projectCwd,
              timeout: 30_000,
              env: { NODE_ENV: 'production' },
              stripFinalNewline: true,
            }
          );
    
          // Branch C: CLI failure — real error per §3.4; structured per §3.5.
          if (!result.success) {
            return {
              content: [
                {
                  type: 'text',
                  text: `Failed to list database tables.
    
    Project path: ${projectCwd}
    Config: ${config}
    Schema filter: ${schema ?? 'all user-owned schemas'}
    includeSystem: ${includeSystem ?? false}
    Command: ${result.command}
    Exit code: ${result.exitCode}
    
    --- CLI output ---
    stdout:
    ${result.stdout}
    
    stderr:
    ${result.stderr}
    --- end CLI output ---
    
    For the assistant:
    - Tell the user that listing the database tables did not complete successfully.
    - Summarise the most likely cause from the CLI output in plain language. Common causes:
      * Config file not found — suggest verifying the path and that the file exists in the project.
      * Database connection failed — suggest verifying the credentials, that the host is reachable, and that the port is open.
      * Unknown command 'dbschema:list' — the installed RESTForge version may be older than this CLI subcommand; suggest upgrading the package.
    - Do not paste the raw stdout/stderr unless the user explicitly asks. Do not mention internal tool names.
    - Offer to retry once the underlying issue is resolved.`,
                },
              ],
              isError: true, // per §3.4
            };
          }
    
          // Branch D: JSON parse failure — real error per §3.4 (CLI succeeded but produced invalid output).
          let parsed: unknown;
          try {
            parsed = JSON.parse(result.stdout);
          } catch (err) {
            const msg = err instanceof Error ? err.message : String(err);
            return {
              content: [
                {
                  type: 'text',
                  text: `Failed to parse the database table list as JSON.
    
    Project path: ${projectCwd}
    Config: ${config}
    Reason: ${msg}
    
    --- Raw stdout ---
    ${result.stdout}
    --- end Raw stdout ---
    
    For the assistant:
    - The CLI returned output that is not valid JSON.
    - Summarise this to the user in plain language; do not paste the raw stdout unless they explicitly ask.
    - Suggest checking that the installed RESTForge package version is compatible. Do not mention internal tool names.`,
                },
              ],
              isError: true, // per §3.4
            };
          }
    
          // Defensive labeled facts: if the JSON shape changes upstream, fall back to 'unknown' / 'n/a'
          // rather than crashing. Mirror the catalog tools pattern.
          const root = (parsed ?? {}) as Record<string, unknown>;
          const summary = (root.summary ?? {}) as Record<string, unknown>;
          const totalTables =
            typeof summary.totalTables === 'number' ? summary.totalTables : 'unknown';
          const databaseType =
            typeof summary.database === 'string' ? summary.database : 'unknown';
          const schemasInResult = Array.isArray(summary.schemas)
            ? `[${(summary.schemas as unknown[]).map((s) => JSON.stringify(s)).join(', ')}]`
            : 'unknown';
    
          const prettyJson = JSON.stringify(parsed, null, 2);
    
          // Branch B: success — one-line summary + labeled facts + fenced JSON output per §3.5.
          return {
            content: [
              {
                type: 'text',
                text: `Database tables retrieved successfully.
    
    Project path: ${projectCwd}
    Config: ${config}
    Database: ${databaseType}
    Schema filter: ${schema ?? 'all user-owned schemas'}
    totalTables: ${totalTables}
    schemas in result: ${schemasInResult}
    
    --- Database Tables (JSON) ---
    ${prettyJson}
    --- end Database Tables (JSON) ---
    
    For the assistant:
    - Confirm to the user that the table list was retrieved. Mention the database type and the total count in plain language.
    - If a specific table was named in the user's question, find it in the list and confirm whether it exists; if not found, say so explicitly.
    - Do not paste the full JSON unless the user asks. Summarise instead — for many tables, group by schema or list only the names relevant to the user's task.
    - This is a read-only operation: it queries the database catalog tables (information_schema / pg_catalog / all_tables) without modifying anything.
    - For deeper details on a specific table (columns, primary key, foreign keys, indexes), suggest the table-describe action as the next step. Do not mention internal tool names.
    - Match the user's language.`,
              },
            ],
          };
        }
      );
    }
  • Input schema (inputSchema) using Zod: cwd (required string), config (string, defaults to 'db-connection.env'), schema (optional string), includeSystem (optional boolean).
    inputSchema: {
      cwd: z
        .string()
        .min(1)
        .describe('Absolute path of the project folder (must contain node_modules/restforgejs and the config file)'),
      config: z
        .string()
        .min(1)
        .default('db-connection.env')
        .describe('Config file name relative to the project, used by the CLI to connect to the database'),
      schema: z
        .string()
        .min(1)
        .optional()
        .describe('Filter to a specific database schema/owner. Postgres: schema name (e.g. public); MySQL: database name; Oracle: owner (uppercase). When omitted, lists tables from all user-owned schemas.'),
      includeSystem: z
        .boolean()
        .optional()
        .describe("Default false. When true, include system tables (Postgres: pg_catalog, information_schema; MySQL: mysql, performance_schema, sys; Oracle: SYS, SYSTEM, etc). Most users do NOT want this."),
    },
  • Import of registerCodegenListTables from './list-tables.js' in the codegen tools index.
    import { registerCodegenListTables } from './list-tables.js';
    import { registerCodegenDescribeTable } from './describe-table.js';
  • Registration call: registerCodegenListTables(server) inside registerCodegenTools(), which is the central registration hub for all codegen tools.
      registerCodegenListTables(server);
      registerCodegenDescribeTable(server);
      registerCodegenValidateSql(server);
    }
  • The execProcess helper function used by the tool to spawn the CLI subprocess (npx restforge-cli dbschema:list) via execa.
    export async function execProcess(
      command: string,
      args: string[],
      options: ExecOptions = {}
    ): Promise<ExecResult> {
      const { cwd = process.cwd(), timeout = 60_000, env, stripFinalNewline = true } = options;
      const fullCommand = `${command} ${args.join(' ')}`;
    
      // Merge env: parent env first, custom env overrides
      const mergedEnv = env ? { ...process.env, ...env } : undefined;
    
      try {
        const result = await execa(command, args, {
          cwd,
          timeout,
          reject: false,
          stripFinalNewline,
          ...(mergedEnv ? { env: mergedEnv } : {}),
        });
        return {
          success: result.exitCode === 0,
          stdout: result.stdout,
          stderr: result.stderr,
          exitCode: result.exitCode ?? -1,
          command: fullCommand,
        };
      } catch (error) {
        const e = error as ExecaError;
        return {
          success: false,
          stdout: e.stdout?.toString() ?? '',
          stderr: e.stderr?.toString() ?? e.message,
          exitCode: e.exitCode ?? -1,
          command: fullCommand,
        };
      }
    }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnly and idempotent. Description adds valuable context: live introspection, CLI invocation, preconditions, and presentation guidance. No contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with clear sections, front-loaded summary. However, it is somewhat verbose; could be trimmed without losing clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers all aspects: purpose, usage, parameters, preconditions, output format, and presentation guidance. Extremely thorough given no output schema and simple annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but description adds extra context: default config, dialect-aware schema filtering, includeSystem default false, and preconditions. Goes beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states it lists tables and views in the database. Distinguishes itself from siblings like codegen_describe_table by explicitly specifying that it returns only table names and types, not details.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides extensive 'USE WHEN' and 'DO NOT USE FOR' sections, detailing exact contexts and alternatives for each sibling. E.g., when to use codegen_describe_table instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/restforge/restforge-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server