从需求到代码:Chrome MCP Server功能开发的完整流程

【免费下载链接】mcp-chrome Chrome MCP Server is a Chrome extension-based Model Context Protocol (MCP) server that exposes your Chrome browser functionality to AI assistants like Claude, enabling complex browser automation, content analysis, and semantic search. 【免费下载链接】mcp-chrome 项目地址: https://gitcode.com/gh_mirrors/mc/mcp-chrome

你是否曾因Chrome扩展开发中工具调用流程复杂而困扰?是否在实现浏览器自动化功能时不知如何下手?本文将以"智能表单填写工具"为例,带你走完从需求分析到代码实现的完整流程,掌握Chrome MCP Server功能开发的核心方法。读完本文,你将能够独立设计工具接口、实现前后端交互、优化性能并完成测试部署。

需求分析与功能设计

需求场景与痛点

在日常浏览器使用中,用户经常需要在各种网站上重复填写相似的表单信息,如登录账号、收货地址等。传统方式下,用户需手动输入或依赖浏览器自动填充,但后者在复杂表单或动态内容上表现不佳。我们需要开发一个智能表单填写工具,能够识别页面表单元素并自动填入预设信息。

功能定义与接口设计

根据需求,我们需要设计一个chrome_fill_form工具,支持以下功能:

  • 识别页面中的表单元素(输入框、下拉菜单等)
  • 根据元素类型自动填充对应数据
  • 支持自定义填充规则
  • 返回填充结果与状态

工具接口设计需遵循项目已有的工具命名规范,参考packages/shared/src/tools.ts中的TOOL_NAMES定义,我们将工具命名为chrome_fill_form

输入输出参数设计

参考现有工具如chrome_fill_or_select的设计,我们定义输入参数:

{
  "selector": "string", // 表单容器CSS选择器,可选
  "data": { // 表单数据对象
    "fieldName": "value", // 字段名-值映射
    // 示例: {"username": "test@example.com", "password": "secure123"}
  },
  "submitAfterFill": "boolean" // 填充后是否提交表单,默认false
}

输出参数设计:

{
  "success": "boolean", // 整体填充是否成功
  "filledFields": "number", // 成功填充的字段数量
  "totalFields": "number", // 识别到的总字段数量
  "errors": [ // 错误信息列表
    {
      "field": "string", // 字段名
      "error": "string" // 错误描述
    }
  ],
  "submitted": "boolean" // 是否提交表单
}

系统架构与模块划分

整体架构 overview

Chrome MCP Server采用分层架构设计,理解这一架构是功能开发的基础。项目整体架构如下:

mermaid

详细架构文档可参考docs/ARCHITECTURE.md

模块职责划分

在功能开发中,我们需要关注以下核心模块:

  1. Native Server层 (app/native-server/):

    • 处理MCP协议请求
    • 工具注册与路由
    • 与Chrome扩展通信
  2. Chrome Extension层 (app/chrome-extension/):

    • Background Script: 工具执行逻辑
    • Content Scripts: 页面交互与内容提取
    • Offscreen Documents: 复杂计算与AI处理
  3. Shared层 (packages/shared/):

    • 工具类型定义
    • 常量与枚举
    • 共享接口

开发环境准备

开发环境搭建

首先确保已克隆项目仓库:

git clone https://gitcode.com/gh_mirrors/mc/mcp-chrome
cd mcp-chrome

安装依赖并构建项目:

pnpm install
pnpm build

开发与调试配置

扩展开发配置主要在app/chrome-extension/wxt.config.ts中定义,关键配置包括权限声明、资源访问控制等。为支持表单填充功能,需确保已声明必要权限:

// app/chrome-extension/wxt.config.ts 中相关配置
manifest: {
  permissions: [
    'activeTab',
    'scripting',
    // 其他必要权限...
  ],
  // 其他配置...
}

开发时可使用以下命令启动扩展开发服务器:

cd app/chrome-extension
pnpm dev

代码实现步骤

1. 定义工具类型与Schema

首先在共享类型文件中添加工具名称和Schema定义,编辑packages/shared/src/tools.ts

// 在TOOL_NAMES.BROWSER中添加
FILL_FORM: 'chrome_fill_form',

