Skip to content

Scaffold the Gemini CLI Transform extension#1

Merged
simoncoombes merged 2 commits into
mainfrom
scaffold-gemini-extension
Jul 16, 2026
Merged

Scaffold the Gemini CLI Transform extension#1
simoncoombes merged 2 commits into
mainfrom
scaffold-gemini-extension

Conversation

@simoncoombes

@simoncoombes simoncoombes commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

This adds the scaffolding for the Gemini CLI extension, per the proposal William approved when spinning up the repo. The extension installs the Transform MCP server into Gemini CLI over browser OAuth, no API key needed.

What is here

  • gemini-extension.json - the extension manifest (server URL, version, contextFileName).
  • AGENTS.md - agent guidance that ships with the extension: the upload/PUT/file_ref flow, poll-do-not-resubmit, the prompt-injection boundary, and the OAuth-first auth note.
  • README.md - install command, usage, and links out to the docs and the unstructured-mcp-integrations index for other tools.
  • LICENSE (MIT), CONTRIBUTING.md, CODEOWNERS, editor/attributes/ignore dotfiles.
  • scripts/validate.sh - plain-bash check that the manifest is valid JSON and every file references the same server URL, wired into CI (.github/workflows/validate.yml).

Most of this content was written and reviewed earlier in the retired transform-mcp-helper repo; this is the Gemini-only slice, moved to its own repo because Gemini installs and lists one extension per repo.

How it was verified

  • ./scripts/validate.sh passes locally.
  • Confirmed against the gemini-cli docs that a GitHub-URL install updates via git ls-remote on the default branch (documented in CONTRIBUTING.md), so the manifest version does not drive updates for this install method.

After merge

Add the gemini-cli-extension topic and repo description, then a follow-up PR to unstructured-mcp-integrations adding an index row that links here.


Summary by cubic

Scaffolded the Unstructured Transform extension for Gemini CLI, adding the manifest, agent guidance, and validation workflow. Installs the transform MCP server in gemini via browser OAuth (no API key) to parse documents into markdown, JSON, HTML, or text.

  • New Features

    • Added gemini-extension.json with contextFileName and mcpServers.transform.httpUrl set to https://mcp.transform.unstructured.io.
    • Included AGENTS.md with upload/PUT/file_ref flow, polling guidance with backoff, error handling, and auth boundaries.
    • Wrote README.md with install and usage; added LICENSE, CONTRIBUTING.md, CODEOWNERS, and editor/ignore configs.
    • Added scripts/validate.sh and CI to enforce JSON validity and server URL consistency; hardened to parse JSON with python3 if jq is absent, match the URL as a fixed string, scan all tracked files via git, and pinned actions/checkout to v4.2.2.
  • Migration

    • Install: gemini extensions install https://github.com/Unstructured-IO/transform-gemini-extension
    • Then run: /mcp auth transform to sign in via browser OAuth.

Written for commit cd6db6a. Summary will update on new commits.

Review in cubic

