alloc-context 0.2.1__tar.gz → 0.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. {alloc_context-0.2.1 → alloc_context-0.2.3}/PKG-INFO +18 -17
  2. {alloc_context-0.2.1 → alloc_context-0.2.3}/README.md +10 -9
  3. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloc_context.egg-info/PKG-INFO +18 -17
  4. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloc_context.egg-info/SOURCES.txt +3 -0
  5. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/__init__.py +1 -1
  6. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/bazaar.py +95 -177
  7. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/server.py +25 -1
  8. alloc_context-0.2.3/alloccontext/mcp/tool_catalog.py +311 -0
  9. {alloc_context-0.2.1 → alloc_context-0.2.3}/pyproject.toml +12 -12
  10. alloc_context-0.2.3/tests/test_check_pypi_release_json.py +55 -0
  11. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_glama_well_known.py +1 -1
  12. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_mcp_bazaar.py +6 -0
  13. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_server_json.py +1 -1
  14. alloc_context-0.2.3/tests/test_tool_catalog.py +65 -0
  15. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_workflows.py +16 -2
  16. {alloc_context-0.2.1 → alloc_context-0.2.3}/LICENSE +0 -0
  17. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloc_context.egg-info/dependency_links.txt +0 -0
  18. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloc_context.egg-info/entry_points.txt +0 -0
  19. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloc_context.egg-info/requires.txt +0 -0
  20. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloc_context.egg-info/top_level.txt +0 -0
  21. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/__main__.py +0 -0
  22. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/config.py +0 -0
  23. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/constants.py +0 -0
  24. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/horizon.py +0 -0
  25. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/__init__.py +0 -0
  26. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/alt_quote_registry.py +0 -0
  27. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/alt_quote_store.py +0 -0
  28. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/alt_quotes.py +0 -0
  29. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/asset_registry.py +0 -0
  30. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/cf_benchmarks.py +0 -0
  31. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/cf_history.py +0 -0
  32. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/coinbase_client.py +0 -0
  33. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/coinbase_portfolio.py +0 -0
  34. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/coingecko.py +0 -0
  35. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/coinmarketcap.py +0 -0
  36. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/env_keys.py +0 -0
  37. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/etf_flows.py +0 -0
  38. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/exchange/__init__.py +0 -0
  39. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/exchange/coinbase_adapter.py +0 -0
  40. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/exchange/kraken_adapter.py +0 -0
  41. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/exchange/live.py +0 -0
  42. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/exchange/portfolio.py +0 -0
  43. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/exchange/registry.py +0 -0
  44. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/exchange/types.py +0 -0
  45. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/exchange_http.py +0 -0
  46. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/fear_greed.py +0 -0
  47. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/fred.py +0 -0
  48. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/http_errors.py +0 -0
  49. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/kalshi.py +0 -0
  50. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/kalshi_api.py +0 -0
  51. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/kalshi_client.py +0 -0
  52. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/kalshi_files.py +0 -0
  53. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/kalshi_state.py +0 -0
  54. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/kraken_client.py +0 -0
  55. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/kraken_portfolio.py +0 -0
  56. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/macro_calendar.py +0 -0
  57. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/macro_normalize.py +0 -0
  58. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/market_snapshots.py +0 -0
  59. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/outcome.py +0 -0
  60. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/parse_helpers.py +0 -0
  61. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/portfolio_holdings.py +0 -0
  62. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/quote_resolver.py +0 -0
  63. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/ingest/runner.py +0 -0
  64. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/__init__.py +0 -0
  65. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/assets.py +0 -0
  66. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/bridge.py +0 -0
  67. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/bridge_portfolio.py +0 -0
  68. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/contracts.py +0 -0
  69. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/glama.py +0 -0
  70. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/handlers.py +0 -0
  71. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/http.py +0 -0
  72. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/instructions.py +0 -0
  73. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/payer.py +0 -0
  74. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/payment_middleware.py +0 -0
  75. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/setup.py +0 -0
  76. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/staleness.py +0 -0
  77. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/tool_fields.py +0 -0
  78. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/upstream.py +0 -0
  79. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/validation.py +0 -0
  80. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/x402_bazaar_dynamic.py +0 -0
  81. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/x402_config.py +0 -0
  82. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/x402_pricing.py +0 -0
  83. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/mcp/x402_stables.py +0 -0
  84. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/__init__.py +0 -0
  85. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/allocation_analysis.py +0 -0
  86. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/band.py +0 -0
  87. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/breadth.py +0 -0
  88. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/cf_math.py +0 -0
  89. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/cluster.py +0 -0
  90. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/cluster_config.py +0 -0
  91. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/comparison.py +0 -0
  92. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/context.py +0 -0
  93. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/delta.py +0 -0
  94. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/etf.py +0 -0
  95. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/fear_greed.py +0 -0
  96. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/macro.py +0 -0
  97. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/portfolio.py +0 -0
  98. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/portfolio_payload.py +0 -0
  99. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/rebalance.py +0 -0
  100. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/regime.py +0 -0
  101. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/sentiment.py +0 -0
  102. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/snapshots.py +0 -0
  103. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/rollup/tape.py +0 -0
  104. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/status_report.py +0 -0
  105. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/store/__init__.py +0 -0
  106. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/store/db.py +0 -0
  107. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/store/jsonutil.py +0 -0
  108. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/store/meta.py +0 -0
  109. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/store/retention.py +0 -0
  110. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/store/status.py +0 -0
  111. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/timeutil.py +0 -0
  112. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/user_config.py +0 -0
  113. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/x402_production_check.py +0 -0
  114. {alloc_context-0.2.1 → alloc_context-0.2.3}/alloccontext/x402_smoke_redact.py +0 -0
  115. {alloc_context-0.2.1 → alloc_context-0.2.3}/setup.cfg +0 -0
  116. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_backup_sqlite.py +0 -0
  117. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_bridge.py +0 -0
  118. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_bridge_portfolio.py +0 -0
  119. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_bump_version.py +0 -0
  120. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_coinbase_portfolio.py +0 -0
  121. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_config_cli.py +0 -0
  122. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_context_bundle_schema.py +0 -0
  123. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_context_snapshots.py +0 -0
  124. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_db_schema.py +0 -0
  125. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_deploy.py +0 -0
  126. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_dev_stack.py +0 -0
  127. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_etf.py +0 -0
  128. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_exchanges_config.py +0 -0
  129. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_fear_greed.py +0 -0
  130. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_fred.py +0 -0
  131. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_holdings_scoped_delta_regime.py +0 -0
  132. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_holdings_scoped_market.py +0 -0
  133. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_horizon.py +0 -0
  134. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_ingest_outcome.py +0 -0
  135. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_ingest_runner.py +0 -0
  136. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_ingest_store_integration.py +0 -0
  137. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_kalshi_api.py +0 -0
  138. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_kraken_portfolio.py +0 -0
  139. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_live_ingest_handlers.py +0 -0
  140. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_macro.py +0 -0
  141. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_market_breadth.py +0 -0
  142. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_mcp_assets_regime.py +0 -0
  143. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_mcp_contracts.py +0 -0
  144. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_mcp_data_staleness.py +0 -0
  145. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_mcp_handlers.py +0 -0
  146. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_mcp_health.py +0 -0
  147. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_mcp_http_lifecycle.py +0 -0
  148. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_mcp_live_portfolio.py +0 -0
  149. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_mcp_server.py +0 -0
  150. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_mcp_validation.py +0 -0
  151. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_mcp_x402.py +0 -0
  152. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_mcp_x402_http.py +0 -0
  153. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_mcp_x402_pricing.py +0 -0
  154. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_mcp_x402_stables.py +0 -0
  155. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_payer.py +0 -0
  156. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_portfolio_holdings.py +0 -0
  157. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_quote_resolver.py +0 -0
  158. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_rebalance.py +0 -0
  159. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_rollup.py +0 -0
  160. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_script_runtime.py +0 -0
  161. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_security_hardening.py +0 -0
  162. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_setup.py +0 -0
  163. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_snapshots_and_delta.py +0 -0
  164. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_status_report.py +0 -0
  165. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_user_config.py +0 -0
  166. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_x402_bazaar_dynamic.py +0 -0
  167. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_x402_production_check.py +0 -0
  168. {alloc_context-0.2.1 → alloc_context-0.2.3}/tests/test_x402_smoke_redact.py +0 -0
