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

@attrove/mcp

v0.4.0

Published

Search Gmail, Slack, Outlook, Google Calendar, and meetings — one MCP, one query.

Readme

@attrove/mcp

Search Gmail, Slack, Outlook, Google Calendar, and meetings — one MCP, one query. Works in Claude Code, Cursor, Claude Desktop, and ChatGPT.

Installation

npm install @attrove/mcp
# or
yarn add @attrove/mcp
# or
pnpm add @attrove/mcp

Quick Start

Recommended: Attrove CLI

Use the CLI as the install layer for hosted OAuth MCP:

npx @attrove/cli install claude-code

That writes a remote MCP config pointed at https://api.attrove.com/mcp, lets Claude Code, Cursor, and Claude Desktop discover OAuth automatically, and avoids embedding sk_ secrets directly into client JSON.

Other hosted install commands:

npx @attrove/cli install cursor
npx @attrove/cli install claude-desktop

Claude Code defaults to project scope (.mcp.json). Cursor and Claude Desktop default to user scope.

Verify the first useful answer

After OAuth completes in your AI client, ask:

"Use Attrove to list my connected integrations."

You should see at least one connected source such as Gmail, Slack, Outlook, Google Calendar, Google Meet, or Teams. Then ask:

"What needs my attention this week? Include the source messages or meetings you used."

That second prompt is the activation check: it should return an answer grounded in your connected context, not just confirm that the MCP server is installed.

Advanced Local Fallback

Use the local stdio server only if you explicitly want local credential-backed MCP:

npx @attrove/cli login
npx @attrove/cli local install claude-code
npx @attrove/cli connect gmail

Claude Desktop

Claude Desktop supports two transport options:

HTTP transport (recommended) — uses OAuth discovery, no API key copy/paste needed:

{
  "mcpServers": {
    "attrove": {
      "type": "streamable-http",
      "url": "https://api.attrove.com/mcp"
    }
  }
}

Prefer npx @attrove/cli install claude-desktop to write this for you.

Legacy stdio transport — use only if you explicitly want local env-based auth:

{
  "mcpServers": {
    "attrove": {
      "command": "npx",
      "args": ["-y", "@attrove/mcp@latest"],
      "env": {
        "ATTROVE_SECRET_KEY": "sk_...",
        "ATTROVE_USER_ID": "user-uuid"
      }
    }
  }
}

Cursor

Preferred hosted install:

npx @attrove/cli install cursor

Or use Cursor's install URL from a partner-issued connect session. Manual remote config also works:

{
  "mcpServers": {
    "attrove": {
      "type": "http",
      "url": "https://api.attrove.com/mcp"
    }
  }
}

On first use, Cursor discovers OAuth via .well-known/oauth-protected-resource and sends the user through the Attrove connect flow automatically.

Claude Code (Terminal)

Preferred hosted install:

npx @attrove/cli install claude-code

If you are onboarding a provisioned end user from a terminal or agent, use the durable connect-session handoff:

npx @attrove/cli connect --session <session-id>

Advanced local fallback is still supported:

npx @attrove/cli login
npx @attrove/cli local install claude-code

ChatGPT (beta / fallback)

ChatGPT and other AI assistants that support MCP connectors can connect via the hosted HTTP endpoint.

ChatGPT's MCP install UX is still evolving. Treat it as a fallback path behind Claude Code, Cursor, and Claude Desktop.

Basic requirement: add https://api.attrove.com/mcp as a remote MCP server. OAuth-capable clients should discover the authorization flow automatically.

Example setup steps (may vary):

  1. Open ChatGPT Settings → Connectors → Enable Developer Mode
  2. Click Create Connector and configure:
    • Name: Attrove
    • URL: https://api.attrove.com/mcp
  3. If ChatGPT requests auth details manually instead of following OAuth discovery, use this path only as a temporary compatibility fallback.

Once connected, you can ask ChatGPT questions like:

  • "What emails need my attention this week?"
  • "Summarize my meeting with the marketing team"
  • "What has John been asking about lately?"

Direct CLI Usage

npx @attrove/cli install claude-code

# advanced local fallback:
npx @attrove/cli login
npx @attrove/cli local install claude-code
npx @attrove/cli connect gmail

# or manual env injection:
ATTROVE_SECRET_KEY=sk_... ATTROVE_USER_ID=user-uuid npx @attrove/mcp

Common Use Cases

Once connected, you can ask your AI assistant natural language questions. Here are some examples:

Meeting prep:

"What context do I need for my 2pm meeting with the marketing team?"

Email follow-ups:

"Are there any emails from last week that I haven't responded to?"

Project status:

"What's the latest on the Q4 roadmap discussions?"

People search:

"What has John from Acme Corp been asking about recently?"

Historical context:

"Find the thread where we discussed the pricing changes last month"

Available Tools

attrove_query

Ask questions about the user's communications and get AI-generated answers.

Parameters:

  • query (required): The question to ask
  • integration_ids (optional): Filter to specific integration IDs (array of UUID strings)
  • include_sources (optional): Include source snippets in the response
  • instructions (optional): Custom instructions for the AI — controls output format, filtering, and behavior. Takes priority over default style. Max 20,000 chars
  • context (optional): Authoritative reference data for answer generation. Treated as ground truth by the AI. Influences query rewriting but not used for vector search. Max 20,000 chars

Example prompts:

  • "What did Sarah say about the Q4 budget?"
  • "Summarize my meeting with the engineering team"
  • "What are the action items from yesterday's standup?"
  • "When is my next meeting with the product team?"
  • "What context do I need before my 3pm call?"

attrove_search

Search for specific messages or conversations.

Parameters:

  • query (required): The search query
  • after_date (optional): Only messages after this date (YYYY-MM-DD)
  • before_date (optional): Only messages before this date (YYYY-MM-DD)
  • sender_domains (optional): Filter by sender domains
  • include_body_text (optional): Include message content in results (default: true, bodies truncated to 1000 characters)

Example prompts:

  • "Find all emails about the product launch"
  • "Show me conversations with the marketing team"
  • "Search for messages mentioning the deadline extension"
  • "Find discussions with acme.com from last month"

attrove_integrations

List the user's connected integrations.

Parameters: None

Example prompts:

  • "What services are connected?"
  • "Show me my integrations"

attrove_events

List calendar events from the user's connected calendar accounts.

Parameters:

  • start_date (optional): Start of date range (YYYY-MM-DD)
  • end_date (optional): End of date range (YYYY-MM-DD)
  • limit (optional): Max events to return (default 25, max 100)

Example prompts:

  • "What's on my calendar today?"
  • "Do I have any meetings tomorrow?"
  • "When is my next meeting with Sarah?"
  • "What's my schedule for Friday?"

attrove_meetings

List meetings with AI-generated summaries and action items.

Parameters:

  • start_date (optional): Start of date range (YYYY-MM-DD)
  • end_date (optional): End of date range (YYYY-MM-DD)
  • provider (optional): Filter by meeting provider (google_meet, zoom, teams)
  • limit (optional): Max meetings to return (default 10, max 50)

Example prompts:

  • "What happened in my last meeting?"
  • "Summarize yesterday's standup"
  • "What are the action items from the product review?"
  • "Show me my recent meetings"

attrove_notes

List notes — analyst observations, partner-pushed context, and session summaries that have been RAG-indexed into the user's context.

Parameters:

  • ref_type (optional): Filter by reference type (message, meeting, event, entity)
  • ref_id (optional): Filter by referenced item ID (e.g. msg_xxx, mtg_xxx). Must be provided together with ref_type.
  • limit (optional): Max notes to return (default 20, max 100)

Example prompts:

  • "What notes do I have about the pricing discussion?"
  • "Show me notes linked to yesterday's standup"
  • "Have we captured any observations on this thread?"

attrove_push_note

Save a note to the user's Attrove context. Notes are RAG-indexed and become queryable via attrove_query and attrove_search, enabling AI assistants to capture decisions and session context that persists across conversations.

Parameters:

  • body (required): Note content (server-enforced max 10,000 characters)
  • title (optional): Short title for the note
  • ref_type (optional): Link to an existing item type. Must be provided together with ref_id.
  • ref_id (optional): ID of the item to link (e.g. msg_xxx, mtg_xxx, evt_xxx, ent_xxx)
  • external_id (optional): Dedup key. Re-pushing with the same external_id updates the existing note instead of creating a new one.

Example prompts:

  • "Save a note that we decided to use Redis for caching"
  • "Capture the takeaways from this meeting as a note"
  • "Remember that the Q4 revenue trend suggests we should pull in the launch"

attrove_push_meeting

Save a meeting transcript or summary to the user's Attrove context. Use this when another meeting MCP (Otter, Read.ai, Fireflies, Fathom) or a user-shared transcript (Granola export, voice memo, manual notes) has meeting content that should become queryable alongside Gmail, Slack, calendar, and native meeting data.

Parameters:

  • title (required): Meeting title
  • start_time (required): ISO 8601 datetime with timezone
  • end_time (required): ISO 8601 datetime with timezone
  • transcript (optional): Full meeting transcript
  • summary (optional): Detailed summary
  • short_summary (optional): 1-3 sentence summary
  • attendees (optional): Attendee objects with name and optional email
  • action_items (optional): Action item objects with text and optional assignee
  • external_id (optional): Dedup key. Re-pushing with the same external_id updates the existing meeting.

Example prompts:

  • "Save this Granola transcript into Attrove"
  • "Import the Fireflies meeting summary so I can query it later"
  • "Add these manual meeting notes to my communication context"

