Skip to main content
Glama

Google Forms MCP

Give an existing AI assistant the ability to create, refine, publish, and update native Google Forms. The assistant handles natural language; this server maintains versioned drafts, applies explicit patches, enforces confirmation, and performs deterministic Forms API calls.

What works

  • Native Google Form creation in the authenticated user's account

  • Multi-section forms

  • Short text, paragraph, multiple choice, checkboxes, dropdown, linear scale, date, and time questions

  • Required questions and descriptions

  • Persistent SQLite drafts with version numbers and undo

  • Targeted patches that preserve unrelated questions and settings

  • Direct targeted updates to existing native Google Forms

  • Preview-before-publish and confirmation safety boundaries

  • Minimal OAuth scope: forms.body

  • MCP 2.x stdio transport

  • Authenticated Streamable HTTP transport for Claude and ChatGPT connectors

  • Companion skill in skill/google-forms/SKILL.md

Related MCP server: formslist-mcp

Current MVP limits

Version 0.4 does not yet configure conditional branching, create quizzes, upload files, change themes, or read responses. Google may create an empty form if the follow-up item population request fails; the tool records that partial form and blocks duplicate retries rather than pretending creation succeeded.

Install

uv sync --extra dev

The MCP executable is then available at:

<project>/.venv/bin/google-forms-mcp

Google OAuth setup

  1. Create or select a project in Google Cloud Console.

  2. Enable the Google Forms API.

  3. Configure the OAuth consent screen.

  4. Create an OAuth client with application type Desktop app.

  5. Download the JSON file to:

    ~/.config/google-forms-mcp/credentials.json

    Override the location with GOOGLE_FORMS_CLIENT_SECRET if needed.

  6. Authorize once:

    uv run google-forms-auth

The refresh token is stored at ~/.config/google-forms-mcp/token.json with owner-only permissions when the platform supports them. Override it with GOOGLE_FORMS_TOKEN.

Multi-user public mode

Version 0.4 adds a public onboarding mode where each user connects their own Google account and receives a private MCP bearer token for Claude, ChatGPT, or another HTTP MCP client.

Set:

GOOGLE_FORMS_MULTIUSER=true
GOOGLE_FORMS_PUBLIC_BASE_URL=https://forms.example.com
GOOGLE_FORMS_WEB_CLIENT_SECRET=/run/secrets/google-web-client.json
GOOGLE_FORMS_MULTIUSER_DATA_DIR=/var/lib/google-forms-mcp

The Google credential must be an OAuth client with application type Web application. Register this exact redirect URI:

https://forms.example.com/oauth/google/callback

Users visit /, select Connect Google Forms, approve only identity and Forms-body access, and receive a gfm_... token shown once. They configure their AI application's MCP authorization header with that token.

Multi-user protections include:

  • Fernet-encrypted Google credentials with a private server-side master key

  • SHA-256-hashed MCP tokens; plaintext tokens are never stored

  • Per-user draft databases and confirmation keys

  • Browser-bound, one-use PKCE OAuth state with expiration

  • Per-user request limits across all of the user's tokens

  • Token revocation and Google disconnect

  • Per-user audit events without prompts, form contents, OAuth tokens, or MCP tokens

See docs/public-product.md for deployment, Google consent-screen, privacy, and client-connection requirements.

Connect an MCP client

Hermes Agent

Use Hermes' MCP CLI rather than editing its configuration manually:

hermes mcp add google-forms \
  --command /absolute/path/to/google-forms-mcp/.venv/bin/google-forms-mcp

hermes mcp test google-forms

Restart the active Hermes agent after adding the server so its tools are discovered.

Other stdio MCP clients

Configure the command as:

{
  "command": "/absolute/path/to/google-forms-mcp/.venv/bin/google-forms-mcp",
  "args": []
}

The exact configuration file varies by client.

Claude and ChatGPT remote connector

Run the authenticated HTTP entrypoint and publish it behind HTTPS:

GOOGLE_FORMS_CONNECTOR_TOKEN='<random-token>' \
GOOGLE_FORMS_CONNECTOR_PUBLIC_HOSTS='forms.example.com' \
uv run google-forms-connector

Connect Claude or ChatGPT to https://your-domain.example/mcp and configure the Authorization request header with the connector bearer token. The hosted connector currently represents one Google account. See docs/connectors.md for deployment, platform setup, and security details.

Tools

preview_google_form

Validates a structured form specification and returns a normalized draft. It never authenticates or creates anything.

create_form_draft

Saves a validated draft at version 1 without contacting Google.

get_form_draft

Returns the current version, normalized specification, publication state, and summary.

patch_form_draft

Applies only the requested operations and creates a new version. Supported operations include form titles/descriptions, section renames, adding/deleting/renaming questions, question descriptions, required flags, and adding/removing choice options.

undo_draft_change

Moves the draft back one version. A subsequent patch creates a new history branch and discards the abandoned future revisions.

publish_form_draft

Creates and publishes the native Google Form from the reviewed draft only when confirm=true and expected_version matches the reviewed version, then records the resulting form ID on the draft. Published drafts become immutable; further changes use the existing-form update tool.

update_existing_google_form

Previews or applies explicit patch operations to a published native Google Form. The preview returns the current Google revision_id, exact operations, and a signed plan_token. The confirmed call executes the immutable signed plan and fails closed if either the plan is altered or Google changed after review.

