A side-by-side look at the MCP Server Atlassian Jira and Google Forms MCP MCP servers: transport, auth, tools, quality signals, and the config to install either one in Claude, Cursor, Windsurf or VS Code.
Verdict: choose MCP Server Atlassian Jira for workplace & productivity work as a local process; choose Google Forms MCP for workplace & productivity as a local process. You can also run both side by side in one mcpServers block.
ATLASSIAN_SITE_NAME, ATLASSIAN_USER_EMAIL, ATLASSIAN_API_TOKEN.jira_get, jira_post, jira_put.GOOGLE_FORMS_CLIENT_ID, GOOGLE_FORMS_CLIENT_SECRET, GOOGLE_FORMS_REFRESH_TOKEN.auth_status, setup_instructions, set_client.Rows where the two servers differ are marked.
| Spec | ||
|---|---|---|
| Category | Workplace & Productivity | Workplace & Productivity |
| Quality signal | 65/100 · Great | 57/100 · Good |
| Install command | Confirmed | Confirmed |
| Transport | Local subprocess (stdio) | Local subprocess (stdio) |
| Auth | API key required | Not declared |
| Pricing | Free | Not declared |
| Required env vars | ATLASSIAN_SITE_NAMEATLASSIAN_USER_EMAILATLASSIAN_API_TOKEN | GOOGLE_FORMS_CLIENT_IDGOOGLE_FORMS_CLIENT_SECRETGOOGLE_FORMS_REFRESH_TOKEN |
| Verified owner | Community listing | Community listing |
| GitHub stars | 77 | 0 |
| Directory activity | 6 views 0 installs 0 upvotes | 3 views 0 installs 0 upvotes |
| Tools | 5 | 19 |
| Full listing | View MCP Server Atlassian Jira | View Google Forms MCP |
jira_getRead any Jira data. Returns TOON format by default (30-60% fewer tokens than JSON).
**IMPORTANT - Cost Optimization:**
- ALWAYS use `jq` param to filter response fields. Unfiltered responses are very expensive!
- Use `maxResults` query param to restrict result count (e.g., `maxResults: "5"`)
- If unsure about available fields, first fetch ONE item with `maxResults: "1"` and NO jq filter to explore the schema, then use jq in subsequent calls
**Schema Discovery Pattern:**
1. First call: `path: "/rest/api/3/search/jql", queryParams: {"maxResults": "1", "jql": "project=PROJ"}` (no jq) - explore available fields
2. Then use: `jq: "issues[*].{key: key, summary: fields.summary, status: fields.status.name}"` - extract only what you need
**Output format:** TOON (default, token-efficient) or JSON (`outputFormat: "json"`)
**Common paths:**
- `/rest/api/3/project` - list all projects
- `/rest/api/3/project/{projectKeyOrId}` - get project details
- `/rest/api/3/search/jql` - search issues with JQL (use `jql` query param). NOTE: `/rest/api/3/search` is deprecated!
- `/rest/api/3/issue/{issueIdOrKey}` - get issue details
- `/rest/api/3/issue/{issueIdOrKey}/comment` - list issue comments
- `/rest/api/3/issue/{issueIdOrKey}/worklog` - list issue worklogs
- `/rest/api/3/issue/{issueIdOrKey}/transitions` - get available transitions
- `/rest/api/3/user/search` - search users (use `query` param)
- `/rest/api/3/status` - list all statuses
- `/rest/api/3/issuetype` - list issue types
- `/rest/api/3/priority` - list priorities
**JQ examples:** `issues[*].key`, `issues[0]`, `issues[*].{key: key, summary: fields.summary}`
**Example JQL queries:** `project=PROJ`, `assignee=currentUser()`, `status="In Progress"`, `created >= -7d`
API reference: https://developer.atlassian.com/cloud/jira/platform/rest/v3/jira_postCreate Jira resources. Returns TOON format by default (token-efficient).
**IMPORTANT - Cost Optimization:**
- Use `jq` param to extract only needed fields from response (e.g., `jq: "{key: key, id: id}"`)
- Unfiltered responses include all metadata and are expensive!
**Output format:** TOON (default) or JSON (`outputFormat: "json"`)
**Common operations:**
1. **Create issue:** `/rest/api/3/issue`
body: `{"fields": {"project": {"key": "PROJ"}, "summary": "Issue title", "issuetype": {"name": "Task"}, "description": {"type": "doc", "version": 1, "content": [{"type": "paragraph", "content": [{"type": "text", "text": "Description"}]}]}}}`
2. **Add comment:** `/rest/api/3/issue/{issueIdOrKey}/comment`
body: `{"body": {"type": "doc", "version": 1, "content": [{"type": "paragraph", "content": [{"type": "text", "text": "Comment text"}]}]}}`
3. **Add worklog:** `/rest/api/3/issue/{issueIdOrKey}/worklog`
body: `{"timeSpentSeconds": 3600, "comment": {"type": "doc", "version": 1, "content": [{"type": "paragraph", "content": [{"type": "text", "text": "Work done"}]}]}}`
4. **Transition issue:** `/rest/api/3/issue/{issueIdOrKey}/transitions`
body: `{"transition": {"id": "31"}}`
5. **Add attachment:** `/rest/api/3/issue/{issueIdOrKey}/attachments`
Note: Requires multipart form data (complex - use Jira UI for attachments)
API reference: https://developer.atlassian.com/cloud/jira/platform/rest/v3/jira_putReplace Jira resources (full update). Returns TOON format by default.
**IMPORTANT - Cost Optimization:** Use `jq` param to extract only needed fields from response
**Output format:** TOON (default) or JSON (`outputFormat: "json"`)
**Common operations:**
1. **Update issue (full):** `/rest/api/3/issue/{issueIdOrKey}`
body: `{"fields": {"summary": "New title", "description": {...}, "assignee": {"accountId": "..."}}}`
2. **Update project:** `/rest/api/3/project/{projectIdOrKey}`
body: `{"name": "New Project Name", "description": "Updated description"}`
3. **Set issue property:** `/rest/api/3/issue/{issueIdOrKey}/properties/{propertyKey}`
body: `{"value": "property value"}`
Note: PUT replaces the entire resource. For partial updates, prefer PATCH.
API reference: https://developer.atlassian.com/cloud/jira/platform/rest/v3/jira_patchPartially update Jira resources. Returns TOON format by default.
**IMPORTANT - Cost Optimization:** Use `jq` param to filter response fields.
**Output format:** TOON (default) or JSON (`outputFormat: "json"`)
**Common operations:**
1. **Update issue fields:** `/rest/api/3/issue/{issueIdOrKey}`
body: `{"fields": {"summary": "Updated title"}}` (only updates specified fields)
2. **Update comment:** `/rest/api/3/issue/{issueIdOrKey}/comment/{commentId}`
body: `{"body": {"type": "doc", "version": 1, "content": [{"type": "paragraph", "content": [{"type": "text", "text": "Updated comment"}]}]}}`
3. **Update worklog:** `/rest/api/3/issue/{issueIdOrKey}/worklog/{worklogId}`
body: `{"timeSpentSeconds": 7200}`
Note: PATCH only updates the fields you specify, leaving others unchanged.
API reference: https://developer.atlassian.com/cloud/jira/platform/rest/v3/jira_deleteDelete Jira resources. Returns TOON format by default.
**Output format:** TOON (default) or JSON (`outputFormat: "json"`)
**Common operations:**
1. **Delete issue:** `/rest/api/3/issue/{issueIdOrKey}`
Query param: `deleteSubtasks=true` to delete subtasks
2. **Delete comment:** `/rest/api/3/issue/{issueIdOrKey}/comment/{commentId}`
3. **Delete worklog:** `/rest/api/3/issue/{issueIdOrKey}/worklog/{worklogId}`
4. **Delete attachment:** `/rest/api/3/attachment/{attachmentId}`
5. **Remove watcher:** `/rest/api/3/issue/{issueIdOrKey}/watchers`
Query param: `accountId={accountId}`
Note: Most DELETE endpoints return 204 No Content on success.
API reference: https://developer.atlassian.com/cloud/jira/platform/rest/v3/auth_statusShows whether this server is connected to Google: token presence and source (env variables or a stored in-chat login), expiry, the Google account email, granted vs missing OAuth scopes, where the credentials file lives and where the OAuth client comes from. Makes no network calls and never returns the token itself. Call it first when other tools report the server is not connected.setup_instructionsStep-by-step checklist for connecting this server to Google: creating a Google Cloud project and a Desktop-app OAuth client, publishing the consent screen (mandatory — Testing-mode refresh tokens die after 7 days), downloading the client JSON and handing its PATH to set_client. Works without any credentials; the checklist shortens to 'enable the API + log in' when an OAuth client is already configured (one client serves the whole mcp-google-* line). Never asks the user to paste secrets into the chat.set_clientSaves the OAuth client credentials from the JSON file downloaded from Google Cloud Console ('Download JSON' on a Desktop-app client). Pass the file PATH — the secret must never be pasted into the chat. The client is stored once in the shared ~/.config/mcp-google-auth/client.json (owner-only) and reused by every mcp-google-* server; tokens stay per-server. After this, call start_login.start_loginFirst step of connecting from the chat, without editing config files or restarting the client. Returns authorizeUrl — show it to the user as a clickable link and ask them to open it in the browser ON THIS MACHINE, pick the Google account and approve access. A one-shot listener on 127.0.0.1 catches Google's redirect; the code is exchanged locally and never passes through the chat. Does not open the browser itself. The attempt lives 10 minutes; when the browser shows the success page, call finish_login.finish_loginSecond step: confirms the browser consent finished, saves the tokens to an owner-only file and verifies the login with a read-only identity call, returning the account email and the granted scopes. After success every tool works immediately — no client restart. If the user granted only part of the requested permissions, the login is still saved and missingScopes lists what will not work. Logging in under a different Google account replaces the previous login (its refresh token is revoked best-effort) and the response carries previousAccountEmail so the change never goes unnoticed.logoutRevokes the stored token at Google (oauth2.googleapis.com/revoke) and deletes the local credentials file. Tokens supplied via env variables are NOT touched — remove them from the MCP client config manually; envTokenStillSet in the response says whether any are still in effect.create_formCreates a new Google Form and returns it (formId, revisionId, responderUri, publishSettings). The API only accepts a title and an optional document title at creation (the Drive file name — it cannot be changed later through this API) — 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. If the chained publish step fails, the form still exists: the result carries formId with published:false and publish_error — finish with set_publish_settings, never create_form again. Share the responderUri with respondents once published.get_formReturns 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_infoChanges the form's title and/or description. Only the provided fields are touched (the updateMask is computed automatically); at least one field is required. The document title (the Drive file name) is set once at create_form and cannot be changed through the Forms API — renaming the file needs the Drive API, which this server does not cover. Returns the batchUpdate replies with the new revisionId.update_form_settingsToggles quiz mode (grading with points) and/or the email collection mode. Quiz mode only enables grading — points, correct answers and feedback are set per question afterwards via update_question with the questionItem.question.grading mask (add_question cannot set them). 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_settingsPublishes 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_questionAdds 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). Quiz grading (points, correct answers, feedback) cannot be set here — after adding, use update_question with the questionItem.question.grading mask. File-upload questions cannot be created via the API, and question grids (questionGroupItem) need raw_request with a batchUpdate body.Paste either block (or both) into your client config, e.g. claude_desktop_config.json or ~/.cursor/mcp.json. We only show a config when the install command is confirmed.
{
"mcpServers": {
"aashari-mcp-server-atlassian-jira": {
"command": "npx",
"args": [
"-y",
"@aashari/mcp-server-atlassian-jira"
],
"env": {
"ATLASSIAN_SITE_NAME": "YOUR_ATLASSIAN_SITE_NAME_HERE",
"ATLASSIAN_USER_EMAIL": "YOUR_ATLASSIAN_USER_EMAIL_HERE",
"ATLASSIAN_API_TOKEN": "YOUR_ATLASSIAN_API_TOKEN_HERE"
}
}
}
}
{
"mcpServers": {
"google-forms-mcp": {
"command": "npx",
"args": [
"-y",
"mcp-google-forms@latest"
],
"env": {
"GOOGLE_FORMS_CLIENT_ID": "YOUR_GOOGLE_FORMS_CLIENT_ID_HERE",
"GOOGLE_FORMS_CLIENT_SECRET": "YOUR_GOOGLE_FORMS_CLIENT_SECRET_HERE",
"GOOGLE_FORMS_REFRESH_TOKEN": "YOUR_GOOGLE_FORMS_REFRESH_TOKEN_HERE"
}
}
}
}