Environment Variables

These are only required for stdio / manual installs. Remote HTTP MCP installs do not need them.

| Variable | Required | Description | |----------|----------|-------------| | ATTROVE_SECRET_KEY | Yes | Your Attrove secret key (sk_...) | | ATTROVE_USER_ID | Yes | User ID to scope API calls | | ATTROVE_BASE_URL | No | Custom API base URL | | ATTROVE_DEBUG | No | Set to true for verbose error logging |

Programmatic Usage

You can also use the server programmatically:

import { createServer, startServer } from '@attrove/mcp';

// Create a server instance
const server = createServer({
  apiKey: 'sk_...',
  userId: 'user-uuid'
});

// Or start directly with stdio transport
await startServer({
  apiKey: 'sk_...',
  userId: 'user-uuid'
});

HTTP Endpoint (Hosted)

For AI assistants that connect via HTTP, prefer adding the hosted endpoint directly and letting the client discover OAuth:

  • MCP URL: https://api.attrove.com/mcp
  • OAuth discovery: https://api.attrove.com/.well-known/oauth-protected-resource

Manual curl testing can still use bearer auth:

# Test the endpoint
curl -X POST https://api.attrove.com/mcp \
  -H "Authorization: Bearer sk_..." \
  -H "X-Attrove-User-Id: user-uuid" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'

Or integrate in your own server using the HTTP handler:

import { createHttpHandler } from '@attrove/mcp';

const handler = createHttpHandler(
  {
    apiKey: 'sk_...',
    userId: 'user-uuid',
    baseUrl: 'https://api.attrove.com', // optional: custom API endpoint
  },
  {
    enableJsonResponse: true, // optional: use JSON instead of SSE (default: true)
    timeoutMs: 30000, // optional: request timeout in ms (default: 30000)
  }
);

// With Fastify (recommended)
fastify.post('/mcp', async (request, reply) => {
  const result = await handler.handleRequest(request.raw, reply.raw, request.body);

  if (!result.handled) {
    // Handle timeout with 504, other errors with 500
    const statusCode = result.isTimeout ? 504 : 500;
    const userMessage = result.isTimeout
      ? 'Request timed out. Try a simpler query or reduce the scope.'
      : 'An unexpected error occurred. Please try again.';

    // Only send response if headers haven't been sent (e.g., during streaming)
    if (!reply.raw.headersSent) {
      reply.code(statusCode).send({
        success: false,
        error: { code: result.isTimeout ? 'REQUEST_TIMEOUT' : 'INTERNAL_ERROR', message: userMessage }
      });
    } else if (!reply.raw.writableEnded) {
      reply.raw.end(); // Ensure stream is closed
    }
    return;
  }

  // Optional: monitor cleanup failures for resource leak detection
  if (result.cleanupFailed) {
    console.warn('MCP cleanup failed - potential resource leak');
  }
});

// With raw Node.js HTTP server
import { createServer } from 'node:http';
const server = createServer(async (req, res) => {
  // Note: You'll need to parse the body yourself for raw HTTP
  const result = await handler.handleRequest(req, res);
  if (!result.handled) {
    res.writeHead(500, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ error: result.error }));
  }
});

Getting API Credentials

  1. Sign up at attrove.com
  2. Create an organization in the dashboard
  3. Generate an API key (sk_...)
  4. Provision a user to get a user ID
import { Attrove } from '@attrove/sdk';

const admin = Attrove.admin({
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret'
});

// Create a user
const { id, apiKey } = await admin.users.create({
  email: '[email protected]'
});

// Use `apiKey` as ATTROVE_SECRET_KEY and `id` as ATTROVE_USER_ID

Troubleshooting

"ATTROVE_SECRET_KEY environment variable is required"

Make sure you've set the environment variables correctly in your MCP configuration.

Tools not showing up

  1. Restart Claude/Cursor after configuration changes
  2. Check the MCP server logs for errors
  3. Verify your API key is valid

Debugging errors

Set ATTROVE_DEBUG=true to enable verbose error logging with stack traces:

{
  "mcpServers": {
    "attrove": {
      "command": "npx",
      "args": ["-y", "@attrove/mcp@latest"],
      "env": {
        "ATTROVE_SECRET_KEY": "sk_...",
        "ATTROVE_USER_ID": "user-uuid",
        "ATTROVE_DEBUG": "true"
      }
    }
  }
}

Rate limiting

The Attrove API has rate limits. If you're making many requests, you may need to wait before trying again.

Requirements

  • Node.js 18.0.0 or later

AI-Friendly Documentation

For AI assistants and code generation tools, Attrove provides machine-readable documentation:

  • llms.txt: https://attrove.com/llms.txt - Condensed API reference for LLMs
  • Examples: https://github.com/attrove/examples - Example code with CLAUDE.md context

Links

License

MIT