npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vinisxs/email-agent-proxy

v0.2.1

Published

MCP server exposing the Agent Gateway email API as typed tools for MCP-aware agent runtimes

Readme

Intents MCP Server

Model Context Protocol (MCP) server for the Email Agent Intents API.

Overview

This package provides an MCP-compatible interface to the Email Agent Intents API, enabling AI assistants (Hermes, OpenClawd, opencode, and other MCP-aware agents) to create, query, and manage email agent actions through a standardized MCP tool interface.

This is the canonical documentation for personal AI agents. A distributable skill describing the MCP tools ships alongside the server at skill/SKILL.md — install it together with the server in any skill-aware runtime.

Tools

Agents interact with an email-inbox metaphor, not the intent queue. Every write tool creates a pending intent behind the scenes and returns an optimistic response; the intent queue itself is invisible to agents (see the agent-gateway spec).

email.search

Search the whole mailbox — not just the inbox — using Gmail search operators, backed by GET /api/v1/messages/search. Results merge mirror rows with pending intent overlays (pending sends appear in results; pending label/archive/move changes are reflected before they execute), and reach mail outside the local mirror by delegating to Gmail and hydrating the missing messages on demand.

q accepts Gmail operators — from:, to:, cc:, bcc:, subject:, label:, in:, is: (unread/read/starred), has: (e.g. has:attachment), filename:, after:, before:, older_than:, newer_than:, larger:, smaller: — plus quoted phrases, OR, and - negation. Plain terms match subject/snippet. Omit q to list recent messages; is_read and labels filter that plain list (they are ignored when q is present, since q already expresses is:/label:).

Input:

{
  "q": "from:[email protected] subject:invoice after:2024/01/01 -label:archived",
  "is_read": true,
  "labels": "optional,comma,separated,list",
  "limit": 20,
  "offset": 0
}

All fields are optional. limit is 1–50 (default 20); offset defaults to 0.

Output:

{
  "isError": false,
  "data": {
    "messages": [
      {
        "id": "message-id",
        "thread_id": "thread-id",
        "subject": "...",
        "snippet": "...",
        "labels": ["INBOX"],
        "is_read": false,
        "is_starred": false,
        "received_at": "2024-01-01T00:00:00Z",
        "status": "mirrored",
        "action_type": "optional-pending-action-type"
      }
    ],
    "total": 100,
    "limit": 20,
    "offset": 0
  }
}

email.read

Read a single email by message ID. Accepts a mirror ID or a virtual msg:pending:<action_id> ID for a pending send/reply.

Input:

{ "message_id": "required-message-id" }

Output: a single message object with the same shape as the entries in email.search.

email.send

Send a new email. Creates a Gmail draft and a pending intent; returns optimistically.

Input:

{
  "to": "[email protected]",
  "subject": "Subject",
  "body": "Body text",
  "cc": "optional-address-or-array",
  "bcc": "optional-address-or-array"
}

Output:

{
  "isError": false,
  "data": {
    "id": "msg:pending:<action_id>",
    "status": "pending"
  }
}

email.reply

Reply to an existing email.

Input:

{
  "message_id": "required-message-id",
  "body": "Reply text",
  "cc": "optional-address-or-array",
  "bcc": "optional-address-or-array"
}

Output: same shape as email.send.

email.archive

Archive an email. Input: { "message_id": "required-message-id" }

email.apply_label

Apply labels to an email. Input: { "message_id": "required-message-id", "labels": ["Label1", "Label2"] }

email.move

Move an email to a folder. Input: { "message_id": "required-message-id", "folder": "folder-name" }

email.mark_read / email.mark_unread

Mark an email as read/unread. Input: { "message_id": "required-message-id" }

email.delete

Delete an email. Input: { "message_id": "required-message-id" }

send and reply return { id: "msg:pending:<action_id>", status: "pending" } — a virtual id, since the message doesn't exist yet. archive, apply_label, move, mark_read, mark_unread, and delete mutate an existing message and return { id: "<message_id>", status: "pending" }, echoing back the same id the tool was called with.

Configuration

The server requires two environment variables:

| Variable | Description | Required | |----------|-------------|----------| | MAIL_API_BASE_URL | Base URL of the Intents API (must be absolute http/https) | Yes | | MAIL_AGENT_API_KEY | API key for authentication | Yes | | MAIL_REQUEST_TIMEOUT_MS | Request timeout in milliseconds (default: 10000) | No |