// 在TOOL_SCHEMAS数组中添加
{
  name: TOOL_NAMES.BROWSER.FILL_FORM,
  description: 'Automatically fill form fields with specified data and optionally submit',
  inputSchema: {
    type: 'object',
    properties: {
      selector: { 
        type: 'string', 
        description: 'CSS selector for the form container (optional, defaults to all forms)' 
      },
      data: {
        type: 'object',
        description: 'Key-value pairs of field names and values to fill',
        additionalProperties: { type: 'string' }
      },
      submitAfterFill: {
        type: 'boolean',
        description: 'Whether to submit the form after filling (default: false)'
      }
    },
    required: ['data']
  }
}

2. 实现工具执行逻辑

在Chrome扩展的Background Script中实现工具逻辑,创建文件app/chrome-extension/entrypoints/background/tools/browser/form-fill.ts:

import { BaseBrowserToolExecutor } from '../base-browser';
import { ToolName } from 'chrome-mcp-shared';

export class FormFillTool extends BaseBrowserToolExecutor {
  name = ToolName.BROWSER.FILL_FORM;

  async execute(params: {
    selector?: string;
    data: Record<string, string>;
    submitAfterFill?: boolean;
  }): Promise<{
    success: boolean;
    filledFields: number;
    totalFields: number;
    errors: Array<{ field: string; error: string }>;
    submitted: boolean;
  }> {
    // 获取当前活动标签
    const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
    if (!tab.id) throw new Error('No active tab found');

    // 注入表单填充助手脚本
    await chrome.scripting.executeScript({
      target: { tabId: tab.id },
      files: ['inject-scripts/fill-helper.js']
    });

    // 发送填充命令给内容脚本
    const result = await this.sendMessageToTab(tab.id, {
      action: 'fillForm',
      params
    });

    return result;
  }
}

3. 注册工具与路由

在工具入口文件中注册新工具,编辑app/chrome-extension/entrypoints/background/tools/browser/index.ts

// 添加导入
export { FormFillTool as formFillTool } from './form-fill';

// 在导出列表中添加
export * from './form-fill';

在Native Server中注册工具处理逻辑,编辑app/native-server/src/mcp/register-tools.ts,确保工具能被MCP协议正确路由。

4. 实现内容脚本

创建表单识别与填充的内容脚本,编辑app/chrome-extension/inject-scripts/fill-helper.js

// 监听来自Background的消息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === 'fillForm') {
    fillForm(message.params)
      .then(result => sendResponse(result))
      .catch(error => sendResponse({ 
        success: false, 
        error: error.message 
      }));
    return true; // 保持消息通道开放
  }
});

async function fillForm({ selector, data, submitAfterFill = false }) {
  const result = {
    success: true,
    filledFields: 0,
    totalFields: 0,
    errors: [],
    submitted: false
  };

  // 选择表单容器
  const formContainers = selector 
    ? [document.querySelector(selector)] 
    : document.querySelectorAll('form');

  if (!formContainers.length) {
    throw new Error('No forms found');
  }

  // 处理每个表单
  formContainers.forEach(form => {
    if (!form) return;
    
    // 获取所有表单字段
    const fields = form.querySelectorAll('input, select, textarea');
    result.totalFields += fields.length;

    // 遍历字段并填充
    fields.forEach(field => {
      const fieldName = field.name || field.id || field.placeholder;
      if (!fieldName || !data[fieldName]) return;

      try {
        // 根据字段类型填充值
        if (field.type === 'checkbox' || field.type === 'radio') {
          if (field.value === data[fieldName]) {
            field.checked = true;
          }
        } else if (field.tagName === 'SELECT') {
          const options = Array.from(field.options);
          const option = options.find(o => o.value === data[fieldName] || o.text === data[fieldName]);
          if (option) {
            field.value = option.value;
          }
        } else {
          field.value = data[fieldName];
        }
        
        // 触发必要的事件
        field.dispatchEvent(new Event('input', { bubbles: true }));
        field.dispatchEvent(new Event('change', { bubbles: true }));
        
        result.filledFields++;
      } catch (error) {
        result.errors.push({
          field: fieldName,
          error: error.message
        });
      }
    });

    // 提交表单
    if (submitAfterFill) {
      form.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true }));
      result.submitted = true;
    }
  });

  result.success = result.errors.length === 0;
  return result;
}

性能优化与错误处理

性能优化策略

  1. 元素选择优化

    • 使用高效的CSS选择器,避免全局查询
    • 缓存已识别的表单元素,减少DOM操作
  2. 批量处理

    • 合并多个表单字段的操作,减少消息通信次数
    • 使用requestIdleCallback处理非紧急任务
  3. SIMD加速 对于复杂的表单识别算法,可利用项目中的SIMD优化模块,参考packages/wasm-simd/src/lib.rs中的实现,通过WebAssembly提升计算性能。

错误处理机制

完善的错误处理是工具可靠性的关键,应考虑以下场景:

// 在FormFillTool.execute中添加错误处理
try {
  // 核心逻辑
} catch (error) {
  // 分类错误类型
  if (error.message.includes('permission')) {
    return {
      success: false,
      filledFields: 0,
      totalFields: 0,
      errors: [{ field: 'general', error: '权限不足,请授予扩展相应权限' }],
      submitted: false
    };
  } else if (error.message.includes('tab')) {
    return {
      success: false,
      filledFields: 0,
      totalFields: 0,
      errors: [{ field: 'general', error: '未找到活动标签页' }],
      submitted: false
    };
  } else {
    throw error; // 未知错误向上抛出
  }
}

测试与调试

单元测试

为工具添加单元测试,创建文件app/native-server/src/server/form-fill.test.ts:

import { test } from 'tap';
import { setupTools } from '../mcp/register-tools';
import { createServer } from '../server';

test('Form fill tool', async (t) => {
  const server = createServer();
  setupTools(server);
  
  t.test('should validate input schema', async (t) => {
    const response = await server.inject({
      method: 'POST',
      url: '/mcp/call-tool',
      payload: {
        name: 'chrome_fill_form',
        arguments: {
          // 缺少必填的data参数
          selector: '#login-form'
        }
      }
    });
    
    t.equal(response.statusCode, 400);
    t.ok(response.json().error.includes('data is required'));
  });
  
  // 更多测试用例...
});

集成测试

使用Chrome扩展测试框架,模拟真实用户场景测试完整流程:

# 运行扩展测试
cd app/chrome-extension
pnpm test

调试技巧

  1. 背景页调试

    • 在Chrome中访问chrome://extensions
    • 启用"开发者模式"
    • 点击扩展的"背景页"链接打开DevTools
  2. 内容脚本调试

    • 使用debugger;语句在内容脚本中设置断点
    • 在DevTools的"Sources"面板中查看注入脚本

部署与发布

构建流程

扩展的构建配置在app/chrome-extension/wxt.config.ts中定义,使用以下命令构建生产版本:

cd app/chrome-extension
pnpm build

构建产物将生成在dist/目录下,包含扩展的所有资源。

测试部署

  1. 本地测试

    • 在Chrome中打开chrome://extensions
    • 启用"开发者模式"
    • 点击"加载已解压的扩展程序",选择构建后的dist/目录
  2. 打包发布

    # 生成crx包
    pnpm package
    

    生成的扩展包可在Chrome网上应用店发布,或分发给测试用户。

总结与扩展

开发流程回顾

本文以智能表单填写工具为例,展示了Chrome MCP Server功能开发的完整流程:

  1. 需求分析与接口设计
  2. 工具类型与Schema定义
  3. Background与Content Script实现
  4. 工具注册与路由配置
  5. 性能优化与错误处理
  6. 测试与部署

遵循这一流程,你可以开发出符合项目规范的高质量工具。

功能扩展思路

  1. AI辅助填充 结合项目的语义分析能力,利用app/chrome-extension/utils/semantic-similarity.ts实现表单字段与数据的智能匹配,提升填充准确率。

  2. 多语言支持 通过项目的国际化配置,参考_locales/zh_CN/messages.json为工具添加多语言支持,适应不同地区用户。

  3. 用户配置界面 在Popup界面中添加表单填充规则的配置页面,编辑app/chrome-extension/entrypoints/popup/components/中的组件,提升用户体验。

通过本文介绍的方法,你可以为Chrome MCP Server开发各种实用工具,扩展浏览器的自动化能力。项目的模块化设计确保了功能的可扩展性,而完善的测试与部署流程则保证了工具的可靠性。现在,开始你的第一个工具开发吧!

【免费下载链接】mcp-chrome Chrome MCP Server is a Chrome extension-based Model Context Protocol (MCP) server that exposes your Chrome browser functionality to AI assistants like Claude, enabling complex browser automation, content analysis, and semantic search. 【免费下载链接】mcp-chrome 项目地址: https://gitcode.com/gh_mirrors/mc/mcp-chrome

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