Skip to main content
Glama
giantrotta24

google-mcp

by giantrotta24

gmail_search_personal

Search your personal Gmail account using query parameters to find specific emails. Control the number of results returned.

Instructions

Search Gmail for the configured personal account.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes
max_resultsNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • tools.py:30-36 (handler)
    The tool handler for gmail_search_personal. Decorated with @mcp.tool(). Loads personal account credentials, then calls gmail_search() from api.py.
    @mcp.tool()
    def gmail_search_personal(query: str, max_results: int = 20) -> dict[str, Any]:
        """Search Gmail for the configured personal account."""
        result = _load_or_error("personal")
        if isinstance(result, dict):
            return result
        return gmail_search(result, query, max_results)
  • tools.py:30-30 (registration)
    Tool registration via FastMCP @mcp.tool() decorator on the gmail_search_personal function.
    @mcp.tool()
  • Helper that loads credentials for the given account and wraps RuntimeError into an error envelope.
    def _load_or_error(account: Account):
        """Return credentials or an error envelope if Keychain lookup fails."""
        try:
            return load_credentials(account)
        except RuntimeError as e:
            return {"ok": False, "error": str(e), "code": 401}
  • api.py:35-95 (helper)
    Core Gmail search logic called by gmail_search_personal. Builds Gmail API service, lists messages matching query, fetches metadata for each, and returns results.
    def gmail_search(
        creds: Credentials,
        query: str,
        max_results: int = 20,
    ) -> dict[str, Any]:
        """Search Gmail and return message summaries."""
        from google.auth.exceptions import RefreshError
        from googleapiclient.discovery import build
    
        max_results = min(max_results, 50)
    
        try:
            service = build("gmail", "v1", credentials=creds)
    
            list_response = (
                service.users()
                .messages()
                .list(userId="me", q=query, maxResults=max_results)
                .execute(num_retries=3)
            )
    
            messages = list_response.get("messages", [])
            results: list[dict[str, Any]] = []
    
            for msg in messages:
                detail = (
                    service.users()
                    .messages()
                    .get(
                        userId="me",
                        id=msg["id"],
                        format="metadata",
                        metadataHeaders=["From", "Subject", "Date"],
                    )
                    .execute(num_retries=3)
                )
    
                headers = {
                    h["name"]: h["value"] for h in detail.get("payload", {}).get("headers", [])
                }
    
                results.append(
                    {
                        "id": detail["id"],
                        "thread_id": detail["threadId"],
                        "from": headers.get("From", ""),
                        "subject": headers.get("Subject", ""),
                        "date": headers.get("Date", ""),
                        "snippet": detail.get("snippet", ""),
                        "labels": detail.get("labelIds", []),
                    }
                )
    
            return {"ok": True, "data": results}
    
        except HttpError as e:
            return _parse_http_error(e)
        except RefreshError as e:
            return {"ok": False, "error": f"token refresh failed: {e}", "code": 401}
        except Exception as e:
            return {"ok": False, "error": f"upstream failure: {type(e).__name__}", "code": 503}
  • Type definition for Account (Literal['personal', 'work']) used in the tool signature and throughout the codebase.
    Account = Literal["personal", "work"]
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral disclosure. It only states 'search', implying a read operation but does not confirm safety, auth needs, rate limits, or any side effects. Minimal transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is very short (one sentence), front-loaded, but at the cost of completeness. It does not convey enough detail, so conciseness is average.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple tool and existence of output schema, the description is minimally adequate but lacks details on search behavior, limitations, or account specificity beyond the name. Could be more complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so description must compensate. It adds no meaning beyond the parameter names (query, max_results). No explanation of query format, max_results bounds, or defaults. Fails to compensate for low schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Search Gmail for the configured personal account' uses a specific verb ('Search') and resource ('Gmail'), and distinguishes from sibling tool 'gmail_search_work' by specifying 'personal account'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for personal account searches via 'personal account', providing clear context. However, it does not explicitly state when not to use or mention alternatives, though the sibling differentiation helps.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/giantrotta24/multi-account-google-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server