altfinance-mcp 0.3.0__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.
@@ -0,0 +1,133 @@
1
+ # Environment variables
2
+ .env
3
+ .env.local
4
+ .env.*
5
+ *.csv
6
+ *.json
7
+ *.pkl
8
+ env
9
+
10
+ # Gmail Assistant tokens, logs, and reports
11
+ Gmail_Assistant/token.json
12
+ Gmail_Assistant/logs/
13
+ Gmail_Assistant/reports/
14
+ Gmail_Assistant/config/backups/
15
+
16
+ # Windows reserved device names (created accidentally by 2>NUL in bash)
17
+ NUL
18
+ **/nul.ipynb
19
+
20
+ # ---- Sensitive credentials and secrets ----
21
+ # Private keys / certificates
22
+ *.pem
23
+ *.key
24
+ *.p12
25
+ *.pfx
26
+ *.jks
27
+
28
+ # Auth tokens and session cookies
29
+ *token*.txt
30
+ *.token
31
+ *cookie*.txt
32
+ .saleroom_cookie_header.txt
33
+
34
+ # AWS credentials
35
+ .aws/credentials
36
+ aws_credentials*
37
+
38
+ # Project-specific: Cartier deliverable (contains client-embedded AWS/API keys pending rotation)
39
+ Cartier_Search_Engine/
40
+
41
+ # Claude Code worktrees (may duplicate credentials)
42
+ .claude/worktrees/
43
+
44
+ # Virtualenv / caches / build artifacts
45
+ .venv/
46
+ venv/
47
+ __pycache__/
48
+ *.pyc
49
+ *.pyo
50
+
51
+ # Logs
52
+ *.log
53
+ Scheduled_Local_Tasks/Pipeline_Status_Logs/
54
+
55
+ # Downloaded / temporary data
56
+ downloaded_files/
57
+
58
+ # Large binary tools bundled locally (not source)
59
+ ffmpeg-master-latest-win64-gpl/
60
+
61
+ # Downloaded media (scraping artifacts)
62
+ **/youtube_videos/
63
+ *.mp4
64
+ *.mov
65
+ *.webm
66
+
67
+ # Large pipeline output / test fixtures (regenerated, not source)
68
+ test_*.jsonl
69
+ **/Pipeline_Output/*.jsonl
70
+ **/Merged/*.jsonl
71
+
72
+ # Gemini reclassification notebook outputs (large generated data)
73
+ AI_Models/Gemini/1_gemini_output_watches_reclassify*.ipynb
74
+ AI_Models/Gemini/2_gemini_merge_output_watches*.ipynb
75
+
76
+ # Failed-log artifacts
77
+ *.log.failed*
78
+
79
+ # ---- Direct-vendor scraping (Bidpath, EasyLive, etc.) ----
80
+ # Whitelist vendor configs that should be tracked (override global *.json rule)
81
+ !Data Collection/vendor-configs/
82
+ !Data Collection/vendor-configs/*.json
83
+
84
+ # Whitelist small reference outputs (top-100 vendor list, discovery results, probe results)
85
+ !Data Collection/vendor_top100.json
86
+ !Data Collection/vendor_directory.json
87
+ !Data Collection/bidpath_probe_results.json
88
+ !Data Collection/step5_jewelry_targets_filtered.json
89
+
90
+ # Block large local caches (regenerable from S3)
91
+ Data Collection/_cache_*.json
92
+ Data Collection/cross_platform_matches.json
93
+ Data Collection/cross_platform_merge_manifest.json
94
+ Data Collection/saleroom_split_manifest.json
95
+ Data Collection/bonhams_enrichment_candidates*.json
96
+ Data Collection/bonhams_enrichment_strict.json
97
+ Data Collection/bonhams_enrichment_summary.json
98
+ Data Collection/bonhams_enrichment_execution_summary.json
99
+ Data Collection/bonhams_categories_enrichment_summary.json
100
+ Data Collection/bonhams_jewelry_v2_summary.json
101
+ Data Collection/bonhams_gwh_v2_summary.json
102
+ Data Collection/enrichment_strategy_comparison.json
103
+ Data Collection/step5_jewelry_targets.json
104
+ Data Collection/saleroom_vendors_captured.txt
105
+ Data Collection/cross_platform_matches.csv
106
+ Data Collection/enrich_bonhams_*.sql
107
+
108
+ # Auth files (already in .saleroom_cookie_header.txt rule above, but be explicit)
109
+ Data Collection/.saleroom_cookie_header.txt
110
+ Data Collection/.saleroom_user_agent.txt
111
+ Data Collection/.saleroom_cookies.json
112
+ Data Collection/Tajan/*_out.ipynb
113
+
114
+ # Repeat-detection cache: keep only small artifacts; skip ALL the giant parquet datasets
115
+ repeat_detection_cache/jewelry_lots.parquet
116
+ repeat_detection_cache/jewelry_verified.parquet
117
+ repeat_detection_cache/*.parquet
118
+
119
+ # Barrett-Jackson raw API dump (large, regenerable from S3/API)
120
+ Data Collection/Barrett-Jackson/bj_api_pre2023.jsonl
121
+
122
+ # Branding storybook/Figma BUILD artifacts (~956MB of node_modules + storybook-static,
123
+ # regenerable; the storybooks deploy to the altfinancedbstatuspage S3 bucket).
124
+ # NOTE: Branding/AltFinance is intentionally NOT ignored — it's source (docs, email_system, covers).
125
+ Branding/Bloomberg/
126
+ Branding/BusinessInsider/
127
+ Branding/AlphaSense/
128
+ Branding/LoversByShan/
129
+ Branding/Figma_Projects/
130
+ Branding/JPMorgan/
131
+
132
+ # Safety net: never track node_modules anywhere (a JPMorgan storybook leaked ~7.5k untracked files)
133
+ **/node_modules/
@@ -0,0 +1,282 @@
1
+ # Community Post Drafts — AltFinance Launch
2
+
3
+ > These are draft posts for various communities. Adapt tone and length as needed before posting.
4
+ > Remember the 90/10 rule: lead with value, not product.
5
+
6
+ ---
7
+
8
+ ## 1. r/ClaudeAI — MCP Server Announcement
9
+
10
+ **Title:** I built an MCP server that gives Claude access to 990K luxury auction records (watches, handbags, jewelry)
11
+
12
+ **Body:**
13
+
14
+ I've been building a luxury asset data platform for a while now and just shipped an MCP server that lets Claude query auction results directly.
15
+
16
+ **What it does:**
17
+
18
+ Three tools — `list_tables`, `get_table_schema`, and `query_table`. Once connected, you can ask Claude things like:
19
+
20
+ - "Find the top 10 most expensive Rolex Daytona watches sold since 2020"
21
+ - "How many Hermes Birkin bags were sold at Christie's vs Sotheby's?"
22
+ - "Show me diamond jewelry that sold for over $100K last year, sorted by price"
23
+
24
+ Claude translates your natural language into structured queries against the API automatically. It handles filtering (11 operators including `like`, `in`, `is_null`), sorting, field selection, and pagination.
25
+
26
+ **The data:**
27
+
28
+ | Table | Records | Sources |
29
+ |-------|---------|---------|
30
+ | Watches | 390K+ | Christie's, Sotheby's, Phillips, Bonhams, and 100+ more |
31
+ | Handbags | 120K+ | Same major houses + specialist auction houses |
32
+ | Jewelry | 480K+ | Jewelry and gemstone auction results worldwide |
33
+
34
+ Each record includes lot details, sale price, estimates, auction house, sale date, descriptions, and more (up to 122 fields for watches).
35
+
36
+ **Setup (takes 2 minutes):**
37
+
38
+ 1. `pip install altfinance-mcp`
39
+ 2. Add to your Claude Desktop config (`%APPDATA%\Claude\claude_desktop_config.json` on Windows, `~/Library/Application Support/Claude/claude_desktop_config.json` on Mac):
40
+
41
+ ```json
42
+ {
43
+ "mcpServers": {
44
+ "altfinance": {
45
+ "command": "altfinance-mcp",
46
+ "env": {
47
+ "ALTFINANCE_API_KEY": "your-api-key-here"
48
+ }
49
+ }
50
+ }
51
+ }
52
+ ```
53
+
54
+ 3. Restart Claude Desktop.
55
+
56
+ For Claude Code: `claude mcp add altfinance -- altfinance-mcp`
57
+
58
+ **Getting an API key:**
59
+
60
+ Sign up at altfndata.com. There's a free tier (1K rows/day) so you can try it out without committing.
61
+
62
+ Happy to answer any questions about the data, setup, or how the MCP tools work under the hood. The server itself is a thin wrapper over our REST API using httpx — Claude does all the heavy lifting of translating your question into the right query.
63
+
64
+ ---
65
+
66
+ ## 2. r/datasets — Dataset Announcement
67
+
68
+ **Title:** 990K luxury auction records — watches, handbags, and jewelry from 100+ auction houses (API access)
69
+
70
+ **Body:**
71
+
72
+ I've spent the last couple of years building a structured dataset of luxury goods auction results and wanted to share it with this community.
73
+
74
+ **What's in the data:**
75
+
76
+ | Category | Records | Fields | Key Columns |
77
+ |----------|---------|--------|-------------|
78
+ | Watches | 390K+ | 122 | brand, model, reference number, sale price (USD), estimate range, auction house, sale date, movement, case material, dial color, complications |
79
+ | Handbags | 120K+ | 67 | brand, model, material, color, sale price (USD), estimates, auction house, sale date, condition |
80
+ | Jewelry | 480K+ | 99 | item type, gemstone, carat weight, color, clarity, metal, sale price (USD), estimates, auction house, sale date |
81
+
82
+ **Sources:** Christie's, Sotheby's, Phillips, Bonhams, Artcurial, Dorotheum, Heritage Auctions, and 100+ more worldwide. Data is collected from public auction results and standardized into a consistent schema.
83
+
84
+ **Coverage:** Results going back 10+ years for major houses, with new results added regularly via automated pipelines.
85
+
86
+ **How to access:**
87
+
88
+ REST API at `api.altfndata.com`:
89
+
90
+ ```bash
91
+ # List available tables
92
+ curl -H "X-API-Key: YOUR_KEY" https://api.altfndata.com/v1/tables
93
+
94
+ # Query watches
95
+ curl -X POST -H "X-API-Key: YOUR_KEY" \
96
+ -H "Content-Type: application/json" \
97
+ -d '{"filters":[{"field":"brand","operator":"eq","value":"Rolex"}],"sort_field":"price_usd","sort_direction":"desc","limit":10}' \
98
+ https://api.altfndata.com/v1/tables/watches/query
99
+ ```
100
+
101
+ Filter operators: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `like`, `in`, `not_in`, `is_null`, `is_not_null`
102
+
103
+ Also available as an MCP server for Claude Desktop/Code users: `pip install altfinance-mcp`
104
+
105
+ **Free tier:** 1K rows/day, 10 requests/min — enough to explore the data and build prototypes.
106
+
107
+ Sign up at altfndata.com.
108
+
109
+ If there's interest, I could also share some analysis or summary statistics from the data (price distributions, top brands by volume, etc.).
110
+
111
+ ---
112
+
113
+ ## 3. r/algotrading — Alternative Data for Luxury Assets
114
+
115
+ **Title:** Alternative data: 990K auction records for luxury watches, handbags, and jewelry — accessible via REST API
116
+
117
+ **Body:**
118
+
119
+ Posting this for the alt-data crowd here. I've built a structured dataset + API covering luxury goods auction results that might be interesting for anyone looking at alternative asset classes or non-traditional price signals.
120
+
121
+ **The pitch in one sentence:** A REST API with 990K records from 100+ auction houses covering luxury watches (390K), handbags (120K), and jewelry (480K), with standardized schemas and programmatic access.
122
+
123
+ **Why this might be useful for quant/systematic approaches:**
124
+
125
+ - **Price discovery:** Luxury watches (Rolex, Patek Philippe, Audemars Piguet) are traded in a fragmented market. Auction data provides the closest thing to a consolidated tape.
126
+ - **Macro correlation:** Luxury auction results can signal consumer sentiment and wealth effects before they show up in retail data.
127
+ - **Cross-asset analysis:** The API covers three distinct luxury categories in a single schema, so you can analyze correlations across collectible asset classes.
128
+ - **Comparable sales:** If you're building valuation models for fractional ownership platforms or luxury lending, this is your training data.
129
+
130
+ **Technical details:**
131
+
132
+ - **Endpoints:** `/v1/tables` (list), `/v1/tables/{name}/schema` (schema), `/v1/tables/{name}/query` (query via POST or GET)
133
+ - **Filters:** 11 operators — `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `like`, `in`, `not_in`, `is_null`, `is_not_null`
134
+ - **Sorting:** Any column, asc/desc
135
+ - **Pagination:** limit + offset
136
+ - **Auth:** API key in header (`X-API-Key`)
137
+ - **Format:** JSON responses
138
+ - **Rate limits:** Free tier at 10 req/min, 1K rows/day. Paid tiers go up to 60 req/min, 50K rows/day.
139
+
140
+ **Sample query:**
141
+
142
+ ```python
143
+ import requests
144
+
145
+ headers = {"X-API-Key": "YOUR_KEY"}
146
+ payload = {
147
+ "filters": [
148
+ {"field": "brand", "operator": "eq", "value": "Rolex"},
149
+ {"field": "price_usd", "operator": "gt", "value": 50000}
150
+ ],
151
+ "fields": ["brand", "model", "reference_number", "price_usd", "sale_date", "auction_house"],
152
+ "sort_field": "sale_date",
153
+ "sort_direction": "desc",
154
+ "limit": 100
155
+ }
156
+ resp = requests.post("https://api.altfndata.com/v1/tables/watches/query",
157
+ json=payload, headers=headers)
158
+ data = resp.json()
159
+ ```
160
+
161
+ **What I'd love feedback on:**
162
+
163
+ 1. What additional fields or enrichments would make this useful for quantitative work? (currently up to 122 fields per record for watches)
164
+ 2. Would bulk export (CSV/Parquet) matter more than API access for backtesting?
165
+ 3. Any interest in a time-series endpoint (e.g., monthly average price by brand/model)?
166
+
167
+ Sign up for a free key at altfndata.com. Also available as an MCP server for Claude users: `pip install altfinance-mcp`.
168
+
169
+ ---
170
+
171
+ ## 4. Hacker News — Show HN
172
+
173
+ **Title:** Show HN: AltFinance – API for luxury auction data (990K records from 100+ auction houses)
174
+
175
+ **Body:**
176
+
177
+ Hi HN,
178
+
179
+ I built an API that provides structured access to luxury goods auction results. It covers three categories — watches (390K records), handbags (120K), and jewelry (480K) — from Christie's, Sotheby's, Phillips, Bonhams, and 100+ other auction houses.
180
+
181
+ The problem: luxury asset data is fragmented across hundreds of auction house websites, each with different formats, currencies, and naming conventions. There's no consolidated feed. If you're an investor, analyst, or builder working with luxury collectibles, you have to manually piece together data from dozens of sources.
182
+
183
+ What I built:
184
+
185
+ - A collection pipeline that scrapes, standardizes, and enriches auction results across 100+ houses
186
+ - A REST API (FastAPI) with flexible querying — 11 filter operators, sorting, field selection, pagination
187
+ - An MCP server so Claude Desktop users can query the data in natural language
188
+ - Anti-scraping protections: rate limits, daily row quotas, per-table access control
189
+
190
+ Tech stack: Python, FastAPI, AWS Athena (Apache Iceberg tables), S3, Fargate, Gemini for AI classification of lot categories.
191
+
192
+ Free tier: 10 req/min, 1K rows/day.
193
+
194
+ API docs: api.altfndata.com/docs
195
+ MCP server: pip install altfinance-mcp
196
+ Website: altfndata.com
197
+
198
+ I'd appreciate feedback on the API design, pricing model, or the data itself. Happy to answer questions.
199
+
200
+ ---
201
+
202
+ ## 5. r/Watches — Data Insight Post (Value-First, No Hard Sell)
203
+
204
+ **Title:** I analyzed 390K+ watch auction records — here are some patterns I found interesting
205
+
206
+ **Body:**
207
+
208
+ I've been building a database of luxury watch auction results as a side project for the past couple of years. The dataset now covers 390K+ lots from Christie's, Sotheby's, Phillips, Bonhams, and dozens of other houses going back 10+ years. Thought I'd share some of the patterns I've found interesting.
209
+
210
+ **A few things the data shows:**
211
+
212
+ **Brand concentration:** A small number of brands dominate the auction market by volume. Rolex, Patek Philippe, and Omega together account for a significant chunk of all watch lots. But when you look at average hammer price, the picture shifts — Patek and A. Lange & Sohne punch well above their volume share.
213
+
214
+ **The "Phillips effect":** Phillips has carved out a distinct position. Their average sale price per lot trends notably higher than other houses, even for the same references. Whether that's selection bias (they curate aggressively) or buyer premium (their audience skews differently) is an interesting question.
215
+
216
+ **Estimate accuracy:** Auction houses are surprisingly good at estimating — most lots sell within the estimate range. But the interesting cases are the outliers: lots that sell for 3-5x the high estimate. These tend to cluster around specific references and provenance features.
217
+
218
+ **Seasonal patterns:** There are clear seasonal rhythms. The major houses run their marquee watch sales in May/June and November. Average prices in these months tend to run higher — likely because they save the best consignments for the flagship sales, not because of seasonal demand.
219
+
220
+ **Material matters more than you'd think:** Steel sport watches from certain brands (you can probably guess which ones) have outperformed precious metal dress watches from the same brands over the last decade. The data is pretty clear on this one.
221
+
222
+ I'm happy to dig into specific questions if anyone is curious about a particular brand, reference, or trend. This is one of those projects where the more I look at the data, the more questions come up.
223
+
224
+ *[Note: no product link, no API mention. If asked "where can I access this data?" in comments, then naturally mention the API.]*
225
+
226
+ ---
227
+
228
+ ## 6. Product Hunt — Launch Day (Save for Phase 2)
229
+
230
+ **Tagline:** The Bloomberg Terminal for luxury collectibles
231
+
232
+ **Description:**
233
+
234
+ AltFinance gives you structured API access to 990K+ auction results across luxury watches, handbags, and jewelry. Data from Christie's, Sotheby's, Phillips, Bonhams, and 100+ auction houses worldwide.
235
+
236
+ Query by brand, model, price range, auction house, date, and 100+ other fields. Built for investment firms, analysts, collectors, and developers building in the luxury asset space.
237
+
238
+ Also available as an MCP server for Claude — ask Claude questions about the luxury market in natural language.
239
+
240
+ **Key Features:**
241
+ - 390K+ watch records, 120K+ handbag records, 480K+ jewelry records
242
+ - REST API with 11 filter operators
243
+ - MCP server for Claude Desktop and Claude Code
244
+ - Free tier available
245
+ - Data updated regularly via automated pipelines
246
+
247
+ ---
248
+
249
+ ## 7. awesome-mcp-servers GitHub PR
250
+
251
+ **Entry to add (in the appropriate category):**
252
+
253
+ ```markdown
254
+ - [AltFinance MCP](https://pypi.org/project/altfinance-mcp/) - Query 990K+ luxury auction records (watches, handbags, jewelry) from 100+ auction houses. Provides tools to list tables, get schemas, and run filtered queries against the AltFinance API.
255
+ ```
256
+
257
+ ---
258
+
259
+ ## Posting Schedule
260
+
261
+ | Week | Community | Post Type |
262
+ |------|-----------|-----------|
263
+ | 1 | r/ClaudeAI | MCP announcement (Post #1) |
264
+ | 1 | PulseMCP + MCP Registry | Submit listing |
265
+ | 1 | awesome-mcp-servers | Submit PR (Post #7) |
266
+ | 2 | r/datasets | Dataset announcement (Post #2) |
267
+ | 3 | r/algotrading | Alt data post (Post #3) |
268
+ | 4 | Hacker News | Show HN (Post #4) |
269
+ | 5 | r/Watches | Data insight post (Post #5) — no product link |
270
+ | 6 | r/SideProject | Build story |
271
+ | 8+ | PurseForum | Handbag trend analysis (organic) |
272
+ | 8+ | WatchUSeek | Watch analysis (organic) |
273
+ | Phase 2 | Product Hunt | Coordinated launch (Post #6) |
274
+
275
+ ## Tips Before Posting
276
+
277
+ 1. **Reddit accounts** — Make sure the posting account has established karma and history. New accounts get auto-filtered.
278
+ 2. **Don't cross-post** — Each community should get a unique, tailored post. Don't copy-paste.
279
+ 3. **Respond to every comment** — Engagement in the first 2 hours determines visibility on Reddit and HN.
280
+ 4. **Timing** — Post on Tuesday-Thursday mornings (US time) for best Reddit/HN visibility.
281
+ 5. **r/Watches post has no product link** — This is intentional. Only mention the API if someone asks in comments. This builds credibility and avoids removal.
282
+ 6. **HN formatting** — Keep the Show HN body concise. HN readers prefer brevity over marketing copy.
@@ -0,0 +1,108 @@
1
+ # AltFinance MCP & API — Deployment Progress
2
+
3
+ **Date**: 2026-03-03
4
+ **Status**: Infrastructure code complete, awaiting tooling install for deployment
5
+
6
+ ---
7
+
8
+ ## What Was Done
9
+
10
+ ### Infrastructure Code (all files written and ready)
11
+
12
+ | File | Purpose |
13
+ |------|---------|
14
+ | `infra/app.py` | CDK entry point — instantiates the stack |
15
+ | `infra/cdk.json` | CDK config |
16
+ | `infra/requirements.txt` | `aws-cdk-lib` + `constructs` |
17
+ | `infra/stacks/__init__.py` | Package init |
18
+ | `infra/stacks/api_stack.py` | Main CDK stack — VPC, ECR, ECS Fargate, ALB (HTTPS), Route 53, IAM (least-privilege Athena/Glue/S3), CloudWatch logs |
19
+ | `infra/scripts/deploy.py` | Docker build + ECR push + ECS force-redeploy (uses boto3 since AWS CLI isn't on PATH) |
20
+ | `infra/scripts/provision_key.py` | Generate API keys per tier (free/standard/premium), auto-add to `api_keys.json`, prints Claude Desktop config snippet |
21
+ | `infra/scripts/publish_mcp.py` | Rebuild + publish `altfinance-mcp` to PyPI via twine |
22
+ | `API_Management/.dockerignore` | Excludes `__pycache__`, `.env`, etc. from Docker builds |
23
+ | `API_Management/Dockerfile` | Modified — added non-root `appuser` for security hardening |
24
+ | `altfinance-mcp/QUICKSTART.md` | 1-page beta user guide (MCP setup, API usage, examples, filter operators) |
25
+
26
+ ### Key Findings
27
+
28
+ - **Wildcard ACM cert exists**: `arn:aws:acm:us-east-1:766784195791:certificate/613ff2e7-abfa-4168-8f68-adf74c6e074a` for `*.altfndata.com` — reused in CDK stack (no new cert needed)
29
+ - **altfinance-mcp NOT on PyPI** — wheel built locally at `dist/` but never uploaded. `publish_mcp.py` script handles this.
30
+ - **IAM user lacks Route53 permissions** — `api_stack.py` has a comment explaining how to skip auto-DNS and set the A record manually if needed
31
+ - **Node.js and Docker not installed** — required before running `cdk deploy` and `docker build`
32
+
33
+ ### Architecture Decisions
34
+
35
+ | Decision | Choice | Rationale |
36
+ |----------|--------|-----------|
37
+ | Load balancer | ALB (not API Gateway) | API Gateway has 30s hard timeout; Athena queries can take 60s |
38
+ | NAT strategy | 1 NAT gateway | Saves ~$32/mo vs 2; acceptable for beta |
39
+ | Compute | On-demand Fargate (not Spot) | Customer-facing API shouldn't have interruptions |
40
+ | API keys | Baked into container | For 5-10 beta users, rebuild+deploy is fine; Phase 2 moves to DynamoDB |
41
+ | Sizing | 0.25 vCPU / 0.5 GB RAM | Athena does the heavy lifting; container just sends boto3 calls |
42
+ | Redundancy | 1 task (desired_count=1) | Sufficient for beta; ECS auto-restarts on crash |
43
+ | VPC | New dedicated VPC | Isolated from the 28+ data pipeline Fargate tasks |
44
+
45
+ ### Estimated Monthly Cost: ~$59
46
+
47
+ | Resource | Cost |
48
+ |----------|------|
49
+ | NAT Gateway | ~$32 |
50
+ | ALB | ~$17 |
51
+ | Fargate (0.25 vCPU/0.5GB 24/7) | ~$8.50 |
52
+ | ECR + CloudWatch + Route53 | ~$1.50 |
53
+
54
+ ---
55
+
56
+ ## What's Left To Do
57
+
58
+ ### Prerequisites (install these first)
59
+
60
+ | Tool | How to Install | Why |
61
+ |------|----------------|-----|
62
+ | **Node.js** | https://nodejs.org (LTS) | CDK CLI runs on Node.js |
63
+ | **Docker Desktop** | https://docker.com/products/docker-desktop | Build + push container image |
64
+ | **AWS CDK CLI** | `npm install -g aws-cdk` (after Node.js) | `cdk deploy` command |
65
+
66
+ ### IAM Permissions Needed
67
+
68
+ Add to IAM user `sobuobi@altfndata.com`:
69
+ - `route53:ListHostedZones`, `route53:ChangeResourceRecordSets`, `route53:GetHostedZone`
70
+ - CloudFormation full access (for CDK)
71
+ - Or skip Route53 in CDK and manually create the A record in AWS Console
72
+
73
+ ### Deployment Sequence
74
+
75
+ ```bash
76
+ # 1. One-time setup
77
+ npm install -g aws-cdk
78
+ cd C:\Users\sharo\altfinance_monitoring_console\infra
79
+ pip install -r requirements.txt
80
+ cdk bootstrap aws://766784195791/us-east-1
81
+
82
+ # 2. Deploy infrastructure
83
+ cdk deploy AltFinanceApiStack
84
+
85
+ # 3. Build and push Docker image
86
+ python scripts/deploy.py
87
+
88
+ # 4. Verify
89
+ curl https://api.altfndata.com/v1/health
90
+
91
+ # 5. Provision beta user keys
92
+ python scripts/provision_key.py "Acme Capital" --tier standard --add
93
+ python scripts/deploy.py # Redeploy with new keys baked in
94
+
95
+ # 6. Publish MCP to PyPI
96
+ python scripts/publish_mcp.py
97
+
98
+ # 7. Send QUICKSTART.md + API key to beta users
99
+ ```
100
+
101
+ ### Phase 2 Items (not started)
102
+
103
+ - Stripe billing integration
104
+ - DynamoDB for API key storage (no more baking keys into container)
105
+ - DynamoDB for quota persistence (currently in-memory, resets on restart)
106
+ - Self-service portal on `app.altfndata.com`
107
+ - MCP directory listings (PulseMCP, awesome-mcp-servers, Anthropic registry)
108
+ - Test suite for API and MCP server
@@ -0,0 +1,21 @@
1
+ FROM public.ecr.aws/docker/library/python:3.12-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # Install dependencies first for layer caching
6
+ COPY pyproject.toml README.md ./
7
+ COPY src/ ./src/
8
+ RUN pip install --no-cache-dir .
9
+
10
+ # Non-root user for security
11
+ RUN adduser --disabled-password --no-create-home appuser
12
+ USER appuser
13
+
14
+ # Default to remote MCP mode
15
+ ENV ALTFINANCE_TRANSPORT=streamable-http
16
+ ENV ALTFINANCE_HOST=0.0.0.0
17
+ ENV ALTFINANCE_PORT=8000
18
+
19
+ EXPOSE 8000
20
+
21
+ CMD ["python", "-m", "altfinance_mcp"]
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AltFinance Data
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.