@@ -1,15 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alloc-context
3
- Version: 0.2.1
4
- Summary: Portfolio-aware crypto context for agents — holdings, market, optional allocation analysis
3
+ Version: 0.2.3
4
+ Summary: Portfolio-aware crypto context for agents — holdings-scoped market, sentiment, optional allocation analysis
5
5
  License: Elastic-2.0
6
- Project-URL: Homepage, https://github.com/negillett/alloc-context
7
- Project-URL: Documentation, https://github.com/negillett/alloc-context/blob/main/docs/agent-integration.md
8
- Project-URL: Repository, https://github.com/negillett/alloc-context
9
- Project-URL: Issues, https://github.com/negillett/alloc-context/issues
10
- Project-URL: Changelog, https://github.com/negillett/alloc-context/releases
6
+ Project-URL: Homepage, https://mcp.alloc-context.com/llms.txt
7
+ Project-URL: Documentation, https://github.com/AllocContext/alloc-context/blob/main/docs/agent-integration.md
8
+ Project-URL: Repository, https://github.com/AllocContext/alloc-context
9
+ Project-URL: Issues, https://github.com/AllocContext/alloc-context/issues
10
+ Project-URL: Changelog, https://github.com/AllocContext/alloc-context/releases
11
11
  Project-URL: MCP Server, https://mcp.alloc-context.com/mcp
12
- Keywords: mcp,x402,bitcoin,ethereum,crypto,cryptocurrency,portfolio,allocation,holdings,rebalance,coinbase,kraken,agents
12
+ Keywords: mcp,x402,holdings,portfolio,crypto,cryptocurrency,bitcoin,ethereum,agents,allocation,rebalance,coinbase,kraken
13
13
  Classifier: Development Status :: 4 - Beta
14
14
  Classifier: Intended Audience :: Developers
15
15
  Classifier: Programming Language :: Python :: 3
@@ -44,14 +44,15 @@ Dynamic: license-file
44
44
 
45
45
  # AllocContext
46
46
 
