Skip to main content
Glama
restforge

@restforge-dev/mcp-server

Official
by restforge

Detect RESTForge Config Files

runtime_detect_config
Read-onlyIdempotent

Scan the config/ folder for .env files and identify available configuration files to use with RESTForge runtime. Helps confirm which config to pass when generating launch scripts.

Instructions

Detect RESTForge configuration files by scanning the 'config/' folder for .env files. Each .env file is a candidate config to pass via --config= when invoking the RESTForge runtime.

USE WHEN:

  • The user asks "which config files are available?", "config apa saja yang ada", "list .env"

  • Before generating a launcher script — to confirm which config file to pass

  • Before invoking 'runtime_generate_launcher' — to know if a config exists at all

  • The user mentions running the server but the config file is unknown or ambiguous

DO NOT USE FOR:

  • Listing project names -> use 'runtime_detect_project'

  • Reading content of a specific .env file -> use 'setup_read_env'

  • Validating connection credentials in a config -> use 'setup_validate_config' or 'runtime_validate_preflight'

Preconditions:

  • The 'config/' folder must exist at /config/. If missing, the precondition response will say so.

PRESENTATION GUIDANCE:

  • Match the user's language.

  • Never mention internal tool names.

  • When exactly one config file is found, proceed without asking. When multiple are found, ask the user which environment they want.

  • The filename is what gets passed as --config=; the runtime will resolve it relative to the config/ folder automatically.

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

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cwdYesAbsolute path of the project folder root (must contain config/)

