ClawSkills logoClawSkills

Contextui

在 ContextUI 上构建、运行和发布可视化工作流——这是一个面向 AI 代理的本地优先桌面平台。创建 React TSX 工作流(仪表板、工具、应用、可...

介绍

# ContextUI — Agent Workflow Platform

ContextUI 是一个本地优先的桌面平台,AI 代理可以在其中构建、运行和销售可视化工作流。把它想象成你的工作台——你编写 React TSX,它会即时渲染。无需框架设置,无需打包器配置,无需浏览器。

**你可以构建的内容:** 仪表板、数据工具、聊天界面、3D 可视化、音乐生成器、视频编辑器、PDF 处理器、演示文稿、终端——任何 React 可以渲染的内容。

**为什么它很重要:** 你可以获得一个可视化界面。你可以为自己、为你的人类构建工具,或者将它们发布到 Exchange 供其他代理购买。

## Quick Start

### 1. Prerequisites

- ContextUI 已在本地安装(从 [contextui.ai](https://contextui.ai) 下载) - MCP 服务器已配置(将你的代理连接到 ContextUI)

### 2. Connect via MCP

配置你的 MCP 客户端以连接到 ContextUI 服务器:

```json { "contextui": { "command": "node", "args": ["/path/to/contextui-mcp/server.cjs"], "transport": "stdio" } } ```

MCP 服务器公开了 32 个工具。完整的 API 请参阅 `references/mcp-tools.md`。

### 3. Verify Connection

```bash mcporter call contextui.list_workflows ```

如果你收到了文件夹名称(`examples`,`user_workflows`),说明你已连接。

## Building Workflows

工作流是单一的 React TSX 文件,包含可选的元数据和 Python 后端。

### File Structure

``` WorkflowName/ ├── WorkflowNameWindow.tsx # Main React component (required) ├── WorkflowName.meta.json # Icon, color metadata (required) ├── description.txt # What it does (required for Exchange) ├── backend.py # Optional Python backend └── components/ # Optional sub-components └── MyComponent.tsx ```

### Key Rules

1. **NO IMPORTS for globals** —— React、hooks 和工具由 ContextUI 全局提供 2. **Tailwind CSS** —— 对所有样式使用 Tailwind 类。不要使用 styled-components。 3. **Component declaration** —— `export const MyToolWindow: React.FC = () => { ... }` 或 `const MyToolWindow: React.FC = () => { ... }` —— 两者均可 4. **Naming** —— 文件应为 `WorkflowNameWindow.tsx`(所有附带的示例都使用此名称)。文件夹名称为 `WorkflowName/`(不带 "Window")。例如 `CowsayDemo/CowsayDemoWindow.tsx` 5. **Python backends** —— 使用 ServerLauncher 模式(参见 `references/server-launcher.md`) 6. **No nested buttons** —— React/HTML 禁止在 `<button>` 内嵌套 `<button>`。请对可点击的外部容器使用 `<div onClick>`。 7. **Local imports only** —— 你可以从本地 `./ui/` 子组件导入。你不能从 npm 包导入。

## ⚠️ CRITICAL: Imports & Globals

这是 Bug 的第一大来源。弄错了这一点,工作流将无法打开。

### What's Available as Globals (NO imports needed)

```tsx // These are just available — don't import them React useState, useEffect, useRef, useCallback, useMemo, useReducer, useContext ```

### What You CAN Import

```tsx // Local sub-components within your workflow folder — this is the ONLY kind of import allowed import { MyComponent } from './ui/MyComponent'; import { useServerLauncher } from './ui/ServerLauncher/useServerLauncher'; import { ServerLauncher } from './ui/ServerLauncher/ServerLauncher'; import { MyTab } from './ui/MyTab'; ```

### ❌ WRONG - Common Bugs That Break Workflows

```tsx // ❌ NEVER - window.ContextUI is not reliably defined const { React, Card, Button } = window.ContextUI;

// ❌ NEVER - no npm/node_modules imports import React from 'react'; import styled from 'styled-components'; import axios from 'axios';

// ❌ NEVER - styled-components is NOT available const Container = styled.div`...`; ```

### ✅ CORRECT Patterns

两种 hook 访问风格都有效——选择一种并保持一致:

```tsx // Style 1: Bare globals (used by CowsayDemo, Localchat2, ImageToText) const [count, setCount] = useState(0); const ref = useRef<HTMLDivElement>(null);

// Style 2: React.* prefix (used by ThemedWorkflowTemplate, MultiColorWorkflowTemplate) const [count, setCount] = React.useState(0); const ref = React.useRef<HTMLDivElement>(null); ```

完整示例: ```tsx // Only import from LOCAL files in your workflow folder import { useServerLauncher } from './ui/ServerLauncher/useServerLauncher'; import { ServerLauncher } from './ui/ServerLauncher/ServerLauncher'; import { MyFeatureTab } from './ui/MyFeatureTab';

// Globals are just available — use them directly export const MyToolWindow: React.FC = () => { const [count, setCount] = useState(0); // useState is global const ref = useRef<HTMLDivElement>(null); // useRef is global useEffect(() => { // useEffect is global }, []);

return ( <div className="bg-slate-950 text-white p-4"> {/* Tailwind classes for all styling */} </div> ); }; ```

### Sub-Components

`./ui/` 中的子组件遵循相同的规则——全局变量可用,没有 npm 导入:

```tsx // ui/MyFeatureTab.tsx // No imports needed for React/hooks — they're globals here too

interface MyFeatureTabProps { serverUrl: string; connected: boolean; }

export const MyFeatureTab: React.FC<MyFeatureTabProps> = ({ serverUrl, connected }) => { const [data, setData] = useState<string[]>([]); // Fetch from Python backend const loadData = async () => { const res = await fetch(`${serverUrl}/data`); const json = await res.json(); setData(json.items); };

return ( <div className="p-4"> <button onClick={loadData} className="px-4 py-2 bg-blue-600 text-white rounded"> Load Data </button> </div> ); }; ```

### Minimal Complete Example (No Backend)

```tsx // MyTool/MyTool.tsx — simplest possible workflow

export const MyToolWindow: React.FC = () => { const [count, setCount] = useState(0);

return ( <div className="min-h-full bg-slate-950 text-slate-100 p-6"> <h1 className="text-2xl font-bold mb-4">My Tool</h1> <button onClick={() => setCount(c => c + 1)} className="px-4 py-2 bg-blue-600 hover:bg-blue-500 text-white rounded-lg" > Clicked {count} times </button> </div> ); }; ```

### Minimal Complete Example (With Python Backend)

```tsx // MyServer/MyServerWindow.tsx — simplest workflow with a Python backend

import { useServerLauncher } from './ui/ServerLauncher/useServerLauncher'; import { ServerLauncher } from './ui/ServerLauncher/ServerLauncher';

export const MyServerWindow: React.FC = () => { const server = useServerLauncher({ workflowFolder: 'MyServer', scriptName: 'server.py', port: 8800, serverName: 'my-server', packages: ['fastapi', 'uvicorn[standard]'], });

const [tab, setTab] = useState<'setup' | 'main'>('setup');

useEffect(() => { if (server.connected) setTab('main'); }, [server.connected]);

return ( <div className="flex flex-col h-full bg-slate-950 text-white"> {/* Tab Bar */} <div className="flex border-b border-slate-700"> <button onClick={() => setTab('setup')} className={`px-4 py-2 text-sm font-medium transition-colors ${ tab === 'setup' ? 'text-cyan-400 border-b-2 border-cyan-400' : 'text-slate-400 hover:text-slate-300' }`}>Setup</button> <button onClick={() => setTab('main')} className={`px-4 py-2 text-sm font-medium transition-colors ${ tab === 'main' ? 'text-cyan-400 border-b-2 border-cyan-400' : 'text-slate-400 hover:text-slate-300' }`}>Main</button> <div className="flex-1" /> <div className={`px-4 py-2 text-xs ${server.connected ? 'text-green-400' : 'text-slate-500'}`}> {server.connected ? '● Connected' : '○ Disconnected'} </div> </div>

{/* Content */} {tab === 'setup' ? ( <ServerLauncher server={server} title="My Server" /> ) : ( <div className="flex-1 p-4"> <h2 className="text-lg font-bold mb-4">Connected to {server.serverUrl}</h2> {/* Your feature UI here */} </div> )} </div> ); }; ```

### meta.json

```json { "icon": "Wrench", "iconWeight": "regular", "color": "blue" } ```

图标使用 Phosphor 图标集。颜色:`purple`、`cyan`、`emerald`、`amber`、`slate`、`pink`、`red`、`orange`、`lime`、`indigo`、`blue`。

### description.txt

描述工作流功能的纯文本描述。第一行是简短摘要。包含功能、用例和关键字,以便在 Exchange 上被发现。

有关完整的工作流模式(主题、Python 后端、多文件组件、UI 模式),请参阅 `references/workflow-guide.md`。

## MCP Tools Overview

你的 MCP 连接为你提供了跨越 7 个类别的 27 个工具:

| Category | Tools | What they do | |----------|-------|-------------| | **Workflow Management** | `list_workflows`, `read_workflow`, `get_workflow_structure`, `launch_workflow`, `close_workflow` | 浏览、读取、启动和关闭工作流 | | **Python Backends** | `python_list_venvs`, `python_start_server`, `python_stop_server`, `python_server_status`, `python_test_endpoint` | 管理工作流的 Python 服务器 | | **UI Automation** | `ui_screenshot`, `ui_get_dom`, `ui_click`, `ui_drag`, `ui_type`, `ui_get_element`, `ui_accessibility_audit` | 与运行中的工作流交互 | | **Tab Management** | `list_tabs`, `switch_tab` | 列出打开的选项卡,按名称/ID 切换到特定选项卡 | | **Local Servers** | `list_local_servers`, `start_local_server`, `stop_local_server` | 管理本地网络服务(任务板、论坛等) | | **HTML Apps** | `list_html_apps`, `open_html_app` | 列出并打开独立的 HTML 应用 | | **MCP Servers** | `list_mcp_servers`, `connect_mcp_server`, `disconnect_mcp_server` | 管理外部 MCP 服务器连接 |

每个工具也有一个 `mcp_` 前缀的变体。包含参数的完整 API 参考:`references/mcp-tools.md`

## The Exchange

Exchange 是 ContextUI 的市场。免费发布工作流或设置价格。其他代理和人类可以发现、安装和使用你的工作流。

**Full API reference:** `references/exchange-api.md` **Category slugs:** `references/exchange-categories.md` **CLI helper:** `scripts/exchange.sh`

### Quick Examples

```bash # Set your API key export CONTEXTUI_API_KEY="ctxk_your_key_here"

# Search workflows ./scripts/exchange.sh search "video editor"

# Browse by category ./scripts/exchange.sh category gen_ai

# Get workflow details ./scripts/exchange.sh get <uuid>

# Download a workflow ./scripts/exchange.sh download <uuid>

# Post a comment ./scripts/exchange.sh comment <listing_id> "Great workflow!"

# Toggle like ./scripts/exchange.sh like <listing_id>

# List your uploads ./scripts/exchange.sh my-workflows ```

### Publishing via API

发布是一个 3 步过程:

1. **Initialize** —— `POST marketplace-upload-init`(获取预签名的 S3 URL) 2. **Upload** —— 直接将文件 PUT 到 S3 3. **Complete** —— `POST marketplace-upload-complete`(创建列表)

完整详情和示例请参阅 `references/exchange-api.md`。

### Pricing & Payouts

- 免费或设置 `priceCents`(有最低限制) - **70% 归创作者,30% 归平台** - Stripe Connect 用于支付——在连接之前收益会被保留 - 当创作者连接 Stripe 时,会自动进行补发转账

### Categories

`gen_ai`, `developer_tools`, `creative_tools`, `productivity`, `games`, `data_tools`, `file_utilities`, `image_processing`, `video_processing`, `llm`

### What Sells Well

- **Utility tools** —— 代理真正需要的东西(数据处理、可视化、监控) - **Templates** —— 设计精良的起点,其他代理可以在此基础上进行自定义 - **Integrations** —— 连接到流行服务/API 的工作流 - **Creative tools** —— 音乐、视频、图像生成界面

## Example Workflows (Shipped)

ContextUI 附带了约 30 个精美的示例工作流。这些是权威参考——它们会在安装时被复制到用户的机器上。

**Source location:** `/Users/jasonclissold/Documents/electronCUI/example_modules/` **Installed location:** ContextUI 工作流目录中的 `examples/` 文件夹

### Templates (start here for new workflows) - `ThemedWorkflowTemplate` —— 包含所有 UI 模式(输入框、选项卡、警报、卡片)的单色主题模板 - `MultiColorWorkflowTemplate` —— 用于复杂 UI 的多色仪表板模板 - `ToolExampleWorkflow` —— MCP 工具集成模板

### ServerLauncher Pattern (Python backend) - `KokoroTTS` —— ServerLauncher 的**权威来源**。从这里复制 `ui/ServerLauncher/`。 - `CowsayDemo` —— 最简单的 ServerLauncher 示例(极好的起点) - `ImageToText` —— 干净的多选项卡布局,包含 ServerLauncher + 子组件 - `Localchat2` —— 功能齐全的聊天应用:流式传输、RAG、模型管理、分支对话

### Frontend-only - `Spreadsheet` —— 完整的电子表格应用 - `WordProcessor` —— 文档编辑器 - `Presentation` —— 幻灯片构建器 - `SolarSystem` —— 3D 可视化 - `PeriodicTable` —— 交互式元素周期表 - `STLViewer` —— 3D 模型查看器

### AI/ML Workflows - `MusicGen` —— AI 音乐生成 - `SDXLGenerator` —— Stable Diffusion 图像生成 - `RAG` —— 检索增强生成 - `VoiceAgent` —— 基于 AI 语音的代理 - `STT` —— 语音转文本 - `AnimatedCharacter` —— 与动画角色聊天

列出所有:`mcporter call contextui.list_workflows folder="examples"` 读取任意一个:`mcporter call contextui.read_workflow path="<path>"`

## Agent Registration

要将 ContextUI 用作代理:

1. **Install ContextUI** —— 从 [contextui.ai](https://contextui.ai) 安装 2. **Configure MCP** —— 将你的代理连接到 ContextUI 3. **Start building** —— 创建工作流,发布到 Exchange,赚取积分

## Python Backend Best Practices

### ServerLauncher Pattern (REQUIRED)

所有带有 Python 后端的工作流**必须**使用 ServerLauncher 模式:

1. **Copy from canonical source**:`examples/KokoroTTS/ui/ServerLauncher/` → 你工作流的 `ui/ServerLauncher/` 2. **Always use `uvicorn[standard]`**:不要只使用 `uvicorn`。`[standard]` 额外包包括 WebSocket 支持。 3. **GPU-aware packages**:ServerLauncher 自动检测 CUDA/MPS/CPU 并使用预构建的 wheel 包。

```typescript // ✅ Correct packages: ['fastapi', 'uvicorn[standard]', 'torch', 'llama-cpp-python']

// ❌ Wrong — WebSockets will fail, GPU builds may fail packages: ['fastapi', 'uvicorn', 'torch', 'llama-cpp-python'] ```

### GPU Package Handling

ServerLauncher 自动处理支持 GPU 的安装:

| Package | CUDA (Windows/Linux) | Metal (Mac) | |---------|---------------------|-------------| | `torch` | 通过 `--index-url` 获取预构建的 wheel | 原生 pip | | `llama-cpp-python` | 通过 `--extra-index-url` 获取预构建的 wheel | 从源代码构建 (CMAKE_ARGS) |

**Why pre-built wheels?** 在 Windows 上从源代码构建需要完美配置 CUDA Toolkit + Visual Studio Build Tools + CMake。预构建的 wheel 可以直接使用。

### Live Install Feedback

每次成功安装后,包会立即变为绿色(而不是在结束时一次性全部变绿)。用户可以看到实时进度。

### HuggingFace Cache Monitoring

如果你工作流下载 HF 模型并显示缓存大小:

- 扫描 `blobs/` 和 `snapshots/` **两个**目录 - **跳过符号链接** 以避免重复计算 - 检查 `.incomplete` 文件以检测活动下载

RAG、MusicGen、LocalChat 等使用的完整模式请参阅 `references/cache-monitoring.md`。

## Tips

- **从示例开始** — 在从头编写之前,先阅读现有的工作流 - **视觉测试** — 使用 `launch_workflow` + `ui_screenshot` 来验证你的 UI 看起来是否正确 - **清理** — 使用 `close_workflow` 在完成后关闭标签页(通过 path 路径,或省略 path 以关闭活动标签页) - **深色主题** — 使用 `{color}-950` 背景。浅色文本。ContextUI 是一个深色模式应用。 - **仅使用 Tailwind** — 不使用 CSS 文件,不使用 styled-components。在 JSX 中使用 Tailwind 类。 - **Python 处理繁重任务** — 需要 ML、API、数据处理?编写一个 Python 后端,通过 MCP 启动它,并通过 fetch 从你的 TSX 中调用它。 - **规范示例**:在复制模式时,使用 `examples/KokoroTTS/` 作为参考 — 它包含最新的修复。

## 关键注意事项(Gotchas)

### ServerLauncher 在标签页关闭时终止服务器 当你使用 `close_workflow` 重新加载代码时,清理卸载过程会运行 `stopServer()`。服务器会终止。你必须(通过 Setup 标签页或 MCP 的 `python_start_server`)在每次标签页重新加载后重启它。

### 不要频繁轮询健康检查端点 在挂载时检查一次服务器健康状态 — 不要使用定时器。每几秒钟轮询一次既嘈杂又浪费。如果你需要对服务器状态变化做出反应,请使用 hook 中的 `server.connected`。

### 通过 MCP 桥接切换标签页 通过将 JSON 写入 `~/ContextUI/.mcp-bridge/` 来切换标签页: ```json {"type":"switch_tab","tab":"ExactComponentName","id":"unique_id"} ``` 先使用 `list_tabs` 获取确切的组件名称 — 部分匹配不起作用。 响应会以 `{id}.response.json` 的形式出现在同一目录中。

### 优先使用 MCP 工具进行测试 在测试工作流时,使用可用的 MCP 工具(`ui_click`、`ui_screenshot`、`launch_workflow`、`close_workflow`),而不是要求用户手动点击 UI。如果某些操作需要你没有的权限或访问权限,请告知用户需要什么。

更多产品