Hotdry.
ai-systems

使用 TypeScript 集成 DeepChat 与本地日历、邮件和文件 API 构建隐私优先的个人 AI 助手

面向隐私需求,介绍 DeepChat 的 MCP 协议与本地数据源的 TypeScript 集成方法,包括 API 连接参数、安全监控和落地清单。

在数字化时代,个人数据如日历事件、邮件往来和文件内容已成为日常决策的核心。然而,云端 AI 助手往往涉及数据上传,引发隐私泄露风险。DeepChat 作为一个开源的多模型 AI 聊天平台,通过其 Model Context Protocol (MCP) 支持工具调用机制,能够无缝集成本地 API,实现隐私优先的个人 AI 助手。本文将聚焦于使用 TypeScript 开发此类集成,强调数据查询和响应生成的工程化实践,避免不必要的云端依赖,确保用户数据始终本地处理。

DeepChat 的核心优势在于其对 MCP 协议的完整支持,该协议定义了 Resources、Prompts 和 Tools 三种核心能力。其中,Tools 允许 AI 模型在对话中动态调用外部函数,实现智能数据交互。根据 DeepChat 的官方文档,MCP 支持 StreamableHTTP、SSE 和 Stdio 等传输协议,并内置 Node.js 运行时环境,这为 TypeScript 开发者提供了低门槛的扩展路径。例如,在构建个人 AI 时,我们可以定义工具函数来访问本地日历(如 iCalendar 格式)、邮件服务器(IMAP/SMTP)和文件系统(Node.js fs 模块),让 LLM 如 Ollama 本地模型直接查询这些数据源,而无需将敏感信息发送至远程服务器。这种设计不仅提升了响应速度,还符合 GDPR 等隐私法规要求。

要实现这一集成,首先需设置 DeepChat 的开发环境。克隆仓库后,使用 pnpm 安装依赖:pnpm install 后运行 pnpm run installRuntime。DeepChat 基于 Electron 和 Vue 构建,支持 Windows、macOS 和 Linux 平台。开发模式下,通过 pnpm run dev 启动应用。在 TypeScript 配置中,确保 tsconfig.json 启用严格模式("strict": true),并安装必要的类型定义如 @types/node 和 @types/nodemailer。MCP 工具的注册发生在 src/main/mcp 目录下,我们可以扩展 services 文件夹,添加自定义工具服务。

考虑文件 API 的集成,作为最基础的数据源。文件系统查询常用于 AI 助手检索文档、生成摘要或提取关键词。使用 Node.js 的 fs 模块,在 TypeScript 中定义一个工具函数:

import fs from 'fs/promises';
import path from 'path';

interface FileQueryParams {
  directory: string;
  query: string;
  maxResults: number;
}

async function queryFiles(params: FileQueryParams): Promise<string[]> {
  const { directory, query, maxResults = 10 } = params;
  try {
    const files = await fs.readdir(directory, { withFileTypes: true });
    const results: string[] = [];
    for (const file of files) {
      if (file.isFile() && file.name.toLowerCase().includes(query.toLowerCase())) {
        const filePath = path.join(directory, file.name);
        const content = await fs.readFile(filePath, 'utf-8');
        if (content.length > 0) {  // 简单过滤空文件
          results.push(`${file.name}: ${content.substring(0, 500)}...`);  // 截取摘要
          if (results.length >= maxResults) break;
        }
      }
    }
    return results;
  } catch (error) {
    throw new Error(`文件查询失败: ${error.message}`);
  }
}

此函数接受目录路径、搜索关键词和结果上限参数,返回匹配文件的摘要。在 MCP 服务中注册此工具:

// 在 mcp-service.ts 中
import { Tool } from 'mcp-protocol';  // 假设 MCP 类型

const fileTool: Tool = {
  name: 'query_local_files',
  description: '查询本地文件系统中的文档,支持关键词搜索',
  parameters: {
    type: 'object',
    properties: {
      directory: { type: 'string', description: '文件目录路径' },
      query: { type: 'string', description: '搜索关键词' },
      maxResults: { type: 'number', description: '最大结果数,默认10' }
    },
    required: ['directory', 'query']
  },
  execute: queryFiles
};

// 注册到 MCP 服务
mcpService.registerTool(fileTool);

落地参数建议:directory 默认为用户文档路径(如 process.env.HOME + '/Documents'),maxResults 设为 5-20 以平衡性能;监控点包括文件读取超时(设为 5 秒),使用 Node.js 的 AbortController 实现。风险控制:仅允许读取用户指定目录,避免系统文件访问;集成加密,如使用 crypto 模块对敏感文件内容进行 AES 加密传输。

接下来是邮件 API 集成。邮件数据涉及隐私敏感信息,如联系人或附件,因此需优先使用本地存储的 IMAP 客户端。推荐使用 node-imap 和 simple-parser 库,在 TypeScript 中封装:

import Imap from 'imap';
import { simpleParser } from 'mailparser';

