Gmail访问库

一个TypeScript npm包,提供通过官方Google SDK访问Gmail的功能,支持双模式:独立MCP stdio服务器和Node.js/TypeScript项目的库集成。

  • by appler1009
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 appler1009/gmail-mcp-lib

使用说明

gmail mcp库

TypeScript npm包通过官方Google SDK提供Gmail访问,支持双模:独立的MCP(模型上下文协议)stdio服务器和库,便于集成到Node.js/TypeScript项目中。

特性

  • 双模式:用作独立的MCP服务器或作为库导入
  • 类型安全:所有Gmail操作的全类型TypeScript接口
  • 灵活的令牌解析:支持JSON文件、环境变量和直接参数
  • 完整的Gmail API支持:访问消息、线程、标签、草稿等
  • MCP工具:所有功能都作为MCP工具公开,并使用Zod模式进行验证
  • 错误处理:正确的错误处理和向stderr报告

安装

npm install gmail-mcp-lib

设置

使用前 gmail-mcp-lib,您需要设置Google OAuth2凭据:

  1. 在以下位置创建Google Cloud项目https://console.cloud.google.com
  2. 启用Gmail API
  3. 创建OAuth2凭据(桌面应用程序)
  4. 设置以下环境变量:
export GOOGLE_CLIENT_ID="your-client-id"
export GOOGLE_CLIENT_SECRET="your-client-secret"
export GOOGLE_REDIRECT_URL="http://localhost:3000/callback" # or your redirect URL

令牌解析

使用以下优先级(从高到低)解析令牌:

  1. 直接参数:直接传递给函数的令牌
  2. 环境变量: GMAIL_TOKEN 作为JSON字符串
  3. 文件: token.json 或通过自定义路径 GMAIL_TOKEN_FILE

示例:使用令牌文件

创建一个 token.json 使用您的OAuth2凭据文件:

{
  "accessToken": "ya29.a0AfH6SMBx...",
  "refreshToken": "1//0gKn...",
  "expiryDate": 1234567890,
  "tokenType": "Bearer"
}

示例:使用环境变量

export GMAIL_TOKEN='{"accessToken":"ya29.a0AfH6SMBx...","refreshToken":"1//0gKn...","expiryDate":1234567890,"tokenType":"Bearer"}'

示例:直接参数

const tokens = {
  accessToken: 'ya29.a0AfH6SMBx...',
  refreshToken: '1//0gKn...',
  expiryDate: 1234567890,
  tokenType: 'Bearer',
};

const messages = await listMessages('me', {}, tokens);

用法

作为图书馆

导入和使用单个函数或创建客户端实例:

使用单个函数

import { listMessages, sendMessage, searchMessages } from 'gmail-mcp-lib';

// List messages
const messages = await listMessages('me', {
  maxResults: 10,
});

// Search messages
const unread = await searchMessages('is:unread', {
  maxResults: 5,
});

// Send message
const sent = await sendMessage({
  to: 'recipient@example.com',
  subject: 'Hello',
  body: 'This is a test email',
});

使用客户端实例

import { createGmailClient } from 'gmail-mcp-lib';

const client = createGmailClient();

// List messages
const messages = await client.listMessages('me', {
  q: 'is:unread',
  maxResults: 10,
});

// Get specific message
const message = await client.getMessage('me', 'messageId');

// Send message
const sent = await client.sendMessage('me', {
  to: 'recipient@example.com',
  subject: 'Hello',
  body: 'This is a test email',
  html: false,
});

// Search messages
const results = await client.searchMessages('me', 'from:sender@example.com');

// Create draft
const draft = await client.createDraft('me', {
  to: 'recipient@example.com',
  subject: 'Draft Email',
  body: 'Draft content',
});

// List labels
const labels = await client.listLabels('me');

// Modify message labels
const modified = await client.modifyMessageLabels('me', 'messageId', {
  addLabelIds: ['LABEL_ID'],
  removeLabelIds: ['DRAFT'],
});

// Move to trash
const trashed = await client.trashMessage('me', 'messageId');

// Restore from trash
const restored = await client.untrashMessage('me', 'messageId');

// Archive message (remove from inbox)
const archived = await client.archiveMessage('me', 'messageId');

// Unarchive message (restore to inbox)
const unarchived = await client.unarchiveMessage('me', 'messageId');

// List threads
const threads = await client.listThreads('me', {
  q: 'is:unread',
  maxResults: 5,
});

// Get specific thread
const thread = await client.getThread('me', 'threadId');

作为MCP服务器

通过stdio运行服务器:

gmail-mcp-lib

或者,如果在本地安装:

npx gmail-mcp-lib