Security

  • Never commit the API key: The MAIL_AGENT_API_KEY is a secret. Never embed it in config files, transcripts, or tool outputs.
  • 401 as configuration error: If you receive a 401, the API key is invalid or missing — treat it as a configuration problem, not a retryable error.
  • Key scoping: Use a scoped API key with minimal permissions for the MCP server.

Launching the Server

Configure with init

The fastest way to set up the server is the built-in init command. It collects the two required settings, verifies them against the API, and prints a ready-to-paste MCP config block for your agent runtime (Hermes, OpenClawd, opencode, and other mcpServers-based clients):

npx -y @vinisxs/email-agent-proxy init

Run it with no flags to be prompted interactively, or pass values directly for a scripted setup:

npx -y @vinisxs/email-agent-proxy init \
  --url https://api.example.com \
  --key "$MAIL_AGENT_API_KEY"

init also reads MAIL_API_BASE_URL / MAIL_AGENT_API_KEY from the environment. It probes GET /api/v1/messages/search to confirm the key works and a mailbox is connected; pass --no-check to skip the probe. The generated block embeds your API key — keep the resulting config file private and never commit it.

Install from npm (recommended for external consumers)

Published as @vinisxs/email-agent-proxy — public, no auth or repo access needed:

npx -y @vinisxs/email-agent-proxy

Hermes / OpenClawd / opencode

Add to your MCP configuration:

{
  "mcpServers": {
    "intents": {
      "command": "npx",
      "args": ["-y", "@vinisxs/email-agent-proxy"],
      "env": {
        "MAIL_API_BASE_URL": "${MAIL_API_BASE_URL}",
        "MAIL_AGENT_API_KEY": "${MAIL_AGENT_API_KEY}"
      }
    }
  }
}

opencode

For development/testing in this repository, the server is registered in .opencode/mcp.json. Set the environment variables before running opencode:

export MAIL_API_BASE_URL=http://localhost:3000
export MAIL_AGENT_API_KEY=your-api-key
opencode

Build from source (internal/dev)

For working on the server itself, or for runtimes that need a local path instead of npx:

# Build the package first
cd packages/intents-mcp && pnpm build

# Run with environment variables
MAIL_API_BASE_URL=https://api.example.com \
MAIL_AGENT_API_KEY=your-api-key \
node packages/intents-mcp/dist/index.js

Or for development:

MAIL_API_BASE_URL=https://api.example.com \
MAIL_AGENT_API_KEY=your-api-key \
cd packages/intents-mcp && pnpm dev

Releasing

Publishing runs in CI (.github/workflows/publish-intents-mcp.yml) on tag push:

# bump "version" in package.json first, commit it, then:
git tag intents-mcp-vX.Y.Z
git push origin intents-mcp-vX.Y.Z

Curl Fallback

If the MCP server is unavailable, you can call the REST API directly:

Search Emails

q takes Gmail operators (whole-mailbox reach); URL-encode it. /api/v1/messages?q= remains accepted for backward compatibility.

curl -G "${MAIL_API_BASE_URL}/api/v1/messages/search" \
  --data-urlencode "q=from:alice subject:invoice" --data-urlencode "limit=10" \
  -H "Authorization: Bearer ${MAIL_AGENT_API_KEY}"

Read Email

curl "${MAIL_API_BASE_URL}/api/v1/messages/${message_id}" \
  -H "Authorization: Bearer ${MAIL_AGENT_API_KEY}"

Send Email

curl -X POST "${MAIL_API_BASE_URL}/api/v1/messages" \
  -H "Authorization: Bearer ${MAIL_AGENT_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"to": "[email protected]", "subject": "Hello", "body": "World"}'

Reply to Email

curl -X POST "${MAIL_API_BASE_URL}/api/v1/messages/${message_id}/reply" \
  -H "Authorization: Bearer ${MAIL_AGENT_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"body": "Reply text"}'

Source of Truth

The MCP server source code (packages/intents-mcp/src/) is the authoritative source for input validation schemas and tool behavior. If this documentation conflicts with the actual server behavior, the source code is correct.

Development

# Install dependencies
pnpm install

# Build
pnpm build

# Run tests
pnpm test

# Type check
pnpm typecheck

Architecture

  • src/config.ts - Configuration loading and validation
  • src/schemas.ts - Zod schemas for tool input validation
  • src/http.ts - HTTP client for the Intents API
  • src/logger.ts - Structured logging with pino
  • src/errors.ts - Error mapping to MCP tool results
  • src/server.ts - MCP server setup and tool registration
  • src/index.ts - Entry point