keyid-agent-kit-mcp by aradotso/trending-skills
npx skills add https://github.com/aradotso/trending-skills --skill keyid-agent-kit-mcp技能来自 ara.so — Daily 2026 技能集合。
KeyID Agent Kit 通过 Model Context Protocol 为 AI 代理(Claude、Cursor 或任何 MCP 客户端)提供一个真实、可用的电子邮件地址和 27 种工具。无需注册,无需手动获取 API 密钥,完全免费。由 KeyID.ai 提供支持。
npm install @keyid/agent-kit
# 或
yarn add @keyid/agent-kit
# 或直接运行而无需安装
npx @keyid/agent-kit
| 变量 | 描述 | 默认值 |
|---|---|---|
KEYID_PUBLIC_KEY | Ed25519 公钥(十六进制) | 首次运行时自动生成 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
KEYID_PRIVATE_KEY | Ed25519 私钥(十六进制) | 首次运行时自动生成 |
KEYID_BASE_URL | API 基础 URL | https://keyid.ai |
重要提示: 首次运行后请保存自动生成的密钥,以便您的代理在不同会话中保持相同的电子邮件地址。密钥在首次启动时会打印到 stderr。
编辑 ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) 或 %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"keyid": {
"command": "npx",
"args": ["@keyid/agent-kit"],
"env": {
"KEYID_PUBLIC_KEY": "$KEYID_PUBLIC_KEY",
"KEYID_PRIVATE_KEY": "$KEYID_PRIVATE_KEY"
}
}
}
}
在项目根目录的 .cursor/mcp.json 或全局 Cursor 设置中:
{
"mcpServers": {
"keyid": {
"command": "npx",
"args": ["@keyid/agent-kit"],
"env": {
"KEYID_PUBLIC_KEY": "$KEYID_PUBLIC_KEY",
"KEYID_PRIVATE_KEY": "$KEYID_PRIVATE_KEY"
}
}
}
}
# 运行一次以生成密钥并注册代理
npx @keyid/agent-kit
# 密钥会打印到 stderr — 请保存它们!
# 然后在您的环境或配置中设置它们
export KEYID_PUBLIC_KEY=<从输出中获取的十六进制值>
export KEYID_PRIVATE_KEY=<从输出中获取的十六进制值>
keyid_provision — 注册代理,获取分配的电子邮件地址
keyid_get_email — 获取当前活动的电子邮件地址
keyid_get_inbox — 获取收件箱;支持搜索查询、过滤、分页
keyid_send — 发送电子邮件(收件人、主题、正文、HTML、计划时间、显示名称)
keyid_reply — 通过 message_id 回复消息
keyid_forward — 将消息转发到另一个地址
keyid_update_message — 标记为已读/未读,加星/取消加星
keyid_get_unread_count — 获取未读消息数量
keyid_list_threads — 列出会话线程
keyid_get_thread — 获取包含其所有消息的线程
keyid_create_draft — 保存草稿
keyid_send_draft — 发送先前保存的草稿
keyid_get_auto_reply — 获取当前自动回复/休假回复器配置
keyid_set_auto_reply — 启用/禁用带有自定义消息的自动回复
keyid_get_signature — 获取电子邮件签名
keyid_set_signature — 设置电子邮件签名文本/HTML
keyid_get_forwarding — 获取转发规则
keyid_set_forwarding — 添加或更新转发到另一个地址
keyid_list_contacts — 列出所有已保存的联系人
keyid_create_contact — 创建联系人(姓名、电子邮件、备注)
keyid_delete_contact — 通过 ID 删除联系人
keyid_list_webhooks — 列出已配置的 webhook
keyid_create_webhook — 为入站事件注册 webhook URL
keyid_get_webhook_deliveries — 查看投递历史和失败情况
keyid_manage_list — 在允许列表或阻止列表中添加/删除地址
keyid_get_metrics — 查询使用指标(已发送、已接收、退回)
import { spawn } from 'child_process';
import { createInterface } from 'readline';
// 将 MCP 服务器作为子进程启动
const server = spawn('npx', ['@keyid/agent-kit'], {
env: {
...process.env,
KEYID_PUBLIC_KEY: process.env.KEYID_PUBLIC_KEY,
KEYID_PRIVATE_KEY: process.env.KEYID_PRIVATE_KEY,
},
stdio: ['pipe', 'pipe', 'inherit'],
});
// 发送 JSON-RPC 请求
function sendRequest(method, params = {}) {
const request = {
jsonrpc: '2.0',
id: Date.now(),
method,
params,
};
server.stdin.write(JSON.stringify(request) + '\n');
}
// 读取响应
const rl = createInterface({ input: server.stdout });
rl.on('line', (line) => {
const response = JSON.parse(line);
console.log('Response:', JSON.stringify(response, null, 2));
});
// 初始化 MCP 会话
sendRequest('initialize', {
protocolVersion: '2024-11-05',
capabilities: {},
clientInfo: { name: 'my-app', version: '1.0.0' },
});
// 初始化后,调用 tools/call
function callTool(toolName, toolArgs) {
const request = {
jsonrpc: '2.0',
id: Date.now(),
method: 'tools/call',
params: {
name: toolName,
arguments: toolArgs,
},
};
server.stdin.write(JSON.stringify(request) + '\n');
}
// 获取收件箱
callTool('keyid_get_inbox', { limit: 10 });
// 发送电子邮件
callTool('keyid_send', {
to: 'colleague@example.com',
subject: 'Hello from my AI agent',
body: 'This email was sent by an AI agent using KeyID.',
});
// 回复消息
callTool('keyid_reply', {
message_id: 'msg_abc123',
body: 'Thanks, I will review this today.',
});
// 搜索收件箱
callTool('keyid_get_inbox', {
query: 'from:alice@company.com subject:report',
unread_only: true,
});
// 设置自动回复
callTool('keyid_set_auto_reply', {
enabled: true,
subject: 'Out of Office',
body: 'I am currently unavailable. My AI agent will respond shortly.',
});
// 创建联系人
callTool('keyid_create_contact', {
name: 'Alice Smith',
email: 'alice@company.com',
notes: 'Project lead for Q1 initiative',
});
// 计划发送电子邮件
callTool('keyid_send', {
to: 'team@company.com',
subject: 'Weekly Update',
body: 'Here is the weekly status...',
scheduled_at: '2026-03-25T09:00:00Z',
});
// 设置电子邮件签名
callTool('keyid_set_signature', {
signature: 'Best regards,\nAI Agent\npowered by KeyID.ai',
});
// 获取指标
callTool('keyid_get_metrics', {
period: '7d',
});
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
const transport = new StdioClientTransport({
command: 'npx',
args: ['@keyid/agent-kit'],
env: {
KEYID_PUBLIC_KEY: process.env.KEYID_PUBLIC_KEY,
KEYID_PRIVATE_KEY: process.env.KEYID_PRIVATE_KEY,
},
});
const client = new Client(
{ name: 'my-email-agent', version: '1.0.0' },
{ capabilities: {} }
);
await client.connect(transport);
// 列出可用工具
const tools = await client.listTools();
console.log('Available tools:', tools.tools.map(t => t.name));
// 获取电子邮件地址
const emailResult = await client.callTool({
name: 'keyid_get_email',
arguments: {},
});
console.log('Agent email:', emailResult.content[0].text);
// 检查未读邮件
const unread = await client.callTool({
name: 'keyid_get_unread_count',
arguments: {},
});
console.log('Unread count:', unread.content[0].text);
// 发送电子邮件
await client.callTool({
name: 'keyid_send',
arguments: {
to: 'recipient@example.com',
subject: 'Automated report',
body: 'Your daily report is attached.',
html: '<p>Your <strong>daily report</strong> is attached.</p>',
},
});
await client.close();
import express from 'express';
const app = express();
app.use(express.json());
// 接收 KeyID webhook 事件的端点
app.post('/keyid-webhook', (req, res) => {
const event = req.body;
if (event.type === 'message.received') {
const { from, subject, body, message_id } = event.data;
console.log(`New email from ${from}: ${subject}`);
// 在此处触发您的代理逻辑
handleIncomingEmail({ from, subject, body, message_id });
}
res.json({ ok: true });
});
app.listen(3000);
// 通过 MCP 工具注册 webhook
// (通过您的代理调用一次)
// callTool('keyid_create_webhook', {
// url: 'https://your-server.com/keyid-webhook',
// events: ['message.received'],
// });
// 生成并存储密钥一次,永久复用
import { writeFileSync, readFileSync, existsSync } from 'fs';
import { generateKeyPairSync } from 'crypto'; // 或使用 @noble/ed25519
const KEY_FILE = '.keyid-keys.json';
function loadOrCreateKeys() {
if (existsSync(KEY_FILE)) {
return JSON.parse(readFileSync(KEY_FILE, 'utf8'));
}
// 让 @keyid/agent-kit 在首次运行时自动生成,
// 然后将其打印到 stderr 的内容保存下来
// 或者使用 @noble/ed25519 预先生成:
// const privKey = randomBytes(32);
// const pubKey = await ed.getPublicKeyAsync(privKey);
return null; // 将自动生成
}
// 轮询收件箱并处理新消息
async function agentEmailLoop(client) {
while (true) {
const result = await client.callTool({
name: 'keyid_get_inbox',
arguments: { unread_only: true, limit: 5 },
});
const messages = JSON.parse(result.content[0].text);
for (const msg of messages) {
// 使用您的 LLM/代理逻辑处理
const agentResponse = await processWithAgent(msg);
// 回复
await client.callTool({
name: 'keyid_reply',
arguments: {
message_id: msg.id,
body: agentResponse,
},
});
// 标记为已读
await client.callTool({
name: 'keyid_update_message',
arguments: { message_id: msg.id, read: true },
});
}
// 等待 60 秒再进行下一次轮询
await new Promise(r => setTimeout(r, 60_000));
}
}
// 创建草稿,审核,然后发送
const draft = await client.callTool({
name: 'keyid_create_draft',
arguments: {
to: 'client@example.com',
subject: 'Proposal',
body: draftBody,
},
});
const draftId = JSON.parse(draft.content[0].text).id;
// 人工或代理审核...
// 然后发送:
await client.callTool({
name: 'keyid_send_draft',
arguments: { draft_id: draftId },
});
原因: 密钥在运行之间未持久化。
解决方法: 从首次运行的输出中保存 KEYID_PUBLIC_KEY 和 KEYID_PRIVATE_KEY,并在您的配置或环境中设置它们。
解决方法: 编辑配置后重启 Claude Desktop。验证 JSON 是否有效(没有尾随逗号)。检查 npx 是否在您的 PATH 中。
解决方法: 确保代理已首先配置 — 在调用其他工具之前调用 keyid_provision,或调用 keyid_get_email 以确认代理拥有地址。
解决方法: 检查 keyid_manage_list 以确保发件人未被阻止。检查 keyid_get_metrics 以获取退回数据。
解决方法: 服务器使用 stdio — 确保同一进程中没有其他内容写入 stdout。重启 MCP 服务器进程。
原因: stderr 可能被您的 MCP 客户端抑制。
解决方法: 在添加到您的 MCP 配置之前,先在终端中直接运行 npx @keyid/agent-kit 以捕获密钥输出。
2024-11-05每周安装量
212
代码仓库
GitHub 星标数
10
首次出现
4 天前
安全审计
已安装于
github-copilot211
codex211
warp211
amp211
cline211
kimi-cli211
Skill by ara.so — Daily 2026 Skills collection.
KeyID Agent Kit gives AI agents (Claude, Cursor, or any MCP client) a real, working email address with 27 tools via the Model Context Protocol. No signup, no API keys to acquire manually, no cost. Powered by KeyID.ai.
npm install @keyid/agent-kit
# or
yarn add @keyid/agent-kit
# or run directly without installing
npx @keyid/agent-kit
| Variable | Description | Default |
|---|---|---|
KEYID_PUBLIC_KEY | Ed25519 public key (hex) | Auto-generated on first run |
KEYID_PRIVATE_KEY | Ed25519 private key (hex) | Auto-generated on first run |
KEYID_BASE_URL | API base URL | https://keyid.ai |
Important: Save the auto-generated keys after first run so your agent keeps the same email address across sessions. The keys are printed to stderr on first launch.
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"keyid": {
"command": "npx",
"args": ["@keyid/agent-kit"],
"env": {
"KEYID_PUBLIC_KEY": "$KEYID_PUBLIC_KEY",
"KEYID_PRIVATE_KEY": "$KEYID_PRIVATE_KEY"
}
}
}
}
In .cursor/mcp.json at project root or global Cursor settings:
{
"mcpServers": {
"keyid": {
"command": "npx",
"args": ["@keyid/agent-kit"],
"env": {
"KEYID_PUBLIC_KEY": "$KEYID_PUBLIC_KEY",
"KEYID_PRIVATE_KEY": "$KEYID_PRIVATE_KEY"
}
}
}
}
# Run once to generate keys and register the agent
npx @keyid/agent-kit
# Keys are printed to stderr — save them!
# Then set them in your environment or config
export KEYID_PUBLIC_KEY=<hex-from-output>
export KEYID_PRIVATE_KEY=<hex-from-output>
keyid_provision — Register agent, get assigned email address
keyid_get_email — Get the current active email address
keyid_get_inbox — Fetch inbox; supports search query, filtering, pagination
keyid_send — Send email (to, subject, body, HTML, scheduled time, display name)
keyid_reply — Reply to a message by message_id
keyid_forward — Forward a message to another address
keyid_update_message — Mark read/unread, star/unstar
keyid_get_unread_count — Get count of unread messages
keyid_list_threads — List conversation threads
keyid_get_thread — Get a thread with all its messages
keyid_create_draft — Save a draft
keyid_send_draft — Send a previously saved draft
keyid_get_auto_reply — Get current auto-reply/vacation responder config
keyid_set_auto_reply — Enable/disable auto-reply with custom message
keyid_get_signature — Get email signature
keyid_set_signature — Set email signature text/HTML
keyid_get_forwarding — Get forwarding rules
keyid_set_forwarding — Add or update forwarding to another address
keyid_list_contacts — List all saved contacts
keyid_create_contact — Create a contact (name, email, notes)
keyid_delete_contact — Delete a contact by ID
keyid_list_webhooks — List configured webhooks
keyid_create_webhook — Register a webhook URL for inbound events
keyid_get_webhook_deliveries — View delivery history and failures
keyid_manage_list — Add/remove addresses from allow or blocklist
keyid_get_metrics — Query usage metrics (sent, received, bounces)
import { spawn } from 'child_process';
import { createInterface } from 'readline';
// Start the MCP server as a child process
const server = spawn('npx', ['@keyid/agent-kit'], {
env: {
...process.env,
KEYID_PUBLIC_KEY: process.env.KEYID_PUBLIC_KEY,
KEYID_PRIVATE_KEY: process.env.KEYID_PRIVATE_KEY,
},
stdio: ['pipe', 'pipe', 'inherit'],
});
// Send a JSON-RPC request
function sendRequest(method, params = {}) {
const request = {
jsonrpc: '2.0',
id: Date.now(),
method,
params,
};
server.stdin.write(JSON.stringify(request) + '\n');
}
// Read responses
const rl = createInterface({ input: server.stdout });
rl.on('line', (line) => {
const response = JSON.parse(line);
console.log('Response:', JSON.stringify(response, null, 2));
});
// Initialize MCP session
sendRequest('initialize', {
protocolVersion: '2024-11-05',
capabilities: {},
clientInfo: { name: 'my-app', version: '1.0.0' },
});
// After initialization, call tools/call
function callTool(toolName, toolArgs) {
const request = {
jsonrpc: '2.0',
id: Date.now(),
method: 'tools/call',
params: {
name: toolName,
arguments: toolArgs,
},
};
server.stdin.write(JSON.stringify(request) + '\n');
}
// Get inbox
callTool('keyid_get_inbox', { limit: 10 });
// Send an email
callTool('keyid_send', {
to: 'colleague@example.com',
subject: 'Hello from my AI agent',
body: 'This email was sent by an AI agent using KeyID.',
});
// Reply to a message
callTool('keyid_reply', {
message_id: 'msg_abc123',
body: 'Thanks, I will review this today.',
});
// Search inbox
callTool('keyid_get_inbox', {
query: 'from:alice@company.com subject:report',
unread_only: true,
});
// Set auto-reply
callTool('keyid_set_auto_reply', {
enabled: true,
subject: 'Out of Office',
body: 'I am currently unavailable. My AI agent will respond shortly.',
});
// Create a contact
callTool('keyid_create_contact', {
name: 'Alice Smith',
email: 'alice@company.com',
notes: 'Project lead for Q1 initiative',
});
// Schedule an email
callTool('keyid_send', {
to: 'team@company.com',
subject: 'Weekly Update',
body: 'Here is the weekly status...',
scheduled_at: '2026-03-25T09:00:00Z',
});
// Set email signature
callTool('keyid_set_signature', {
signature: 'Best regards,\nAI Agent\npowered by KeyID.ai',
});
// Get metrics
callTool('keyid_get_metrics', {
period: '7d',
});
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
const transport = new StdioClientTransport({
command: 'npx',
args: ['@keyid/agent-kit'],
env: {
KEYID_PUBLIC_KEY: process.env.KEYID_PUBLIC_KEY,
KEYID_PRIVATE_KEY: process.env.KEYID_PRIVATE_KEY,
},
});
const client = new Client(
{ name: 'my-email-agent', version: '1.0.0' },
{ capabilities: {} }
);
await client.connect(transport);
// List available tools
const tools = await client.listTools();
console.log('Available tools:', tools.tools.map(t => t.name));
// Get email address
const emailResult = await client.callTool({
name: 'keyid_get_email',
arguments: {},
});
console.log('Agent email:', emailResult.content[0].text);
// Check unread
const unread = await client.callTool({
name: 'keyid_get_unread_count',
arguments: {},
});
console.log('Unread count:', unread.content[0].text);
// Send email
await client.callTool({
name: 'keyid_send',
arguments: {
to: 'recipient@example.com',
subject: 'Automated report',
body: 'Your daily report is attached.',
html: '<p>Your <strong>daily report</strong> is attached.</p>',
},
});
await client.close();
import express from 'express';
const app = express();
app.use(express.json());
// Endpoint to receive KeyID webhook events
app.post('/keyid-webhook', (req, res) => {
const event = req.body;
if (event.type === 'message.received') {
const { from, subject, body, message_id } = event.data;
console.log(`New email from ${from}: ${subject}`);
// Trigger your agent logic here
handleIncomingEmail({ from, subject, body, message_id });
}
res.json({ ok: true });
});
app.listen(3000);
// Register the webhook via the MCP tool
// (call this once via your agent)
// callTool('keyid_create_webhook', {
// url: 'https://your-server.com/keyid-webhook',
// events: ['message.received'],
// });
// Generate and store keys once, reuse forever
import { writeFileSync, readFileSync, existsSync } from 'fs';
import { generateKeyPairSync } from 'crypto'; // or use @noble/ed25519
const KEY_FILE = '.keyid-keys.json';
function loadOrCreateKeys() {
if (existsSync(KEY_FILE)) {
return JSON.parse(readFileSync(KEY_FILE, 'utf8'));
}
// Let @keyid/agent-kit auto-generate on first run,
// then save what it prints to stderr
// Or pre-generate using @noble/ed25519:
// const privKey = randomBytes(32);
// const pubKey = await ed.getPublicKeyAsync(privKey);
return null; // will auto-generate
}
// Poll inbox and process new messages
async function agentEmailLoop(client) {
while (true) {
const result = await client.callTool({
name: 'keyid_get_inbox',
arguments: { unread_only: true, limit: 5 },
});
const messages = JSON.parse(result.content[0].text);
for (const msg of messages) {
// Process with your LLM/agent logic
const agentResponse = await processWithAgent(msg);
// Reply
await client.callTool({
name: 'keyid_reply',
arguments: {
message_id: msg.id,
body: agentResponse,
},
});
// Mark as read
await client.callTool({
name: 'keyid_update_message',
arguments: { message_id: msg.id, read: true },
});
}
// Wait 60 seconds before next poll
await new Promise(r => setTimeout(r, 60_000));
}
}
// Create draft, review, then send
const draft = await client.callTool({
name: 'keyid_create_draft',
arguments: {
to: 'client@example.com',
subject: 'Proposal',
body: draftBody,
},
});
const draftId = JSON.parse(draft.content[0].text).id;
// Human or agent reviews...
// Then send:
await client.callTool({
name: 'keyid_send_draft',
arguments: { draft_id: draftId },
});
Cause: Keys not persisted between runs.
Fix: Save KEYID_PUBLIC_KEY and KEYID_PRIVATE_KEY from first run output and set them in your config or environment.
Fix: Restart Claude Desktop after editing config. Verify JSON is valid (no trailing commas). Check that npx is in your PATH.
Fix: Ensure the agent is provisioned first — call keyid_provision before other tools, or call keyid_get_email to confirm the agent has an address.
Fix: Check keyid_manage_list to ensure the sender isn't blocklisted. Check keyid_get_metrics for bounce data.
Fix: The server uses stdio — make sure nothing else is writing to stdout in the same process. Restart the MCP server process.
Cause: stderr may be suppressed by your MCP client.
Fix: Run npx @keyid/agent-kit directly in a terminal first to capture the key output before adding to your MCP config.
2024-11-05Weekly Installs
212
Repository
GitHub Stars
10
First Seen
4 days ago
Security Audits
Gen Agent Trust HubPassSocketWarnSnykWarn
Installed on
github-copilot211
codex211
warp211
amp211
cline211
kimi-cli211
AI Elements:基于shadcn/ui的AI原生应用组件库,快速构建对话界面
60,400 周安装