服务器公开了以下工具:

  • gmailListMessages -列出邮箱中的邮件
  • gmailGetMessage -按ID获取特定消息
  • gmailSearchMessages -使用Gmail搜索语法搜索邮件
  • gmailSendMessage -发送电子邮件
  • gmailCreateDraft -创建电子邮件草稿
  • gmailListLabels -列出邮箱中的所有标签
  • gmailModifyMessageLabels -在邮件中添加或删除标签
  • gmailTrashMessage -将邮件移至垃圾箱
  • gmailUntrashMessage -从回收站还原邮件
  • gmailArchiveMessage -将邮件存档(从收件箱中删除)
  • gmailUnarchiveMessage -已存档邮件(还原到收件箱)
  • gmailListThreads -列出邮箱中的线程
  • gmailGetThread -按ID获取特定线程

所有工具都接受令牌作为参数,遵循相同的令牌解析优先级。

API 参考

类型

interface Tokens {
  accessToken: string;
  refreshToken?: string;
  expiryDate?: number;
  tokenType?: string;
}

interface Message {
  id: string;
  threadId: string;
  labelIds?: string[];
  snippet?: string;
  historyId?: string;
  internalDate?: string;
  payload?: MessagePayload;
  sizeEstimate?: number;
  raw?: string;
}

interface Thread {
  id: string;
  snippet?: string;
  historyId?: string;
  messages?: Message[];
}

interface Label {
  id: string;
  name: string;
  labelListVisibility?: string;
  messageListVisibility?: string;
  type?: string;
}

interface Draft {
  id: string;
  message?: Message;
}

interface SendMessageOptions {
  to: string | string[];
  subject?: string;
  body?: string;
  html?: boolean;
  threadId?: string;
  labelIds?: string[];
  inReplyTo?: string;
}

interface CreateDraftOptions {
  to: string | string[];
  subject?: string;
  body?: string;
  html?: boolean;
  threadId?: string;
}

interface ListMessagesOptions {
  q?: string;
  maxResults?: number;
  pageToken?: string;
  includeSpamTrash?: boolean;
  labelIds?: string[];
}

interface ListThreadsOptions {
  q?: string;
  maxResults?: number;
  pageToken?: string;
  includeSpamTrash?: boolean;
  labelIds?: string[];
}

interface ModifyLabelsOptions {
  addLabelIds?: string[];
  removeLabelIds?: string[];
}

函数

createGmailClient(options?: GmailClientOptions): GmailClient

创建一个新的Gmail客户端实例。

const client = createGmailClient({ tokens: customTokens });

resolveTokens(provided?: Tokens): Tokens

从环境和文件系统中解析令牌。

const tokens = resolveTokens();

消息功能

listMessages(userId?: string, options?: ListMessagesOptions, tokens?: Tokens): Promise<Message[]>
getMessage(messageId: string, tokens?: Tokens, format?: 'full' | 'minimal' | 'raw' | 'metadata'): Promise<Message>
searchMessages(query: string, tokens?: Tokens, options?: Omit<ListMessagesOptions, 'q'>): Promise<Message[]>
sendMessage(options: SendMessageOptions, tokens?: Tokens): Promise<Message>
createDraft(options: CreateDraftOptions, tokens?: Tokens): Promise<Draft>
modifyMessageLabels(messageId: string, options: ModifyLabelsOptions, tokens?: Tokens): Promise<Message>
trashMessage(messageId: string, tokens?: Tokens): Promise<Message>
untrashMessage(messageId: string, tokens?: Tokens): Promise<Message>
archiveMessage(messageId: string, tokens?: Tokens): Promise<Message>
unarchiveMessage(messageId: string, tokens?: Tokens): Promise<Message>

标签功能

listLabels(tokens?: Tokens): Promise<Label[]>

线程函数

listThreads(tokens?: Tokens, options?: ListThreadsOptions): Promise<Thread[]>
getThread(threadId: string, tokens?: Tokens, format?: 'full' | 'minimal' | 'metadata'): Promise<Thread>

建筑

npm run build

编译后的JavaScript将位于 dist 目录。

测试

运行测试套件:

npm test

运行覆盖率测试:

npm run coverage

该软件包的目标是在分支、函数、行和语句上实现70%以上的覆盖率。

发展

开发观察模式:

npm run dev

许可证

麻省理工学院

作者

@苹果1009

备注

  • 代币轮换由外部处理;此程序包不会自动刷新令牌
  • 令牌不会持久化;您必须自己管理令牌持久性
  • 库和服务器模式的错误消息都记录到stderr中
  • MCP服务器使用2空格缩进,并遵循严格的TypeScript约定