Repository navigation
feat(mcp): expose ASO analyzers as an MCP server - #16
Conversation
New optional MCP server lets non-Claude-Code clients (Claude Desktop,
Cursor, Continue, custom agents) call into the skill's analyzers
over MCP / stdio.
Seven tools, all thin wrappers around existing aso_skill convenience
functions:
- aso_score
- aso_optimize
- aso_validate
- aso_analyze_keywords
- aso_plan_ab_test
- aso_itunes_search (uses the existing 24h iTunes cache)
- aso_itunes_app
Built on FastMCP (the high-level decorator API in the MCP Python SDK),
so JSON schemas and tool descriptions are auto-generated from Python
type hints + docstrings -- no hand-rolled schemas to drift.
Install path:
pip install 'aso-skill[mcp]'
New console script `aso-mcp` runs the server over stdio. Claude
Desktop config example and per-client setup notes live at
documentation/mcp/INSTALL.md.
Tests: 12 new tests exercise each tool handler directly plus a smoke
check that all seven tools register on the FastMCP server. Uses
`pytest.importorskip` so the suite still passes on stdlib-only
installs without the optional `mcp` dependency.
Core install stays zero-dependency -- mcp is pulled in only via the
new [mcp] extra.
Full suite: 84 passed in 3.08s.
https://claude.ai/code/session_01CbA3Mp4rD4vW9Yjd2aPEXw
Code Review — PR #16: MCP server for ASO analyzersOverall: Clean, well-scoped addition. The optional-dependency gate, Blockers1. # mcp_server.py:149, 160
api = iTunesAPI(country=country)
return api.search_apps(term, limit=limit)If 2. No input validation on def aso_optimize(platform: str, ...) -> Dict[str, Any]:
def aso_validate(platform: str, ...) -> Dict[str, Any]:If a caller passes if platform not in {"apple", "google"}:
return {"error": f"platform must be 'apple' or 'google', got {platform!r}"}Same applies to the ASO-specific3. The CLAUDE.md constraint is unusual — the 100-char keyword field must be comma-separated with no spaces. Confirm Code quality4. The file already has # before
def aso_score(metadata: Dict[str, Any], ...) -> Dict[str, Any]:
# after
def aso_score(metadata: dict[str, Any], ...) -> dict[str, Any]:Tests5. assert "test_design" in result or "sample_size_requirements" in resultAn 6. Move 7. Missing boundary test for Apple title exactly at 30 chars
Documentation8. CHANGELOG section header doesn't follow Keep a Changelog ### MCP server ← non-standardKeep a Changelog uses ### Added
- `aso_skill.mcp_server` — MCP server exposing seven tools …9. Troubleshooting references clear it via `aso itunes --clear-cache`Verify this subcommand exists in the CLI. If not, either add it or remove the reference. Summary
Happy to look again after the caching and validation items are addressed. |
|
Branch |
Summary
Expose the ASO analyzers as an MCP server so non-Claude-Code clients (Claude Desktop, Cursor, Continue, custom agents) can use the skill without depending on the Claude Code CLI. This finishes Theme C — the "reach beyond Claude Code" theme is now complete (plugin marketplace #14 + ASO Watcher #15 + MCP server #16).
What changed
aso_skill/mcp_server.py— FastMCP-based server (high-level decorator API in the MCP Python SDK). Seven tools, all thin wrappers around existingaso_skillconvenience functions:aso_scorecalculate_aso_scoreaso_optimizeoptimize_app_metadataaso_validateMetadataOptimizer.validate_character_limitsaso_analyze_keywordsanalyze_keyword_setaso_plan_ab_testplan_ab_testaso_itunes_searchiTunesAPI.search_apps(cached)aso_itunes_appiTunesAPI.get_app_by_id(cached)JSON schemas + tool descriptions are auto-generated from Python type hints and docstrings — no hand-rolled schemas to drift out of sync.
pyproject.toml— new[project.optional-dependencies] mcp = ["mcp>=1.0"]and new console scriptaso-mcp = "aso_skill.mcp_server:main". Core install stays zero-dependency.documentation/mcp/INSTALL.md— install + per-client setup. Concrete Claude Desktopclaude_desktop_config.jsonsnippet, troubleshooting section, table of all seven tools.tests/test_mcp_server.py— 12 tests. Each tool handler called directly (no event loop, no Client, no subprocess); one smoke test confirms all seven tools register on the FastMCP server. Usespytest.importorskip("mcp")so the suite still passes for users on stdlib-only installs.CHANGELOG.md—[1.1.4] - Unreleasedentry.How to install
pip install 'aso-skill[mcp]'Then add to Claude Desktop's
claude_desktop_config.json:{ "mcpServers": { "aso-skill": { "command": "aso-mcp" } } }Restart Claude Desktop — the seven tools appear in the picker.
Test plan
python3 -m pytest tests/ -q→ 84 passed in 3.08s (72 prior + 12 new MCP tests)ruff check aso_skill scripts tests→ All checks passedruff format --check aso_skill scripts tests→ 32 files already formattedpip install -e ".[mcp]"installs cleanlywhich aso-mcp→ console script on PATH after installaso-mcpboots and waits on stdio (server starts without error)test_all_tools_registered_on_server)Risks
mcp>=1.0(current stable line). If a breaking change lands, the optional-dep gate means only[mcp]installs break, not core.mcpitself may require Python ≥ 3.10. On Python 3.9,pip install '.[mcp]'will refuse to resolve. Coreaso-skillinstall on 3.9 still works (this PR doesn't changerequires-python).dict[str, Any]annotations on tools likeaso_scoreproduce loose JSON schemas. Acceptable trade-off for not maintaining Pydantic mirrors of the existing dict shapes; LLM callers get the structure from the rich docstring.https://claude.ai/code/session_01CbA3Mp4rD4vW9Yjd2aPEXw
Generated by Claude Code