alloc-context 0.2.0__tar.gz → 0.2.2__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.
- {alloc_context-0.2.0 → alloc_context-0.2.2}/PKG-INFO +12 -3
- {alloc_context-0.2.0 → alloc_context-0.2.2}/README.md +9 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloc_context.egg-info/PKG-INFO +12 -3
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloc_context.egg-info/SOURCES.txt +5 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/__init__.py +1 -1
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/bazaar.py +141 -172
- alloc_context-0.2.2/alloccontext/mcp/glama.py +51 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/http.py +25 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/server.py +124 -61
- alloc_context-0.2.2/alloccontext/mcp/tool_catalog.py +311 -0
- alloc_context-0.2.2/alloccontext/mcp/tool_fields.py +130 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/x402_production_check.py +12 -2
- {alloc_context-0.2.0 → alloc_context-0.2.2}/pyproject.toml +8 -4
- alloc_context-0.2.2/tests/test_glama_well_known.py +51 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_mcp_bazaar.py +34 -0
- alloc_context-0.2.2/tests/test_mcp_server.py +47 -0
- alloc_context-0.2.2/tests/test_tool_catalog.py +65 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_workflows.py +6 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_x402_production_check.py +3 -3
- alloc_context-0.2.0/tests/test_mcp_server.py +0 -26
- {alloc_context-0.2.0 → alloc_context-0.2.2}/LICENSE +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloc_context.egg-info/dependency_links.txt +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloc_context.egg-info/entry_points.txt +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloc_context.egg-info/requires.txt +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloc_context.egg-info/top_level.txt +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/__main__.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/config.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/constants.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/horizon.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/__init__.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/alt_quote_registry.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/alt_quote_store.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/alt_quotes.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/asset_registry.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/cf_benchmarks.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/cf_history.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/coinbase_client.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/coinbase_portfolio.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/coingecko.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/coinmarketcap.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/env_keys.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/etf_flows.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/exchange/__init__.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/exchange/coinbase_adapter.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/exchange/kraken_adapter.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/exchange/live.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/exchange/portfolio.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/exchange/registry.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/exchange/types.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/exchange_http.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/fear_greed.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/fred.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/http_errors.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/kalshi.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/kalshi_api.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/kalshi_client.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/kalshi_files.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/kalshi_state.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/kraken_client.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/kraken_portfolio.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/macro_calendar.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/macro_normalize.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/market_snapshots.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/outcome.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/parse_helpers.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/portfolio_holdings.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/quote_resolver.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/ingest/runner.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/__init__.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/assets.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/bridge.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/bridge_portfolio.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/contracts.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/handlers.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/instructions.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/payer.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/payment_middleware.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/setup.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/staleness.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/upstream.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/validation.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/x402_bazaar_dynamic.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/x402_config.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/x402_pricing.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/mcp/x402_stables.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/__init__.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/allocation_analysis.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/band.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/breadth.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/cf_math.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/cluster.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/cluster_config.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/comparison.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/context.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/delta.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/etf.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/fear_greed.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/macro.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/portfolio.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/portfolio_payload.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/rebalance.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/regime.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/sentiment.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/snapshots.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/rollup/tape.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/status_report.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/store/__init__.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/store/db.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/store/jsonutil.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/store/meta.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/store/retention.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/store/status.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/timeutil.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/user_config.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/alloccontext/x402_smoke_redact.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/setup.cfg +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_backup_sqlite.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_bridge.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_bridge_portfolio.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_bump_version.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_coinbase_portfolio.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_config_cli.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_context_bundle_schema.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_context_snapshots.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_db_schema.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_deploy.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_dev_stack.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_etf.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_exchanges_config.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_fear_greed.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_fred.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_holdings_scoped_delta_regime.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_holdings_scoped_market.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_horizon.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_ingest_outcome.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_ingest_runner.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_ingest_store_integration.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_kalshi_api.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_kraken_portfolio.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_live_ingest_handlers.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_macro.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_market_breadth.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_mcp_assets_regime.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_mcp_contracts.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_mcp_data_staleness.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_mcp_handlers.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_mcp_health.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_mcp_http_lifecycle.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_mcp_live_portfolio.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_mcp_validation.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_mcp_x402.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_mcp_x402_http.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_mcp_x402_pricing.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_mcp_x402_stables.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_payer.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_portfolio_holdings.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_quote_resolver.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_rebalance.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_rollup.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_script_runtime.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_security_hardening.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_server_json.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_setup.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_snapshots_and_delta.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_status_report.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_user_config.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/tests/test_x402_bazaar_dynamic.py +0 -0
- {alloc_context-0.2.0 → alloc_context-0.2.2}/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.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Portfolio-aware crypto context for agents — holdings, market, optional allocation analysis
|
|
5
5
|
License: Elastic-2.0
|
|
6
|
-
Project-URL: Homepage, https://
|
|
6
|
+
Project-URL: Homepage, https://mcp.alloc-context.com/llms.txt
|
|
7
7
|
Project-URL: Documentation, https://github.com/negillett/alloc-context/blob/main/docs/agent-integration.md
|
|
8
8
|
Project-URL: Repository, https://github.com/negillett/alloc-context
|
|
9
9
|
Project-URL: Issues, https://github.com/negillett/alloc-context/issues
|
|
10
10
|
Project-URL: Changelog, https://github.com/negillett/alloc-context/releases
|
|
11
11
|
Project-URL: MCP Server, https://mcp.alloc-context.com/mcp
|
|
12
|
-
Keywords: mcp,x402,bitcoin,ethereum,portfolio,allocation,
|
|
12
|
+
Keywords: mcp,x402,bitcoin,ethereum,crypto,cryptocurrency,portfolio,allocation,holdings,rebalance,coinbase,kraken,agents
|
|
13
13
|
Classifier: Development Status :: 4 - Beta
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -44,6 +44,9 @@ Dynamic: license-file
|
|
|
44
44
|
|
|
45
45
|
# AllocContext
|
|
46
46
|
|
|
47
|
+
[](https://smithery.ai/server/@negillett/alloc-context)
|
|
48
|
+
[](https://glama.ai/mcp/servers/negillett/alloc-context)
|
|
49
|
+
|
|
47
50
|
mcp-name: io.github.negillett/alloc-context
|
|
48
51
|
|
|
49
52
|
**Portfolio-aware crypto context for agents** — discover holdings, market,
|
|
@@ -110,6 +113,7 @@ Not financial advice.
|
|
|
110
113
|
| **Discovery** | [llms.txt](https://mcp.alloc-context.com/llms.txt), [x402 manifest](https://mcp.alloc-context.com/.well-known/x402.json) |
|
|
111
114
|
| **Pricing** | **$0.02** cached context/math · **$0.05** live ingest or portfolio |
|
|
112
115
|
| **Payment** | x402 on Base — USDC or EURC |
|
|
116
|
+
| **Market scope** | Holdings-scoped (BTC/ETH OHLC; alt quote snapshots); bridge auto-scopes from portfolio |
|
|
113
117
|
|
|
114
118
|
Agents and wallets connect directly to the hosted endpoint — see
|
|
115
119
|
[agent-integration.md](docs/agent-integration.md). The Cursor bridge above
|
|
@@ -128,6 +132,11 @@ combines local portfolio reads with this upstream for market context.
|
|
|
128
132
|
| `check_allocation_bands` | Batch band checks for multiple target scenarios |
|
|
129
133
|
| `get_portfolio_state` | Live NAV and holdings from Kraken or Coinbase |
|
|
130
134
|
|
|
135
|
+
Market context is **holdings-scoped**: band assets (BTC/ETH) use OHLC bars; alt
|
|
136
|
+
holdings (e.g. HYPE) use quote snapshots when cached. The bridge auto-scopes
|
|
137
|
+
`assets` from your portfolio (symbols only upstream). See
|
|
138
|
+
[context-bundle.md#market-coverage](docs/context-bundle.md#market-coverage).
|
|
139
|
+
|
|
131
140
|
See [mcp.md](docs/mcp.md) for arguments, pricing, and resources.
|
|
132
141
|
|
|
133
142
|
## Self-host and development
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# AllocContext
|
|
2
2
|
|
|
3
|
+
[](https://smithery.ai/server/@negillett/alloc-context)
|
|
4
|
+
[](https://glama.ai/mcp/servers/negillett/alloc-context)
|
|
5
|
+
|
|
3
6
|
mcp-name: io.github.negillett/alloc-context
|
|
4
7
|
|
|
5
8
|
**Portfolio-aware crypto context for agents** — discover holdings, market,
|
|
@@ -66,6 +69,7 @@ Not financial advice.
|
|
|
66
69
|
| **Discovery** | [llms.txt](https://mcp.alloc-context.com/llms.txt), [x402 manifest](https://mcp.alloc-context.com/.well-known/x402.json) |
|
|
67
70
|
| **Pricing** | **$0.02** cached context/math · **$0.05** live ingest or portfolio |
|
|
68
71
|
| **Payment** | x402 on Base — USDC or EURC |
|
|
72
|
+
| **Market scope** | Holdings-scoped (BTC/ETH OHLC; alt quote snapshots); bridge auto-scopes from portfolio |
|
|
69
73
|
|
|
70
74
|
Agents and wallets connect directly to the hosted endpoint — see
|
|
71
75
|
[agent-integration.md](docs/agent-integration.md). The Cursor bridge above
|
|
@@ -84,6 +88,11 @@ combines local portfolio reads with this upstream for market context.
|
|
|
84
88
|
| `check_allocation_bands` | Batch band checks for multiple target scenarios |
|
|
85
89
|
| `get_portfolio_state` | Live NAV and holdings from Kraken or Coinbase |
|
|
86
90
|
|
|
91
|
+
Market context is **holdings-scoped**: band assets (BTC/ETH) use OHLC bars; alt
|
|
92
|
+
holdings (e.g. HYPE) use quote snapshots when cached. The bridge auto-scopes
|
|
93
|
+
`assets` from your portfolio (symbols only upstream). See
|
|
94
|
+
[context-bundle.md#market-coverage](docs/context-bundle.md#market-coverage).
|
|
95
|
+
|
|
87
96
|
See [mcp.md](docs/mcp.md) for arguments, pricing, and resources.
|
|
88
97
|
|
|
89
98
|
## Self-host and development
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: alloc-context
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Portfolio-aware crypto context for agents — holdings, market, optional allocation analysis
|
|
5
5
|
License: Elastic-2.0
|
|
6
|
-
Project-URL: Homepage, https://
|
|
6
|
+
Project-URL: Homepage, https://mcp.alloc-context.com/llms.txt
|
|
7
7
|
Project-URL: Documentation, https://github.com/negillett/alloc-context/blob/main/docs/agent-integration.md
|
|
8
8
|
Project-URL: Repository, https://github.com/negillett/alloc-context
|
|
9
9
|
Project-URL: Issues, https://github.com/negillett/alloc-context/issues
|
|
10
10
|
Project-URL: Changelog, https://github.com/negillett/alloc-context/releases
|
|
11
11
|
Project-URL: MCP Server, https://mcp.alloc-context.com/mcp
|
|
12
|
-
Keywords: mcp,x402,bitcoin,ethereum,portfolio,allocation,
|
|
12
|
+
Keywords: mcp,x402,bitcoin,ethereum,crypto,cryptocurrency,portfolio,allocation,holdings,rebalance,coinbase,kraken,agents
|
|
13
13
|
Classifier: Development Status :: 4 - Beta
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -44,6 +44,9 @@ Dynamic: license-file
|
|
|
44
44
|
|
|
45
45
|
# AllocContext
|
|
46
46
|
|
|
47
|
+
[](https://smithery.ai/server/@negillett/alloc-context)
|
|
48
|
+
[](https://glama.ai/mcp/servers/negillett/alloc-context)
|
|
49
|
+
|
|
47
50
|
mcp-name: io.github.negillett/alloc-context
|
|
48
51
|
|
|
49
52
|
**Portfolio-aware crypto context for agents** — discover holdings, market,
|
|
@@ -110,6 +113,7 @@ Not financial advice.
|
|
|
110
113
|
| **Discovery** | [llms.txt](https://mcp.alloc-context.com/llms.txt), [x402 manifest](https://mcp.alloc-context.com/.well-known/x402.json) |
|
|
111
114
|
| **Pricing** | **$0.02** cached context/math · **$0.05** live ingest or portfolio |
|
|
112
115
|
| **Payment** | x402 on Base — USDC or EURC |
|
|
116
|
+
| **Market scope** | Holdings-scoped (BTC/ETH OHLC; alt quote snapshots); bridge auto-scopes from portfolio |
|
|
113
117
|
|
|
114
118
|
Agents and wallets connect directly to the hosted endpoint — see
|
|
115
119
|
[agent-integration.md](docs/agent-integration.md). The Cursor bridge above
|
|
@@ -128,6 +132,11 @@ combines local portfolio reads with this upstream for market context.
|
|
|
128
132
|
| `check_allocation_bands` | Batch band checks for multiple target scenarios |
|
|
129
133
|
| `get_portfolio_state` | Live NAV and holdings from Kraken or Coinbase |
|
|
130
134
|
|
|
135
|
+
Market context is **holdings-scoped**: band assets (BTC/ETH) use OHLC bars; alt
|
|
136
|
+
holdings (e.g. HYPE) use quote snapshots when cached. The bridge auto-scopes
|
|
137
|
+
`assets` from your portfolio (symbols only upstream). See
|
|
138
|
+
[context-bundle.md#market-coverage](docs/context-bundle.md#market-coverage).
|
|
139
|
+
|
|
131
140
|
See [mcp.md](docs/mcp.md) for arguments, pricing, and resources.
|
|
132
141
|
|
|
133
142
|
## Self-host and development
|
|
@@ -62,6 +62,7 @@ alloccontext/mcp/bazaar.py
|
|
|
62
62
|
alloccontext/mcp/bridge.py
|
|
63
63
|
alloccontext/mcp/bridge_portfolio.py
|
|
64
64
|
alloccontext/mcp/contracts.py
|
|
65
|
+
alloccontext/mcp/glama.py
|
|
65
66
|
alloccontext/mcp/handlers.py
|
|
66
67
|
alloccontext/mcp/http.py
|
|
67
68
|
alloccontext/mcp/instructions.py
|
|
@@ -70,6 +71,8 @@ alloccontext/mcp/payment_middleware.py
|
|
|
70
71
|
alloccontext/mcp/server.py
|
|
71
72
|
alloccontext/mcp/setup.py
|
|
72
73
|
alloccontext/mcp/staleness.py
|
|
74
|
+
alloccontext/mcp/tool_catalog.py
|
|
75
|
+
alloccontext/mcp/tool_fields.py
|
|
73
76
|
alloccontext/mcp/upstream.py
|
|
74
77
|
alloccontext/mcp/validation.py
|
|
75
78
|
alloccontext/mcp/x402_bazaar_dynamic.py
|
|
@@ -117,6 +120,7 @@ tests/test_etf.py
|
|
|
117
120
|
tests/test_exchanges_config.py
|
|
118
121
|
tests/test_fear_greed.py
|
|
119
122
|
tests/test_fred.py
|
|
123
|
+
tests/test_glama_well_known.py
|
|
120
124
|
tests/test_holdings_scoped_delta_regime.py
|
|
121
125
|
tests/test_holdings_scoped_market.py
|
|
122
126
|
tests/test_horizon.py
|
|
@@ -153,6 +157,7 @@ tests/test_server_json.py
|
|
|
153
157
|
tests/test_setup.py
|
|
154
158
|
tests/test_snapshots_and_delta.py
|
|
155
159
|
tests/test_status_report.py
|
|
160
|
+
tests/test_tool_catalog.py
|
|
156
161
|
tests/test_user_config.py
|
|
157
162
|
tests/test_workflows.py
|
|
158
163
|
tests/test_x402_bazaar_dynamic.py
|
|
@@ -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"
|
|
@@ -43,28 +61,49 @@ SERVICE_TITLE = (
|
|
|
43
61
|
# CDP Bazaar indexes service_name (≤32 chars) and up to five tags from payments.
|
|
44
62
|
BAZAAR_SERVICE_NAME = "AllocContext portfolio MCP"
|
|
45
63
|
SERVICE_TAGS = (
|
|
64
|
+
"crypto",
|
|
65
|
+
"cryptocurrency",
|
|
66
|
+
"bitcoin",
|
|
46
67
|
"btc",
|
|
68
|
+
"ethereum",
|
|
47
69
|
"eth",
|
|
48
70
|
"holdings",
|
|
49
71
|
"portfolio",
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"agent-tools",
|
|
53
|
-
"mcp",
|
|
72
|
+
"allocation",
|
|
73
|
+
"rebalance",
|
|
54
74
|
"sentiment",
|
|
55
75
|
"macro",
|
|
56
|
-
"
|
|
57
|
-
"
|
|
76
|
+
"coinbase",
|
|
77
|
+
"kraken",
|
|
78
|
+
"agent-tools",
|
|
79
|
+
"mcp",
|
|
80
|
+
"x402",
|
|
81
|
+
)
|
|
82
|
+
BAZAAR_INDEX_TAGS = (
|
|
83
|
+
"crypto",
|
|
84
|
+
"cryptocurrency",
|
|
85
|
+
"portfolio",
|
|
86
|
+
"holdings",
|
|
87
|
+
"btc",
|
|
58
88
|
)
|
|
59
|
-
BAZAAR_INDEX_TAGS = ("btc", "eth", "portfolio", "holdings", "mcp")
|
|
60
89
|
|
|
61
90
|
DISCOVERY_KEYWORD_MARKERS = (
|
|
91
|
+
"crypto",
|
|
92
|
+
"cryptocurrency",
|
|
93
|
+
"digital assets",
|
|
94
|
+
"crypto portfolio",
|
|
62
95
|
"portfolio allocation",
|
|
96
|
+
"portfolio context",
|
|
63
97
|
"allocation drift",
|
|
64
98
|
"rebalance plan",
|
|
65
99
|
"fear and greed",
|
|
66
100
|
"etf flows",
|
|
67
101
|
"holdings",
|
|
102
|
+
"holdings-scoped",
|
|
103
|
+
"coinbase",
|
|
104
|
+
"kraken",
|
|
105
|
+
"market context",
|
|
106
|
+
"sentiment",
|
|
68
107
|
)
|
|
69
108
|
|
|
70
109
|
LISTING_DESCRIPTION = (
|
|
@@ -77,54 +116,22 @@ LISTING_DESCRIPTION = (
|
|
|
77
116
|
f"MCP at {OFFICIAL_HOSTED_MCP_URL} — see {USE_DOCS_PATH}."
|
|
78
117
|
)
|
|
79
118
|
|
|
80
|
-
_ASSET_FILTER_SCHEMA = {
|
|
81
|
-
"type": "array",
|
|
82
|
-
"items": {"type": "string", "enum": ["BTC", "ETH", "CASH"]},
|
|
83
|
-
"description": "Subset market and ETF fields (default BTC and ETH).",
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
_TARGET_PCT_SCHEMA = {
|
|
87
|
-
"type": "object",
|
|
88
|
-
"description": "Target weights keyed by BTC, ETH, CASH.",
|
|
89
|
-
"properties": {
|
|
90
|
-
"BTC": {"type": "number"},
|
|
91
|
-
"ETH": {"type": "number"},
|
|
92
|
-
"CASH": {"type": "number"},
|
|
93
|
-
},
|
|
94
|
-
"required": ["BTC", "ETH", "CASH"],
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
_BAND_SCHEMA = {
|
|
98
|
-
"type": "number",
|
|
99
|
-
"description": "Drift band width (for example 0.15 = 15%).",
|
|
100
|
-
}
|
|
101
|
-
|
|
102
119
|
_MCP_TOOLS: tuple[dict[str, Any], ...] = (
|
|
103
120
|
{
|
|
104
121
|
"tool_name": "get_market_context",
|
|
105
122
|
"description": (
|
|
106
|
-
"
|
|
107
|
-
"sentiment, macro
|
|
108
|
-
"
|
|
109
|
-
"
|
|
123
|
+
"Return read-only fused market backdrop for crypto portfolio context: "
|
|
124
|
+
"sentiment (Fear & Greed, Kalshi), macro events, FRED indicators, ETF "
|
|
125
|
+
"flows, and market breadth — no portfolio holdings. Use "
|
|
126
|
+
"get_context_bundle when you also need holdings, delta, or regime. "
|
|
127
|
+
"freshness=cached reads the ingest DB; freshness=live runs ingest first."
|
|
110
128
|
),
|
|
111
129
|
"input_schema": {
|
|
112
130
|
"type": "object",
|
|
113
131
|
"properties": {
|
|
114
|
-
"scope":
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
"description": "Rollup horizon for macro and context bundle.",
|
|
118
|
-
},
|
|
119
|
-
"freshness": {
|
|
120
|
-
"type": "string",
|
|
121
|
-
"enum": ["cached", "live"],
|
|
122
|
-
"description": (
|
|
123
|
-
"cached reads the ingest DB; live runs ingest first "
|
|
124
|
-
"(requires ingest API keys on the host)."
|
|
125
|
-
),
|
|
126
|
-
},
|
|
127
|
-
"assets": _ASSET_FILTER_SCHEMA,
|
|
132
|
+
"scope": SCOPE_SCHEMA,
|
|
133
|
+
"freshness": FRESHNESS_SCHEMA,
|
|
134
|
+
"assets": ASSET_FILTER_SCHEMA,
|
|
128
135
|
},
|
|
129
136
|
},
|
|
130
137
|
"example": {"scope": "daily", "freshness": "cached", "assets": ["BTC", "ETH"]},
|
|
@@ -142,25 +149,20 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
|
|
|
142
149
|
{
|
|
143
150
|
"tool_name": "get_context_bundle",
|
|
144
151
|
"description": (
|
|
145
|
-
"
|
|
146
|
-
"market, sentiment, macro, regime hints, and delta vs the prior "
|
|
147
|
-
"
|
|
148
|
-
"
|
|
152
|
+
"Return the full read-only ContextBundle JSON: portfolio holdings, "
|
|
153
|
+
"market, sentiment, macro, regime hints, and delta vs the prior saved "
|
|
154
|
+
"snapshot. Use get_market_context for market-only; use get_context_at "
|
|
155
|
+
"for a historical snapshot. Optional target_pct and band attach "
|
|
156
|
+
"allocation_analysis drift math."
|
|
149
157
|
),
|
|
150
158
|
"input_schema": {
|
|
151
159
|
"type": "object",
|
|
152
160
|
"properties": {
|
|
153
|
-
"scope":
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
"
|
|
158
|
-
"type": "string",
|
|
159
|
-
"enum": ["cached", "live"],
|
|
160
|
-
},
|
|
161
|
-
"assets": _ASSET_FILTER_SCHEMA,
|
|
162
|
-
"target_pct": _TARGET_PCT_SCHEMA,
|
|
163
|
-
"band": _BAND_SCHEMA,
|
|
161
|
+
"scope": SCOPE_SCHEMA,
|
|
162
|
+
"freshness": FRESHNESS_SCHEMA,
|
|
163
|
+
"assets": ASSET_FILTER_SCHEMA,
|
|
164
|
+
"target_pct": TARGET_PCT_SCHEMA,
|
|
165
|
+
"band": BAND_SCHEMA,
|
|
164
166
|
},
|
|
165
167
|
},
|
|
166
168
|
"example": {
|
|
@@ -190,45 +192,28 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
|
|
|
190
192
|
{
|
|
191
193
|
"tool_name": "get_rebalance_plan",
|
|
192
194
|
"description": (
|
|
193
|
-
"Compute USD deltas and exchange
|
|
194
|
-
"BTC/ETH/CASH
|
|
195
|
-
"
|
|
195
|
+
"Compute read-only USD deltas and suggested exchange move lines to "
|
|
196
|
+
"reach a BTC/ETH/CASH target split. Pure math — no exchange API calls. "
|
|
197
|
+
"Requires allocation_pct, target_pct, and nav_usd. Use get_portfolio_state "
|
|
198
|
+
"or get_context_bundle when you need live weights first."
|
|
196
199
|
),
|
|
197
200
|
"input_schema": {
|
|
198
201
|
"type": "object",
|
|
199
202
|
"properties": {
|
|
200
|
-
"allocation_pct":
|
|
201
|
-
|
|
202
|
-
"description": "Current weights keyed by BTC, ETH, CASH.",
|
|
203
|
-
"properties": {
|
|
204
|
-
"BTC": {"type": "number"},
|
|
205
|
-
"ETH": {"type": "number"},
|
|
206
|
-
"CASH": {"type": "number"},
|
|
207
|
-
},
|
|
208
|
-
"required": ["BTC", "ETH", "CASH"],
|
|
209
|
-
},
|
|
210
|
-
"target_pct": {
|
|
211
|
-
"type": "object",
|
|
212
|
-
"description": "Target weights keyed by BTC, ETH, CASH.",
|
|
213
|
-
"properties": {
|
|
214
|
-
"BTC": {"type": "number"},
|
|
215
|
-
"ETH": {"type": "number"},
|
|
216
|
-
"CASH": {"type": "number"},
|
|
217
|
-
},
|
|
218
|
-
"required": ["BTC", "ETH", "CASH"],
|
|
219
|
-
},
|
|
203
|
+
"allocation_pct": allocation_pct_schema(role="Current"),
|
|
204
|
+
"target_pct": allocation_pct_schema(role="Target"),
|
|
220
205
|
"nav_usd": {
|
|
221
206
|
"type": "number",
|
|
222
|
-
"description": "Portfolio
|
|
207
|
+
"description": "Portfolio net asset value in USD.",
|
|
223
208
|
},
|
|
224
209
|
"exchange": {
|
|
225
210
|
"type": "string",
|
|
226
211
|
"enum": ["kraken", "coinbase"],
|
|
227
212
|
"description": (
|
|
228
|
-
"
|
|
213
|
+
"Spot exchange for move wording: kraken (default) or coinbase."
|
|
229
214
|
),
|
|
230
215
|
},
|
|
231
|
-
"band":
|
|
216
|
+
"band": BAND_SCHEMA,
|
|
232
217
|
},
|
|
233
218
|
"required": ["allocation_pct", "target_pct", "nav_usd"],
|
|
234
219
|
},
|
|
@@ -251,10 +236,10 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
|
|
|
251
236
|
{
|
|
252
237
|
"tool_name": "get_portfolio_state",
|
|
253
238
|
"description": (
|
|
254
|
-
"
|
|
255
|
-
"
|
|
256
|
-
"
|
|
257
|
-
"
|
|
239
|
+
"Fetch live read-only portfolio NAV, holdings[], and band weights from "
|
|
240
|
+
"Kraken or Coinbase credentials passed in this call (never stored). "
|
|
241
|
+
"Requires exchange, api_key, and api_secret. Returns available=false "
|
|
242
|
+
"with reason on invalid credentials — no side effects."
|
|
258
243
|
),
|
|
259
244
|
"input_schema": {
|
|
260
245
|
"type": "object",
|
|
@@ -262,11 +247,13 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
|
|
|
262
247
|
"exchange": {
|
|
263
248
|
"type": "string",
|
|
264
249
|
"enum": ["kraken", "coinbase"],
|
|
265
|
-
"description": "Spot exchange to query.",
|
|
250
|
+
"description": "Spot exchange to query: kraken or coinbase.",
|
|
266
251
|
},
|
|
267
252
|
"api_key": {
|
|
268
253
|
"type": "string",
|
|
269
|
-
"description":
|
|
254
|
+
"description": (
|
|
255
|
+
"Read-only exchange API key (Coinbase CDP key name)."
|
|
256
|
+
),
|
|
270
257
|
},
|
|
271
258
|
"api_secret": {
|
|
272
259
|
"type": "string",
|
|
@@ -274,19 +261,8 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
|
|
|
274
261
|
"Read-only API secret (Kraken base64 secret or Coinbase EC PEM)."
|
|
275
262
|
),
|
|
276
263
|
},
|
|
277
|
-
"target_pct":
|
|
278
|
-
|
|
279
|
-
"description": "Optional target weights for allocation_analysis.",
|
|
280
|
-
"properties": {
|
|
281
|
-
"BTC": {"type": "number"},
|
|
282
|
-
"ETH": {"type": "number"},
|
|
283
|
-
"CASH": {"type": "number"},
|
|
284
|
-
},
|
|
285
|
-
},
|
|
286
|
-
"band": {
|
|
287
|
-
"type": "number",
|
|
288
|
-
"description": "Drift band width when target_pct is supplied (e.g. 0.15).",
|
|
289
|
-
},
|
|
264
|
+
"target_pct": OPTIONAL_TARGET_PCT_SCHEMA,
|
|
265
|
+
"band": BAND_SCHEMA,
|
|
290
266
|
},
|
|
291
267
|
"required": ["exchange", "api_key", "api_secret"],
|
|
292
268
|
},
|
|
@@ -309,34 +285,19 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
|
|
|
309
285
|
{
|
|
310
286
|
"tool_name": "check_allocation_band",
|
|
311
287
|
"description": (
|
|
312
|
-
"Check
|
|
313
|
-
"vs
|
|
314
|
-
"
|
|
288
|
+
"Check read-only drift: are BTC/ETH/CASH band weights outside the drift "
|
|
289
|
+
"band vs target_pct? Returns rebalance_hint (within_band, "
|
|
290
|
+
"consider_rebalance, etc.). Single scenario — use check_allocation_bands "
|
|
291
|
+
"for multiple targets. Use get_rebalance_plan when you need USD move lines."
|
|
315
292
|
),
|
|
316
293
|
"input_schema": {
|
|
317
294
|
"type": "object",
|
|
318
295
|
"properties": {
|
|
319
|
-
"allocation_pct":
|
|
320
|
-
|
|
321
|
-
"properties": {
|
|
322
|
-
"BTC": {"type": "number"},
|
|
323
|
-
"ETH": {"type": "number"},
|
|
324
|
-
"CASH": {"type": "number"},
|
|
325
|
-
},
|
|
326
|
-
"required": ["BTC", "ETH", "CASH"],
|
|
327
|
-
},
|
|
328
|
-
"target_pct": {
|
|
329
|
-
"type": "object",
|
|
330
|
-
"properties": {
|
|
331
|
-
"BTC": {"type": "number"},
|
|
332
|
-
"ETH": {"type": "number"},
|
|
333
|
-
"CASH": {"type": "number"},
|
|
334
|
-
},
|
|
335
|
-
"required": ["BTC", "ETH", "CASH"],
|
|
336
|
-
},
|
|
296
|
+
"allocation_pct": allocation_pct_schema(role="Current"),
|
|
297
|
+
"target_pct": allocation_pct_schema(role="Target"),
|
|
337
298
|
"band": {
|
|
338
299
|
"type": "number",
|
|
339
|
-
"description": "Drift band width (default 0.15 = 15%).",
|
|
300
|
+
"description": "Drift band width as a fraction (default 0.15 = 15%).",
|
|
340
301
|
},
|
|
341
302
|
},
|
|
342
303
|
"required": ["allocation_pct", "target_pct"],
|
|
@@ -357,16 +318,20 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
|
|
|
357
318
|
{
|
|
358
319
|
"tool_name": "get_context_at",
|
|
359
320
|
"description": (
|
|
360
|
-
"Load a
|
|
361
|
-
"
|
|
321
|
+
"Load a read-only ContextBundle snapshot from ingest history at a point "
|
|
322
|
+
"in time. Use get_context_bundle for the latest snapshot; use "
|
|
323
|
+
"get_context_delta to compare two timestamps. Returns unavailable when "
|
|
324
|
+
"no snapshot matches as_of and match."
|
|
362
325
|
),
|
|
363
326
|
"input_schema": {
|
|
364
327
|
"type": "object",
|
|
365
328
|
"properties": {
|
|
366
|
-
"as_of":
|
|
367
|
-
"scope":
|
|
368
|
-
"match":
|
|
369
|
-
"assets":
|
|
329
|
+
"as_of": AS_OF_SCHEMA,
|
|
330
|
+
"scope": SCOPE_SCHEMA,
|
|
331
|
+
"match": MATCH_SCHEMA,
|
|
332
|
+
"assets": ASSET_FILTER_SCHEMA,
|
|
333
|
+
"target_pct": TARGET_PCT_SCHEMA,
|
|
334
|
+
"band": BAND_SCHEMA,
|
|
370
335
|
},
|
|
371
336
|
"required": ["as_of"],
|
|
372
337
|
},
|
|
@@ -385,15 +350,18 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
|
|
|
385
350
|
{
|
|
386
351
|
"tool_name": "get_context_delta",
|
|
387
352
|
"description": (
|
|
388
|
-
"Compare two ContextBundle snapshots and return notable_shifts
|
|
353
|
+
"Compare two read-only ContextBundle snapshots and return notable_shifts "
|
|
354
|
+
"between them. Requires prior_as_of; omit current_as_of to diff against "
|
|
355
|
+
"the latest live bundle. Use get_context_at to load one snapshot without "
|
|
356
|
+
"diffing."
|
|
389
357
|
),
|
|
390
358
|
"input_schema": {
|
|
391
359
|
"type": "object",
|
|
392
360
|
"properties": {
|
|
393
|
-
"prior_as_of":
|
|
394
|
-
"scope":
|
|
395
|
-
"current_as_of":
|
|
396
|
-
"assets":
|
|
361
|
+
"prior_as_of": PRIOR_AS_OF_SCHEMA,
|
|
362
|
+
"scope": SCOPE_SCHEMA,
|
|
363
|
+
"current_as_of": CURRENT_AS_OF_SCHEMA,
|
|
364
|
+
"assets": ASSET_FILTER_SCHEMA,
|
|
397
365
|
},
|
|
398
366
|
"required": ["prior_as_of"],
|
|
399
367
|
},
|
|
@@ -410,39 +378,15 @@ _MCP_TOOLS: tuple[dict[str, Any], ...] = (
|
|
|
410
378
|
{
|
|
411
379
|
"tool_name": "check_allocation_bands",
|
|
412
380
|
"description": (
|
|
413
|
-
"Evaluate allocation drift against multiple
|
|
381
|
+
"Evaluate read-only allocation drift against multiple target_pct/band "
|
|
382
|
+
"scenarios in one call. Each scenario requires target_pct; optional name "
|
|
383
|
+
"and band (default 0.15). Use check_allocation_band for a single target."
|
|
414
384
|
),
|
|
415
385
|
"input_schema": {
|
|
416
386
|
"type": "object",
|
|
417
387
|
"properties": {
|
|
418
|
-
"allocation_pct":
|
|
419
|
-
|
|
420
|
-
"properties": {
|
|
421
|
-
"BTC": {"type": "number"},
|
|
422
|
-
"ETH": {"type": "number"},
|
|
423
|
-
"CASH": {"type": "number"},
|
|
424
|
-
},
|
|
425
|
-
"required": ["BTC", "ETH", "CASH"],
|
|
426
|
-
},
|
|
427
|
-
"scenarios": {
|
|
428
|
-
"type": "array",
|
|
429
|
-
"items": {
|
|
430
|
-
"type": "object",
|
|
431
|
-
"properties": {
|
|
432
|
-
"name": {"type": "string"},
|
|
433
|
-
"target_pct": {
|
|
434
|
-
"type": "object",
|
|
435
|
-
"properties": {
|
|
436
|
-
"BTC": {"type": "number"},
|
|
437
|
-
"ETH": {"type": "number"},
|
|
438
|
-
"CASH": {"type": "number"},
|
|
439
|
-
},
|
|
440
|
-
},
|
|
441
|
-
"band": {"type": "number"},
|
|
442
|
-
},
|
|
443
|
-
"required": ["target_pct"],
|
|
444
|
-
},
|
|
445
|
-
},
|
|
388
|
+
"allocation_pct": allocation_pct_schema(role="Current"),
|
|
389
|
+
"scenarios": SCENARIOS_SCHEMA,
|
|
446
390
|
},
|
|
447
391
|
"required": ["allocation_pct", "scenarios"],
|
|
448
392
|
},
|
|
@@ -616,9 +560,12 @@ portfolio never persist on our servers.
|
|
|
616
560
|
|
|
617
561
|
## Search keywords
|
|
618
562
|
|
|
619
|
-
bitcoin, ethereum, btc, eth,
|
|
620
|
-
|
|
621
|
-
|
|
563
|
+
bitcoin, ethereum, btc, eth, crypto, cryptocurrency, digital assets, altcoin,
|
|
564
|
+
stablecoin, crypto portfolio, portfolio allocation, portfolio context, holdings,
|
|
565
|
+
holdings-scoped, coinbase, kraken, market context, market data, sentiment,
|
|
566
|
+
macro calendar, etf flows, allocation drift, allocation bands, rebalance plan,
|
|
567
|
+
fear and greed, fear greed index, nav, agent tools, ai agents, mcp, x402,
|
|
568
|
+
model context protocol, context bundle
|
|
622
569
|
|
|
623
570
|
## Examples
|
|
624
571
|
|
|
@@ -673,3 +620,25 @@ def build_well_known_x402(
|
|
|
673
620
|
},
|
|
674
621
|
},
|
|
675
622
|
}
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
def build_mcp_server_card(*, version: str) -> dict[str, Any]:
|
|
626
|
+
"""Smithery static server card (SEP-1649) — free metadata when POST /mcp is x402."""
|
|
627
|
+
return {
|
|
628
|
+
"serverInfo": {
|
|
629
|
+
"name": SERVICE_TITLE,
|
|
630
|
+
"version": version,
|
|
631
|
+
"description": LISTING_DESCRIPTION,
|
|
632
|
+
},
|
|
633
|
+
"authentication": {
|
|
634
|
+
"required": True,
|
|
635
|
+
"schemes": ["x402"],
|
|
636
|
+
"description": (
|
|
637
|
+
"x402 exact payment on Base mainnet (USDC or EURC) per tool call; "
|
|
638
|
+
"see /.well-known/x402.json for pricing."
|
|
639
|
+
),
|
|
640
|
+
},
|
|
641
|
+
"tools": [server_card_tool_entry(spec) for spec in _MCP_TOOLS],
|
|
642
|
+
"resources": list(MCP_SERVER_RESOURCES),
|
|
643
|
+
"prompts": list(MCP_SERVER_PROMPTS),
|
|
644
|
+
}
|