google_forms_auth_status

Reports credential paths and whether the expected files exist. It does not expose token contents.

Example request

Ask the connected assistant:

Create a two-section retreat RSVP. In Basics, require name and email and ask whether the person is attending. In Logistics, ask for transportation as multiple choice and available days as checkboxes. Preview it before creating anything.

A valid tool payload looks like:

{
  "spec": {
    "title": "Retreat RSVP",
    "description": "Please respond by Friday.",
    "sections": [
      {
        "title": "Basics",
        "questions": [
          {"title": "Name", "type": "short_text", "required": true},
          {"title": "Email", "type": "short_text", "required": true},
          {
            "title": "Will you attend?",
            "type": "multiple_choice",
            "options": ["Yes", "No"]
          }
        ]
      },
      {
        "title": "Logistics",
        "questions": [
          {
            "title": "Transportation",
            "type": "dropdown",
            "options": ["Driving", "Need a ride", "Public transit"]
          },
          {
            "title": "Available days",
            "type": "checkboxes",
            "options": ["Friday", "Saturday", "Sunday"]
          }
        ]
      }
    ]
  }
}

The assistant saves this with create_form_draft. A targeted follow-up such as “remove Public transit and make Transportation required” becomes:

{
  "draft_id": "<draft-id>",
  "operations": [
    {
      "operation": "remove_option",
      "question_title": "Transportation",
      "option": "Public transit"
    },
    {
      "operation": "set_required",
      "question_title": "Transportation",
      "required": true
    }
  ]
}

patch_form_draft returns the exact change list and version 2 while every unrelated field remains unchanged. After approval, the assistant calls publish_form_draft with the draft ID, expected_version: 2, and confirm: true.

Development

uv run pytest -q
uv run ruff check .
uv run mypy

The tests use in-memory fakes and never contact Google.

Security

  • Never commit credentials.json or token.json; both are ignored by Git.

  • The server requests only the Forms body scope and does not read responses.

  • Draft databases, SQLite sidecars, and confirmation keys are restricted to owner read/write permissions where supported.

  • Creation, publication, and existing-form updates require explicit confirmation tied to reviewed versions or signed plans.

  • If Google allocates a form but later setup fails, the form ID is retained and automatic retries are blocked to avoid duplicate forms.

  • For shared installations, run one server per Google account or isolate each account's token path.

Available Tools

8 tools
create_form_draftA

Save a persistent, versioned form draft without creating a Google Form.

Inputs: spec (required). Returns: object

get_form_draftC

Return the current version of a persistent form draft.

Inputs: draft_id (required). Returns: object

google_forms_auth_statusA

Report whether the active user's Google authorization is configured.

Inputs: no named parameters. Returns: object

patch_form_draftC

Apply targeted operations to a draft while preserving unrelated content.

Inputs: draft_id (required), operations (required). Returns: object

preview_google_formB

Validate and preview a Google Form without creating or saving anything.

Inputs: spec (required). Returns: object

publish_form_draftC

Create a native Google Form from the exact approved draft version.

Inputs: draft_id (required), confirm, expected_version. Returns: object

undo_draft_changeC

Move a draft back by one version without touching Google Forms.

Inputs: draft_id (required). Returns: object

update_existing_google_formC

Preview or apply a signed targeted update plan to an existing Google Form.

Inputs: form_id (required), confirm, operations, plan_token. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.3/5.0

    Scored across 8 tools

    Disambiguation4/5

    Most tools map to distinct stages of a draft lifecycle (create/get/patch/undo/publish), so an agent can route most requests cleanly. However, preview_google_form overlaps with update_existing_google_form's preview mode, and publish_form_draft vs update_existing_google_form both write to live Google Forms, creating some boundary ambiguity.

    Naming Consistency4/5

    Names are consistently snake_case with a verb_noun shape (create_form_draft, patch_form_draft, undo_draft_change). Minor deviations exist: the noun is phrased variously as 'form_draft', 'existing_google_form', and the namespace-prefixed google_forms_auth_status breaks the pattern slightly.

    Tool Count5/5

    Eight tools is well-scoped for a draft-based form authoring workflow. Each tool (create, get, patch, undo, preview, publish, update, auth) earns its place without redundancy.

    Completeness4/5

    The draft lifecycle is covered end-to-end: create/get/patch/undo/publish plus preview, update-existing, and auth. Minor gaps remain, such as no delete_form_draft, no way to list drafts, and no read/fetch tool for existing Google Forms beyond updating them.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      MCP server for reading, editing, and publishing Google Forms with the official Google Forms API. Enables AI agents to programmatically create, modify, and manage forms and responses.
      MIT
    • F
      license
      A
      quality
      C
      maintenance
      MCP server for FormsList, a form-backend SaaS. Enables creating form endpoints, reading submissions, configuring auto-responses, and generating embed snippets via natural language.
      7
      -
    • A
      license
      A
      quality
      B
      maintenance
      An MCP server for the Google Forms API that enables creating and editing forms, publishing them, reading responses, and setting up push notifications from AI clients using natural language.
      19
      285 npm
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Turns existing backend APIs (OpenAPI) and SQL databases (PostgreSQL, MariaDB, ClickHouse) into hosted MCP servers for AI clients, with built-in dashboards, forms, and credential encryption.
      5,309 npm
      Apache 2.0