MCP server that creates Google Docs with native Tabs (Oct 2024 sidebar feature) — for Claude Desktop and Claude Code
Drift inferred · capture-to-capture
No drift recorded — single capability capture; advisories appear once its surface changes.
transport stdio · streamable-http · http counts 1 tools · 0 res
· 0 prompts
permission surface via code analysis
tools
-
gdocs_xxx
prompt-surface
shipped agent-instruction files + hidden-content / dangerous-code findings —
quoted from the analyzed source
analyzed commit 46e0fa4 · analyzer v28 · 1d ago
skills & prompt files 1
- agent-rules Sundeepg98-google-docs-mcp-46e0fa4/CLAUDE.md
danger signals21
- over-broad OAuth scope https://www.googleapis.com/auth/documents
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/auth.py :55
"https://www.googleapis.com/auth/documents", - over-broad OAuth scope https://www.googleapis.com/auth/spreadsheets
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/auth.py :82
"https://www.googleapis.com/auth/spreadsheets", - over-broad OAuth scope https://mail.google.com/
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/services/apps_script/api.py :145
"https://mail.google.com/", - over-broad OAuth scope gmail.modify Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/services/apps_script/api.py :147
"https://www.googleapis.com/auth/gmail.modify", - over-broad OAuth scope https://www.googleapis.com/auth/drive
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/services/apps_script/api.py :154
"https://www.googleapis.com/auth/drive", - over-broad OAuth scope https://www.googleapis.com/auth/spreadsheets
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/services/apps_script/test_lifecycle_tools.py :286
manifest={"oauth_scopes": ["https://www.googleapis.com/auth/spreadsheets"]}, - over-broad OAuth scope https://www.googleapis.com/auth/spreadsheets
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/services/apps_script/test_manifest_builder.py :214
scope = "https://www.googleapis.com/auth/spreadsheets" - over-broad OAuth scope https://mail.google.com/
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/services/apps_script/test_manifest_builder.py :276
"https://mail.google.com/", - over-broad OAuth scope gmail.modify Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/services/apps_script/test_manifest_builder.py :278
"https://www.googleapis.com/auth/gmail.modify", - over-broad OAuth scope https://www.googleapis.com/auth/drive
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/services/apps_script/test_manifest_builder.py :281
"https://www.googleapis.com/auth/drive", - over-broad OAuth scope https://www.googleapis.com/auth/documents
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/services/apps_script/test_manifest_builder.py :322
"https://www.googleapis.com/auth/documents", - over-broad OAuth scope https://www.googleapis.com/auth/drive
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/test_base_tier_scopes.py :21
"https://www.googleapis.com/auth/drive", - over-broad OAuth scope https://mail.google.com/
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/test_base_tier_scopes.py :25
"https://mail.google.com/", - over-broad OAuth scope gmail.modify Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/test_base_tier_scopes.py :27
"https://www.googleapis.com/auth/gmail.modify", - over-broad OAuth scope https://www.googleapis.com/auth/documents
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/test_base_tier_scopes.py :48
"https://www.googleapis.com/auth/documents", - over-broad OAuth scope https://www.googleapis.com/auth/spreadsheets
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/test_base_tier_scopes.py :50
"https://www.googleapis.com/auth/spreadsheets", - over-broad OAuth scope https://www.googleapis.com/auth/documents
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/test_credentials.py :77
"https://www.googleapis.com/auth/documents", - over-broad OAuth scope https://www.googleapis.com/auth/documents
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/test_scope_union_single_source.py :60
"https://www.googleapis.com/auth/documents", - over-broad OAuth scope https://www.googleapis.com/auth/spreadsheets
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/test_scope_union_single_source.py :62
"https://www.googleapis.com/auth/spreadsheets", - over-broad OAuth scope https://www.googleapis.com/auth/documents
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/test_setup_apps_script_for_user.py :288
"https://www.googleapis.com/auth/documents", - over-broad OAuth scope https://mail.google.com/
expected for this server's purpose
Sundeepg98-google-docs-mcp-46e0fa4/tests/unit/test_user_store.py :286
assert _valid_gas_url("https://mail.google.com/macros/s/X/exec") is False
evidence-backed
findings quoted directly from the published source artifact — not inferred
code files: 305
filesystem 24
- fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/auth.py :13
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/automation_ledger.py :45
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/cli.py :19
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/config.py :11
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/docx_import.py :58
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/durable_nonce.py :23
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/http_server/_helpers.py :15
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/http_server/middleware.py :676
"TrustedHost middleware running fail-open (allow all hosts) -- " - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/http_server/routes/convert.py :43
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/job_store.py :46
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/oauth_google.py :33
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/preview.py :27
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/retrofit.py :29
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/server.py :18
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/services/admin/tools.py :71
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/services/apps_script/_frames_staging.py :63
import shutil - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/services/apps_script/doc_menu.py :321
After this returns, open (or reload) the Doc — the menu appears in - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/services/apps_script/encode_video.py :74
import shutil - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/services/apps_script/sheet_menu.py :338
``gdocs_find_doc_by_title``. After this returns, open (or reload) the - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/services/apps_script/slides_menu.py :330
``gdocs_find_file``. After this returns, open (or reload) the - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/services/drive/api.py :20
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/setup_apps_script.py :47
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/setup_state.py :21
from pathlib import Path - fs Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/user_store.py :48
from pathlib import Path
shell / exec 1
- shell Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/services/apps_script/encode_video.py :75
import subprocess
network 11
- net Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/cli.py :20
from urllib import error as urlerror - net Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/crypto.py :34
from urllib.parse import urlencode - net Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/errors.py :31
"via requests.post) — it bypasses the Drive connector entirely. " - net Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/google_api_client.py :57
import socket - net Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/http_server/middleware.py :109
# in depth that guarantees NO log line - from httpx, urllib3, uvicorn, - net Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/license.py :41
- Internal license server: ``httpx.get(server, params={"key": token})`` - net Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/oauth_google.py :35
import httpx - net Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/services/admin/tools.py :1756
"requests.post(URL, files={'file': ('doc.docx', open('/path/to/doc.docx','rb'), " - net Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/setup_apps_script.py :49
from urllib import error as urlerror - net Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/storage/vercel_kv_backend.py :53
on Hobby tier per PR-Δ6 ADR). One httpx.Client per process with the - net Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/user_store.py :50
from urllib.parse import urlparse
secrets 5
- secrets Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/key_provider.py :188
master = os.environ.get("MCP_BEARER_TOKEN") - secrets Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/keys.py :253
master = os.environ.get("MCP_BEARER_TOKEN", "") - secrets Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/license.py :236
raw = os.environ.get("MCP_LICENSE_KEY") - secrets Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/services/admin/tools.py :307
expected = os.environ.get("MCP_ADMIN_TOKEN") - secrets Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/storage/vercel_kv_backend.py :146
resolved_token = rest_token or os.environ.get("KV_REST_API_TOKEN", "")
database 4
- db Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/automation_ledger.py :41
import sqlite3 - db Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/durable_nonce.py :19
import sqlite3 - db Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/job_store.py :41
import sqlite3 - db Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/user_store.py :44
import sqlite3
tool registrations 1
- gdocs_xxx Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/decorators.py :5
declared dependencies 16
- fastmcp@>=3.4.2
- google-api-python-client@>=2.197.0
- google-auth@>=2.53.0
- google-auth-oauthlib@>=1.4.0
- markdown-it-py@>=4.2.0
- python-docx@>=1.2.0
- typing-extensions@>=4.15.0
- starlette@>=1.3.1,<1.4
- cryptography@>=48.0.0,<49
- pytest@>=9.0.3
- pytest-json-report@>=1.5
- pytest-asyncio@>=1.4.0
- pytest-cov@>=7.1.0
- hypothesis@>=6.155.2
- pyright@>=1.1.410
- ruff@>=0.15.17
transport_posture 1
- binds all interfaces (0.0.0.0) Sundeepg98-google-docs-mcp-46e0fa4/src/appscriptly/http_server/app.py :249
uvicorn.run(app, host="0.0.0.0", port=port, log_level="info")