pic-id-mcp

pic-id-mcp

Local vision-capable MCP server that lets AI agents describe screenshots, UI, charts, and photos via vision and OCR tools, with support for multiple providers and automatic fallback.

Category
Visit Server

README

pic-id-mcp

English | 中文

pic-id is first and foremost an MCP server for AI agents — 4 MCP tools (vision / ocr / list_models / providers) describe screenshots, UI, charts, and photos through 14 preset providers with automatic fallback. The Tauri 2 desktop app is an optional add-on: a visual console for usage stats, call logs, provider/model testing, and convenient MCP configuration. Zero credentials in the repo.

Core: the MCP server

  • 4 MCP tools: vision, ocr, list_models, providers — with automatic provider fallback (main fails → next enabled provider)
  • 14 preset providers: OpenAI, Anthropic, Gemini, Kimi, Qwen, GLM, Z.AI, MiniMax, MiMo, SenseNova, Ollama — one-click setup
  • Custom provider: any OpenAI / Anthropic / Ollama / Gemini compatible endpoint
  • Transports: stdio (primary — the client manages the process lifecycle) + Streamable HTTP; plug into ZCode / Claude / Cursor
  • Config hot-reload: config/secrets changes are picked up on the next tool call, no server restart needed
  • Zero sensitive data in repo: credentials live in OS app-data, never committed

Optional: the desktop app

A tray-resident liquid-glass window parked at the bottom-right:

  • Home: usage stats, token usage breakdown by provider/model, call logs (MCP + REST, paginated)
  • Settings: manage providers, keys, models, MCP primary/fallback — saved and hot-applied
  • Playground: real vision tests with the fallback trail
  • Optional launch-at-startup; auto-updates via tauri-plugin-updater

