mcp-google-forms
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| GOOGLE_FORMS_API_BASE | No | API root override. | https://forms.googleapis.com |
| GOOGLE_FORMS_CLIENT_ID | No | OAuth2 client id (refresh flow). | |
| GOOGLE_FORMS_TIMEOUT_MS | No | Per-request timeout, ms. | 60000 |
| GOOGLE_FORMS_MAX_RETRIES | No | Retries on transient errors. | 3 |
| GOOGLE_FORMS_ACCESS_TOKEN | No | Alternative: a static access token (~1 h lifetime), mostly for testing. | |
| GOOGLE_FORMS_CLIENT_SECRET | No | OAuth2 client secret (refresh flow). | |
| GOOGLE_FORMS_REFRESH_TOKEN | No | OAuth2 refresh token (refresh flow). |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| create_formA | Creates a new Google Form and returns it (formId, revisionId, responderUri, publishSettings). The API only accepts a title and an optional document title at creation — add questions with add_question and change settings with update_form_settings afterwards. IMPORTANT: API-created forms are UNPUBLISHED by default and do not accept responses; pass publish=true to publish immediately, or call set_publish_settings later. Share the responderUri with respondents once published. |
| get_formA | Returns the full form: info (title, description), settings (quiz mode, email collection), items[] with their itemId/questionId and question definitions, publishSettings, responderUri and linkedSheetId. Items are returned in order — their 0-based positions are the indexes that update_question, delete_item and move_item address, so call this before mutating items. |
| update_form_infoA | Changes the form's title, description and/or document title (the Drive file name). Only the provided fields are touched (the updateMask is computed automatically); at least one field is required. Returns the batchUpdate replies with the new revisionId. |
| update_form_settingsA | Toggles quiz mode (grading with points) and/or the email collection mode. email_collection_type: DO_NOT_COLLECT, VERIFIED (respondent must be signed in; email verified) or RESPONDER_INPUT (respondent types an email). At least one field is required; only the provided fields are touched. |
| set_publish_settingsA | Publishes or unpublishes the form and opens/closes response collection. is_accepting_responses defaults to mirroring is_published (publish = start accepting, unpublish = stop). Use is_published=true with is_accepting_responses=false to keep a published form visible but closed. Fails on legacy forms created before the publish model existed — those are managed only in the Forms UI. |
| add_questionA | Adds a question to the form (a convenience wrapper over batchUpdate createItem). Types: text (short answer), paragraph (long answer), radio (single choice), checkbox (multiple choice), dropdown, scale (linear scale low..high), date, time, rating (stars/hearts/thumbs). Choice types require options[]. Returns the created itemId and questionId from the batchUpdate replies. index inserts at that 0-based position; omit it to append at the end (costs one extra read to count items). File-upload questions cannot be created via the API, and question grids (questionGroupItem) need raw_request with a batchUpdate body. |
| update_questionA | Updates an existing item (question or other) via batchUpdate updateItem. The item is addressed by its 0-based index — call get_form first to see current positions and the item's current shape. item is a raw Forms API Item object with the new values; update_mask names the fields to replace, e.g. "title" or "title,questionItem.question.required". Only masked fields change; masking a field the item object leaves unset clears it. |
| delete_itemA | Deletes the item at the given 0-based index (question, page break, text block, ...). Deletion shifts every later item one position down — re-check indexes with get_form between successive deletes. |
| move_itemA | Moves the item at from_index to to_index (both 0-based, to_index is the position after removal). Use get_form to see the current order first. |
| list_responsesA | Lists submitted responses: responseId, createTime, lastSubmittedTime, respondentEmail (only when email collection is on), answers keyed by questionId (map questionId → question via get_form), and totalScore for graded quizzes. submitted_after keeps only responses submitted strictly after that RFC3339 UTC timestamp — the API's only filter; there is no ordering or email filter, do that client-side. Paginate with page_token from nextPageToken. Note: this endpoint has a lower per-minute quota than other reads — poll incrementally with submitted_after rather than re-listing everything. The API is read-only for responses; submitting them programmatically is impossible. |
| get_responseA | Fetches a single submission by its responseId (from list_responses): answers keyed by questionId, createTime, lastSubmittedTime, respondentEmail and totalScore when available. Map questionId to the question text via get_form. |
| manage_watchesA | Manages Cloud Pub/Sub push-notification watches on a form. action=create needs event_type (RESPONSES = new submissions, SCHEMA = form structure changes) and topic_name; the topic must live in your Cloud project and grant the Pub/Sub Publisher role to forms-notifications@system.gserviceaccount.com. action=list shows your watches; delete and renew need watch_id. Watches expire after 7 days — renew extends 7 days from now and reactivates a SUSPENDED watch. Notifications carry only formId/watchId/eventType attributes (no payload): on RESPONSES call list_responses with submitted_after, on SCHEMA call get_form. Limits: 1 watch per user per form+event type, 20 per Cloud project. |
| raw_requestA | Escape hatch to call any Google Forms API v1 path directly, for requests the typed tools don't cover — e.g. a batchUpdate with questionGroupItem grids, writeControl/requiredRevisionId, includeFormInResponse, or several requests at once: path "v1/forms/:batchUpdate", method POST, body {"requests":[...]}. The path may carry a query string (e.g. "v1/forms//responses?filter=timestamp%20%3E%202026-08-01T00:00:00Z"). The Bearer token is added automatically; the method defaults to GET. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/A1-x-Tech/mcp-google-forms'
If you have feedback or need assistance with the MCP directory API, please join our Discord server