Skip to main content
Glama
restforge

@restforge-dev/mcp-server

Official
by restforge

Validate RESTForge Config

setup_validate_config
Read-onlyIdempotent

Validate RESTForge license and database, Redis, Kafka connections from config file to confirm everything works before deployment.

Instructions

Validate the RESTForge license and connections to database, redis, and kafka based on the config file.

USE WHEN:

  • The db-connection.env file has been filled in (license + DB credentials)

  • After credentials have been written or updated, to verify they actually work

  • Before starting runtime or codegen operations

  • Verifying license and access to external services before deploy

  • Diagnosing configuration issues

  • The user asks things like "test connection", "cek license", "validate config", "apakah config sudah benar", "is the database reachable", "tes koneksi", "verify the configuration", "cek apakah license valid"

  • Before validating, consider calling 'setup_read_env' to confirm what is currently set — especially when the user describes the validation relative to a recent change (e.g. "cek apakah license barunya valid"). // per §5.3

  • The user wants to validate CONFIGURATION (license, database connection, kafka, redis), not payload files

DO NOT USE FOR:

  • Writing the config file -> use 'setup_write_env'

  • Adjusting individual fields -> use 'setup_update_env'

  • Generating module code -> use codegen_* domain tools

  • Checking if payload JSON files are still in sync with the database schema -> use 'codegen_validate_payload'

Often called as the final step after 'setup_write_env' or 'setup_update_env' has filled in or changed credentials, to confirm that they actually work. // per §5.2

This tool runs: npx restforge validate --config= in the given cwd. This tool is READ-ONLY and safe to call repeatedly.

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. "fill in the credentials", "update a single value", "set up the initial config").

  • Speak in plain language. Summarise the validation result by component (license, database, optional redis/kafka); do not paste the raw CLI output unless the user explicitly asks.

  • The CLI output may contain license fragments, host names, or user names. Do not echo license keys, passwords, or full connection URIs into chat. Confirm validation status only.

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

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cwdYesAbsolute path of the project folder
configFileNoConfig file name in the config/ folder. Default: db-connection.envdb-connection.env