Security

  • REST binds to 127.0.0.1 only, with a strict CORS allowlist (Tauri webview origins), Host-header validation (DNS rebinding defense), and optional http_auth_token
  • Secrets are never returned by the REST API — only "configured" status; writes use server-side merge semantics
  • secrets.toml is written with 0600 permissions on Unix
  • Call logs are whitelisted: image count/size and prompt preview (200 chars) only, never base64 or credentials
  • Production builds ship with a strict CSP ('nonce-{{nonce}}' is required so Tauri's IPC scripts are allowed)

Desktop architecture notes

  • The app binary is named pic-id.exe (unique — a shared app.exe name would collide with other Tauri apps and break taskkill /IM app.exe)
  • Single-instance enforced (second launch focuses the existing window — prevents stray sidecars)
  • The sidecar binds a port from a fixed pool 8100..=8300 (chosen above Windows excluded port ranges, e.g. 7954-8053); the Tauri shell records the picked port in its state before spawning and exposes it to the UI via the server_info command — no log parsing, no file polling

Quick Start

Prerequisites

  • Rust 1.77+ (stable)
  • Node.js 18+ / pnpm
  • Windows / Linux / macOS

Install from source

git clone https://github.com/HaoyueQin/picture-identification-MCP.git
cd picture-identification-MCP

# 1. Build the core MCP server (headless)
cargo build --release -p picid-server
# → binary at target/release/pic-id-server.exe

# 2. Optionally build the desktop console (add-on)
pnpm install
pnpm tauri build
# → exe at src-tauri/target/release/pic-id.exe

Run

# MCP server (for agent integration)
.\target\release\pic-id-server --stdio

# Desktop console
.\src-tauri\target\release\pic-id.exe

# Test instance (isolated config)
$env:PIC_ID_HOME = ".\test-home"
.\src-tauri\target\release\pic-id.exe

Configure

  1. Copy config.example.toml to your OS config directory:

    • Windows: %APPDATA%/pic-id/config.toml
    • Linux: ~/.config/pic-id/config.toml
    • macOS: ~/Library/Application Support/pic-id/config.toml
  2. Create secrets.toml in the same directory (never commit this file):

# OpenAI
[providers."openai"]
token = "sk-your-key-here"

# Anthropic
[providers."anthropic"]
token = "sk-ant-your-key-here"

Or use environment variables:

export PIC_ID__providers__openai__token="sk-..."

Run

# stdio mode (for agent integration)
./target/release/pic-id-server --stdio

# HTTP mode (for GUI + REST API)
./target/release/pic-id-server --http --http-port 8001

ZCode / Claude / Cursor Integration

Add to your MCP configuration:

{
  "mcpServers": {
    "pic-id": {
      "command": "C:\\path\\to\\pic-id-server.exe",
      "args": ["--stdio"]
    }
  }
}

Use the release binary (cargo build --release -p picid-server output, or the path shipped with an installer) — point at the debug build only for development.

Or for HTTP mode:

{
  "mcpServers": {
    "pic-id": {
      "url": "http://127.0.0.1:8001/mcp"
    }
  }
}

Architecture

picture-identification-MCP/
├── crates/
│   ├── core/       # Shared library: config, provider adapters, logging
│   └── server/     # Headless MCP server (rmcp + axum)
├── src-tauri/      # Tauri 2 GUI shell
├── ui/             # Vue 3 + TypeScript frontend
└── docs/           # API reference, specs

Provider pipeline

ImageInput → normalize() → NormalizedImage → Provider.describe()
                                                   ↓
                                          mpsc::Receiver<VisionEvent>
                                                   ↓
                                    Delta | Thinking | Usage | Done

Config Reference

See config.example.toml for all options. Key fields:

Field Type Default Description
server.http_port u16 8001 HTTP bind port
providers[].id string Unique provider id
providers[].kind enum open_ai_compat / anthropic / ollama / gemini
providers[].model string "" Default model (empty = auto-detect)
providers[].enabled bool true Enable/disable

REST API

When running in HTTP mode, the server also exposes a loopback REST API:

Endpoint Method Description
/api/health GET Health check
/api/config GET / PUT Raw config read / write (TOML validated)
/api/config/providers GET List all providers from config (with key/active status)
/api/config/providers POST Add or update one provider (deduped by id)
/api/config/providers/{id} DELETE Remove a provider
/api/secrets GET {"configured": [ids]} — status only, never values
/api/secrets PUT Merge {"providers": {"id": {"token": "…"} | null}}; null removes
/api/models GET Detected models per provider
/api/logs GET Recent call logs
/api/vision POST Run vision with automatic fallback (same as MCP tool)
/api/ocr POST Run OCR with automatic fallback (same as MCP tool)

Auth: if [server].http_auth_token is set, every endpoint requires Authorization: Bearer <token>. The desktop UI sends it automatically via the server_info Tauri command.

Auto-update

The desktop app uses tauri-plugin-updater with GitHub Releases as the update source. The signing private key lives in ~/.tauri/pic-id.key (never in the repo); the public key is baked into src-tauri/tauri.conf.json's plugins.updater.pubkey.

To publish an update:

  1. Bump version in src-tauri/tauri.conf.json

  2. Build with the signing key:

    $env:TAURI_SIGNING_PRIVATE_KEY = Get-Content "$HOME\.tauri\pic-id.key" -Raw
    $env:TAURI_SIGNING_PRIVATE_KEY_PASSWORD = ""
    pnpm tauri build
    
  3. The NSIS bundle produces pic-id_<version>_x64-setup.exe plus its .sig

  4. Create a GitHub Release v<version> and upload the .exe, the .sig and a hand-written latest.json (Tauri v2 does not generate it: signature = the .sig file content, url = the release asset URL, pub_date = RFC 3339)

  5. The updater endpoint is https://github.com/HaoyueQin/picture-identification-MCP/releases/latest/download/latest.json

Settings → Updates lets users check manually or on launch.

Acknowledgments

Reference projects — what we borrowed from each:

  • esengine/DeepSeek-Reasonix (MIT) — the MCP model-level primary/fallback configuration (per-model "provider/model" selection instead of provider-level) and the token usage dashboard layout (input cache-miss / cache-hit / output / hit-rate breakdown by provider and model)
  • HaoyueQin/DeepSeekMonitorWindows (MIT) — the liquid-glass UI style (frosted backdrop-filter: blur() panels, inner-edge highlights, translucent border simulating glass thickness) and the tray-resident small-window pattern (480×700, parked bottom-right, skip taskbar)
  • JayHome137/DeepSeekMonitor & felikschu/deepseek-monitor — upstream projects that DeepSeekMonitorWindows adapts from; our usage-stats orientation follows their monitoring dashboard ideas
  • Apple Human Interface Guidelines — visual inspiration for the liquid-glass design language (frosted surfaces, translucency, layering)

Core frameworks and libraries:

  • rmcp — Rust MCP SDK (stdio + Streamable HTTP transports)
  • Tauri — cross-platform desktop app framework (v2, with tray-icon, updater, single-instance, shell, log plugins)
  • Vue 3 + Vite — frontend framework and build tool
  • axum / tokio / reqwest — async HTTP stack

License

MIT © HaoyueQin

Presets

14 vision-capable providers are pre-configured. Need more? Open an issue and the maintainer will add the preset.

Image size limits: some preset providers restrict input image resolution. SenseNova (sensenova) rejects images whose longer side exceeds ~256 px — real screenshots fail with invalid image base64 content. Use a provider that supports large images (OpenAI / Gemini / Kimi / Qwen…) for screenshots.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured