← Back to search

io.github.michaelrobertsutton/verified-googledocs-mcp

michaelrobertsutton Scanned 1d ago

MCP server for Google Docs with verified writes — every mutation returns before/after proof.

C
61.1 / 100

Versions

0.1.0latest
first seen Jun 30, 2026
PermissionsTool SafetyAuthAnnotationsCode QualityStabilitySpecVuln HistoryAuthorTransparencyCommunity

Tools 30

good_mutating
annotations: none low

bad_mutating
annotations: none low

non_mutating
annotations: none low

error_returning
annotations: none low

raises_tool_error
annotations: none low

random_read
annotations: none low

read
annotations: none low

sections
annotations: none low

dict_tool
annotations: none low

list_tool
annotations: none low

list_tabs
annotations: none low

List the tabs in a Google Doc. Use this tool first when you need to read or edit a document but do not yet know its tab structure. Returns tab IDs, titles, nesting level, and index. Required before calling read_document or find_sections because every tool in this server requires an explicit tab_id. For documents created before Google's tabbed-docs feature, returns a single synthetic tab with id "_body" that covers the whole document.

doc_id str
read_document
annotations: none low

Read the content of a specific tab in a Google Doc. Use this tool when you need to read the text, headings, tables, or structure of a document tab. Call list_tabs first to get the tab_id. format="markdown" (default): returns markdown text. Out-of-subset elements (images, smart chips, footnotes) appear as stable placeholder tokens and are listed in lossy_elements. format="structured": returns paragraph positions and style runs from the raw Docs JSON, suitable for computing exact edit ranges. format="outline": returns only the tab's headings (level, text, start_index, end_index), in document order. Use this when you only need geometry — e.g. to see the tab's section structure before deciding where to write — without pulling the whole tab as markdown. If you already know which heading you want to target, find_sections is the lighter tool: it filters to matches and returns section (not just heading) ranges. Drive's files.export cannot scope to a single tab, which is why this server uses its own Docs JSON converter for markdown output.

doc_id str format string tab_id str
find_sections
annotations: none low

Find headings in a document tab and return their document ranges. Use this tool when you need to locate a section by its heading text before performing a targeted edit on that section. The returned ranges carry a computed_at_revision stamp; range-editing tools in later milestones will refuse stale ranges (ranges computed against an older document revision). Call find_sections immediately before editing — do not cache returned ranges across separate edits. Matching is case-insensitive and substring-based: a query of "intro" will match a heading "Introduction".

doc_id str tab_id str heading str
replace_text
annotations: none low

Replace occurrences of a text string in a Google Doc tab. Use this tool when you need to make an exact-text substitution in a document tab. Call list_tabs first to get the tab_id, then read_document to confirm the text you want to replace is present as-is. The tool locates every occurrence of ``find`` using a normalization ladder (exact → curly/straight quote equivalence → NBSP/whitespace collapse → soft-hyphen strip) and refuses the write if the match count does not equal ``expected_matches``. This prevents accidental multi-replacement and duplicate-sentence collapse. Set ``dry_run=True`` to preview the operation without writing; the response carries ``applied: false`` and the matched span information but makes no API call. On success the response carries before/after excerpts (±200 chars), the normalization rung used, pre/post revision IDs, and ``audit_logged``. Errors are returned as typed envelopes with ``error_code``, ``message``, ``diagnostics``, and ``retryable`` so the caller can act on them precisely: ZERO_MATCH – find string not found; near-miss span included MATCH_COUNT_MISMATCH – wrong number of matches; all locations listed REVISION_CONFLICT – document changed mid-call; re-read and retry STRUCTURAL_BOUNDARY – match crosses a paragraph boundary INVALID_INPUT – empty find, or find equals replace TAB_NOT_FOUND – tab_id not in document; available tabs listed SUGGESTIONS_PRESENT – tab has pending suggested edits; accept/reject them in the Docs UI first, then retry (a pending suggestion makes the write's computed indices unsafe — see verified writes, below)

find str doc_id str tab_id str dry_run bool replace str expected_matches int
format_text
annotations: none low

Apply character styling (bold/italic/underline) to a matched text span. Use this tool when you need to style existing text in place — bold a phrase, un-bold it, italicize it — without touching its content. Unlike replace_text (which deletes and reinserts text and cannot express styling), this tool compiles ONLY ``updateTextStyle`` requests, so it is safe to use inside a table cell even when the table has hand-merged cells: no delete/insert/merge request is ever compiled, and the response reports every ``compiled_request_kinds`` entry so that claim is checked, not just asserted. Call list_tabs first to get the tab_id, then read_document to confirm the text you want to style is present as-is. ``style`` maps any of ``bold``/``italic``/``underline`` to ``true`` or ``false`` — e.g. ``{"bold": true}`` to bold, ``{"bold": false}`` to un-bold. At least one key is required. Matching uses the same normalization ladder and match-count guard as replace_text (exact → curly/straight quote equivalence → NBSP/whitespace collapse → soft-hyphen strip; refuses unless the match count equals ``expected_matches``). If the matched text already carries every requested style value, the call is a no-op: it returns ``applied: true``, ``style_mutated: false``, and issues no write at all (so an idempotent re-run does not create a new document revision). The response includes, per matched span, the actual textRun style flags before and after (``runs_before``/``runs_after``) — not a markdown or plain-text diff, since genuine bold and a literal ``**word**`` both render identically as text. ``content_mutated`` is always ``false``, proven by ``compiled_request_kinds`` containing only ``updateTextStyle``. Style reflects ``textRun.textStyle`` only: a heading rendered bold by its named/paragraph style rather than an explicit run style will not show ``bold: true`` here, matching every other style read in this server. A pending style-only suggestion on the target span is allowed through (see SUGGESTIONS_PRESENT below) and evidence reflects the base, non-suggested style, same as every read in this server. Set ``dry_run=True`` to preview the operation without writing; the response carries ``applied: false`` and a *predicted* ``runs_after`` (the requested fields overlaid on the current runs) but makes no API call. Errors are returned as typed envelopes with ``error_code``, ``message``, ``diagnostics``, and ``retryable`` so the caller can act on them precisely: ZERO_MATCH – find string not found; near-miss span included MATCH_COUNT_MISMATCH – wrong number of matches; all locations listed STRUCTURAL_BOUNDARY – match crosses a paragraph or table-cell boundary REVISION_CONFLICT – document changed mid-call; re-read and retry VERIFICATION_FAILED – the write landed but could not be confirmed on re-read; check diagnostics before assuming a manual restore is needed — a concurrent edit near the target text is a common, benign cause INVALID_INPUT – empty find, or style is empty/unknown-key/non-bool TAB_NOT_FOUND – tab_id not in document; available tabs listed SUGGESTIONS_PRESENT – tab has a pending suggested insertion/deletion (not a style suggestion); accept/reject it in the Docs UI first, then retry

find str style string doc_id str tab_id str dry_run bool expected_matches int
list_open_items
annotations: none low

List all open comments and pending suggested edits on a document. Use this tool when you need a single unified view of all open review items on a document. Returns both Drive-level comments (labeled scope='document') and per-tab suggested edits in one response. Comments come from the Drive API and cannot be attributed to a specific tab — Drive comment anchors are opaque. If tab_id is provided it filters the suggestions returned to that tab only. To include suggestions from every tab, set include_all_tabs=true. Comments are always returned document-wide regardless of tab_id. Suggestions are extracted from the raw Docs JSON (suggestedInsertionIds / suggestedDeletionIds / suggestedTextStyleChanges) and are per-tab. The document is fetched with suggestionsViewMode=SUGGESTIONS_INLINE so that suggestion fields are populated.

doc_id str tab_id str include_all_tabs bool
get_comment_thread_tool
annotations: none low

Retrieve the full reply chain for a comment. Use this tool when you need to read a comment thread in full before deciding on a response or resolution. Returns the comment content, all replies, quoted text, resolved status, and author. Requires both the doc_id (the Google Doc's file ID) and the comment_id from the Drive API.

doc_id str comment_id str
add_anchored_comment
annotations: none low

Add a comment to a document, validated against a quoted passage. Use this tool when you need to create a comment on specific text in a document tab. The quote must exist in the tab — the tool locates it via the same normalization ladder as replace_text and returns QUOTE_NOT_FOUND with nearest candidate anchors if the quote is absent. NOTE: The Drive API may render the created comment as document-level even when quotedFileContent is supplied. This behaviour is pending confirmation from a live anchoring spike; for now the comment is created with the quote embedded in its content and the tool returns comment-state evidence. Returns comment-state evidence: applied, comment_id, resolved, reply_count, content, quoted_text, audit_logged. Errors: QUOTE_NOT_FOUND – quote not found in the tab; nearest candidates listed INVALID_INPUT – empty body or quote TAB_NOT_FOUND – tab_id not in document

body str quote str doc_id str tab_id str
reply_to_comment
annotations: none low

Add a reply to an existing comment thread. Use this tool when you need to respond to a reviewer comment without resolving it. The reply is added to the thread and the tool re-queries the comment to return post-state evidence. Returns comment-state evidence: applied, comment_id, resolved, reply_count, content, quoted_text, audit_logged. Errors: INVALID_INPUT – empty body or comment not found

body str doc_id str comment_id str
resolve_comment
annotations: none low

Resolve a comment on a document and verify the resolution landed. Use this tool when you need to mark a reviewer comment as resolved. Resolves via Drive replies.create(action='resolve') — the only mechanism that actually resolves comments in Drive API v3. Using comments.update with resolved=true is silently ignored (resolved is a read-only field), which is the incumbent server's bug. After issuing the resolve the tool re-queries the comment and returns the actual final state. A comment that is still open after the resolve attempt is reported as COMMENT_STILL_OPEN — never as success. Returns comment-state evidence: applied, comment_id, resolved, reply_count, content, quoted_text, audit_logged. Errors: COMMENT_STILL_OPEN – comment did not resolve; post-state included INVALID_INPUT – comment not found

doc_id str comment_id str
replace_range_markdown
annotations: none low

Replace a document range with compiled markdown. Use this tool when you need to replace a section of a document with new markdown content. Obtain start_index, end_index, and computed_at_revision from find_sections. The range stamp is validated against the current document revision — a stale stamp raises STALE_RANGE ("re-run find_sections"). The structural guardrail inventories tables, images, chips, and footnotes inside the target range before writing. If the replacement markdown does not account for them the write is refused unless allow_structural_loss=true. A blast-radius check compares structural element counts outside the edited range pre/post; any change there is a hard failure. Set dry_run=true to validate and preview without writing. The returned payload (applied, revisions, structural_match, input_blocks/ post_blocks) is itself the confirmation the write landed — it already re-read the document and diffed it against the input. A follow-up read_document to double-check is a redundant round-trip; only re-read if you need the content for a subsequent step. Errors: STALE_RANGE – range stamp is outdated; re-run find_sections UNSUPPORTED_MARKDOWN – markdown contains an unsupported construct INVALID_INPUT – structural guardrail refused or blast-radius violation INVALID_RANGE – start_index/end_index don't fit the tab's current extent, or the Docs API rejected the write as index-invalid TAB_NOT_FOUND – tab_id not in document REVISION_CONFLICT – document changed mid-call; re-read and retry SUGGESTIONS_PRESENT – tab has pending suggested edits; accept/reject them in the Docs UI first, then retry

doc_id str tab_id str dry_run bool markdown str end_index int start_index int computed_at_revision str allow_structural_loss bool
replace_tab_markdown
annotations: none low

Replace the entire content of a document tab with compiled markdown. Use this tool when you need to completely replace a tab's content with new markdown. tab_id is required and must identify an existing tab. The structural guardrail refuses writes that would silently lose tables, images, chips, or footnotes unless allow_structural_loss=true. Set dry_run=true to validate and preview without writing. The returned payload (applied, revisions, structural_match, input_blocks/ post_blocks) is itself the confirmation the write landed — it already re-read the document and diffed it against the input. A follow-up read_document to double-check is a redundant round-trip; only re-read if you need the content for a subsequent step. Errors: UNSUPPORTED_MARKDOWN – markdown contains an unsupported construct INVALID_INPUT – structural guardrail refused TAB_NOT_FOUND – tab_id missing or not in document REVISION_CONFLICT – document changed mid-call; re-read and retry SUGGESTIONS_PRESENT – tab has pending suggested edits; accept/reject them in the Docs UI first, then retry

doc_id str tab_id str dry_run bool markdown str allow_structural_loss bool
append_markdown
annotations: none low

Append compiled markdown at the end of a document tab. Use this tool when you need to add new content at the end of a tab without disturbing existing content. Inserts before the final trailing newline. Set dry_run=true to validate and preview without writing. The returned payload (applied, revisions, structural_match, input_blocks/ post_blocks) is itself the confirmation the write landed — it already re-read the document and diffed it against the input. A follow-up read_document to double-check is a redundant round-trip; only re-read if you need the content for a subsequent step. Errors: UNSUPPORTED_MARKDOWN – markdown contains an unsupported construct TAB_NOT_FOUND – tab_id not in document REVISION_CONFLICT – document changed mid-call; re-read and retry

doc_id str tab_id str dry_run bool markdown str
insert_image
annotations: none low

Insert an inline image after the paragraph containing anchor text. Use this tool when you need to add an image to a specific location in a document tab. The anchor resolves via the same normalization ladder as replace_text (exact → curly/straight quotes → NBSP/whitespace → soft-hyphen). The image is inserted as an inline object in a new paragraph immediately after the paragraph containing the resolved anchor. source must be a publicly fetchable URL (http/https). Local file paths are rejected with IMAGE_SOURCE_UNSUPPORTED — the Docs API fetches the image from the URL directly and cannot access local files. Set dry_run=true to preview the resolved anchor position without writing. Returns structural evidence: applied, revision_before/after, inline_object_confirmed (whether the post-read confirms an inline object near the anchor paragraph), audit_logged. Errors: QUOTE_NOT_FOUND – anchor not found; nearest candidates listed IMAGE_SOURCE_UNSUPPORTED – source is a local path, not a URL INVALID_INPUT – anchor is inside a table (anchor must be body text) TAB_NOT_FOUND – tab_id not in document REVISION_CONFLICT – document changed mid-call; re-read and retry SUGGESTIONS_PRESENT – tab has pending suggested edits; accept/reject them in the Docs UI first, then retry

anchor str doc_id str source str tab_id str dry_run bool
diff_tab_vs_file
annotations: none low

Export a document tab as markdown and diff against a local file. Use this tool when you need to compare a Google Doc tab against a local markdown file. The server reads the file directly (it runs locally). Returns a structured diff with tagged hunks (equal/insert/delete/replace) and a unified diff string. This is a read-only tool — it makes no changes to the document or file. Returns: doc_id, tab_id, file_path, revision_id, identical (bool), hunks (list of tagged diff blocks), unified_diff (unified diff string) Errors: TAB_NOT_FOUND – tab_id not in document INVALID_INPUT – file not found at file_path

doc_id str tab_id str file_path str
list_tables
annotations: none low

List every top-level table in a document tab. Use this tool to discover and address the tables in a tab before calling get_table or replace_table_row — both require a table_index, which this tool assigns in document order. Returns tables: a list of table_index, rows, columns, start_index, end_index, preceding_heading (the nearest heading above the table, or null if none), first_row, and has_merged_cells — plus doc_id, tab_id, and revision_id. Errors: TAB_NOT_FOUND – tab_id not in document AUTH_EXPIRED – no valid token

doc_id str tab_id str
get_table
annotations: none low

Read one table's full cell grid. Use this tool to read every cell of a specific table — identified by the table_index returned from list_tables — before editing a row with replace_table_row. Returns doc_id, tab_id, revision_id, table_index, rows, columns, cells (the row-major cell grid, list[list[str]]), and has_merged_cells. Errors: TAB_NOT_FOUND – tab_id not in document TABLE_NOT_FOUND – table_index does not exist in the tab AUTH_EXPIRED – no valid token

doc_id str tab_id str table_index int
replace_table_row
annotations: none low

Replace every cell in one row of an existing table with plain text. Use this tool — the workhorse for updating existing tables in place — to overwrite one row's cells after locating the table and row with list_tables and get_table. cells are PLAIN STRINGS, not markdown, and the list length must equal the row's column count. Each cell's pre-existing bold/italic/underline style is preserved on the replacement text. The tool refuses tables that contain merged cells and rows where a cell contains a nested table. Set dry_run=true to preview without writing. dry_run is authoritative for index validity: the same assembled request list is index-simulated whether dry_run is true or false, and the suggestion guard below runs identically on both paths, so a passing dry_run means the real write will pass too — provided nothing about the document changes in between (a new suggestion, a concurrent edit) before the real write is issued. Returns evidence: applied, table_index, row_index, row_before, row_after, cells_match, revision_before, revision_after, audit_logged. In dry-run mode row_after_preview and planned_requests replace row_after and cells_match. Errors: TAB_NOT_FOUND – tab_id not in document TABLE_NOT_FOUND – table_index does not exist in the tab INVALID_INPUT – merged cells, a nested table in a target cell, a wrong cell count, or a bad row_index REVISION_CONFLICT – document changed mid-call; re-read and retry SUGGESTIONS_PRESENT – tab has pending suggested edits; accept/reject them in the Docs UI first, then retry VERIFICATION_FAILED – post-write re-read does not match the requested cells INDEX_SIMULATION_FAILED – compiled requests would land at an invalid index; caught before the API call AUTH_EXPIRED – no valid token

cells string doc_id str tab_id str dry_run bool row_index int table_index int
insert_table
annotations: none low

Create a new table populated from rows, inserted after an anchor. Use this tool to add a brand-new table to a document tab. rows is a list of rows of plain strings — no markdown, no bolding applied — with the first row treated as the header positionally. anchor must be exact text present in the tab; the table is inserted after the paragraph containing it, the same anchoring insert_image uses. Set dry_run=true to preview without writing. dry_run is authoritative for index validity: the same assembled request list is index-simulated whether dry_run is true or false, and the suggestion guard below runs identically on both paths, so a passing dry_run means the real write will pass too — provided nothing about the document changes in between (a new suggestion, a concurrent edit) before the real write is issued. Returns evidence: applied, table_index (use it for follow-up replace_table_row calls), rows, columns, first_row, table_confirmed, revision_before, revision_after, audit_logged. Errors: TAB_NOT_FOUND – tab_id not in document QUOTE_NOT_FOUND – anchor not found; nearest candidates listed INVALID_INPUT – empty or ragged rows, a non-string cell, or an anchor that falls inside a table REVISION_CONFLICT – document changed mid-call; re-read and retry SUGGESTIONS_PRESENT – tab has pending suggested edits; accept/reject them in the Docs UI first, then retry VERIFICATION_FAILED – post-write re-read did not confirm the inserted table at the expected location INDEX_SIMULATION_FAILED – compiled requests would land at an invalid index; caught before the API call AUTH_EXPIRED – no valid token

rows string anchor str doc_id str tab_id str dry_run bool
export_pdf
annotations: none low

Export the whole document as a PDF to a local path. Use this tool when a caller needs a render-measured page count to check against a page limit, or simply needs a PDF copy on disk. Drive's export is doc-level, not tab-scoped, so this exports every tab in the document, not just one. output_path must fall inside VERIFIED_GOOGLEDOCS_MCP_ALLOWED_FILE_ROOTS (defaults to the user's home directory) and must never resolve to a credential path; its parent directory must already exist. page_count is best-effort and is None when the PDF hides its page markers inside a compressed stream — never a guessed number. Drive refuses exports whose PDF would exceed roughly 10 MB. This is a read/export tool: nothing in the document changes, so the return value has no "applied" key. Returns doc_id, output_path, bytes_written, sha256, page_count, existed_before, audit_logged. Errors: INVALID_INPUT – a bad output_path (missing parent directory, outside the allowed roots, a denylisted credential path, or an existing target that isn't a regular file), or Drive refused the export (not found, permission denied, or the size limit) AUTH_EXPIRED – no valid token

doc_id str output_path str

Permissions 3

network medium
Server uses network capabilities via: urllib
filesystem low
Server uses filesystem capabilities via: open(), os, pathlib, tempfile
env_vars low
Server uses env_vars capabilities via: os.environ

Scan Findings 95

low
Tool 'good_mutating' has no annotations annotation_checker · 100%
low
Tool 'bad_mutating' has no annotations annotation_checker · 100%
low
Tool 'non_mutating' has no annotations annotation_checker · 100%
low
Tool 'error_returning' has no annotations annotation_checker · 100%
low
Tool 'raises_tool_error' has no annotations annotation_checker · 100%
low
Tool 'random_read' has no annotations annotation_checker · 100%
low
Tool 'read' has no annotations annotation_checker · 100%
low
Tool 'sections' has no annotations annotation_checker · 100%
low
Tool 'dict_tool' has no annotations annotation_checker · 100%
low
Tool 'list_tool' has no annotations annotation_checker · 100%
low
Tool 'list_tabs' has no annotations annotation_checker · 100%
low
Tool 'read_document' has no annotations annotation_checker · 100%
low
Tool 'find_sections' has no annotations annotation_checker · 100%
low
Tool 'replace_text' has no annotations annotation_checker · 100%
low
Tool 'format_text' has no annotations annotation_checker · 100%
low
Tool 'list_open_items' has no annotations annotation_checker · 100%
low
Tool 'get_comment_thread_tool' has no annotations annotation_checker · 100%
low
Tool 'add_anchored_comment' has no annotations annotation_checker · 100%
low
Tool 'reply_to_comment' has no annotations annotation_checker · 100%
low
Tool 'resolve_comment' has no annotations annotation_checker · 100%
low
Tool 'replace_range_markdown' has no annotations annotation_checker · 100%
low
Tool 'replace_tab_markdown' has no annotations annotation_checker · 100%
low
Tool 'append_markdown' has no annotations annotation_checker · 100%
low
Tool 'insert_image' has no annotations annotation_checker · 100%
low
Tool 'diff_tab_vs_file' has no annotations annotation_checker · 100%
low
Tool 'list_tables' has no annotations annotation_checker · 100%
low
Tool 'get_table' has no annotations annotation_checker · 100%
low
Tool 'replace_table_row' has no annotations annotation_checker · 100%
low
Tool 'insert_table' has no annotations annotation_checker · 100%
low
Tool 'export_pdf' has no annotations annotation_checker · 100%
medium
OAuth implementation without PKCE auth_checker · 75%
info
Sandbox failed to start for behavioral verification behavioral_verifier · 100%
medium
Vulnerable dependency: fastmcp@3.0,<4 (GHSA-5h2m-4q8j-pqpj) dependency_analyzer · 95%
medium
Vulnerable dependency: fastmcp@3.0,<4 (GHSA-c2jp-c369-7pvx) dependency_analyzer · 95%
medium
Vulnerable dependency: fastmcp@3.0,<4 (GHSA-m8x7-r2rg-vh5g) dependency_analyzer · 95%
medium
Vulnerable dependency: fastmcp@3.0,<4 (GHSA-mxxr-jv3v-6pgc) dependency_analyzer · 95%
medium
Vulnerable dependency: fastmcp@3.0,<4 (GHSA-rcfx-77hg-w2wv) dependency_analyzer · 95%
medium
Vulnerable dependency: fastmcp@3.0,<4 (GHSA-rj5c-58rq-j5g5) dependency_analyzer · 95%
medium
Vulnerable dependency: fastmcp@3.0,<4 (GHSA-rww4-4w9c-7733) dependency_analyzer · 95%
medium
Vulnerable dependency: fastmcp@3.0,<4 (GHSA-vv7q-7jx5-f767) dependency_analyzer · 95%
medium
Vulnerable dependency: fastmcp@3.0,<4 (PYSEC-2026-1364) dependency_analyzer · 95%
medium
Vulnerable dependency: fastmcp@3.0,<4 (PYSEC-2026-1365) dependency_analyzer · 95%
medium
Vulnerable dependency: fastmcp@3.0,<4 (PYSEC-2026-2474) dependency_analyzer · 95%
medium
Vulnerable dependency: fastmcp@3.0,<4 (PYSEC-2026-2475) dependency_analyzer · 95%
medium
Vulnerable dependency: fastmcp@3.0,<4 (PYSEC-2026-2476) dependency_analyzer · 95%
medium
Vulnerable dependency: fastmcp@3.0,<4 (PYSEC-2026-338) dependency_analyzer · 95%
medium
Vulnerable dependency: mcp@1.27,<2 (GHSA-3qhf-m339-9g5v) dependency_analyzer · 95%
medium
Vulnerable dependency: mcp@1.27,<2 (GHSA-9h52-p55h-vw2f) dependency_analyzer · 95%
medium
Vulnerable dependency: mcp@1.27,<2 (GHSA-j975-95f5-7wqh) dependency_analyzer · 95%
medium
Vulnerable dependency: mcp@1.27,<2 (GHSA-jpw9-pfvf-9f58) dependency_analyzer · 95%
medium
Vulnerable dependency: mcp@1.27,<2 (GHSA-vj7q-gjh5-988w) dependency_analyzer · 95%
medium
Vulnerable dependency: mcp@1.27,<2 (PYSEC-2026-1616) dependency_analyzer · 95%
medium
Vulnerable dependency: mcp@1.27,<2 (PYSEC-2026-1617) dependency_analyzer · 95%
medium
Vulnerable dependency: mcp@1.27,<2 (PYSEC-2026-1618) dependency_analyzer · 95%
medium
Vulnerable dependency: mcp@1.27,<2 (PYSEC-2026-3482) dependency_analyzer · 95%
medium
Vulnerable dependency: mcp@1.27,<2 (PYSEC-2026-3483) dependency_analyzer · 95%
info
pyproject.toml metadata manifest_parser · 100%
info
Tool: good_mutating manifest_parser · 90%
info
Tool: bad_mutating manifest_parser · 90%
info
Tool: non_mutating manifest_parser · 90%
info
Tool: error_returning manifest_parser · 90%
info
Tool: raises_tool_error manifest_parser · 90%
info
Tool: random_read manifest_parser · 90%
info
Tool: read manifest_parser · 90%
info
Tool: sections manifest_parser · 90%
info
Tool: dict_tool manifest_parser · 90%
info
Tool: list_tool manifest_parser · 90%
info
Tool: list_tabs manifest_parser · 90%
info
Tool: read_document manifest_parser · 90%
info
Tool: find_sections manifest_parser · 90%
info
Tool: replace_text manifest_parser · 90%
info
Tool: format_text manifest_parser · 90%
info
Tool: list_open_items manifest_parser · 90%
info
Tool: get_comment_thread_tool manifest_parser · 90%
info
Tool: add_anchored_comment manifest_parser · 90%
info
Tool: reply_to_comment manifest_parser · 90%
info
Tool: resolve_comment manifest_parser · 90%
info
Tool: replace_range_markdown manifest_parser · 90%
info
Tool: replace_tab_markdown manifest_parser · 90%
info
Tool: append_markdown manifest_parser · 90%
info
Tool: insert_image manifest_parser · 90%
info
Tool: diff_tab_vs_file manifest_parser · 90%
info
Tool: list_tables manifest_parser · 90%
info
Tool: get_table manifest_parser · 90%
info
Tool: replace_table_row manifest_parser · 90%
info
Tool: insert_table manifest_parser · 90%
info
Tool: export_pdf manifest_parser · 90%
info
Required env vars (3) manifest_parser · 80%
info
Sandbox failed to start for output poisoning scan output_poisoning · 100%
medium
Permission: network access detected permission_analyzer · 80%
low
Permission: filesystem access detected permission_analyzer · 80%
low
Permission: env_vars access detected permission_analyzer · 90%
critical
Tool poisoning in 'list_tabs': Cross-tool prerequisite: 'use X tool first' poisoning · 85%
info
No dependency files found for SBOM generation sbom_generator · 100%
medium
No build provenance detected (SLSA L0) slsa_assessor · 90%