sf-symbols-mcp

sf-symbols-mcp

An MCP server that helps AI agents pick the right SF Symbol for a UI function without hallucinating symbol names, using layered retrieval and verified catalog entries.

Category
访问服务器

README

sf-symbols-mcp

npm data CI license

An MCP server that helps AI agents pick the right SF Symbol for a UI function — "download the invoice", "archive this message", "show account settings" — without hallucinating symbol names.

Every result is a verified catalog entry (SF Symbols 7.2, 7,781 symbols, 7,006 with vision-derived annotations), found through layered retrieval: query decomposition → lexical search (BM25/FTS5) → local semantic embeddings → curated UI-convention priors → visual-description matching → explainable ranking with availability and restriction filtering.

No API keys. No network at query time. No native build steps. The prebuilt catalog and a small embedding model ship in the data package; queries run in ~100 ms on the built-in node:sqlite plus a 34 MB ONNX model.

On the project's golden-query benchmark the right symbol family is in the top 3 for 98.8% of decomposed queries (top 5: 100%).

Installation

Requires Node ≥ 22.13. The install pulls ~110 MB (catalog database + embedding model) once; everything afterwards is offline.

Claude Code:

claude mcp add sf-symbols -- npx -y sf-symbols-mcp

Claude Desktop / Cursor / any MCP client — add to your MCP config:

{
  "mcpServers": {
    "sf-symbols": {
      "command": "npx",
      "args": ["-y", "sf-symbols-mcp"]
    }
  }
}

Usage

Ask your agent things like:

"Which SF Symbol should I use for the download button?" "Give me an icon for muting a conversation, must work on iOS 15." "What's the filled variant of the bell icon for a selected tab?"

The agent calls search_sf_symbols and gets verified names with reasons:

// search_sf_symbols { query: "download the invoice", primaryAction: "download", object: "invoice" }
{
  "results": [
    {
      "name": "tray.and.arrow.down",
      "score": 0.61,
      "reason": "standard download icon; semantic similarity",
      "description": "A rectangular tray, open at the top, has a solid down arrow pointing into its opening…",
      "family": { "baseName": "tray.and.arrow.down", "variants": [{ "name": "tray.and.arrow.down.fill", "modifiers": ["fill"] }] },
      "availability": { "iOS": "13.0", "macOS": "10.15", "…": "…" },
      "warnings": []
    }
    // …
  ]
}

Tools

Tool Purpose
search_sf_symbols Find symbols for a natural-language UI function. Optional structured fields (primaryAction, object, direction, state, excludedMetaphors, platforms, …) let the calling LLM decompose the query for sharply better ranking. explain: true returns the score breakdown.
get_sf_symbol_info Full metadata: availability, categories, family and variants, restriction status, semantic/visual annotations with provenance.
compare_sf_symbols Structured diff of 2–6 candidates: semantics, pairwise visual similarity, availability deltas, when-to-use-which guidance.
resolve_sf_symbol_variant Pick fill/slash/badge/enclosure variants by UI state and platform conventions (selected tab-bar → .fill, off → .slash, watchOS prefers fill, …). Never invents names.
find_visually_similar_symbols Symbols that look alike (CLIP + perceptual hash): confusable glyphs, simpler alternatives.
update_local_catalog Refresh from your locally installed SF Symbols app (macOS). New symbols become searchable immediately; annotations are preserved.

Results carry scores, one-line reasons, family variants, availability, and typed warnings (restricted symbols, renamed inputs, close calls, ambiguous glyphs).

How it works

SF Symbols.app plists ──extract──▶ normalized catalog (names, availability,
        (macOS, plutil)             categories, aliases, restrictions)
renders (Swift, public APIs) ──▶ vision passes (literal → semantic → reconcile)
                                  + family analysis + deterministic features
                        ──build──▶ catalog.db (SQLite FTS5 + embedding BLOBs)
                                   + bge-small ONNX model, shipped via npm
  • Never fabricates: retrieval happens only over catalog rows; curated mappings are CI-validated against the catalog.
  • Sees the glyphs: each symbol was rendered locally and described by a vision model in three passes (literal content → UI semantics → reconciliation against the name, with contradictions stored, not hidden), plus per-family variant analysis and cross-model consensus checks.
  • Family-aware: bell/bell.fill/bell.badge/bell.slash collapse to one result with variants attached; the plain base symbol fronts the family unless your query implies a variant ("muted", "line through it").
  • Explainable: weighted linear scoring (lexical, semantic, action/object match, curated prior, visual) with explicit penalties (direction conflicts, antonym actions, excluded metaphors, restrictions, deprecations).

Versioning

The data package minor-tracks SF Symbols releases; the server takes any compatible data version. A new SF Symbols release means a data-package update only — npx picks it up automatically.

Maintainer pipeline (not needed by users)

All Apple-derived intermediates live in gitignored generated-local/.

pnpm extract        # read the local SF Symbols app metadata (macOS, plutil)
pnpm render         # deterministic 256px monochrome PNGs (Swift, public APIs)
pnpm features       # pHash, fill-score, symmetry, family grammar validation
pnpm annotate all --yes   # 3-pass vision annotation + family + consensus
pnpm embed          # bge-small text vectors + CLIP image vectors (local)
pnpm build-data --profile=default   # assemble catalog.db
pnpm eval           # golden-query ranking regression (81 queries)
pnpm pack-data      # stage packages/data for publishing

Annotation providers (pick one; ~22,000 requests per full catalog):

  • OpenRouter (cheap, default google/gemini-2.5-flash, ≈ $15–20 total): export OPENROUTER_API_KEY=…, then start with pnpm annotate pass1 --pilot=50 --yes and review before the full run. Useful flags: --concurrency=N, --route=<provider> to pin the upstream, --shard=i/n to split a pass across parallel processes.
  • Anthropic Batches: export ANTHROPIC_API_KEY=…claude-sonnet-5 with structured outputs, ≈ $130 per full catalog.

Every annotation stores provenance (model, prompt version, batch id) and resumes from per-symbol checkpoints. Releasing: pnpm publish --access public in packages/data, then packages/server.

Data profiles & licensing posture

Profile Contents
default (published) Symbol names, availability, categories (facts), plus independently authored annotations, embeddings, curated lexicons. No Apple-authored keyword lists or restriction sentences.
local (your machine only) Everything, including Apple's search keywords — created by update_local_catalog from your own SF Symbols installation.
safe (fallback) Only independently authored data + bare names.

Apple IP notice

This project does not include, embed, or redistribute any Apple artwork, fonts, symbol images, SVG templates, or Apple-authored metadata files. Symbol names are used as factual identifiers for interoperability; all symbol descriptions in the published data are independently authored. Some symbols may be used only as-is to refer to the Apple technology they represent, and no symbol may be used in app icons, logos, or any trademark-related way.

To use the local-extraction features you must install the SF Symbols app yourself and accept Apple's license. Locally rendered previews stay on your machine and must not be redistributed. See NOTICE for the full statement.

SF Symbols is a trademark of Apple Inc. This project is not affiliated with, endorsed, or sponsored by Apple Inc.

Development

pnpm install && pnpm test        # unit + e2e (e2e needs a local catalog build)
pnpm typecheck
pnpm --filter sf-symbols-mcp build   # bundle the server (single-file dist)

License

MIT for all original code and independently authored data. See LICENSE and NOTICE.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选