Skip to content

Add full Gmail connector tools#32

Merged
pmbstyle merged 1 commit intomainfrom
feat/gmail-full-tools
Apr 6, 2026
Merged

Add full Gmail connector tools#32
pmbstyle merged 1 commit intomainfrom
feat/gmail-full-tools

Conversation

@pmbstyle
Copy link
Copy Markdown
Owner

@pmbstyle pmbstyle commented Apr 6, 2026

Summary

  • add full Gmail connector support for send/reply, archive/trash/delete, read-unread, labels, and attachment download
  • add convenience Gmail helpers for label-by-name and Inbox/archive aliases
  • update connector docs and bump version to 0.4.8

Testing

  • uv run pytest tests/test_gmail_mcp_server.py tests/test_connector_tools.py
  • uv run ruff check src/octopal/mcp_servers/gmail.py src/octopal/tools/connectors/gmail.py tests/test_gmail_mcp_server.py tests/test_connector_tools.py

Copy link
Copy Markdown
Owner Author

@pmbstyle pmbstyle left a comment

Choose a reason for hiding this comment

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

PR Review: Add full Gmail connector tools 👻

Solid work overall. Clean architecture, good test coverage, proper error handling. Here's my analysis:

✅ What I like

Well-layered architecture — MCP server (API client) cleanly separated from connector tools (proxy layer). The _gmail_tool factory pattern is elegant and consistent.

Robust email building_build_raw_message handles multipart (text+HTML), proper threading headers (In-Reply-To, References), address normalization with deduplication. Good stuff.

Error handlingGmailApiError with structured reason/message/details, graceful non-JSON fallback, 401 auto-retry with token refresh.

Test coverage — Unit tests for all helpers + integration tests for API methods with mock HTTP clients. The BytesParser roundtrip test for _build_raw_message is especially nice.

Input boundsmax_results capped at 25, batch_get_messages limited to 25 IDs. Smart.

⚠️ Issues worth addressing

1. json parameter shadows built-in module

In GmailApiClient._request(), the json kwarg shadows the json module imported at the top of the file. This works because Python closures, but it's a bug magnet:

async def _request(self, method, path, *, params=None, json=None):

Suggest renaming to json_body or json_payload.

2. list_messages auto-hydrates N+1

When list_messages returns 25 message IDs, it immediately fires 25 parallel get_message calls via asyncio.gather. For max_results=25 that's 26 API calls in one method. This could:

  • Hit Gmail API rate limits (especially in batch scenarios)
  • Make it impossible to get just the IDs without hydration

Consider: add a hydrate=True parameter, or return IDs by default and let callers hydrate as needed.

3. _resolve_label_id has no caching

Every add_label_by_name / remove_label_by_name call fetches ALL labels to resolve the name→ID mapping. If an agent does 5 label operations, that's 5 full label list fetches. A simple LRU cache (or even a dict with TTL) would help.

4. delete_message is permanent with no safety net

The tool permanently deletes email. Even at the tool schema level, there's no confirmation mechanism. Consider:

  • Adding a confirm boolean parameter that must be true
  • Or at minimum, return a warning in the description

5. Version skip: 0.4.6 → 0.4.8

Skipping 0.4.7 — intentional or leftover from a squash?

💡 Nice-to-haves (non-blocking)

  • gmail_send_message schema has no max length on to/cc/bcc arrays — consider capping at ~50 recipients
  • _extract_body doesn't handle charset parameter in Content-Type — could garble non-UTF8 emails
  • No draft support — would be useful for review-before-send workflows

Verdict: Ship it ✅

The issues above are follow-ups, not blockers. The core is solid. Well done.

Copy link
Copy Markdown
Owner Author

@pmbstyle pmbstyle left a comment

Choose a reason for hiding this comment

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

Nice

@pmbstyle pmbstyle merged commit 9d71543 into main Apr 6, 2026
3 checks passed
@pmbstyle pmbstyle deleted the feat/gmail-full-tools branch April 6, 2026 22: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.

1 participant