RFC 0001: AuroraView MCP Server
状态: Implementing (Phase 3 Complete) 作者: AuroraView Team 创建日期: 2024-12-30 更新日期: 2024-12-31 目标版本: v0.4.0
摘要
本 RFC 提议为 AuroraView 框架创建一个专用的 MCP (Model Context Protocol) 服务器,使 AI 助手能够直接与 AuroraView 应用进行交互、测试和调试。该服务器将提供一套标准化的工具集,用于连接 WebView 实例、调用 Python API、触发事件、截图、运行示例等操作。
核心目标:
- Standalone 模式:支持独立 AuroraView 应用的 AI 自动化
- DCC 集成模式:支持在 Maya、Blender、Houdini、Unreal 等 DCC 软件中运行的 AuroraView 面板
- AI 自动化:结合 Midscene.js 实现自然语言驱动的 UI 自动化
- 跨语言 SDK:同时提供 Python 和 TypeScript/Node.js SDK
动机
当前状态分析
目前,AI 助手与 AuroraView 应用的交互存在以下限制:
- 间接连接:需要通过 Chrome DevTools MCP 连接,但该工具会创建新的浏览器实例而非连接到现有 WebView2
- 配置复杂:需要手动获取 WebSocket 端点 ID,每次重启应用都需要更新配置
- 功能受限:Chrome DevTools MCP 的
evaluate_script对异步操作支持不完善 - 无法直接调用 Python API:只能通过 JS 桥接间接调用
- DCC 环境受限:无法连接到嵌入在 Maya/Blender/Houdini 中的 AuroraView 面板
行业趋势对比
| 工具 | 特点 | 可借鉴 |
|---|---|---|
| Chrome DevTools MCP | 通用浏览器调试 | CDP 连接方式 |
| Playwright MCP | 端到端测试 | 页面选择、截图 |
| Tauri MCP (概念) | 桌面应用集成 | 原生 API 调用 |
| ShotGrid MCP | 行业特定集成 | 领域专用工具设计 |
| Midscene.js | AI UI 自动化 | 自然语言交互、视觉理解 |
需求分析
- 自动发现:自动发现运行中的 AuroraView 实例,无需手动配置
- 直接 API 调用:直接调用 Python 后端 API,绕过 JS 桥接
- 完整测试能力:支持 UI 测试、API 测试、性能测试
- 开发调试:实时日志、状态检查、热重载触发
- Gallery 集成:运行示例、查看源码、管理进程
- DCC 支持:连接和控制 DCC 软件中的 AuroraView 面板
- AI 自动化:自然语言驱动的 UI 操作和测试
设计方案
技术选型分析:Python vs Node.js
对比分析
| 维度 | Python MCP SDK | TypeScript MCP SDK |
|---|---|---|
| 官方支持 | ✅ 官方 SDK | ✅ 官方 SDK (更活跃) |
| 生态成熟度 | 较新 | 更成熟 (11.2k stars) |
| DCC 兼容性 | ✅ 原生支持 Maya/Houdini/Blender Python | ❌ 需要额外进程 |
| Midscene 集成 | 需要桥接 | ✅ 原生 TypeScript |
| 异步支持 | asyncio | ✅ 原生 async/await |
| 类型安全 | 可选 (typing) | ✅ 强类型 |
| 部署复杂度 | 简单 (uvx) | 需要 Node.js 环境 |
| 与 AuroraView 集成 | ✅ 直接调用 Python API | 需要 IPC |
推荐方案:双 SDK 架构
┌─────────────────────────────────────────────────────────────────────┐
│ AI Assistant │
│ (Claude, GPT, Copilot) │
└─────────────────────────────────────────────────────────────────────┘
│
MCP Protocol (stdio/SSE)
│
┌───────────────────────┴───────────────────────┐
│ │
▼ ▼
┌───────────────────┐ ┌───────────────────┐
│ Python MCP SDK │ │ Node.js MCP SDK │
│ (auroraview-mcp) │ │ (@auroraview/mcp) │
├───────────────────┤ ├───────────────────┤
│ • DCC 环境优先 │ │ • Midscene 集成 │
│ • 直接 Python API │ │ • 前端开发优先 │
│ • 简单部署 │ │ • 类型安全 │
└─────────┬─────────┘ └─────────┬─────────┘
│ │
└─────────────────┬─────────────────────────┘
│
CDP / WebSocket
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Standalone │ │ Maya │ │ Unreal │
│ WebView │ │ QtWebView │ │ WebView │
└─────────────┘ └─────────────┘ └─────────────┘推荐策略:
- Phase 1: Python SDK 优先 - 快速验证,支持 DCC 环境
- Phase 2: Node.js SDK - Midscene 深度集成,前端开发体验
- 共享: 核心协议和工具定义保持一致
DCC 集成架构
场景分析
┌─────────────────────────────────────────────────────────────────────┐
│ DCC Application │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Maya / Blender / Houdini │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ Qt Host Window │ │ │
│ │ │ ┌───────────────────────────────────────────────┐ │ │ │
│ │ │ │ AuroraView Panel │ │ │ │
│ │ │ │ ┌─────────────────────────────────────────┐ │ │ │ │
│ │ │ │ │ WebView2 (CDP) │ │ │ │ │
│ │ │ │ │ ┌─────────────────────────────────┐ │ │ │ │ │
│ │ │ │ │ │ Your Tool UI (React/Vue) │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ │ │ │ window.auroraview.api.xxx() │ │ │ │ │ │
│ │ │ │ │ └─────────────────────────────────┘ │ │ │ │ │
│ │ │ │ └──────────────────┬──────────────────────┘ │ │ │ │
│ │ │ └─────────────────────┼────────────────────────┘ │ │ │
│ │ └────────────────────────┼──────────────────────────┘ │ │
│ └───────────────────────────┼──────────────────────────────┘ │
└──────────────────────────────┼──────────────────────────────────┘
│ CDP (port 9222+)
▼
┌─────────────────────┐
│ AuroraView MCP │
│ Server │
└─────────────────────┘
│
▼
┌─────────────────────┐
│ AI Assistant │
│ "点击重命名按钮" │
└─────────────────────┘DCC 特定工具
python
# ==================== DCC Tools ====================
@mcp.tool()
async def list_dcc_instances() -> list[dict]:
"""发现所有 DCC 环境中的 AuroraView 实例。
Returns:
实例列表,包含:
- dcc_type: "maya" | "blender" | "houdini" | "nuke" | "unreal"
- dcc_version: "2025.1"
- panel_name: "Asset Browser"
- port: 9222
- pid: 12345
"""
@mcp.tool()
async def get_dcc_context() -> dict:
"""获取当前 DCC 环境上下文。
Returns:
- scene_path: 当前场景文件路径
- selected_objects: 选中的对象列表
- current_frame: 当前帧
- project_path: 项目路径
"""
@mcp.tool()
async def execute_dcc_command(command: str, **kwargs) -> Any:
"""执行 DCC 原生命令。
Args:
command: 命令名称(如 "maya.cmds.ls", "bpy.ops.object.select_all")
**kwargs: 命令参数
Returns:
命令执行结果
Example:
# Maya
execute_dcc_command("maya.cmds.ls", selection=True)
# Blender
execute_dcc_command("bpy.ops.object.select_all", action='SELECT')
"""
@mcp.tool()
async def sync_selection() -> dict:
"""同步 DCC 和 WebView 之间的选择状态。
Returns:
- dcc_selection: DCC 中选中的对象
- webview_selection: WebView UI 中选中的项目
"""Midscene.js 集成架构
为什么需要 Midscene 集成?
- 自然语言 UI 控制:用户可以说 "点击重命名按钮" 而不是写 CSS 选择器
- 视觉理解:AI 可以 "看到" UI 并理解布局
- 智能断言:用 "检查是否显示成功消息" 代替精确的元素检查
- 跨 DCC 通用:同样的指令在 Maya/Blender/Houdini 中都能工作
集成方案
typescript
// packages/auroraview-mcp-node/src/midscene-integration.ts
import { MidsceneAgent } from '@anthropic/midscene';
import type { Page } from 'playwright';
export class AuroraViewMidsceneAgent {
private agent: MidsceneAgent;
private page: Page;
constructor(page: Page) {
this.page = page;
this.agent = new MidsceneAgent(page, {
model: 'gpt-4o', // 或其他多模态模型
});
}
/**
* 执行自然语言 UI 操作
*/
async aiAct(instruction: string): Promise<void> {
// 注入 AuroraView 上下文
const context = await this.getAuroraViewContext();
await this.agent.ai(`
当前应用: AuroraView ${context.appName}
当前页面: ${context.pageTitle}
可用 API: ${context.apiMethods.join(', ')}
执行: ${instruction}
`);
}
/**
* 提取结构化数据
*/
async aiQuery<T>(demand: string): Promise<T> {
return await this.agent.aiQuery(demand);
}
/**
* 自然语言断言
*/
async aiAssert(assertion: string): Promise<void> {
await this.agent.aiAssert(assertion);
}
/**
* 获取 AuroraView 上下文增强 AI 理解
*/
private async getAuroraViewContext() {
return await this.page.evaluate(() => ({
appName: document.title,
pageTitle: document.title,
apiMethods: window.__auroraview_api_methods || [],
currentState: window.auroraview?.state?.getAll() || {},
}));
}
}MCP 工具集成
typescript
// Node.js MCP Server with Midscene
import { McpServer } from '@modelcontextprotocol/server';
import { AuroraViewMidsceneAgent } from './midscene-integration';
const server = new McpServer('auroraview');
// AI 驱动的 UI 操作
server.tool('ai_act', {
description: '使用自然语言执行 UI 操作',
parameters: {
instruction: { type: 'string', description: '自然语言指令' },
},
async handler({ instruction }) {
const agent = await getConnectedAgent();
await agent.aiAct(instruction);
return { success: true };
},
});
// AI 数据提取
server.tool('ai_query', {
description: '使用自然语言提取页面数据',
parameters: {
demand: { type: 'string', description: '数据需求描述' },
},
async handler({ demand }) {
const agent = await getConnectedAgent();
return await agent.aiQuery(demand);
},
});
// AI 断言
server.tool('ai_assert', {
description: '使用自然语言验证页面状态',
parameters: {
assertion: { type: 'string', description: '断言描述' },
},
async handler({ assertion }) {
const agent = await getConnectedAgent();
await agent.aiAssert(assertion);
return { passed: true };
},
});
// DCC 特定的 AI 操作
server.tool('ai_dcc_action', {
description: '在 DCC 环境中执行 AI 驱动的操作',
parameters: {
action: { type: 'string', description: '操作描述' },
dcc_type: { type: 'string', enum: ['maya', 'blender', 'houdini', 'unreal'] },
},
async handler({ action, dcc_type }) {
const agent = await getConnectedAgent();
// 根据 DCC 类型调整上下文
const dccContext = await getDCCContext(dcc_type);
await agent.aiAct(`
在 ${dcc_type} 环境中:
当前选中: ${dccContext.selection.join(', ')}
当前场景: ${dccContext.scenePath}
执行: ${action}
`);
return { success: true };
},
});架构概览(更新版)
┌─────────────────────────────────────────────────────────────┐
│ AI Assistant │
│ (Claude, GPT, etc.) │
└─────────────────────────────────────────────────────────────┘
│
│ MCP Protocol (stdio/SSE)
▼
┌─────────────────────────────────────────────────────────────┐
│ AuroraView MCP Server │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Discovery │ │ Tools │ │ Resources │ │
│ │ Module │ │ Module │ │ Module │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ │ │ │ │
│ └───────────────┼───────────────────┘ │
│ │ │
│ ┌──────────┴──────────┐ │
│ │ Connection Pool │ │
│ └──────────┬──────────┘ │
└─────────────────────────┼───────────────────────────────────┘
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ WebView │ │ WebView │ │ WebView │
│ Instance │ │ Instance │ │ Instance │
│ (CDP) │ │ (CDP) │ │ (CDP) │
└──────────┘ └──────────┘ └──────────┘完整 API 预览
python
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("auroraview")
# ==================== Discovery Tools ====================
@mcp.tool()
async def discover_instances() -> list[dict]:
"""发现所有运行中的 AuroraView 实例。
Returns:
实例列表,每个包含 id, port, title, url, pid
"""
@mcp.tool()
async def connect(port: int = 9222) -> dict:
"""连接到指定端口的 AuroraView 实例。
Args:
port: CDP 端口号,默认 9222
Returns:
连接状态和实例信息
"""
@mcp.tool()
async def disconnect() -> dict:
"""断开当前连接。"""
# ==================== Page Tools ====================
@mcp.tool()
async def list_pages() -> list[dict]:
"""列出所有页面。
Returns:
页面列表,每个包含 id, url, title
"""
@mcp.tool()
async def select_page(page_id: str = None, url_pattern: str = None) -> dict:
"""选择要操作的页面。
Args:
page_id: 页面 ID
url_pattern: URL 匹配模式(支持通配符)
Returns:
选中的页面信息
"""
@mcp.tool()
async def get_page_info() -> dict:
"""获取当前页面的详细信息。
Returns:
包含 url, title, auroraview_ready, api_methods 等
"""
# ==================== API Tools ====================
@mcp.tool()
async def call_api(method: str, **kwargs) -> Any:
"""调用 AuroraView Python API。
Args:
method: API 方法名(如 "get_samples", "run_sample")
**kwargs: 方法参数
Returns:
API 返回值
Example:
call_api("run_sample", name="hello_world")
"""
@mcp.tool()
async def list_api_methods() -> list[dict]:
"""列出所有可用的 API 方法。
Returns:
方法列表,每个包含 name, signature, docstring
"""
@mcp.tool()
async def emit_event(event: str, data: dict = None) -> dict:
"""向前端触发事件。
Args:
event: 事件名称
data: 事件数据
Returns:
发送状态
"""
# ==================== UI Tools ====================
@mcp.tool()
async def take_screenshot(
selector: str = None,
full_page: bool = False,
path: str = None
) -> str:
"""截取页面截图。
Args:
selector: CSS 选择器(可选,截取特定元素)
full_page: 是否截取完整页面
path: 保存路径(可选,不提供则返回 base64)
Returns:
截图文件路径或 base64 数据
"""
@mcp.tool()
async def get_snapshot() -> dict:
"""获取页面可访问性树快照。
Returns:
A11y 树结构,包含所有可交互元素
"""
@mcp.tool()
async def click(selector: str = None, uid: str = None) -> dict:
"""点击元素。
Args:
selector: CSS 选择器
uid: 快照中的元素 UID
Returns:
操作结果
"""
@mcp.tool()
async def fill(selector: str, value: str) -> dict:
"""填充输入框。
Args:
selector: CSS 选择器
value: 要填充的值
Returns:
操作结果
"""
@mcp.tool()
async def evaluate(script: str) -> Any:
"""执行 JavaScript 代码。
Args:
script: JavaScript 代码
Returns:
执行结果
"""
# ==================== Gallery Tools ====================
@mcp.tool()
async def get_samples(category: str = None, tags: list[str] = None) -> list[dict]:
"""获取示例列表。
Args:
category: 分类过滤
tags: 标签过滤
Returns:
示例列表
"""
@mcp.tool()
async def run_sample(name: str) -> dict:
"""运行示例。
Args:
name: 示例名称
Returns:
运行状态和进程信息
"""
@mcp.tool()
async def stop_sample(pid: int = None, name: str = None) -> dict:
"""停止运行中的示例。
Args:
pid: 进程 ID
name: 示例名称
Returns:
停止状态
"""
@mcp.tool()
async def get_sample_source(name: str) -> str:
"""获取示例源代码。
Args:
name: 示例名称
Returns:
Python 源代码
"""
@mcp.tool()
async def list_processes() -> list[dict]:
"""列出所有运行中的示例进程。
Returns:
进程列表
"""
# ==================== Debug Tools ====================
@mcp.tool()
async def get_console_logs(level: str = None, limit: int = 100) -> list[dict]:
"""获取控制台日志。
Args:
level: 日志级别过滤(log, warn, error)
limit: 最大条数
Returns:
日志列表
"""
@mcp.tool()
async def get_network_requests(
url_pattern: str = None,
method: str = None
) -> list[dict]:
"""获取网络请求记录。
Args:
url_pattern: URL 匹配模式
method: HTTP 方法过滤
Returns:
请求列表
"""
@mcp.tool()
async def get_backend_status() -> dict:
"""获取 Python 后端状态。
Returns:
包含 ready, uptime, memory, handlers 等信息
"""
@mcp.tool()
async def reload_page(hard: bool = False) -> dict:
"""重新加载页面。
Args:
hard: 是否强制刷新(清除缓存)
Returns:
重载状态
"""
# ==================== Resources ====================
@mcp.resource("auroraview://instances")
async def get_instances_resource() -> str:
"""当前运行的 AuroraView 实例列表。"""
@mcp.resource("auroraview://page/{page_id}")
async def get_page_resource(page_id: str) -> str:
"""指定页面的详细信息。"""
@mcp.resource("auroraview://samples")
async def get_samples_resource() -> str:
"""所有可用示例的列表。"""
@mcp.resource("auroraview://sample/{name}/source")
async def get_sample_source_resource(name: str) -> str:
"""指定示例的源代码。"""
@mcp.resource("auroraview://logs")
async def get_logs_resource() -> str:
"""最近的控制台日志。"""详细说明
1. 自动发现机制
python
class InstanceDiscovery:
"""AuroraView 实例发现器。"""
# 默认扫描端口范围
DEFAULT_PORTS = [9222, 9223, 9224, 9225]
async def discover(self) -> list[Instance]:
"""扫描本地端口,发现运行中的实例。"""
instances = []
for port in self.DEFAULT_PORTS:
try:
# 尝试获取 CDP 版本信息
async with httpx.AsyncClient() as client:
resp = await client.get(
f"http://127.0.0.1:{port}/json/version",
timeout=1.0
)
if resp.status_code == 200:
data = resp.json()
# 检查是否是 AuroraView 实例
if self._is_auroraview(data):
instances.append(Instance(
port=port,
browser=data.get("Browser"),
ws_url=data.get("webSocketDebuggerUrl"),
))
except Exception:
continue
return instances
def _is_auroraview(self, data: dict) -> bool:
"""检查是否是 AuroraView 实例。"""
# 通过 User-Agent 或其他特征判断
return "Edg" in data.get("Browser", "") or "Chrome" in data.get("Browser", "")2. 连接管理
python
class ConnectionManager:
"""CDP 连接管理器。"""
def __init__(self):
self._connections: dict[int, CDPConnection] = {}
self._current: CDPConnection | None = None
async def connect(self, port: int) -> CDPConnection:
"""建立 CDP 连接。"""
if port in self._connections:
self._current = self._connections[port]
return self._current
# 获取 WebSocket URL
async with httpx.AsyncClient() as client:
resp = await client.get(f"http://127.0.0.1:{port}/json/version")
ws_url = resp.json()["webSocketDebuggerUrl"]
# 建立 WebSocket 连接
conn = CDPConnection(port, ws_url)
await conn.connect()
self._connections[port] = conn
self._current = conn
return conn
async def get_pages(self) -> list[Page]:
"""获取所有页面。"""
if not self._current:
raise RuntimeError("Not connected")
async with httpx.AsyncClient() as client:
resp = await client.get(
f"http://127.0.0.1:{self._current.port}/json/list"
)
pages_data = resp.json()
pages = []
for data in pages_data:
# 过滤掉 about:blank
if data.get("url") != "about:blank":
pages.append(Page(
id=data["id"],
url=data["url"],
title=data.get("title", ""),
ws_url=data["webSocketDebuggerUrl"],
))
return pages3. API 调用桥接
python
class APIBridge:
"""Python API 调用桥接。"""
def __init__(self, page: Page):
self._page = page
self._call_id = 0
async def call(self, method: str, **kwargs) -> Any:
"""调用 Python API。"""
self._call_id += 1
call_id = f"mcp_{self._call_id}"
# 构建调用脚本
if kwargs:
params_json = json.dumps(kwargs)
script = f"""
(async () => {{
try {{
const result = await window.auroraview.call("{method}", {params_json});
return {{ ok: true, result }};
}} catch (e) {{
return {{ ok: false, error: e.message }};
}}
}})()
"""
else:
script = f"""
(async () => {{
try {{
const result = await window.auroraview.api.{method}();
return {{ ok: true, result }};
}} catch (e) {{
return {{ ok: false, error: e.message }};
}}
}})()
"""
# 通过 CDP 执行
result = await self._page.evaluate(script)
if not result.get("ok"):
raise APIError(result.get("error", "Unknown error"))
return result.get("result")
async def list_methods(self) -> list[dict]:
"""列出所有可用方法。"""
script = """
(() => {
const methods = [];
if (window.auroraview && window.auroraview.api) {
// Proxy 对象无法直接枚举,需要后端提供方法列表
// 这里返回已知的标准方法
return window.__auroraview_api_methods || [];
}
return methods;
})()
"""
return await self._page.evaluate(script)4. 截图与快照
python
class ScreenshotTool:
"""截图工具。"""
async def take_screenshot(
self,
page: Page,
selector: str = None,
full_page: bool = False,
path: str = None,
) -> str:
"""截取截图。"""
# 使用 CDP Page.captureScreenshot
params = {
"format": "png",
"captureBeyondViewport": full_page,
}
if selector:
# 获取元素边界
bounds = await page.evaluate(f"""
(() => {{
const el = document.querySelector("{selector}");
if (!el) return null;
const rect = el.getBoundingClientRect();
return {{
x: rect.x,
y: rect.y,
width: rect.width,
height: rect.height
}};
}})()
""")
if bounds:
params["clip"] = bounds
result = await page.send_cdp("Page.captureScreenshot", params)
data = result["data"] # base64
if path:
import base64
with open(path, "wb") as f:
f.write(base64.b64decode(data))
return path
return f"data:image/png;base64,{data}"项目结构
Python SDK 结构
packages/auroraview-mcp/
├── pyproject.toml
├── README.md
├── src/
│ └── auroraview_mcp/
│ ├── __init__.py
│ ├── __main__.py # 入口点
│ ├── server.py # MCP 服务器主文件
│ ├── discovery.py # 实例发现
│ ├── connection.py # CDP 连接管理
│ ├── api_bridge.py # API 调用桥接
│ ├── tools/
│ │ ├── __init__.py
│ │ ├── discovery.py # 发现工具
│ │ ├── page.py # 页面工具
│ │ ├── api.py # API 工具
│ │ ├── ui.py # UI 工具
│ │ ├── gallery.py # Gallery 工具
│ │ ├── debug.py # 调试工具
│ │ └── dcc.py # DCC 特定工具
│ └── resources/
│ ├── __init__.py
│ └── providers.py # 资源提供者
└── tests/
├── test_discovery.py
├── test_connection.py
├── test_api_bridge.py
└── test_tools.pyNode.js SDK 结构
packages/auroraview-mcp-node/
├── package.json
├── tsconfig.json
├── README.md
├── src/
│ ├── index.ts # 入口点
│ ├── server.ts # MCP 服务器
│ ├── discovery.ts # 实例发现
│ ├── connection.ts # CDP 连接
│ ├── midscene/
│ │ ├── index.ts
│ │ ├── agent.ts # Midscene Agent 封装
│ │ ├── context.ts # AuroraView 上下文
│ │ └── prompts.ts # AI 提示模板
│ ├── tools/
│ │ ├── index.ts
│ │ ├── discovery.ts
│ │ ├── page.ts
│ │ ├── api.ts
│ │ ├── ui.ts
│ │ ├── ai.ts # AI/Midscene 工具
│ │ └── dcc.ts # DCC 工具
│ └── types/
│ └── index.ts
├── tests/
│ ├── server.test.ts
│ ├── midscene.test.ts
│ └── dcc.test.ts
└── dist/配置示例
Claude Desktop / CodeBuddy 配置
json
{
"mcpServers": {
"auroraview": {
"command": "uvx",
"args": ["auroraview-mcp"],
"env": {
"AURORAVIEW_DEFAULT_PORT": "9222",
"AURORAVIEW_AUTO_CONNECT": "true"
}
},
"auroraview-ai": {
"command": "npx",
"args": ["-y", "@auroraview/mcp"],
"env": {
"MIDSCENE_MODEL_NAME": "gpt-4o",
"MIDSCENE_MODEL_API_KEY": "your-api-key"
}
}
}
}开发模式配置
json
{
"mcpServers": {
"auroraview": {
"command": "uv",
"args": [
"--directory",
"/path/to/dcc_webview/packages/auroraview-mcp",
"run",
"auroraview-mcp"
]
}
}
}DCC 环境配置
json
{
"mcpServers": {
"auroraview-maya": {
"command": "uvx",
"args": ["auroraview-mcp"],
"env": {
"AURORAVIEW_DCC_MODE": "maya",
"AURORAVIEW_SCAN_PORTS": "9222,9223,9224,9225"
}
}
}
}使用示例
基本工作流
User: 帮我测试 Gallery 的搜索功能
AI: 我来连接 Gallery 并测试搜索功能。
[调用 discover_instances]
→ 发现 1 个实例在端口 9222
[调用 connect(port=9222)]
→ 已连接到 AuroraView Gallery
[调用 get_snapshot]
→ 获取页面结构,找到搜索框
[调用 fill(selector="input[placeholder*='Search']", value="cookie")]
→ 已输入搜索词
[调用 take_screenshot]
→ 截图显示搜索结果
[调用 evaluate("document.querySelectorAll('.sample-card').length")]
→ 返回 1(只显示 Cookie Management Demo)
搜索功能正常工作,输入 "cookie" 后正确过滤出相关示例。运行示例
User: 运行 hello_world 示例
AI: [调用 run_sample(name="hello_world")]
→ 示例已启动,PID: 12345
[调用 list_processes]
→ 显示运行中的进程
示例已成功启动,你可以在新窗口中看到效果。DCC 环境工作流
User: 在 Maya 中帮我测试资产浏览器面板
AI: 我来连接 Maya 中的 AuroraView 面板。
[调用 list_dcc_instances]
→ 发现 Maya 2025 实例,端口 9223,面板: "Asset Browser"
[调用 connect(port=9223)]
→ 已连接到 Maya Asset Browser
[调用 get_dcc_context]
→ 场景: /projects/shot_010.ma
→ 选中: ["pCube1", "pSphere1"]
[调用 ai_act("在资产列表中搜索 'character'")]
→ AI 识别搜索框并输入
[调用 ai_assert("显示了角色资产列表")]
→ 断言通过
[调用 sync_selection]
→ 同步 Maya 和面板的选择状态
资产浏览器面板工作正常。AI 自动化工作流 (Midscene)
User: 用自然语言测试 Gallery 的完整流程
AI: 我来使用 AI 自动化测试 Gallery。
[调用 ai_act("点击 'Getting Started' 分类")]
→ AI 识别并点击分类按钮
[调用 ai_assert("显示了入门示例列表")]
→ 断言通过
[调用 ai_act("在搜索框中输入 'cookie' 并按回车")]
→ AI 执行搜索操作
[调用 ai_query("{ samples: string[], count: number }")]
→ 返回 { samples: ["Cookie Management Demo"], count: 1 }
[调用 ai_act("点击第一个示例的 'Run Demo' 按钮")]
→ AI 识别并点击按钮
[调用 ai_assert("示例窗口已打开")]
→ 断言通过
Gallery 测试完成,所有功能正常。向后兼容性
兼容策略
- 独立包:作为独立的 Python/Node.js 包发布,不影响现有 AuroraView 功能
- 可选依赖:
pip install auroraview[mcp]或npm install @auroraview/mcp - 版本对齐:MCP 服务器版本与 AuroraView 主版本保持兼容
- DCC 兼容:支持 Maya 2020+、Blender 3.0+、Houdini 19+、Unreal 5.0+
依赖要求
Python SDK
toml
[project]
name = "auroraview-mcp"
requires-python = ">=3.10" # MCP SDK 要求
dependencies = [
"mcp>=1.2.0",
"httpx>=0.25.0",
"websockets>=12.0",
]
[project.optional-dependencies]
dev = [
"pytest>=8.0",
"pytest-asyncio>=0.23",
]
midscene = [
"playwright>=1.40.0",
]Node.js SDK
json
{
"name": "@auroraview/mcp",
"dependencies": {
"@modelcontextprotocol/server": "^1.0.0",
"playwright": "^1.40.0",
"zod": "^3.25.0"
},
"optionalDependencies": {
"@anthropic/midscene": "^1.0.0"
}
}实现计划
Phase 1: Python SDK 核心功能 (v0.3.0) - 2 周
- [x] 项目结构搭建
- [x] 实例发现 (
discover_instances) - [x] 连接管理 (
connect,disconnect) - [x] 页面操作 (
list_pages,select_page,get_page_info) - [x] 基本 API 调用 (
call_api,list_api_methods) - [x] 截图 (
take_screenshot) - [x] 基本测试和文档
Phase 2: Gallery 集成 (v0.3.1) - 1 周
- [x] Gallery 工具 (
run_gallery,stop_gallery,get_gallery_status) - [x] Gallery 工具 (
get_samples,run_sample,stop_sample) - [x] 源码查看 (
get_sample_source) - [x] 进程管理 (
list_processes,stop_all_samples) - [x] 项目信息 (
get_project_info) - [x] 资源提供者实现 (
auroraview://gallery,auroraview://project,auroraview://processes)
Phase 3: DCC 支持 (v0.4.0) - 2 周
- [x] DCC 实例发现 (
list_dcc_instances) - [x] DCC 上下文 (
get_dcc_context) - [x] DCC 命令执行 (
execute_dcc_command) - [x] 选择同步 (
sync_selection,set_dcc_selection) - [x] 场景信息 (
get_dcc_scene_info) - [x] 时间线控制 (
get_dcc_timeline,set_dcc_frame) - [x] Maya/Blender/Houdini/Nuke/Unreal/3ds Max 类型检测
- [x] 单元测试
Phase 4: Node.js SDK (v0.4.1) - 2 周
- [ ] TypeScript MCP Server 基础
- [ ] CDP 连接管理
- [ ] 核心工具移植
- [ ] 类型定义
Phase 5: Midscene 集成 (v0.5.0) - 2 周
- [ ] Midscene Agent 封装
- [ ] AI 工具 (
ai_act,ai_query,ai_assert) - [ ] DCC AI 工具 (
ai_dcc_action) - [ ] 上下文增强
- [ ] 提示模板
Phase 6: 高级功能 (v0.6.0) - 2 周
- [ ] 多实例管理
- [ ] 性能监控
- [ ] 自动化测试集成
- [ ] SSE 传输支持
- [ ] 提示模板 (Prompts)
- [ ] 调试增强 (
get_console_logs,get_network_requests)
风险与缓解
| 风险 | 影响 | 缓解策略 |
|---|---|---|
| MCP SDK 版本不稳定 | 高 | 锁定稳定版本,关注官方更新 |
| DCC Python 版本限制 | 中 | MCP Server 独立进程,通过 IPC 通信 |
| Midscene 模型成本 | 中 | 支持本地模型,提供缓存机制 |
| CDP 端口冲突 | 低 | 自动端口扫描,支持配置 |
参考资料
- Model Context Protocol 官方文档
- MCP Python SDK
- MCP TypeScript SDK
- Chrome DevTools Protocol
- Midscene.js 文档
- AuroraView 项目文档
- AuroraView GitHub
项目组织策略
推荐方案:混合策略
基于 Anthropic 官方 MCP servers 仓库的组织方式,以及 AuroraView 项目的特点,推荐采用混合策略:
Phase 1:在当前项目内开发(快速验证)
dcc_webview/
├── packages/
│ ├── auroraview-sdk/ # 已有 JS SDK
│ ├── auroraview-mcp/ # Python MCP Server
│ │ ├── pyproject.toml # 独立的 Python 包
│ │ ├── src/
│ │ └── tests/
│ └── auroraview-mcp-node/ # Node.js MCP Server
│ ├── package.json
│ ├── src/
│ └── tests/选择理由:
| 方面 | 说明 |
|---|---|
| 快速迭代 | 与 Gallery 一起开发测试 |
| 代码复用 | 直接使用 auroraview-sdk 的类型 |
| 版本对齐 | 确保 MCP API 与 AuroraView 兼容 |
| CI 复用 | 使用现有的 justfile 命令 |
Phase 2:成熟后考虑拆分(可选)
当 MCP Server 稳定后(v1.0),可以考虑:
- 保留在 monorepo 中(推荐,参考 Anthropic 官方做法)
- 或拆分为独立仓库(如果社区需求强烈)
方案对比
方案 A:Monorepo(推荐)
| 方面 | 说明 |
|---|---|
| 代码复用 | 直接使用 auroraview-sdk 的类型定义和工具函数 |
| 版本同步 | MCP 版本与 AuroraView 主版本自动对齐 |
| CI/CD 统一 | 复用现有的 justfile、GitHub Actions |
| 测试集成 | 可以直接测试 MCP → Gallery 的完整流程 |
| 开发效率 | 修改 AuroraView API 后可立即更新 MCP |
| 文档统一 | 在同一个 docs 目录下维护 |
缺点:
- 增加项目复杂度
- Python 3.7 vs MCP 需要 3.10+(通过独立包解决)
- 发布耦合
方案 B:独立仓库
| 方面 | 说明 |
|---|---|
| 独立发布 | MCP 可以独立版本迭代 |
| 依赖隔离 | 不受主项目 Python 3.7 限制 |
| 社区贡献 | 更容易吸引 MCP 生态贡献者 |
| 轻量安装 | 用户只需安装 MCP 包 |
缺点:
- 需要手动维护版本兼容性
- 需要复制部分类型定义
- 需要重新搭建构建系统
- 跨仓库测试更困难
依赖隔离策略
toml
# packages/auroraview-mcp/pyproject.toml
[project]
name = "auroraview-mcp"
requires-python = ">=3.10" # MCP 独立要求,不影响主项目 3.7
dependencies = [
"mcp>=1.2.0",
"httpx>=0.25.0",
]发布策略
| 包 | 发布方式 | 版本策略 |
|---|---|---|
auroraview | PyPI (maturin) | 主版本 |
auroraview-mcp | PyPI (独立) | 跟随主版本 |
@auroraview/mcp | npm | 跟随主版本 |
justfile 集成
makefile
# 在现有 justfile 中添加
mcp-dev:
cd packages/auroraview-mcp && uv run auroraview-mcp
mcp-test:
cd packages/auroraview-mcp && uv run pytest
mcp-node-dev:
cd packages/auroraview-mcp-node && npm run dev
mcp-publish:
cd packages/auroraview-mcp && uv build && uv publish总结
| 维度 | 推荐 | 原因 |
|---|---|---|
| 开发位置 | 当前项目 | 快速迭代、代码复用、版本同步 |
| 包管理 | 独立包 | auroraview-mcp 独立于 auroraview |
| Python 版本 | 3.10+ | MCP SDK 要求,不影响主项目 3.7 |
| 发布 | 独立发布 | 可以独立版本迭代 |
更新记录
| 日期 | 版本 | 变更 |
|---|---|---|
| 2024-12-30 | Draft | 初始草案 |
| 2024-12-30 | Draft v2 | 添加 DCC 集成、Node.js SDK、Midscene 集成分析 |
| 2024-12-30 | Draft v3 | 添加项目组织策略(混合策略) |
| 2024-12-30 | Implementing | Phase 1 实现完成 - Python SDK 核心功能 |
| 2024-12-30 | Implementing | Phase 2 实现完成 - Gallery 集成工具 |
| 2024-12-31 | Implementing | Phase 3 实现完成 - DCC 支持(get_dcc_context, execute_dcc_command, sync_selection, set_dcc_selection, get_dcc_scene_info, get_dcc_timeline, set_dcc_frame) |
