Game Asset Finder MCP
Game Asset Finder MCP
一个面向游戏开发的“搜索优先”MCP 服务。它同时查询多个公开素材源和可选的本地素材库,把不同站点的结果统一成同一套字段,并做中文关键词扩展、许可证归一化、相关性排序、跨源去重、来源均衡、缓存和游标分页。
项目基于当前 MCP TypeScript SDK v2,使用 stdio 运行,适用于 Codex、ChatGPT 桌面端及其他支持本地 MCP 的客户端。
设计与优化
项目采用 provider 注册表和统一结果模型,并重点优化了跨来源搜索层:
单个来源失败不会拖垮全局搜索,响应会明确标记各来源状态。
关键词权重和中英文游戏术语扩展提升了中文查询的召回率。
加入 TTL/LRU 缓存、相同并发请求合并、provider 总时限、有限重试和
Retry-After。加入统一许可证过滤、规范 URL 去重、镜像来源合并、稳定排序和来源多样化。
用
limit + nextCursor分页,避免一次把大量结果塞进模型上下文。本地索引采用增量扫描、SHA-256、原子写入、允许根目录约束和符号链接跳过。
工具面压缩为 4 个,降低代理选错工具的概率。
Related MCP server: @codesift/mcp
数据源
id | 内容 | 凭据 | 许可证特点 |
| 2D、3D、UI、音频、字体素材包 | 无 | CC0 |
| 2D、3D、音乐、音效 | 无 | 每个条目不同 |
| 免费游戏素材列表 | 无 | 每个作者/页面不同 |
| 图片、纹理、图标参考 | 无 | CC / 公共领域 |
| PBR 材质、HDRI、3D | 无 | CC0 |
| 纹理、HDRI、3D | 无 | CC0 |
| 音效、录音 |
| 每个条目不同 |
| 配置目录中的本地素材 | 本地目录 | 由 sidecar 描述 |
任何远程来源都可能临时超时或限流。返回值中的 sourceStatuses 会逐源给出 ok / partial / disabled / timeout / rate_limited / error;其他成功来源仍然返回结果。
安装
要求 Node.js 20.18.1 或更高版本。
git clone https://github.com/sudoriaa/game-asset-finder-mcp.git
cd game-asset-finder-mcp
npm ci
npm run build
npm test也可以执行:
.\install.ps1直接启动:
node .\dist\index.jsstdio 的标准输出是 MCP JSON-RPC 通道,服务日志只写入标准错误。
接入 Codex
在 ~/.codex/config.toml 或可信项目的 .codex/config.toml 中加入:
[mcp_servers.game_assets]
command = "node"
args = ["C:\\path\\to\\game-asset-finder-mcp\\dist\\index.js"]
cwd = "C:\\path\\to\\game-asset-finder-mcp"
startup_timeout_sec = 30
tool_timeout_sec = 90
enabled = true
[mcp_servers.game_assets.env]
GAME_ASSET_LOCAL_ROOTS = "D:\\GameAssets;E:\\SharedAssets"
GAME_ASSET_CACHE_TTL_SECONDS = "600"如果启用 Freesound,建议从本机环境转发密钥,而不是把值写进配置:
[mcp_servers.game_assets]
env_vars = ["FREESOUND_API_KEY"]也可以用 Codex CLI 添加 stdio server:
codex mcp add game-assets -- node "C:\path\to\game-asset-finder-mcp\dist\index.js"
codex mcp list保存配置后重启客户端,再用 /mcp 查看连接状态。仓库中的 mcp-config.example.toml 可直接复制修改。
MCP 工具
search_game_assets
跨源搜索。主要参数:
{
"query": "像素风地牢角色",
"types": ["sprite", "tileset"],
"sources": ["kenney", "opengameart", "itch"],
"formats": ["png"],
"tags": ["retro"],
"license_policy": "commercial",
"include_unknown_license": false,
"limit": 12,
"refresh": false
}license_policy 可取:
any:显示所有结果,并明确标记未知许可证。commercial:只保留已知可商用的许可证;可用include_unknown_license放回未知项。cc0:只保留 CC0 / Public Domain Mark。no-attribution:只保留已知可商用且无需署名的条目。
下一页把返回的 nextCursor 原样放进 cursor,其他查询参数保持不变。修改查询条件后继续使用旧游标会返回 CURSOR_QUERY_MISMATCH。
hasMore 表示当前缓存候选快照里还有下一页,不代表远端站点的全部历史结果都已抓取;需要更深结果时,优先缩小关键词、类型或来源范围并重新搜索。
get_game_asset
读取刚刚搜索到的完整记录:
{ "asset_id": "kenney:roguelike-characters" }返回来源、作者、许可证、预览、文件变体、镜像来源、匹配原因和可直接加入 credits 的署名文本。远程条目先搜索后读取;本地条目也可从索引直接读取。
list_asset_sources
列出所有 provider、启用状态、支持的素材类型、凭据要求、缓存配置和本地索引状态。
index_local_assets
扫描 GAME_ASSET_LOCAL_ROOTS:
{ "mode": "incremental", "max_files": 20000 }incremental 会复用大小与修改时间未变化的 SHA-256;rebuild 会全部重算。索引写到 GAME_ASSET_DATA_DIR/local-assets.json,不会修改素材文件。
本地素材 sidecar
在 hero.png 旁放置 hero.png.asset.json 或 hero.asset.json:
{
"title": "Azure Knight",
"description": "32x32 pixel hero with idle and run frames",
"type": "sprite",
"tags": ["player", "knight", "pixel-art"],
"author": "Studio Name",
"author_url": "https://example.com",
"license": "CC-BY-4.0",
"license_url": "https://creativecommons.org/licenses/by/4.0/",
"source_url": "https://example.com/azure-knight"
}没有 sidecar 的本地文件仍可搜索,但许可证显示为未知。
环境变量
变量 | 默认值 | 说明 |
| 空 | 本地素材根目录;Windows 用 |
| 项目下 | 本地索引目录 |
|
| 查询缓存秒数 |
|
| 查询缓存最大条数 |
|
| 单一 provider 时限 |
|
| 单次远程响应上限 |
|
| 429/临时错误的重试次数 |
|
| 本地索引默认文件上限 |
| 空 | 用逗号分隔的 provider id |
| 空 | 可选 Freesound API key |
开发与验证
npm run check
npm test
npm run test:unit
npm run test:mcp测试覆盖中文查询扩展、类型识别、许可证策略、URL 规范化、去重、缓存击穿合并、局部 provider 失败、分页与游标、本地增量索引,以及真实 stdio MCP 客户端的 tools/list / tools/call。
结果使用提示
MCP 返回的是素材发现与许可证元数据,不替代来源页的最终条款。未知许可证会明确保留为 id: null;发布前可用 commercial、cc0 或 no-attribution 缩小范围,并在 get_game_asset 中保存来源与署名信息。
Available Tools
4 toolsget_game_assetGet game asset detailsARead-onlyIdempotent
Read the full normalized record for an asset returned by search_game_assets, including files, license guidance, alternates, and attribution text.
| Name | Required | Description | Default |
|---|---|---|---|
| asset_id | Yes | assetId returned by search_game_assets. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the agent knows it's safe. The description adds value by revealing what fields the full record includes (files, license guidance, alternates, attribution text) beyond what the simple asset_id schema implies. This behavioral context about the richness of the return data is helpful and not redundant with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence front-loading the purpose and result content. Every word earns its place – 'full normalized record', 'including files, license guidance, alternates, and attribution text' adds concrete value without fluff. Could not be shorter without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 1 parameter, 100% schema coverage, no output schema, and clear annotations, the description is mostly complete. It doesn't explain what 'alternates' or 'attribution text' means in detail, but the agent can infer from context. It also doesn't mention pagination or error cases, but for a simple read-retrieval tool this is acceptable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already has 100% coverage with a well-described 'asset_id' parameter. The description adds context by stating the parameter is the assetId from search_game_assets, clarifying the origin domain and that it's not just any ID. The schema says it well, but the description reinforces the provenance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Read', specifies the resource 'full normalized record for an asset', and distinguishes this tool from siblings by noting it operates on results from search_game_assets. It lists what's included (files, license guidance, alternates, attribution text) and contrasts with search_game_assets which returns abbreviated results.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states 'returned by search_game_assets', telling the agent to call this tool after using its sibling. It implies this is for retrieving full details of a specific asset rather than listing or searching, but doesn't explicitly say when not to use it or what use case would require a different tool. Some guidance is provided by the sibling list context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
index_local_assetsIndex local game assetsAIdempotent
Incrementally scan GAME_ASSET_LOCAL_ROOTS, hash changed files, read optional .asset.json metadata, and atomically refresh the local search index. Symbolic links are skipped.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | incremental | |
| max_files | No | Optional cap for this scan. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint=false, destructiveHint=false, idempotentHint=true. The description adds concrete behavioral details: files are hashed, optional .asset.json metadata is read, symlinks are skipped, and index refresh is atomic. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the primary action. Every word adds value—no redundancy, no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the core process but omits several details: no mention of return value (no output schema), no prerequisites (e.g., configured roots), no explanation of the 'rebuild' mode, and no indication of performance or idempotency. Adequate but incomplete for a tool with no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 50% (only max_files has a description). The tool description does not add any meaning to the parameters—it doesn't explain the mode enum or clarify max_files beyond what the schema already provides. This leaves the agent without guidance on choosing mode or setting the cap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: incrementally scan local asset roots, hash changed files, read metadata, and atomically refresh the search index. It uses specific verbs and resources, and is distinct from sibling tools like get_game_asset or search_game_assets.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is used for updating the local search index but does not explicitly state when to use it versus alternatives (e.g., rebuild vs. incremental, or when to use search_game_assets). No exclusions or prerequisites are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_asset_sourcesList game asset sourcesARead-onlyIdempotent
List provider ids, supported asset kinds, enablement state, local index state, and active limits.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the tool as read-only, idempotent, and non-destructive. The description adds value by specifying the returned fields (e.g., enablement state, local index state), which helps the agent anticipate output. It does not cover potential edge cases like pagination or consistency guarantees, but for a zero-parameter listing, these are minor gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that front-loads the action ('List') and enumerates the key output fields. Every word is informative; there is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity (zero params, no output schema, strong annotations), the description covers the purpose and return values well. It could explicitly state that it returns all available sources, but the lack of filtering parameters strongly implies this. Overall, it is nearly complete for the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has no parameters (100% schema coverage). The description does not need to add param info. By the rubric, baseline 3 is appropriate. No additional meaning is provided beyond the schema, but none is required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the verb 'List' and specifies the exact fields returned (provider ids, supported asset kinds, enablement state, etc.), clearly differentiating from siblings like get_game_asset (single item retrieval) and search_game_assets (filtered search).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for retrieving asset source metadata, but does not explicitly state when to choose this over siblings, nor does it mention prerequisites or exclusions. The context signals and sibling names provide implicit guidance, but direct usage context is absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_game_assetsSearch game assetsARead-onlyIdempotent
Search enabled remote and local game-asset sources concurrently. Results are normalized, license-filtered, relevance-ranked, de-duplicated, source-diversified, cached, and cursor-paginated.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Optional style or content tags. | |
| limit | No | Results per page. | |
| query | Yes | What to find. Chinese and English game-development terms are accepted. | |
| types | No | Optional normalized asset kinds. | |
| cursor | No | Opaque nextCursor returned by the previous page. Keep all other query arguments unchanged. | |
| formats | No | Optional file extensions such as png, glb, wav, or zip. | |
| refresh | No | Bypass the query cache for the first page. | |
| sources | No | Provider ids from list_asset_sources. Empty means every enabled source. | |
| license_policy | No | any, commercially usable, CC0/public domain, or no-attribution only. | any |
| include_unknown_license | No | When a restrictive license policy is selected, retain results whose license is unknown. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare safe and idempotent behavior (readOnlyHint, openWorldHint, idempotentHint, destructiveHint=false). The description adds significant behavioral details beyond these annotations: concurrent search, normalization, license filtering, relevance ranking, de-duplication, source diversification, caching, and cursor pagination. There is no contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that front-loads the main action ('Search enabled remote and local game-asset sources concurrently') and follows with a list of processing steps. Every word earns its place. However, the sentence is somewhat dense; breaking it into two sentences could improve readability without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (10 parameters, no output schema), the description explains the processing pipeline well but does not describe the structure of the returned results. Since there is no output schema, the agent would benefit from knowing what fields each asset result contains (e.g., id, name, source, url, license). The mention of cursor pagination helps, but details on the response envelope are missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage (all 10 parameters have descriptions). The tool description itself does not add any extra parameter-level meaning beyond what the schema already provides. Therefore, the baseline score of 3 is appropriate as the description adds no additional semantic value for parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it searches remote and local game-asset sources concurrently, which directly contrasts with sibling tools: get_game_asset (single asset retrieval), list_asset_sources (listing providers), and index_local_assets (local indexing). The verb 'Search' and resource 'game-asset sources' are specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance is provided on when to use this tool versus alternatives. There are no when-to-use, when-not-to-use, or prerequisite instructions. For example, it doesn't mention that the user should first use list_asset_sources to obtain provider IDs for the sources parameter, or that index_local_assets must be run beforehand to make local assets searchable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v1.0.0- First observed
get_game_asset - First observed
index_local_assets - First observed
list_asset_sources - First observed
search_game_assets
TDQS
Scored across 4 tools
Each tool has a distinct purpose: search, get details, list sources, and index. There is no overlap in functionality, making it easy for an agent to select the right tool.
All tool names follow a consistent verb_noun pattern in snake_case (get_game_asset, list_asset_sources, search_game_assets, index_local_assets). This predictable structure aids agent understanding.
Four tools cover the essential operations for a game asset finder: search, get detail, list sources, and index local assets. The count is well-scoped for the server's stated purpose.
The tools provide a complete workflow: index local assets, search across sources, retrieve detailed records, and list source info. No obvious gaps exist for the domain of finding and retrieving game assets.
Maintenance
Related MCP Connectors
An MCP server that provides asset auto generator
Capability registry for the agentic economy. Semantic search over verified MCP server listings.
Publish and discover MCP servers via the official MCP Registry. Powered by HAPI MCP server.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceA local MCP server for Nexus Mods mod discovery and research, backed by the v2 GraphQL API, enabling search of games, mods, collections, and users.138 npm1ISC
- AlicenseNot gradedqualityDmaintenanceMCP server for local-first lexical code search, providing tools for searching code, finding symbols, and reading chunks from indexed repositories.MIT
- AlicenseNot gradedqualityCmaintenanceAn MCP server that aggregates web search results from multiple engines and optionally renders pages to Markdown, providing a unified search interface.17 npm3ISC
- AlicenseNot gradedqualityDmaintenanceA Python MCP server for searching, downloading, extracting, inspecting, and previewing game assets from multiple public sources.3MIT