47
- [![smithery badge](https://smithery.ai/badge/@negillett/alloc-context)](https://smithery.ai/server/@negillett/alloc-context)
48
- [![Glama MCP server](https://glama.ai/mcp/servers/negillett/alloc-context/badges/score.svg)](https://glama.ai/mcp/servers/negillett/alloc-context)
47
+ [![smithery badge](https://smithery.ai/badge/@AllocContext/alloc-context)](https://smithery.ai/server/@AllocContext/alloc-context)
48
+ [![Glama MCP server](https://glama.ai/mcp/servers/AllocContext/alloc-context/badges/score.svg)](https://glama.ai/mcp/servers/AllocContext/alloc-context)
49
49
 
50
- mcp-name: io.github.negillett/alloc-context
50
+ mcp-name: io.github.AllocContext/alloc-context
51
51
 
52
- **Portfolio-aware crypto context for agents** — discover holdings, market,
53
- sentiment, macro, and regime; optional allocation analysis. Deterministic
54
- JSON over MCP with x402 pay-per-call on Base.
52
+ **Portfolio-aware crypto context for whatever you hold** — discover your
53
+ holdings, holdings-scoped market data, sentiment, macro, and regime; optional
54
+ allocation analysis when you supply targets. Deterministic JSON over MCP with
55
+ x402 pay-per-call on Base.
55
56
 
56
57
  > **Privacy:** nothing stored · one-time read-only · pass-through only — your
57
58
  > keys and portfolio never persist on our servers. See [USE.md](docs/USE.md).
@@ -113,7 +114,7 @@ Not financial advice.
113
114
  | **Discovery** | [llms.txt](https://mcp.alloc-context.com/llms.txt), [x402 manifest](https://mcp.alloc-context.com/.well-known/x402.json) |
114
115
  | **Pricing** | **$0.02** cached context/math · **$0.05** live ingest or portfolio |
115
116
  | **Payment** | x402 on Base — USDC or EURC |
116
- | **Market scope** | Holdings-scoped (BTC/ETH OHLC; alt quote snapshots); bridge auto-scopes from portfolio |
117
+ | **Market scope** | Tailored to your holdings (band OHLC for BTC/ETH; alt quote snapshots); bridge auto-scopes from portfolio |
117
118
 
118
119
  Agents and wallets connect directly to the hosted endpoint — see
119
120
  [agent-integration.md](docs/agent-integration.md). The Cursor bridge above
@@ -130,7 +131,7 @@ combines local portfolio reads with this upstream for market context.
130
131
  | `get_rebalance_plan` | USD rebalance moves from allocation, target, and NAV |
131
132
  | `check_allocation_band` | Drift vs target and whether allocation is outside the band |
132
133
  | `check_allocation_bands` | Batch band checks for multiple target scenarios |
133
- | `get_portfolio_state` | Live NAV and holdings from Kraken or Coinbase |
134
+ | `get_portfolio_state` | Live NAV and holdings (e.g. Coinbase, Kraken read-only keys) |
134
135
 
135
136
  Market context is **holdings-scoped**: band assets (BTC/ETH) use OHLC bars; alt
136
137
  holdings (e.g. HYPE) use quote snapshots when cached. The bridge auto-scopes
@@ -146,7 +147,7 @@ See [self-hosting.md](docs/self-hosting.md) (`self_host: true` in user config)
146
147
  or [local-dev.md](docs/local-dev.md) for the dev stack.
147
148
 
148
149
  ```bash
149
- git clone git@github.com:negillett/alloc-context.git
150
+ git clone git@github.com:AllocContext/alloc-context.git
150
151
  cd alloc-context
151
152
  python3.11 -m venv .venv && source .venv/bin/activate
152
153
  pip install -e ".[dev]"
@@ -1,13 +1,14 @@
1
1
  # AllocContext
2
2
 
3
- [![smithery badge](https://smithery.ai/badge/@negillett/alloc-context)](https://smithery.ai/server/@negillett/alloc-context)
4
- [![Glama MCP server](https://glama.ai/mcp/servers/negillett/alloc-context/badges/score.svg)](https://glama.ai/mcp/servers/negillett/alloc-context)
3
+ [![smithery badge](https://smithery.ai/badge/@AllocContext/alloc-context)](https://smithery.ai/server/@AllocContext/alloc-context)
4
+ [![Glama MCP server](https://glama.ai/mcp/servers/AllocContext/alloc-context/badges/score.svg)](https://glama.ai/mcp/servers/AllocContext/alloc-context)
5
5
 
6
- mcp-name: io.github.negillett/alloc-context
6
+ mcp-name: io.github.AllocContext/alloc-context
7
7
 
8
- **Portfolio-aware crypto context for agents** — discover holdings, market,
9
- sentiment, macro, and regime; optional allocation analysis. Deterministic
10
- JSON over MCP with x402 pay-per-call on Base.
8
+ **Portfolio-aware crypto context for whatever you hold** — discover your
9
+ holdings, holdings-scoped market data, sentiment, macro, and regime; optional
10
+ allocation analysis when you supply targets. Deterministic JSON over MCP with
11
+ x402 pay-per-call on Base.
11
12
 
12
13
  > **Privacy:** nothing stored · one-time read-only · pass-through only — your
13
14
  > keys and portfolio never persist on our servers. See [USE.md](docs/USE.md).
@@ -69,7 +70,7 @@ Not financial advice.
69
70
  | **Discovery** | [llms.txt](https://mcp.alloc-context.com/llms.txt), [x402 manifest](https://mcp.alloc-context.com/.well-known/x402.json) |
70
71
  | **Pricing** | **$0.02** cached context/math · **$0.05** live ingest or portfolio |
71
72
  | **Payment** | x402 on Base — USDC or EURC |
72
- | **Market scope** | Holdings-scoped (BTC/ETH OHLC; alt quote snapshots); bridge auto-scopes from portfolio |
73
+ | **Market scope** | Tailored to your holdings (band OHLC for BTC/ETH; alt quote snapshots); bridge auto-scopes from portfolio |
73
74
 
74
75
  Agents and wallets connect directly to the hosted endpoint — see
75
76
  [agent-integration.md](docs/agent-integration.md). The Cursor bridge above
@@ -86,7 +87,7 @@ combines local portfolio reads with this upstream for market context.
86
87
  | `get_rebalance_plan` | USD rebalance moves from allocation, target, and NAV |
87
88
  | `check_allocation_band` | Drift vs target and whether allocation is outside the band |
88
89
  | `check_allocation_bands` | Batch band checks for multiple target scenarios |
89
- | `get_portfolio_state` | Live NAV and holdings from Kraken or Coinbase |
90
+ | `get_portfolio_state` | Live NAV and holdings (e.g. Coinbase, Kraken read-only keys) |
90
91
 
91
92
  Market context is **holdings-scoped**: band assets (BTC/ETH) use OHLC bars; alt
92
93
  holdings (e.g. HYPE) use quote snapshots when cached. The bridge auto-scopes
@@ -102,7 +103,7 @@ See [self-hosting.md](docs/self-hosting.md) (`self_host: true` in user config)
102
103
  or [local-dev.md](docs/local-dev.md) for the dev stack.
103
104
 
104
105
  ```bash
105
- git clone git@github.com:negillett/alloc-context.git
106
+ git clone git@github.com:AllocContext/alloc-context.git
106
107
  cd alloc-context
107
108
  python3.11 -m venv .venv && source .venv/bin/activate
108
109
  pip install -e ".[dev]"
@@ -1,15 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alloc-context
3
- Version: 0.2.1
4
- Summary: Portfolio-aware crypto context for agents — holdings, market, optional allocation analysis
3
+ Version: 0.2.3
4
+ Summary: Portfolio-aware crypto context for agents — holdings-scoped market, sentiment, optional allocation analysis
5
5
  License: Elastic-2.0
6
- Project-URL: Homepage, https://github.com/negillett/alloc-context
7
- Project-URL: Documentation, https://github.com/negillett/alloc-context/blob/main/docs/agent-integration.md
8
- Project-URL: Repository, https://github.com/negillett/alloc-context
9
- Project-URL: Issues, https://github.com/negillett/alloc-context/issues
10
- Project-URL: Changelog, https://github.com/negillett/alloc-context/releases
6
+ Project-URL: Homepage, https://mcp.alloc-context.com/llms.txt
7
+ Project-URL: Documentation, https://github.com/AllocContext/alloc-context/blob/main/docs/agent-integration.md
8
+ Project-URL: Repository, https://github.com/AllocContext/alloc-context
9
+ Project-URL: Issues, https://github.com/AllocContext/alloc-context/issues
10
+ Project-URL: Changelog, https://github.com/AllocContext/alloc-context/releases
11
11
  Project-URL: MCP Server, https://mcp.alloc-context.com/mcp
12
- Keywords: mcp,x402,bitcoin,ethereum,crypto,cryptocurrency,portfolio,allocation,holdings,rebalance,coinbase,kraken,agents
12
+ Keywords: mcp,x402,holdings,portfolio,crypto,cryptocurrency,bitcoin,ethereum,agents,allocation,rebalance,coinbase,kraken
13
13
  Classifier: Development Status :: 4 - Beta
14
14
  Classifier: Intended Audience :: Developers
15
15
  Classifier: Programming Language :: Python :: 3
@@ -44,14 +44,15 @@ Dynamic: license-file
44
44
 
45
45
  # AllocContext
46
46
 
47
- [![smithery badge](https://smithery.ai/badge/@negillett/alloc-context)](https://smithery.ai/server/@negillett/alloc-context)
48
- [![Glama MCP server](https://glama.ai/mcp/servers/negillett/alloc-context/badges/score.svg)](https://glama.ai/mcp/servers/negillett/alloc-context)
47
+ [![smithery badge](https://smithery.ai/badge/@AllocContext/alloc-context)](https://smithery.ai/server/@AllocContext/alloc-context)
48
+ [![Glama MCP server](https://glama.ai/mcp/servers/AllocContext/alloc-context/badges/score.svg)](https://glama.ai/mcp/servers/AllocContext/alloc-context)
49
49
 
50
- mcp-name: io.github.negillett/alloc-context
50
+ mcp-name: io.github.AllocContext/alloc-context
51
51
 
52
- **Portfolio-aware crypto context for agents** — discover holdings, market,
53
- sentiment, macro, and regime; optional allocation analysis. Deterministic
54
- JSON over MCP with x402 pay-per-call on Base.
52
+ **Portfolio-aware crypto context for whatever you hold** — discover your
53
+ holdings, holdings-scoped market data, sentiment, macro, and regime; optional
54
+ allocation analysis when you supply targets. Deterministic JSON over MCP with
55
+ x402 pay-per-call on Base.
55
56
 
56
57
  > **Privacy:** nothing stored · one-time read-only · pass-through only — your
57
58
  > keys and portfolio never persist on our servers. See [USE.md](docs/USE.md).
@@ -113,7 +114,7 @@ Not financial advice.
113
114
  | **Discovery** | [llms.txt](https://mcp.alloc-context.com/llms.txt), [x402 manifest](https://mcp.alloc-context.com/.well-known/x402.json) |
114
115
  | **Pricing** | **$0.02** cached context/math · **$0.05** live ingest or portfolio |
115
116
  | **Payment** | x402 on Base — USDC or EURC |
116
- | **Market scope** | Holdings-scoped (BTC/ETH OHLC; alt quote snapshots); bridge auto-scopes from portfolio |
117
+ | **Market scope** | Tailored to your holdings (band OHLC for BTC/ETH; alt quote snapshots); bridge auto-scopes from portfolio |
117
118
 
118
119
  Agents and wallets connect directly to the hosted endpoint — see
119
120
  [agent-integration.md](docs/agent-integration.md). The Cursor bridge above
@@ -130,7 +131,7 @@ combines local portfolio reads with this upstream for market context.
130
131
  | `get_rebalance_plan` | USD rebalance moves from allocation, target, and NAV |
131
132
  | `check_allocation_band` | Drift vs target and whether allocation is outside the band |
132
133
  | `check_allocation_bands` | Batch band checks for multiple target scenarios |
133
- | `get_portfolio_state` | Live NAV and holdings from Kraken or Coinbase |
134
+ | `get_portfolio_state` | Live NAV and holdings (e.g. Coinbase, Kraken read-only keys) |
134
135
 
135
136
  Market context is **holdings-scoped**: band assets (BTC/ETH) use OHLC bars; alt
136
137
  holdings (e.g. HYPE) use quote snapshots when cached. The bridge auto-scopes
@@ -146,7 +147,7 @@ See [self-hosting.md](docs/self-hosting.md) (`self_host: true` in user config)
146
147
  or [local-dev.md](docs/local-dev.md) for the dev stack.
147
148
 
148
149
  ```bash
149
- git clone git@github.com:negillett/alloc-context.git
150
+ git clone git@github.com:AllocContext/alloc-context.git
150
151
  cd alloc-context
151
152
  python3.11 -m venv .venv && source .venv/bin/activate
152
153
  pip install -e ".[dev]"
@@ -71,6 +71,7 @@ alloccontext/mcp/payment_middleware.py
71
71
  alloccontext/mcp/server.py
72
72
  alloccontext/mcp/setup.py
73
73
  alloccontext/mcp/staleness.py
74
+ alloccontext/mcp/tool_catalog.py
74
75
  alloccontext/mcp/tool_fields.py
75
76
  alloccontext/mcp/upstream.py
76
77
  alloccontext/mcp/validation.py
@@ -108,6 +109,7 @@ tests/test_backup_sqlite.py
108
109
  tests/test_bridge.py
109
110
  tests/test_bridge_portfolio.py
110
111
  tests/test_bump_version.py
112
+ tests/test_check_pypi_release_json.py
111
113
  tests/test_coinbase_portfolio.py
112
114
  tests/test_config_cli.py
113
115
  tests/test_context_bundle_schema.py
@@ -156,6 +158,7 @@ tests/test_server_json.py
156
158
  tests/test_setup.py
157
159
  tests/test_snapshots_and_delta.py
158
160
  tests/test_status_report.py
161
+ tests/test_tool_catalog.py
159
162
  tests/test_user_config.py
160
163
  tests/test_workflows.py
161
164
  tests/test_x402_bazaar_dynamic.py
@@ -1,3 +1,3 @@
1
1
  """AllocContext — portfolio-aware crypto context for agents (MCP)."""
2
2
 
3
- __version__ = "0.2.1"
3
+ __version__ = "0.2.3"
@@ -10,6 +10,24 @@ from x402.extensions.bazaar import (
10
10
  declare_mcp_discovery_extension,
11
11
  )
12
12
 
13
+ from alloccontext.mcp.tool_catalog import (
14
+ ASSET_FILTER_SCHEMA,
15
+ AS_OF_SCHEMA,
16
+ BAND_SCHEMA,
17
+ CURRENT_AS_OF_SCHEMA,
18
+ FRESHNESS_SCHEMA,
19
+ MATCH_SCHEMA,
20
+ MCP_SERVER_PROMPTS,
21
+ MCP_SERVER_RESOURCES,
22
+ OPTIONAL_TARGET_PCT_SCHEMA,
23
+ PRIOR_AS_OF_SCHEMA,
24
+ SCENARIOS_SCHEMA,
25
+ SCOPE_SCHEMA,
26
+ TARGET_PCT_SCHEMA,
27
+ allocation_pct_schema,
28
+ server_card_tool_entry,
29
+ )
30
+
13
31
  SERVICE_NAME = "AllocContext"
14
32
  OFFICIAL_HOSTED_MCP_URL = "https://mcp.alloc-context.com/mcp"
15
33
  USE_DOCS_PATH = "docs/USE.md"
@@ -89,63 +107,32 @@ DISCOVERY_KEYWORD_MARKERS = (
89
107
  )
90
108
 
91
109
  LISTING_DESCRIPTION = (
92
- "Portfolio-aware crypto context for AI agents: discover holdings, market, "
93
- "sentiment, macro, and regime; optional allocation analysis and rebalance "
94
- "math. Fused backdrop (Fear & Greed, Kalshi, ETF flows), optional live "
95
- "Kraken/Coinbase reads. Structured JSON only no LLM. "
110
+ "Portfolio-aware crypto context for AI agents: discover holdings and "
111
+ "holdings-scoped market, sentiment, macro, and regime; optional allocation "
112
+ "analysis and rebalance math. Fused backdrop (Fear & Greed, Kalshi, ETF "
113
+ "flows), optional live portfolio reads (e.g. Coinbase, Kraken). Structured "
114
+ "JSON only — no LLM. "
96
115
  f"{PRIVACY_COMPACT_COPY} "
97
116
  "Source-available (Elastic License 2.0); self-host friendly; official hosted "
98
117
  f"MCP at {OFFICIAL_HOSTED_MCP_URL} — see {USE_DOCS_PATH}."
99
118
  )
100
119
 
101
- _ASSET_FILTER_SCHEMA = {
102
- "type": "array",
103
- "items": {"type": "string", "enum": ["BTC", "ETH", "CASH"]},
104
- "description": "Subset market and ETF fields (default BTC and ETH).",
105
- }
106
-
107
- _TARGET_PCT_SCHEMA = {
108
- "type": "object",
109
- "description": "Target weights keyed by BTC, ETH, CASH.",
110
- "properties": {
111
- "BTC": {"type": "number"},
112
- "ETH": {"type": "number"},
113
- "CASH": {"type": "number"},
114
- },
115
- "required": ["BTC", "ETH", "CASH"],
116
- }
117
-
118
- _BAND_SCHEMA = {
119
- "type": "number",
120
- "description": "Drift band width (for example 0.15 = 15%).",
121
- }
122
-
123
120
  _MCP_TOOLS: tuple[dict[str, Any], ...] = (
124
121
  {
125
122
  "tool_name": "get_market_context",
126
123
  "description": (
127
- "Fused market backdrop for portfolio context: Fear & Greed, Kalshi "
128
- "sentiment, macro calendar, FRED indicators, ETF flows, and breadth. "
129
- "Use freshness=cached for hosted cache; freshness=live runs ingest "
130
- "first (requires ingest API keys on the host)."
124
+ "Return read-only fused market backdrop for crypto portfolio context: "
125
+ "sentiment (Fear & Greed, Kalshi), macro events, FRED indicators, ETF "
126
+ "flows, and market breadth no portfolio holdings. Use "
127
+ "get_context_bundle when you also need holdings, delta, or regime. "
128
+ "freshness=cached reads the ingest DB; freshness=live runs ingest first."
131
129
  ),
132
130
  "input_schema": {
133
131
  "type": "object",
134
132
  "properties": {
135
- "scope": {
136
- "type": "string",
137
- "enum": ["daily", "weekly"],
138
- "description": "Rollup horizon for macro and context bundle.",
139
- },
140
- "freshness": {
141
- "type": "string",
142
- "enum": ["cached", "live"],
143
- "description": (
144
- "cached reads the ingest DB; live runs ingest first "
145
- "(requires ingest API keys on the host)."
146
- ),
147
- },
148
- "assets": _ASSET_FILTER_SCHEMA,
133
+ "scope": SCOPE_SCHEMA,
134
+ "freshness": FRESHNESS_SCHEMA,
135
+ "assets": ASSET_FILTER_SCHEMA,
149
136
  },
150
137
  },
151
138
  "example": {"scope": "daily", "freshness": "cached", "assets": ["BTC", "ETH"]},
@@ -163,25 +150,20 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
163
150
  {
164
151
  "tool_name": "get_context_bundle",
165
152
  "description": (
166
- "Full ContextBundle JSON: portfolio holdings and band weights, "
167
- "market, sentiment, macro, regime hints, and delta vs the prior "
168
- "saved snapshot. Optional target_pct and band enable "
169
- "allocation_analysis (opt-in drift math)."
153
+ "Return the full read-only ContextBundle JSON: portfolio holdings, "
154
+ "market, sentiment, macro, regime hints, and delta vs the prior saved "
155
+ "snapshot. Use get_market_context for market-only; use get_context_at "
156
+ "for a historical snapshot. Optional target_pct and band attach "
157
+ "allocation_analysis drift math."
170
158
  ),
171
159
  "input_schema": {
172
160
  "type": "object",
173
161
  "properties": {
174
- "scope": {
175
- "type": "string",
176
- "enum": ["daily", "weekly"],
177
- },
178
- "freshness": {
179
- "type": "string",
180
- "enum": ["cached", "live"],
181
- },
182
- "assets": _ASSET_FILTER_SCHEMA,
183
- "target_pct": _TARGET_PCT_SCHEMA,
184
- "band": _BAND_SCHEMA,
162
+ "scope": SCOPE_SCHEMA,
163
+ "freshness": FRESHNESS_SCHEMA,
164
+ "assets": ASSET_FILTER_SCHEMA,
165
+ "target_pct": TARGET_PCT_SCHEMA,
166
+ "band": BAND_SCHEMA,
185
167
  },
186
168
  },
187
169
  "example": {
@@ -211,45 +193,28 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
211
193
  {
212
194
  "tool_name": "get_rebalance_plan",
213
195
  "description": (
214
- "Compute USD deltas and exchange-style move lines toward a target "
215
- "BTC/ETH/CASH allocation from current band weights and NAV. Pure "
216
- "math explicit inputs required."
196
+ "Compute read-only USD deltas and suggested exchange move lines to "
197
+ "reach a BTC/ETH/CASH target split. Pure math no exchange API calls. "
198
+ "Requires allocation_pct, target_pct, and nav_usd. Use get_portfolio_state "
199
+ "or get_context_bundle when you need live weights first."
217
200
  ),
218
201
  "input_schema": {
219
202
  "type": "object",
220
203
  "properties": {
221
- "allocation_pct": {
222
- "type": "object",
223
- "description": "Current weights keyed by BTC, ETH, CASH.",
224
- "properties": {
225
- "BTC": {"type": "number"},
226
- "ETH": {"type": "number"},
227
- "CASH": {"type": "number"},
228
- },
229
- "required": ["BTC", "ETH", "CASH"],
230
- },
231
- "target_pct": {
232
- "type": "object",
233
- "description": "Target weights keyed by BTC, ETH, CASH.",
234
- "properties": {
235
- "BTC": {"type": "number"},
236
- "ETH": {"type": "number"},
237
- "CASH": {"type": "number"},
238
- },
239
- "required": ["BTC", "ETH", "CASH"],
240
- },
204
+ "allocation_pct": allocation_pct_schema(role="Current"),
205
+ "target_pct": allocation_pct_schema(role="Target"),
241
206
  "nav_usd": {
242
207
  "type": "number",
243
- "description": "Portfolio NAV in USD.",
208
+ "description": "Portfolio net asset value in USD.",
244
209
  },
245
210
  "exchange": {
246
211
  "type": "string",
247
212
  "enum": ["kraken", "coinbase"],
248
213
  "description": (
249
- "Exchange-specific move wording (default kraken)."
214
+ "Spot exchange for move wording: kraken (default) or coinbase."
250
215
  ),
251
216
  },
252
- "band": _BAND_SCHEMA,
217
+ "band": BAND_SCHEMA,
253
218
  },
254
219
  "required": ["allocation_pct", "target_pct", "nav_usd"],
255
220
  },
@@ -272,10 +237,11 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
272
237
  {
273
238
  "tool_name": "get_portfolio_state",
274
239
  "description": (
275
- "Live portfolio read: NAV, holdings[], band weights, and optional "
276
- "allocation_analysis when target_pct is supplied. Pass read-only "
277
- "Kraken or Coinbase credentials in the request; never stored "
278
- "server-side."
240
+ "Fetch live read-only portfolio NAV, holdings[], and band weights from "
241
+ "a supported spot exchange (e.g. Kraken, Coinbase) using credentials "
242
+ "passed in this call (never stored). Requires exchange, api_key, and "
243
+ "api_secret. Returns available=false with reason on invalid "
244
+ "credentials — no side effects."
279
245
  ),
280
246
  "input_schema": {
281
247
  "type": "object",
@@ -283,11 +249,13 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
283
249
  "exchange": {
284
250
  "type": "string",
285
251
  "enum": ["kraken", "coinbase"],
286
- "description": "Spot exchange to query.",
252
+ "description": "Spot exchange to query: kraken or coinbase.",
287
253
  },
288
254
  "api_key": {
289
255
  "type": "string",
290
- "description": "Read-only API key (CDP key name for Coinbase).",
256
+ "description": (
257
+ "Read-only exchange API key (Coinbase CDP key name)."
258
+ ),
291
259
  },
292
260
  "api_secret": {
293
261
  "type": "string",
@@ -295,19 +263,8 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
295
263
  "Read-only API secret (Kraken base64 secret or Coinbase EC PEM)."
296
264
  ),
297
265
  },
298
- "target_pct": {
299
- "type": "object",
300
- "description": "Optional target weights for allocation_analysis.",
301
- "properties": {
302
- "BTC": {"type": "number"},
303
- "ETH": {"type": "number"},
304
- "CASH": {"type": "number"},
305
- },
306
- },
307
- "band": {
308
- "type": "number",
309
- "description": "Drift band width when target_pct is supplied (e.g. 0.15).",
310
- },
266
+ "target_pct": OPTIONAL_TARGET_PCT_SCHEMA,
267
+ "band": BAND_SCHEMA,
311
268
  },
312
269
  "required": ["exchange", "api_key", "api_secret"],
313
270
  },
@@ -330,34 +287,19 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
330
287
  {
331
288
  "tool_name": "check_allocation_band",
332
289
  "description": (
333
- "Check whether band weights (BTC/ETH/CASH) are outside a drift band "
334
- "vs target and return hint (within_band, consider_rebalance, etc.). "
335
- "Explicit inputs required."
290
+ "Check read-only drift: are BTC/ETH/CASH band weights outside the drift "
291
+ "band vs target_pct? Returns rebalance_hint (within_band, "
292
+ "consider_rebalance, etc.). Single scenario — use check_allocation_bands "
293
+ "for multiple targets. Use get_rebalance_plan when you need USD move lines."
336
294
  ),
337
295
  "input_schema": {
338
296
  "type": "object",
339
297
  "properties": {
340
- "allocation_pct": {
341
- "type": "object",
342
- "properties": {
343
- "BTC": {"type": "number"},
344
- "ETH": {"type": "number"},
345
- "CASH": {"type": "number"},
346
- },
347
- "required": ["BTC", "ETH", "CASH"],
348
- },
349
- "target_pct": {
350
- "type": "object",
351
- "properties": {
352
- "BTC": {"type": "number"},
353
- "ETH": {"type": "number"},
354
- "CASH": {"type": "number"},
355
- },
356
- "required": ["BTC", "ETH", "CASH"],
357
- },
298
+ "allocation_pct": allocation_pct_schema(role="Current"),
299
+ "target_pct": allocation_pct_schema(role="Target"),
358
300
  "band": {
359
301
  "type": "number",
360
- "description": "Drift band width (default 0.15 = 15%).",
302
+ "description": "Drift band width as a fraction (default 0.15 = 15%).",
361
303
  },
362
304
  },
363
305
  "required": ["allocation_pct", "target_pct"],
@@ -378,16 +320,20 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
378
320
  {
379
321
  "tool_name": "get_context_at",
380
322
  "description": (
381
- "Load a saved ContextBundle snapshot from ingest history by ISO "
382
- "timestamp (match exact or at_or_before)."
323
+ "Load a read-only ContextBundle snapshot from ingest history at a point "
324
+ "in time. Use get_context_bundle for the latest snapshot; use "
325
+ "get_context_delta to compare two timestamps. Returns unavailable when "
326
+ "no snapshot matches as_of and match."
383
327
  ),
384
328
  "input_schema": {
385
329
  "type": "object",
386
330
  "properties": {
387
- "as_of": {"type": "string", "description": "ISO timestamp."},
388
- "scope": {"type": "string", "enum": ["daily", "weekly"]},
389
- "match": {"type": "string", "enum": ["exact", "at_or_before"]},
390
- "assets": _ASSET_FILTER_SCHEMA,
331
+ "as_of": AS_OF_SCHEMA,
332
+ "scope": SCOPE_SCHEMA,
333
+ "match": MATCH_SCHEMA,
334
+ "assets": ASSET_FILTER_SCHEMA,
335
+ "target_pct": TARGET_PCT_SCHEMA,
336
+ "band": BAND_SCHEMA,
391
337
  },
392
338
  "required": ["as_of"],
393
339
  },
@@ -406,15 +352,18 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
406
352
  {
407
353
  "tool_name": "get_context_delta",
408
354
  "description": (
409
- "Compare two ContextBundle snapshots and return notable_shifts."
355
+ "Compare two read-only ContextBundle snapshots and return notable_shifts "
356
+ "between them. Requires prior_as_of; omit current_as_of to diff against "
357
+ "the latest live bundle. Use get_context_at to load one snapshot without "
358
+ "diffing."
410
359
  ),
411
360
  "input_schema": {
412
361
  "type": "object",
413
362
  "properties": {
414
- "prior_as_of": {"type": "string"},
415
- "scope": {"type": "string", "enum": ["daily", "weekly"]},
416
- "current_as_of": {"type": "string"},
417
- "assets": _ASSET_FILTER_SCHEMA,
363
+ "prior_as_of": PRIOR_AS_OF_SCHEMA,
364
+ "scope": SCOPE_SCHEMA,
365
+ "current_as_of": CURRENT_AS_OF_SCHEMA,
366
+ "assets": ASSET_FILTER_SCHEMA,
418
367
  },
419
368
  "required": ["prior_as_of"],
420
369
  },
@@ -431,39 +380,15 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
431
380
  {
432
381
  "tool_name": "check_allocation_bands",
433
382
  "description": (
434
- "Evaluate allocation drift against multiple target/band scenarios."
383
+ "Evaluate read-only allocation drift against multiple target_pct/band "
384
+ "scenarios in one call. Each scenario requires target_pct; optional name "
385
+ "and band (default 0.15). Use check_allocation_band for a single target."
435
386
  ),
436
387
  "input_schema": {
437
388
  "type": "object",
438
389
  "properties": {
439
- "allocation_pct": {
440
- "type": "object",
441
- "properties": {
442
- "BTC": {"type": "number"},
443
- "ETH": {"type": "number"},
444
- "CASH": {"type": "number"},
445
- },
446
- "required": ["BTC", "ETH", "CASH"],
447
- },
448
- "scenarios": {
449
- "type": "array",
450
- "items": {
451
- "type": "object",
452
- "properties": {
453
- "name": {"type": "string"},
454
- "target_pct": {
455
- "type": "object",
456
- "properties": {
457
- "BTC": {"type": "number"},
458
- "ETH": {"type": "number"},
459
- "CASH": {"type": "number"},
460
- },
461
- },
462
- "band": {"type": "number"},
463
- },
464
- "required": ["target_pct"],
465
- },
466
- },
390
+ "allocation_pct": allocation_pct_schema(role="Current"),
391
+ "scenarios": SCENARIOS_SCHEMA,
467
392
  },
468
393
  "required": ["allocation_pct", "scenarios"],
469
394
  },
@@ -647,7 +572,7 @@ model context protocol, context bundle
647
572
  ## Examples
648
573
 
649
574
  Redacted tool JSON samples (evaluate before paying):
650
- https://github.com/negillett/alloc-context/blob/main/docs/examples.md
575
+ https://github.com/AllocContext/alloc-context/blob/main/docs/examples.md
651
576
  """
652
577
 
653
578
 
@@ -715,14 +640,7 @@ def build_mcp_server_card(*, version: str) -> dict[str, Any]:
715
640
  "see /.well-known/x402.json for pricing."
716
641
  ),
717
642
  },
718
- "tools": [
719
- {
720
- "name": spec["tool_name"],
721
- "description": spec["description"],
722
- "inputSchema": spec["input_schema"],
723
- }
724
- for spec in _MCP_TOOLS
725
- ],
726
- "resources": [],
727
- "prompts": [],
643
+ "tools": [server_card_tool_entry(spec) for spec in _MCP_TOOLS],
644
+ "resources": list(MCP_SERVER_RESOURCES),
645
+ "prompts": list(MCP_SERVER_PROMPTS),
728
646
  }