Implementation Reference

  • The main handler function for the 'setup_validate_config' tool. It checks if the config file exists (precondition), then runs 'npx restforge validate --config=<configFile>' via execProcess, returning structured success/failure responses.
        async ({ cwd, configFile }) => {
          const projectCwd = resolve(cwd);
          const configPath = join(projectCwd, 'config', configFile);
    
          // Precondition check: the config file must exist before it can be validated.
          // Treated as a non-error precondition per the authoring guide §3.4.
          try {
            await access(configPath);
          } catch {
            return {
              content: [
                {
                  type: 'text',
                  text: `Precondition not met: the configuration file does not exist yet.
    
    Project path: ${projectCwd}
    Expected file: ${configPath}
    
    For the assistant:
    - The user is trying to validate a configuration that has not been created and filled in yet.
    - Suggest generating the initial RESTForge configuration first, then filling in the license and database credentials, and finally retrying the validation.
    - When explaining to the user, say something like "there's no configuration to validate yet — should I set up the initial config first?". Do not mention internal tool names.`,
                },
              ],
              isError: false, // per §3.4
            };
          }
    
          const result = await execProcess(
            'npx',
            ['restforge', 'validate', `--config=${configFile}`],
            { cwd: projectCwd, timeout: 30_000 }
          );
    
          // Validation failure: real error per §3.4; structured per §3.5.
          if (!result.success) {
            return {
              content: [
                {
                  type: 'text',
                  text: `Configuration validation did not pass.
    
    Project path: ${projectCwd}
    Config file: ${configPath}
    Command: ${result.command}
    Exit code: ${result.exitCode}
    
    --- CLI output ---
    stdout:
    ${result.stdout || '(empty)'}
    
    stderr:
    ${result.stderr || '(empty)'}
    --- end CLI output ---
    
    For the assistant:
    - Tell the user that the validation reported one or more problems.
    - Summarise the likely failing component in plain language (license, database, redis, kafka) based on the CLI output; do not paste the raw stdout/stderr unless the user explicitly asks.
    - Do not echo license keys, passwords, or full connection URIs from the output into chat.
    - Suggest reviewing or updating the relevant credentials and retrying. Do not mention internal tool names.`,
                },
              ],
              isError: true, // per §3.4
            };
          }
    
          // Success: one-line summary + labeled facts + fenced raw output per §3.5.
          return {
            content: [
              {
                type: 'text',
                text: `Configuration validation passed.
    
    Project path: ${projectCwd}
    Config file: ${configPath}
    Command: ${result.command}
    Exit code: ${result.exitCode}
    
    --- CLI output ---
    ${result.stdout || '(empty)'}
    --- end CLI output ---
    
    For the assistant:
    - Confirm to the user that the license and external connections checked out.
    - Summarise in plain language which components were checked and passed (license, database, optional redis/kafka), based on what appears in the CLI output.
    - Do not paste the raw CLI output unless the user explicitly asks. Do not echo license keys or credentials. Do not mention internal tool names.`,
              },
            ],
          };
        }
      );
    }
  • Input schema definition for the tool using Zod: requires 'cwd' (absolute project path) and optional 'configFile' (defaults to 'db-connection.env'). Annotations mark the tool as read-only and idempotent.
    inputSchema: {
      cwd: z.string().min(1).describe('Absolute path of the project folder'),
      configFile: z
        .string()
        .default('db-connection.env')
        .describe('Config file name in the config/ folder. Default: db-connection.env'),
    },
    annotations: {
      title: 'Validate Config',
      readOnlyHint: true,
      idempotentHint: true,
    },
  • The registerSetupValidateConfig function that registers the tool name 'setup_validate_config' on the McpServer with its schema and handler.
    export function registerSetupValidateConfig(server: McpServer): void {
      server.registerTool(
        'setup_validate_config',
        {
          title: 'Validate RESTForge Config',
          description: `Validate the RESTForge license and connections to database, redis, and kafka based on the config file.
    
    USE WHEN:
    - The db-connection.env file has been filled in (license + DB credentials)
    - After credentials have been written or updated, to verify they actually work
    - Before starting runtime or codegen operations
    - Verifying license and access to external services before deploy
    - Diagnosing configuration issues
    - The user asks things like "test connection", "cek license", "validate config",
      "apakah config sudah benar", "is the database reachable", "tes koneksi",
      "verify the configuration", "cek apakah license valid"
    - Before validating, consider calling 'setup_read_env' to confirm what is
      currently set — especially when the user describes the validation relative
      to a recent change (e.g. "cek apakah license barunya valid"). // per §5.3
    - The user wants to validate CONFIGURATION (license, database connection, kafka, redis), not payload files
    
    DO NOT USE FOR:
    - Writing the config file -> use 'setup_write_env'
    - Adjusting individual fields -> use 'setup_update_env'
    - Generating module code -> use codegen_* domain tools
    - Checking if payload JSON files are still in sync with the database schema -> use 'codegen_validate_payload'
    
    Often called as the final step after 'setup_write_env' or 'setup_update_env'
    has filled in or changed credentials, to confirm that they actually work. // per §5.2
    
    This tool runs: npx restforge validate --config=<configFile> in the given cwd.
    This tool is READ-ONLY and safe to call repeatedly.
    
    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. "fill in the credentials", "update a single value", "set up the initial config").
    - Speak in plain language. Summarise the validation result by component (license, database, optional redis/kafka); do not paste the raw CLI output unless the user explicitly asks.
    - The CLI output may contain license fragments, host names, or user names. Do not echo license keys, passwords, or full connection URIs into chat. Confirm validation status only.
    - When a precondition is not met (e.g. config file is missing), 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'),
            configFile: z
              .string()
              .default('db-connection.env')
              .describe('Config file name in the config/ folder. Default: db-connection.env'),
          },
          annotations: {
            title: 'Validate Config',
            readOnlyHint: true,
            idempotentHint: true,
          },
        },
        async ({ cwd, configFile }) => {
          const projectCwd = resolve(cwd);
          const configPath = join(projectCwd, 'config', configFile);
    
          // Precondition check: the config file must exist before it can be validated.
          // Treated as a non-error precondition per the authoring guide §3.4.
          try {
            await access(configPath);
          } catch {
            return {
              content: [
                {
                  type: 'text',
                  text: `Precondition not met: the configuration file does not exist yet.
    
    Project path: ${projectCwd}
    Expected file: ${configPath}
    
    For the assistant:
    - The user is trying to validate a configuration that has not been created and filled in yet.
    - Suggest generating the initial RESTForge configuration first, then filling in the license and database credentials, and finally retrying the validation.
    - When explaining to the user, say something like "there's no configuration to validate yet — should I set up the initial config first?". Do not mention internal tool names.`,
                },
              ],
              isError: false, // per §3.4
            };
          }
    
          const result = await execProcess(
            'npx',
            ['restforge', 'validate', `--config=${configFile}`],
            { cwd: projectCwd, timeout: 30_000 }
          );
    
          // Validation failure: real error per §3.4; structured per §3.5.
          if (!result.success) {
            return {
              content: [
                {
                  type: 'text',
                  text: `Configuration validation did not pass.
    
    Project path: ${projectCwd}
    Config file: ${configPath}
    Command: ${result.command}
    Exit code: ${result.exitCode}
    
    --- CLI output ---
    stdout:
    ${result.stdout || '(empty)'}
    
    stderr:
    ${result.stderr || '(empty)'}
    --- end CLI output ---
    
    For the assistant:
    - Tell the user that the validation reported one or more problems.
    - Summarise the likely failing component in plain language (license, database, redis, kafka) based on the CLI output; do not paste the raw stdout/stderr unless the user explicitly asks.
    - Do not echo license keys, passwords, or full connection URIs from the output into chat.
    - Suggest reviewing or updating the relevant credentials and retrying. Do not mention internal tool names.`,
                },
              ],
              isError: true, // per §3.4
            };
          }
    
          // Success: one-line summary + labeled facts + fenced raw output per §3.5.
          return {
            content: [
              {
                type: 'text',
                text: `Configuration validation passed.
    
    Project path: ${projectCwd}
    Config file: ${configPath}
    Command: ${result.command}
    Exit code: ${result.exitCode}
    
    --- CLI output ---
    ${result.stdout || '(empty)'}
    --- end CLI output ---
    
    For the assistant:
    - Confirm to the user that the license and external connections checked out.
    - Summarise in plain language which components were checked and passed (license, database, optional redis/kafka), based on what appears in the CLI output.
    - Do not paste the raw CLI output unless the user explicitly asks. Do not echo license keys or credentials. Do not mention internal tool names.`,
              },
            ],
          };
        }
      );
    }
  • The registerSetupTools function that calls registerSetupValidateConfig(server) to register it along with all other setup tools.
    export function registerSetupTools(server: McpServer): void {
      registerSetupCreateFolder(server);
      registerSetupInstallPackage(server);
      registerSetupInitConfig(server);
      registerSetupWriteEnv(server);
      registerSetupReadEnv(server);
      registerSetupUpdateEnv(server);
      registerSetupValidateConfig(server);
      registerSetupGetConfigSchema(server);
      registerSetupGetInitTemplate(server);
    }
  • src/server.ts:266-284 (registration)
    The startServer function in the main server entry point that calls registerSetupTools(server), which in turn registers setup_validate_config.
    export async function startServer(): Promise<void> {
      const server = new McpServer(
        {
          name: SERVER_NAME,
          version: SERVER_VERSION,
        },
        {
          instructions: SERVER_INSTRUCTIONS,
        }
      );
    
      registerHealthTools(server, SERVER_VERSION);
      registerSetupTools(server);
      registerCodegenTools(server);
      registerRuntimeTools(server);
    
      const transport = new StdioServerTransport();
      await server.connect(transport);
    }
  • The execProcess helper function used by the handler to run the 'npx restforge validate' CLI command. It wraps execa and returns a structured ExecResult.
    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 declare readOnlyHint and idempotentHint. The description adds that it runs 'npx restforge validate' and explicitly states 'read-only and safe to call repeatedly', reinforcing safety but adding moderate value beyond annotations.

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?

The description is front-loaded with main purpose and well-organized into USE WHEN, DO NOT USE, presentation guidance. While somewhat long, each section contributes essential guidance; minor redundancy could be trimmed.

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

Completeness4/5

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

For a tool with two parameters and no output schema, the description covers validation scope, preconditions, and presentation guidance. It lacks explicit output format but addresses handling of results (e.g., summarizing, no raw output). Relatively complete for its complexity.

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

Parameters3/5

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

Schema coverage is 100%, so baseline is 3. The description mentions 'cwd' and 'configFile' with the default value, consistent with schema but not adding significant new meaning. Adequate given high coverage.

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?

The description clearly states the verb 'validate' and resource 'RESTForge config' (license, database, redis, kafka). It distinguishes from sibling tools like codegen_* and setup_write_env via explicit DO NOT USE conditions, making the purpose unambiguous.

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 comprehensive USE WHEN conditions (e.g., after filling credentials, before runtime) and DO NOT USE list referencing specific alternatives. Includes multi-language examples and a suggestion to call setup_read_env first, covering when to use and when not to.

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