Add the extension manifest, agent guidance, docs, license, and a bash
consistency check with CI. Installs the Transform MCP server
(https://mcp.transform.unstructured.io) into Gemini CLI over OAuth.
@socket-security

socket-security Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedactions/​checkout@​11bd71901bbe5b1630ceea73d27597364c9af68399100100100100

View full report

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 11 files

Tip: instead of fixing issues one by one fix them all with cubic

Re-trigger cubic

Comment thread scripts/validate.sh
Comment thread scripts/validate.sh
Comment thread scripts/validate.sh Outdated
Comment thread .github/workflows/validate.yml Outdated
Comment thread AGENTS.md Outdated
Comment thread README.md Outdated
- validate.sh: match the server URL as a fixed string (dots were being
  treated as regex wildcards), parse the manifest with python3 when jq is
  absent instead of scanning text, and derive the checked file list from
  git ls-remote so new files are covered.
- Pin actions/checkout to the v4.2.2 commit SHA.
- README: describe the check as 'no file references a different URL'.
- AGENTS.md: tell agents to back off between status polls.
@simoncoombes

Copy link
Copy Markdown
Contributor Author

Thanks, good catches. All six addressed in cd6db6a:

  • The fixed-string matching one was a real bug: the canonical URL was used as a regex, so the dots matched any character. Switched to grep -F/grep -Fvqx, and added a mutation test locally to confirm a near-miss like mcpXtransform... now fails.
  • validate.sh now parses the manifest with python3 when jq is missing instead of text-scanning, and derives the file list from git ls-files so new files are covered by the drift check rather than a fixed allowlist.
  • Pinned actions/checkout to the v4.2.2 commit SHA.
  • Reworded the README validation line to "no file references a different URL", and added backoff guidance to the polling step in AGENTS.md.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="scripts/validate.sh">

<violation number="1" location="scripts/validate.sh:63">
P2: A URL with userinfo, a port, or a query is truncated before comparison, so a different endpoint can pass this all-tracked-file check; for example, `https://mcp.transform.unstructured.io@attacker.example` is reduced to the canonical hostname. Comparing complete URL tokens (or parsing the URL) would preserve the intended drift detection.</violation>

<violation number="2" location="scripts/validate.sh:67">
P2: Outside a Git worktree, `git ls-files` fails but this process substitution hides the failure, so the loop scans nothing and the script reports success. Capturing the file list with an explicit status check, or failing when `git ls-files` cannot run, would prevent the consistency check from being silently bypassed.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread scripts/validate.sh
| grep -Fvqx "$canonical"; then
err "$f references a server URL that differs from the canonical one ($canonical)"
fi
done < <(git ls-files)

@cubic-dev-ai cubic-dev-ai Bot Jul 16, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Outside a Git worktree, git ls-files fails but this process substitution hides the failure, so the loop scans nothing and the script reports success. Capturing the file list with an explicit status check, or failing when git ls-files cannot run, would prevent the consistency check from being silently bypassed.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/validate.sh, line 67:

<comment>Outside a Git worktree, `git ls-files` fails but this process substitution hides the failure, so the loop scans nothing and the script reports success. Capturing the file list with an explicit status check, or failing when `git ls-files` cannot run, would prevent the consistency check from being silently bypassed.</comment>

<file context>
@@ -12,40 +12,59 @@ err() {
+                | grep -Fvqx "$canonical"; then
+            err "$f references a server URL that differs from the canonical one ($canonical)"
+        fi
+    done < <(git ls-files)
 fi
 
</file context>
Fix with cubic

Comment thread scripts/validate.sh
while IFS= read -r f; do
[ "$f" = "scripts/validate.sh" ] && continue
[ -f "$f" ] || continue
if grep -oE 'https://mcp\.[A-Za-z0-9./-]*[A-Za-z0-9/-]' "$f" 2>/dev/null \

@cubic-dev-ai cubic-dev-ai Bot Jul 16, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: A URL with userinfo, a port, or a query is truncated before comparison, so a different endpoint can pass this all-tracked-file check; for example, https://mcp.transform.unstructured.io@attacker.example is reduced to the canonical hostname. Comparing complete URL tokens (or parsing the URL) would preserve the intended drift detection.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/validate.sh, line 63:

<comment>A URL with userinfo, a port, or a query is truncated before comparison, so a different endpoint can pass this all-tracked-file check; for example, `https://mcp.transform.unstructured.io@attacker.example` is reduced to the canonical hostname. Comparing complete URL tokens (or parsing the URL) would preserve the intended drift detection.</comment>

<file context>
@@ -12,40 +12,59 @@ err() {
+    while IFS= read -r f; do
+        [ "$f" = "scripts/validate.sh" ] && continue
+        [ -f "$f" ] || continue
+        if grep -oE 'https://mcp\.[A-Za-z0-9./-]*[A-Za-z0-9/-]' "$f" 2>/dev/null \
+                | grep -Fvqx "$canonical"; then
+            err "$f references a server URL that differs from the canonical one ($canonical)"
</file context>
Suggested change
if grep -oE 'https://mcp\.[A-Za-z0-9./-]*[A-Za-z0-9/-]' "$f" 2>/dev/null \
if grep -oE 'https://mcp\.[A-Za-z0-9./:@?&=%_+#~-]*[A-Za-z0-9/@?&=%_+#~-]' "$f" 2>/dev/null \
Fix with cubic

@nisha-pm nisha-pm left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@simoncoombes
simoncoombes merged commit 66d1f5d into main Jul 16, 2026
4 checks passed
@simoncoombes
simoncoombes deleted the scaffold-gemini-extension branch July 16, 2026 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants