🎨 Percival——图像MCP服务器
______________________________________________________________________
🙏 积分和原始存储库
这个项目是优秀的 ai图像mcp,最初由 卡里姆·阿里 (kareemaly).
原始作品的稳健MCP工具架构, uv-基于依赖关系管理和SHA-256/MD5图像分析缓存系统都来自上游项目。我们的重构专注于消除供应商锁定,扩展提供商灵活性,并优化自主代理编排的工具描述。
______________________________________________________________________
🛠️ 发生了什么变化?(重构细节)
进行了以下架构更改以进行转换 ai-image-mcp 进入 珀西瓦尔:
1.完全异步架构(性能)
最初的项目使用了同步I/O和阻塞请求,这可能会降低MCP服务器在大代中的响应能力。
- 更改: 将整个服务器迁移到异步优先模型。核心传输现在使用
httpx.AsyncClient和AsyncOpenAI. - 更改: 所有工具(生成、编辑、视觉、列表、元数据)现在都已
async def无阻塞。 - 好处: 与FastMCP的异步运行时完全兼容,并发请求的吞吐量显著提高。
2.解耦的OpenAI客户端(提供商无关)
- 更改: 集中式异步客户端模块(
utils/client.py)利用Pydantic模型进行响应验证。它针对的变量包括JARVINA_BASE_URL和JARVINA_API_KEY. - 好处: 与任何兼容OpenAI的提供商(例如Venice.ai)进行稳健、类型安全的通信。
3.现代化模型目录(模式3.0)
- 更改: 更新了本地型号目录(
image_models.json)到架构版本3.0以及优化的目录实用程序(utils/model_catalog.py)为了实现高效的标准化。 - 好处: 更丰富的元数据支持矢量清除生成和4K升级等特殊任务。
4.灵活和不可知的沙盒(用户工作区)
- 更改: 集中路径验证
utils/path_utils.py并实施了广泛的、与语言无关的沙盒策略。 - 更改: 用户的 主目录 (
Path.home())默认情况下,它现在是一个允许的root,确保与不同操作系统语言(如葡萄牙语、英语)的Nanobot工作区立即兼容。 - 好处: 消除了“外部允许的根”错误,同时维护了防止任意系统逃逸的安全防护措施。
5.集中配置和标准化日志记录
- 更改: 已全部替换
os.getenv和print统一声明utils/config.py模块和标准Pythonlogging. - 好处: 提高了可观察性,在不干扰MCP的情况下更容易部署
stdio协议。
6.威尼斯有效载荷生成器(确定性参数解析)
原版 generate_image 函数不支持来自非OpenAI提供者的高级参数。
- 更改: 该工具现在通过专用的Venice有效载荷层构建和验证特定于提供商的有效载荷,然后使用
extra_body. - 决议顺序: 显式工具参数>运行时覆盖JSON>模型卡
recommended_api_params>服务器默认值。 - 好处: 充分利用Venice.ai的扩展图像生成能力,具有确定性参数优先级。
5.威尼斯本土交通硬化(兼容性+自愈性)
- 更改: 本地请求
POST /image/generate现在避免发送OpenAI样式size并推导width/height在适用的情况下。 - 更改: 当提供程序返回时,为本机模式添加了有界重试逻辑
unrecognized_keys;被拒绝的密钥会被自动修剪并重试。 - 更改: 传输元数据现在公开了诊断字段(
native_dropped_keys,compat_dropped_keys,fallback_reason)为了提高代理的可观察性。 - 好处: 降低回退频率,减少生产中的400个错误,并为纳米机器人工具推理提供更清晰的诊断。
6.提供者感知缓存
原始缓存系统仅根据提示、模型和图像大小生成哈希值。
- 更改: 这
_get_cache_key()方法现在包括以下域JARVINA_BASE_URL在哈希计算中。 - 好处: 防止提供程序之间的缓存冲突。发送给OpenAI和Venice.ai的相同提示现在会产生单独的、独立的缓存条目。
7.代理优化文档字符串
- 更改: 为了提高自主代理的清晰度,重写了工具描述。
- 好处: 代理管弦乐器现在完全理解了 *当* 查询模型列表 *怎么* 传递特定于提供者的参数,减少幻觉函数调用。
8.视觉模型配置
- 更改: 专注的
JARVINA_VISION_MODEL为图像分析(视觉)模型添加了环境变量,与生成模型分开。 - 好处: 允许独立配置生成模型与分析模型(例如,使用多模态模型,如
qwen-2.5-vl用于视觉任务)。
______________________________________________________________________
🔌 MCP工具
图像生成
| 工具 | 说明 |
|---|---|
recommend_model_for_intent | 使用模型卡(意图、成本、质量、速度、可用性)对人类目标的最佳拟合模型进行排名 |
list_model_cards | 从本地JSON目录中列出结构化模型卡(建议的第一步) |
get_model_card | 获取一张包含功能、层次和定价元数据的型号卡 |
list_image_styles | 列表可用 style_preset 直接从提供者输入(/image/styles) |
verify_model_availability | 执行前确认所选型号在威尼斯仍处于活动状态 |
get_nanobot_profile | 返回nanobot的机器可读集成配置文件和推荐工作流程 |
list_available_models | 直接列出提供者模型(在线,具有短缓存) |
generate_image | 使用可选的特定于提供程序的参数从文本提示生成图像 |
edit_image | 使用具有图像编辑功能的模型编辑现有图像 |
list_generated_images | 在包含元数据的目录中列出所有生成的图像 |
注: create_image_variations 在验证提供程序兼容性之前,将保持禁用状态。图像分析(视觉)
| 工具 | 说明 |
|---|---|
describe_image | 使用视觉模型生成图像的详细描述 |
analyze_image_content | 按类型进行有针对性的分析: general, objects, text, colors, composition, emotions |
compare_images | 比较两张图片,突出异同 |
get_image_metadata | 无需API调用即可获取技术元数据(维度、格式、文件大小、EXIF) |
缓存管理
| 工具 | 说明 |
|---|---|
get_cache_info | 查看缓存统计信息(文件数、总大小) |
clear_image_cache | 删除所有缓存的分析结果 |
get_security_metrics | 检查内存中的安全计数器/事件(身份验证/路径逃逸/提示注入检测) |
clear_security_metrics | 重置内存中的安全计数器/事件 |
get_security_posture | 显示有效的运行时安全配置和警告 |
______________________________________________________________________
🚀 需求
- Python 3.10+
uv包管理器- 共享工作空间虚拟环境(
percival.OS_Dev/.venv)用于运行时和测试
______________________________________________________________________
📦 安装
cd ~/Documentos/percival.OS_Dev
export UV_PROJECT_ENVIRONMENT=~/Documentos/percival.OS_Dev/.venv
uv sync --directory mcp_servers/percival_image_creator_mcp此服务器故意这样做 不 保持本地.venv里面mcp_servers/percival_image_creator_mcp. 版本控制由monorepo根管理(percival.OS_Dev/.git),此服务器目录中没有嵌套的Git元数据。
______________________________________________________________________
⚙️ 配置
Percival是通过环境变量配置的:
| 变量 | 必填 | 默认 | 描述 |
|---|---|---|---|
JARVINA_API_KEY | ✅ | — | 提供程序的API密钥。回落到 VENICE_API_KEY 或 OPENAI_API_KEY |
JARVINA_BASE_URL | ✅ | https://api.openai.com/v1 | 与OpenAI兼容的API终结点的基本URL |
JARVINA_VISION_MODEL | ❌ | qwen-2.5-vl | 用于视觉/分析任务的模型ID |
PERCIVAL_IMAGE_MCP_IMAGE_TRANSPORT | ❌ | auto | 发电运输方式: auto, openai_compat,或 venice_native |
PERCIVAL_IMAGE_MCP_IMAGE_TRANSPORT_FALLBACK | ❌ | true | 允许回退到 openai_compat 如果威尼斯本地运输失败 |
PERCIVAL_IMAGE_MCP_VENICE_NATIVE_RETRIES | ❌ | 1 | 提供程序后的本机重试尝试次数 unrecognized_keys 错误 |
PERCIVAL_IMAGE_MCP_PROVIDER_TIMEOUT_SECONDS | ❌ | 90 | 提供程序生成请求超时 |
PERCIVAL_IMAGE_MCP_GENERATION_OVERRIDES_JSON | ❌ | — | 具有运行时生成参数覆盖的JSON对象 |
PERCIVAL_IMAGE_MCP_DEFAULT_OUTPUT_DIR | ❌ | ~/Pictures | 生成/编辑图像的默认输出目录 |
PERCIVAL_IMAGE_MCP_ALLOWED_ROOTS | ❌ | Home+CWD | 允许使用逗号分隔的绝对根 working_dir |
PERCIVAL_IMAGE_MCP_DISABLE_ROOT_SANDBOX | ❌ | false | 禁用 working_dir 根系封闭(仅用于开发) |
PERCIVAL_IMAGE_MCP_AUTH_TOKEN | ❌ | — | HTTP认证中间件使用的承载令牌 |
PERCIVAL_IMAGE_MCP_ALLOW_REMOTE_HTTP | ❌ | false | 允许非环回HTTP绑定(需要身份验证令牌) |
PERCIVAL_IMAGE_MCP_ALLOW_INSECURE_PROVIDER_URL | ❌ | false | 允许非HTTPS JARVINA_BASE_URL |
PERCIVAL_IMAGE_MCP_ALLOW_PRIVATE_PROVIDER_URL | ❌ | false | 允许提供程序URL解析为本地/私有IP |
PERCIVAL_IMAGE_MCP_ALLOWED_PROVIDER_HOSTS | ❌ | — | 逗号分隔的提供程序主机分配列表 |
PERCIVAL_IMAGE_MCP_ALLOW_HTTP_DOWNLOADS | ❌ | false | 允许 http:// 下载URL |
PERCIVAL_IMAGE_MCP_ALLOW_PRIVATE_DOWNLOADS | ❌ | false | 允许下载URL解析为本地/私有IP |
PERCIVAL_IMAGE_MCP_ALLOWED_DOWNLOAD_HOSTS | ❌ | — | 下载URL的主机分配列表以逗号分隔 |
PERCIVAL_IMAGE_MCP_DOWNLOAD_MAX_BYTES | ❌ | 26214400 | 下载图像URL有效载荷时允许的最大字节数 |
PERCIVAL_IMAGE_MCP_MAX_PROMPT_CHARS | ❌ | 4000 | 生成/编辑提示中接受的最大字符数 |
PERCIVAL_IMAGE_MCP_MAX_NEGATIVE_PROMPT_CHARS | ❌ | 2000 | 中接受的最大字符数 negative_prompt |
PERCIVAL_IMAGE_MCP_MAX_FILENAME_PREFIX_CHARS | ❌ | 80 | 图像文件名前缀中可接受的最大字符数 |
PERCIVAL_IMAGE_MCP_MAX_MODEL_ID_CHARS | ❌ | 128 | 最大长度 model/model_id |
PERCIVAL_IMAGE_MCP_MAX_LIST_FILES | ❌ | 200 | 返回的最大文件数 list_generated_images |
PERCIVAL_IMAGE_MCP_MAX_ANALYSIS_PROMPT_CHARS | ❌ | 4000 | 最大长度 describe_image.prompt |
PERCIVAL_IMAGE_MCP_MAX_COMPARISON_FOCUS_CHARS | ❌ | 200 | 最大长度 compare_images.comparison_focus |
______________________________________________________________________
▶️ 跑步
标准stdio运行时:
export UV_PROJECT_ENVIRONMENT=~/Documentos/percival.OS_Dev/.venv
uv run --no-sync --directory ~/Documentos/percival.OS_Dev/mcp_servers/percival_image_creator_mcp python main.py --mode stdioHTTP传输:
export UV_PROJECT_ENVIRONMENT=~/Documentos/percival.OS_Dev/.venv
PERCIVAL_IMAGE_MCP_AUTH_TOKEN=change-me uv run --no-sync --directory ~/Documentos/percival.OS_Dev/mcp_servers/percival_image_creator_mcp python main.py --mode sse --host 127.0.0.1 --port 8000
PERCIVAL_IMAGE_MCP_AUTH_TOKEN=change-me uv run --no-sync --directory ~/Documentos/percival.OS_Dev/mcp_servers/percival_image_creator_mcp python main.py --mode streamable-http --host 127.0.0.1 --port 8000 --stateless-http打印集成配置文件:
export UV_PROJECT_ENVIRONMENT=~/Documentos/percival.OS_Dev/.venv
uv run --no-sync --directory ~/Documentos/percival.OS_Dev/mcp_servers/percival_image_creator_mcp python main.py --print-profile✅ 测试
export UV_PROJECT_ENVIRONMENT=~/Documentos/percival.OS_Dev/.venv
uv run --no-sync --directory ~/Documentos/percival.OS_Dev/mcp_servers/percival_image_creator_mcp pytest -q______________________________________________________________________
🤖 与nanobot/Claude Desktop集成
将以下条目添加到您的代理的 config.json:
"percival-image": {
"command": "uv",
"args": [
"run",
"--no-sync",
"--directory",
"~/Documentos/percival.OS_Dev/mcp_servers/percival_image_creator_mcp",
"python",
"main.py",
"--mode",
"stdio"
],
"enabledTools": [
"recommend_model_for_intent",
"list_model_cards",
"get_model_card",
"list_image_styles",
"verify_model_availability",
"get_security_metrics",
"clear_security_metrics",
"get_security_posture",
"generate_image",
"edit_image",
"describe_image",
"analyze_image_content",
"compare_images",
"get_image_metadata",
"list_generated_images"
],
"toolTimeout": 45,
"env": {
"UV_PROJECT_ENVIRONMENT": "~/Documentos/percival.OS_Dev/.venv",
"JARVINA_API_KEY": "your-api-key-here",
"JARVINA_BASE_URL": "https://api.venice.ai/api/v1",
"JARVINA_VISION_MODEL": "qwen-2.5-vl"
}
}示例用法
User: Generate a 16:9 cyberpunk cityscape image.
Agent: [calls list_model_cards(task_type="text_to_image")]
[or calls recommend_model_for_intent(task_type="text_to_image", intent="")]
[selects model by model card metadata]
[calls list_image_styles() when LoRA style preset is needed]
[calls verify_model_availability(model_id="venice-sd35", task_type="text_to_image")]
[calls generate_image(model="venice-sd35", aspect_ratio="16:9", negative_prompt="blur, low quality")]
User: Edit that image to remove a background element.
Agent: [calls list_model_cards(task_type="image_edit")]
[calls verify_model_availability(model_id="qwen-image-2-edit", task_type="image_edit")]
[calls edit_image(image_path="...", model="qwen-image-2-edit", prompt="remove background element")]
User: Describe what's in that image.
Agent: [calls describe_image with the generated file path]
[returns cached result on subsequent identical requests]______________________________________________________________________
📁 项目结构
percival_image_creator_mcp/
├── main.py # Entry point
├── server.py # MCP server instance
├── pyproject.toml # Project metadata & dependencies
├── image_models.json # Structured model cards (schema v2.1)
├── tests/ # Unit and mocked integration tests
│ └── fixtures/prompt_injection_corpus.json # Security regression corpus
├── tools/
│ ├── image_generation_tools.py # catalog tools, availability check, generate/edit tools
│ └── image_description_tools.py # describe_image, analyze_image_content, compare_images, metadata, cache tools
└── utils/
├── model_catalog.py # Catalog load/validation/query layer
├── client.py # Provider-agnostic OpenAI client (Percival singleton)
├── nanobot_profile.py # Machine-readable nanobot integration profile + contract version
├── cache_utils.py # SHA-256 + MD5 provider-aware image analysis cache
├── path_utils.py # Image path validation utilities
└── security_utils.py # Prompt/input sanitization + security telemetryNanobot合约(推荐编排)
list_model_cards(task_type=...)get_model_card(model_id)(可选深度检查)verify_model_availability(model_id, task_type=...)generate_image(...)或edit_image(...)
generate_image 和 edit_image 默认情况下运行严格的飞行前检查(strict_model_check=True).
稳定的刀具输出合同
工具返回一个紧凑的JSON信封(生成+视觉+缓存):
{
"ok": true,
"data": {
"...": "...",
"transport": {
"transport_requested": "auto",
"transport_used": "venice_native",
"fallback_used": false,
"native_dropped_keys": []
}
},
"meta": {
"server": "percival-image-creator-mcp",
"contract_version": "2026-03-s3",
"request_id": "img-...",
"timestamp": "2026-03-29T21:31:00Z",
"tool": "generate_image"
},
"legacy_text": "human-readable compatibility text"
}错误形状:
{
"ok": false,
"error": "message",
"code": "error_code",
"details": { "...": "..." },
"meta": {
"server": "percival-image-creator-mcp",
"contract_version": "2026-03-s3",
"request_id": "img-...",
"timestamp": "2026-03-29T21:31:00Z",
"tool": "generate_image"
},
"legacy_text": "Error: ..."
}对于大型目录中的有效载荷控制, list_model_cards 支持:
limitoffsetfields(逗号分隔)
安全强化(PR-SEC-3/PR-SEC-4/PR-SEC-5/PR-SEC-6/PR-SEC-7/PR-SEC-8)
- 视觉输出和EXIF文本被视为 不可信的外部数据.
- 模型/元数据输出中的快速注入模式经过净化,并在结构化中标记
security领域。 - 安全遥测记录在内存中:
- auth_rejected - remote_bind_blocked - loopback_http_without_auth - path_escape_blocked - prompt_injection_detected
- 使用
get_security_metrics用于运行时检查。 - 使用
clear_security_metrics重置事件分析窗口之间的计数器/事件。 - 使用
get_security_posture检查有效的运行时策略+强化警告。 - 出站URL护栏:
- JARVINA_BASE_URL 已验证(方案/主机/专用网络策略)。 - 在下载之前验证提供商返回的图像URL(SSRF控件)。 - 下载大小上限为 PERCIVAL_IMAGE_MCP_DOWNLOAD_MAX_BYTES.
- 缓存硬化:
- 强制缓存目录/文件权限 0700/0600 在支持的地方; - 缓存写入使用原子替换; - 缓存符号链接/路径转义尝试被阻止和审核。
- 输入/滥用护栏:
- 提示/模型/前缀长度受环境可配置限制的约束; - 文件名前缀和模型ID由安全字符策略验证; - 非常大 list_generated_images 结果集被策略截断。
______________________________________________________________________
📖 归因
本项目建立在以下工作的基础上:
- kareemaly/ai图像mcp --提供原始MCP工具架构和缓存系统的直接上游项目。
______________________________________________________________________
📄 许可证
此项目维护原始存储库中的MIT许可证。看 许可证 了解详情。