interface EmailQueryParams {
  host: string;
  port: number;
  user: string;
  password: string;
  searchCriteria: string;  // 如 'subject:meeting'
  limit: number;
}

async function queryEmails(params: EmailQueryParams): Promise<any[]> {
  const { host, port = 993, user, password, searchCriteria, limit = 10 } = params;
  return new Promise((resolve, reject) => {
    const imap = new Imap({
      user,
      password,
      host,
      port,
      tls: true,
      tlsOptions: { rejectUnauthorized: false }  // 本地服务器可调整
    });

    function openInbox(cb: (err: Error | null, box: any) => void) {
      imap.openBox('INBOX', true, cb);
    }

    imap.once('ready', () => {
      openInbox((err, box) => {
        if (err) return reject(err);
        imap.search([searchCriteria], (err, results) => {
          if (err) return reject(err);
          const fetch = imap.fetch(results.slice(0, limit), { bodies: '' });
          const emails: any[] = [];
          fetch.on('message', (msg, seqno) => {
            msg.on('body', (stream) => {
              simpleParser(stream, (err, parsed) => {
                if (!err && parsed) emails.push({ subject: parsed.subject, from: parsed.from?.text, text: parsed.text });
              });
            });
          });
          fetch.once('end', () => {
            imap.end();
            resolve(emails);
          });
        });
      });
    });

    imap.once('error', reject);
    imap.connect();
  });
}

注册为 MCP 工具类似上述,parameters 中 host/port/user/password 需用户预配置(存储在加密的本地数据库,如 electron-store)。参数优化:port 默认 993 (IMAP over SSL),limit 5-15;安全清单:使用环境变量存储凭证,支持 OAuth2 替代明文密码;监控包括连接超时(10 秒)和错误日志记录到本地文件。引用 DeepChat 文档:“MCP 支持内置 Node.js 运行时,工具调用无需额外配置。” 此机制确保邮件查询仅在本地执行,AI 仅接收过滤后的摘要。

对于日历 API,本地集成可使用 ical 库解析 .ics 文件,或集成系统 API 如 macOS 的 CalendarKit(通过 Electron 的 native 模块)。TypeScript 示例聚焦 iCal:

import ical from 'ical-generator';
import fs from 'fs/promises';

interface CalendarQueryParams {
  filePath: string;
  dateRange: { start: string; end: string };
  eventType: string;
}

async function queryCalendar(params: CalendarQueryParams): Promise<any[]> {
  const { filePath, dateRange, eventType = 'all' } = params;
  try {
    const content = await fs.readFile(filePath, 'utf-8');
    const calendar = ical.parseICS(content);  // 需安装 node-ical
    const events = calendar.events().filter(event => {
      const eventDate = event.start();
      return eventDate >= new Date(dateRange.start) && eventDate <= new Date(dateRange.end) &&
             (eventType === 'all' || event.summary().toLowerCase().includes(eventType));
    });
    return events.map(event => ({
      summary: event.summary(),
      start: event.start().toISOString(),
      description: event.description()
    }));
  } catch (error) {
    throw new Error(`日历查询失败: ${error.message}`);
  }
}

MCP 注册同上,parameters 包括 filePath(默认~/Calendar.ics)、dateRange (ISO 格式,如 "2025-10-19T00:00:00Z" 到 "2025-10-26T23:59:59Z")。落地清单:定期同步日历文件(cron 任务,每小时);阈值:事件上限 20 条,避免 token 溢出;回滚策略:若查询失败,fallback 到缓存数据(使用 localForage 存储上周事件)。隐私参数:描述字段脱敏,移除个人信息如电话。

集成完成后,在 DeepChat 的聊天界面,AI 可根据用户查询如 “今天有什么会议?” 自动调用 queryCalendar 工具,生成响应:“根据您的日历,下午 2 点有团队会议,地点:会议室 A。” 类似地,文件和邮件查询支持复杂任务,如 “总结最近邮件中的项目更新” 或 “查找报告文件”。

工程化要点包括:1) 授权机制:使用 Electron 的 ipcRenderer 向主进程请求用户确认敏感操作;2) 性能监控:集成 perf_hooks 追踪工具调用时长,阈值 >2 秒 则优化或缓存;3) 错误处理:统一 try-catch,返回标准化错误码;4) 测试清单:单元测试工具函数(Jest),端到端测试 MCP 调用(模拟 LLM 请求)。风险限制:避免工具滥用,通过 rate limiting(每分钟 5 次调用);数据加密使用 AES-256,密钥由用户管理。

通过上述 TypeScript 集成,DeepChat 转型为高度个性化的隐私 AI 助手,支持无缝数据驱动对话。未来,可扩展至更多本地源如浏览器历史或笔记 app,进一步增强实用性。开发者可从 GitHub 仓库起步,快速原型化此类应用,确保 AI 赋能而不牺牲隐私。

(字数约 1250)

查看归档