MCP server for Attrove — AI-powered context retrieval from Gmail, Slack, Calendar for Claude, Cursor, and ChatGPT
npm install @attrove/mcpMCP (Model Context Protocol) server for Attrove. Enables AI assistants like Claude and Cursor to access your users' unified context from Gmail, Slack, Google Calendar, and more.
``bash`
npm install @attrove/mcpor
yarn add @attrove/mcpor
pnpm add @attrove/mcp
Claude Desktop supports two transport options:
HTTP transport (recommended) — uses OAuth 2.1, no API key needed:
`json`
{
"mcpServers": {
"attrove": {
"type": "streamable-http",
"url": "https://api.attrove.com/mcp"
}
}
}
Stdio transport — add to your Claude Desktop configuration (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
`json`
{
"mcpServers": {
"attrove": {
"command": "npx",
"args": ["-y", "@attrove/mcp@latest"],
"env": {
"ATTROVE_SECRET_KEY": "sk_...",
"ATTROVE_USER_ID": "user-uuid"
}
}
}
}
1. Open Cursor Settings (Cmd+, on macOS, Ctrl+, on Windows/Linux)
2. Search for "MCP" or navigate to Features > MCP Servers
3. Click "Edit in settings.json" or add directly:
`json`
{
"mcpServers": {
"attrove": {
"command": "npx",
"args": ["-y", "@attrove/mcp@latest"],
"env": {
"ATTROVE_SECRET_KEY": "sk_...",
"ATTROVE_USER_ID": "user-uuid"
}
}
}
}
4. Restart Cursor for changes to take effect
5. In the chat, you can now ask questions about your connected integrations
If using Claude Code in the terminal, the MCP server is configured via environment variables:
`bash`
export ATTROVE_SECRET_KEY="sk_..."
export ATTROVE_USER_ID="user-uuid"
ChatGPT and other AI assistants that support MCP connectors can connect via the hosted HTTP endpoint.
> Note: ChatGPT's connector interface may change over time. If these steps don't match your experience, refer to OpenAI's current documentation for the latest instructions.
Basic requirements:
- HTTP endpoint URL: https://api.attrove.com/mcpsk_...
- Authentication: Bearer token ()X-Attrove-User-Id
- Custom header: with your user UUID
Example setup steps (may vary):
1. Open ChatGPT Settings → Connectors → Enable Developer Mode
2. Click Create Connector and configure:
- Name: Attrovehttps://api.attrove.com/mcp
- URL: sk_...
- Authentication: Bearer token
- Token: Your API key ()X-Attrove-User-Id
3. Add custom header:
- Header:
- Value: Your user ID (UUID)
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?"
`bash`
ATTROVE_SECRET_KEY=sk_... ATTROVE_USER_ID=user-uuid npx @attrove/mcp
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"
Ask questions about the user's communications and get AI-generated answers.
Parameters:
- query (required): The question to askintegration_ids
- (optional): Filter to specific integration IDs (array of UUID strings)include_sources
- (optional): Include source snippets in the response
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?"
Search for specific messages or conversations.
Parameters:
- query (required): The search queryafter_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 domainsinclude_body_text
- (optional): Include message content in results (default: true, bodies truncated to 200 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"
List the user's connected integrations.
Parameters: None
Example prompts:
- "What services are connected?"
- "Show me my integrations"
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?"
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"
| 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 |
You can also use the server programmatically:
`typescript
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'
});
`
For AI assistants that connect via HTTP (like ChatGPT), use the hosted endpoint:
`bash`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:
`typescript
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 }));
}
});
`
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
`typescript
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: 'user@example.com'
});
// Use apiKey as ATTROVE_SECRET_KEY and id as ATTROVE_USER_ID`
Make sure you've set the environment variables correctly in your MCP configuration.
1. Restart Claude/Cursor after configuration changes
2. Check the MCP server logs for errors
3. Verify your API key is valid
Set ATTROVE_DEBUG=true to enable verbose error logging with stack traces:
`json`
{
"mcpServers": {
"attrove": {
"command": "npx",
"args": ["-y", "@attrove/mcp@latest"],
"env": {
"ATTROVE_SECRET_KEY": "sk_...",
"ATTROVE_USER_ID": "user-uuid",
"ATTROVE_DEBUG": "true"
}
}
}
}
The Attrove API has rate limits. If you're making many requests, you may need to wait before trying again.
- Node.js 18.0.0 or later
For AI assistants and code generation tools, Attrove provides machine-readable documentation:
- llms.txt: https://attrove.com/llms.txt - Condensed API reference for LLMshttps://github.com/attrove/examples` - Example code with CLAUDE.md context
- Examples:
- Documentation
- API Reference
- TypeScript SDK
- Examples
MIT