form-mcp

tlahav/form-mcp

3.2

If you are the rightful owner of form-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

An MCP server that manages JSON Schema-driven forms with optional LLM-assisted validation, designed for agents to iteratively fill out complex forms.

Tools
8
Resources
0
Prompts
0

form-mcp

An MCP server that manages JSON Schema-driven forms with optional LLM-assisted validation, designed for agents to iteratively fill out complex forms.

Features (MVP)

  • Register JSON Schema-based forms (currently an in-memory demo form).
  • Start form sessions and track partial data per field.
  • Navigate questions (next/previous) via MCP tools.
  • Run JSON Schema validation and record per-field validity.
  • Optional LLM validation prompts per field (stubbed client in MVP).

MCP Tools

  • list_forms: list available form definitions (scanned from src/forms).
  • start_form_session: create a new session for a form (supports optional userId).
  • list_user_forms: list all active sessions for a specific user.
  • get_form_state: inspect session status, data, and field validity.
  • set_field_value: set or update a specific field value by path.
  • next_question / previous_question: move between questions.
  • validate_form: run schema and optional LLM validation.

Form Definitions

Place your JSON Schema form definitions in the src/forms directory. The server loads them on startup. Three samples are included: bug-report, customer-feedback, and event-registration.

Development

Install dependencies and build:

npm install
npm run build

Run the MCP server (stdio mode):

npm start

You can then configure your MCP-compatible client to use this server.

LLM Validation Feature Reference

This section contains the code for the optional LLM validation feature that was removed from the MVP. You can use this to re-implement the feature later.

1. Types (src/formTypes.ts)

Add these types back to support LLM validation configuration and status.

export type LlmValidationConfig = {
  prompt: string;
  model?: string;
  /**
   * Optional threshold in [0,1] that the model should treat as pass/fail
   * if the scoring output is numeric.
   */
  passThreshold?: number;
};

// Update FormFieldState
export type FormFieldState = {
  // ... existing fields ...
  /** LLM quality validity (true = passes prompt check) */
  llmValid: boolean | null;
};

// Update FormDefinition
export type FormDefinition = {
  // ... existing fields ...
  /** Map from JSON path to LLM validation config. */
  llmValidators?: Record<string, LlmValidationConfig>;
};

2. Logic (src/formEngine.ts)

Interface
export type MinimalLlmClient = {
  validateWithPrompt: (config: {
    prompt: string;
    value: unknown;
    path: string;
    model?: string;
  }) => Promise<{ valid: boolean; message?: string }>;
};
Validation Function
export async function runLlmValidation(
  session: FormSession,
  llmClient: MinimalLlmClient,
  paths?: string[],
): Promise<void> {
  const validators = session.definitionSnapshot.llmValidators ?? {};
  const targetPaths = paths ?? Object.keys(validators);

  for (const path of targetPaths) {
    const config = validators[path];
    if (!config) continue;
    const value = session.data[path];
    
    // Skip empty values or handle as needed
    if (value === undefined || value === null || value === "") continue;

    const result = await llmClient.validateWithPrompt({
      prompt: config.prompt,
      value,
      path,
      model: config.model,
    });
    
    const existing = session.fields[path] ?? {
      path,
      value,
      schemaValid: true,
      llmValid: null,
      messages: [],
      touched: !!value,
    };
    
    session.fields[path] = {
      ...existing,
      llmValid: result.valid,
      messages: result.message
        ? [...existing.messages, result.message]
        : existing.messages,
    };
  }
}

3. Example Usage (src/mcpServer.ts)

Stub Client
const llmClient: MinimalLlmClient = {
  async validateWithPrompt({ prompt, value }) {
    // Connect to real LLM here
    return {
      valid: true,
      message: `Checked against: ${prompt}`,
    };
  },
};
Form Definition
const demoForm: FormDefinition = {
  // ...
  llmValidators: {
    bio: {
      prompt: "Evaluate whether this biography is clear, concise, and professional.",
    },
  },
};