Implementation Reference

  • The async handler function for 'runtime_detect_config' that reads the config/ directory, filters .env files, and returns the list of detected config files.
        async ({ cwd }) => {
          const projectCwd = resolve(cwd);
          const configDir = join(projectCwd, 'config');
    
          let entries: string[];
          try {
            entries = await readdir(configDir);
          } catch {
            return {
              content: [
                {
                  type: 'text',
                  text: `Precondition not met: the config folder does not exist.
    
    Project path: ${projectCwd}
    Expected folder: ${configDir}
    
    For the assistant:
    - No config/ folder was found in this project.
    - Before launching the runtime, the user needs at least one .env config file in 'config/'.
    - Suggest setting up the initial config first (e.g. via the setup tools).
    - Match the user's language. Do not mention internal tool names.`,
                },
              ],
              isError: false,
            };
          }
    
          const configs = entries.filter((name) => name.endsWith('.env'));
          const envelope = {
            cwd: projectCwd,
            config_dir: configDir,
            configs,
            count: configs.length,
          };
          const prettyJson = JSON.stringify(envelope, null, 2);
    
          if (configs.length === 0) {
            return {
              content: [
                {
                  type: 'text',
                  text: `No .env config files were found in config/.
    
    Project path: ${projectCwd}
    Config folder: ${configDir}
    Count: 0
    
    --- Detection Result (JSON) ---
    ${prettyJson}
    --- end Detection Result (JSON) ---
    
    For the assistant:
    - The config/ folder exists but contains no .env files.
    - The user needs to create one before launching the runtime (e.g. db-connection.env).
    - Suggest setting up the initial config.
    - Match the user's language. Do not mention internal tool names.`,
                },
              ],
              isError: false,
            };
          }
    
          const isSingle = configs.length === 1;
          const summary = isSingle
            ? `One config file detected: '${configs[0]}'.`
            : `${configs.length} config files detected: ${configs.map((c) => `'${c}'`).join(', ')}.`;
    
          return {
            content: [
              {
                type: 'text',
                text: `${summary}
    
    Project path: ${projectCwd}
    Config folder: ${configDir}
    Count: ${configs.length}
    
    --- Detection Result (JSON) ---
    ${prettyJson}
    --- end Detection Result (JSON) ---
    
    For the assistant:
    - ${
                  isSingle
                    ? `Only one config file is present, so it can be used without asking.`
                    : `Multiple config files are present. Ask the user which environment to use (e.g. db-connection.env vs production.env).`
                }
    - The config filename is passed to the runtime as --config=<filename>.
    - Match the user's language. Do not mention internal tool names.`,
              },
            ],
            isError: false,
          };
        }
      );
    }
  • The registration call including inputSchema definition (cwd string) and tool metadata (title, description, annotations).
        {
          title: 'Detect RESTForge Config Files',
          description: `Detect RESTForge configuration files by scanning the 'config/' folder for .env files. Each .env file is a candidate config to pass via --config=<filename> when invoking the RESTForge runtime.
    
    USE WHEN:
    - The user asks "which config files are available?", "config apa saja yang ada", "list .env"
    - Before generating a launcher script — to confirm which config file to pass
    - Before invoking 'runtime_generate_launcher' — to know if a config exists at all
    - The user mentions running the server but the config file is unknown or ambiguous
    
    DO NOT USE FOR:
    - Listing project names -> use 'runtime_detect_project'
    - Reading content of a specific .env file -> use 'setup_read_env'
    - Validating connection credentials in a config -> use 'setup_validate_config' or 'runtime_validate_preflight'
    
    Preconditions:
    - The 'config/' folder must exist at <cwd>/config/. If missing, the precondition response will say so.
    
    PRESENTATION GUIDANCE:
    - Match the user's language.
    - Never mention internal tool names.
    - When exactly one config file is found, proceed without asking. When multiple are found, ask the user which environment they want.
    - The filename is what gets passed as --config=<filename>; the runtime will resolve it relative to the config/ folder automatically.
    - When a precondition is not met (folder missing or empty), 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 root (must contain config/)'),
          },
          annotations: {
            title: 'Detect Config Files',
            readOnlyHint: true,
            idempotentHint: true,
          },
        },
  • The export function 'registerRuntimeDetectConfig' that registers the tool with the McpServer via server.registerTool().
    export function registerRuntimeDetectConfig(server: McpServer): void {
      server.registerTool(
        'runtime_detect_config',
        {
          title: 'Detect RESTForge Config Files',
          description: `Detect RESTForge configuration files by scanning the 'config/' folder for .env files. Each .env file is a candidate config to pass via --config=<filename> when invoking the RESTForge runtime.
    
    USE WHEN:
    - The user asks "which config files are available?", "config apa saja yang ada", "list .env"
    - Before generating a launcher script — to confirm which config file to pass
    - Before invoking 'runtime_generate_launcher' — to know if a config exists at all
    - The user mentions running the server but the config file is unknown or ambiguous
    
    DO NOT USE FOR:
    - Listing project names -> use 'runtime_detect_project'
    - Reading content of a specific .env file -> use 'setup_read_env'
    - Validating connection credentials in a config -> use 'setup_validate_config' or 'runtime_validate_preflight'
    
    Preconditions:
    - The 'config/' folder must exist at <cwd>/config/. If missing, the precondition response will say so.
    
    PRESENTATION GUIDANCE:
    - Match the user's language.
    - Never mention internal tool names.
    - When exactly one config file is found, proceed without asking. When multiple are found, ask the user which environment they want.
    - The filename is what gets passed as --config=<filename>; the runtime will resolve it relative to the config/ folder automatically.
    - When a precondition is not met (folder missing or empty), 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 root (must contain config/)'),
          },
          annotations: {
            title: 'Detect Config Files',
            readOnlyHint: true,
            idempotentHint: true,
          },
        },
        async ({ cwd }) => {
          const projectCwd = resolve(cwd);
          const configDir = join(projectCwd, 'config');
    
          let entries: string[];
          try {
            entries = await readdir(configDir);
          } catch {
            return {
              content: [
                {
                  type: 'text',
                  text: `Precondition not met: the config folder does not exist.
    
    Project path: ${projectCwd}
    Expected folder: ${configDir}
    
    For the assistant:
    - No config/ folder was found in this project.
    - Before launching the runtime, the user needs at least one .env config file in 'config/'.
    - Suggest setting up the initial config first (e.g. via the setup tools).
    - Match the user's language. Do not mention internal tool names.`,
                },
              ],
              isError: false,
            };
          }
    
          const configs = entries.filter((name) => name.endsWith('.env'));
          const envelope = {
            cwd: projectCwd,
            config_dir: configDir,
            configs,
            count: configs.length,
          };
          const prettyJson = JSON.stringify(envelope, null, 2);
    
          if (configs.length === 0) {
            return {
              content: [
                {
                  type: 'text',
                  text: `No .env config files were found in config/.
    
    Project path: ${projectCwd}
    Config folder: ${configDir}
    Count: 0
    
    --- Detection Result (JSON) ---
    ${prettyJson}
    --- end Detection Result (JSON) ---
    
    For the assistant:
    - The config/ folder exists but contains no .env files.
    - The user needs to create one before launching the runtime (e.g. db-connection.env).
    - Suggest setting up the initial config.
    - Match the user's language. Do not mention internal tool names.`,
                },
              ],
              isError: false,
            };
          }
    
          const isSingle = configs.length === 1;
          const summary = isSingle
            ? `One config file detected: '${configs[0]}'.`
            : `${configs.length} config files detected: ${configs.map((c) => `'${c}'`).join(', ')}.`;
    
          return {
            content: [
              {
                type: 'text',
                text: `${summary}
    
    Project path: ${projectCwd}
    Config folder: ${configDir}
    Count: ${configs.length}
    
    --- Detection Result (JSON) ---
    ${prettyJson}
    --- end Detection Result (JSON) ---
    
    For the assistant:
    - ${
                  isSingle
                    ? `Only one config file is present, so it can be used without asking.`
                    : `Multiple config files are present. Ask the user which environment to use (e.g. db-connection.env vs production.env).`
                }
    - The config filename is passed to the runtime as --config=<filename>.
    - Match the user's language. Do not mention internal tool names.`,
              },
            ],
            isError: false,
          };
        }
      );
    }
  • The 'registerRuntimeTools' function that calls 'registerRuntimeDetectConfig(server)' to wire up the tool.
    export function registerRuntimeTools(server: McpServer): void {
      registerRuntimeDetectProject(server);
      registerRuntimeDetectConfig(server);
      registerRuntimeValidatePreflight(server);
      registerRuntimeCheckLauncherExists(server);
      registerRuntimeGenerateLauncher(server);
      registerRuntimeCheckStatus(server);
    }
  • src/server.ts:280-284 (registration)
    Top-level call to 'registerRuntimeTools(server)' in the main server setup.
      registerRuntimeTools(server);
    
      const transport = new StdioServerTransport();
      await server.connect(transport);
    }
Behavior5/5

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

Adds significant context beyond annotations: scanning behavior, presentation guidance, precondition handling, and filename usage. Annotations already indicate read-only/idempotent.

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 (USE WHEN, etc.), but slightly verbose. Every sentence adds value.

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?

No output schema, but description explains return value (list of filenames) and how to use it. Preconditions and edge cases addressed.

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 covers cwd with 100% description. Description reinforces the precondition that config/ must exist relative to cwd, adding value.

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 tool detects RESTForge config files by scanning the config/ folder for .env files. It differentiates from siblings via explicit DO NOT USE examples.

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 explicit USE WHEN conditions (e.g., user asks for available configs, before generating launcher) and DO NOT USE scenarios with alternative tool names.

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