avanza-mcp 1.1.0__py3-none-any.whl → 1.3.0__py3-none-any.whl
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.
- avanza_mcp/__init__.py +3 -1
- avanza_mcp/client/endpoints.py +28 -0
- avanza_mcp/models/__init__.py +87 -7
- avanza_mcp/models/certificate.py +87 -0
- avanza_mcp/models/chart.py +51 -0
- avanza_mcp/models/common.py +15 -0
- avanza_mcp/models/etf.py +92 -0
- avanza_mcp/models/filter.py +51 -0
- avanza_mcp/models/future_forward.py +63 -0
- avanza_mcp/models/instrument_data.py +26 -0
- avanza_mcp/models/warrant.py +88 -0
- avanza_mcp/prompts/__init__.py +2 -1
- avanza_mcp/prompts/workflows.py +488 -0
- avanza_mcp/resources/__init__.py +2 -1
- avanza_mcp/resources/usage.py +503 -0
- avanza_mcp/services/market_data_service.py +313 -0
- avanza_mcp/tools/__init__.py +15 -1
- avanza_mcp/tools/certificates.py +156 -0
- avanza_mcp/tools/etfs.py +151 -0
- avanza_mcp/tools/futures_forwards.py +174 -0
- avanza_mcp/tools/instrument_data.py +135 -0
- avanza_mcp/tools/warrants.py +139 -0
- {avanza_mcp-1.1.0.dist-info → avanza_mcp-1.3.0.dist-info}/METADATA +56 -1
- avanza_mcp-1.3.0.dist-info/RECORD +40 -0
- avanza_mcp-1.1.0.dist-info/RECORD +0 -26
- {avanza_mcp-1.1.0.dist-info → avanza_mcp-1.3.0.dist-info}/WHEEL +0 -0
- {avanza_mcp-1.1.0.dist-info → avanza_mcp-1.3.0.dist-info}/entry_points.txt +0 -0
- {avanza_mcp-1.1.0.dist-info → avanza_mcp-1.3.0.dist-info}/licenses/LICENSE.md +0 -0
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
"""Usage guide resources for AI callers."""
|
|
2
|
+
|
|
3
|
+
from .. import mcp
|
|
4
|
+
|
|
5
|
+
USAGE_GUIDE = """# Avanza MCP Server - Usage Guide for AI Assistants
|
|
6
|
+
|
|
7
|
+
## 🎯 Critical: When NOT to Use MCP Tools
|
|
8
|
+
|
|
9
|
+
### MCP Tools Are For Interactive Exploration, NOT Bulk Data Processing
|
|
10
|
+
|
|
11
|
+
**Use MCP tools for**:
|
|
12
|
+
- ✅ Single instrument lookups (1-5 items)
|
|
13
|
+
- ✅ Small comparisons (2-10 instruments)
|
|
14
|
+
- ✅ Quick searches and exploration
|
|
15
|
+
- ✅ Interactive data analysis
|
|
16
|
+
|
|
17
|
+
**DO NOT use MCP tools for**:
|
|
18
|
+
- ❌ Fetching data for 50+ instruments
|
|
19
|
+
- ❌ Bulk screening operations
|
|
20
|
+
- ❌ Large-scale data analysis
|
|
21
|
+
- ❌ Building datasets
|
|
22
|
+
|
|
23
|
+
## 📏 The Threshold Rule
|
|
24
|
+
|
|
25
|
+
| Number of Items | Action |
|
|
26
|
+
|----------------|---------|
|
|
27
|
+
| 1-20 items | Use MCP tools directly |
|
|
28
|
+
| 20-50 items | Ask user if they want to continue with tools OR get a script |
|
|
29
|
+
| 50+ items | **DO NOT USE MCP TOOLS** - Provide a script instead |
|
|
30
|
+
|
|
31
|
+
## 🚫 Common Anti-Pattern (DON'T DO THIS)
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
User: "Analyze the top 100 Swedish stocks"
|
|
35
|
+
|
|
36
|
+
❌ BAD Response:
|
|
37
|
+
for stock_id in top_100_stocks:
|
|
38
|
+
get_stock_info(stock_id) # This will make 100 MCP calls!
|
|
39
|
+
get_stock_chart(stock_id) # Another 100 calls!
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Problem**: This creates 200+ MCP tool calls, which is:
|
|
43
|
+
- Slow and inefficient
|
|
44
|
+
- Overloads the MCP connection
|
|
45
|
+
- Not what MCP tools are designed for
|
|
46
|
+
|
|
47
|
+
## ✅ Correct Approach for Large Data Fetching
|
|
48
|
+
|
|
49
|
+
### Option 1: Provide a Python Script
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
User: "Analyze the top 100 Swedish stocks"
|
|
53
|
+
|
|
54
|
+
✅ GOOD Response:
|
|
55
|
+
"For analyzing 100 stocks, you should fetch the data directly using a script
|
|
56
|
+
rather than MCP tools. Here's a Python script you can run:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
import httpx
|
|
60
|
+
import asyncio
|
|
61
|
+
import json
|
|
62
|
+
|
|
63
|
+
async def fetch_stock_info(client, stock_id):
|
|
64
|
+
url = f"https://www.avanza.se/_api/market-guide/stock/{stock_id}"
|
|
65
|
+
response = await client.get(url)
|
|
66
|
+
return response.json()
|
|
67
|
+
|
|
68
|
+
async def main():
|
|
69
|
+
stock_ids = ["5247", "5361", ...] # Your 100 stock IDs
|
|
70
|
+
|
|
71
|
+
async with httpx.AsyncClient() as client:
|
|
72
|
+
tasks = [fetch_stock_info(client, sid) for sid in stock_ids]
|
|
73
|
+
results = await asyncio.gather(*tasks)
|
|
74
|
+
|
|
75
|
+
# Save to file
|
|
76
|
+
with open('stocks_data.json', 'w') as f:
|
|
77
|
+
json.dump(results, f, indent=2)
|
|
78
|
+
|
|
79
|
+
print(f"Fetched {len(results)} stocks")
|
|
80
|
+
|
|
81
|
+
asyncio.run(main())
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
This will efficiently fetch all 100 stocks in parallel and save to a JSON file."
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Option 2: Provide curl Commands
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
User: "Get data for 50 certificates"
|
|
91
|
+
|
|
92
|
+
✅ GOOD Response:
|
|
93
|
+
"For fetching 50 certificates, use the filter endpoint directly with a script:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Get all certificates at once with pagination
|
|
97
|
+
curl 'https://www.avanza.se/_api/market-certificate-filter/' \\
|
|
98
|
+
-H 'Content-Type: application/json' \\
|
|
99
|
+
--data-raw '{
|
|
100
|
+
"filter": {},
|
|
101
|
+
"offset": 0,
|
|
102
|
+
"limit": 50,
|
|
103
|
+
"sortBy": {"field": "name", "order": "asc"}
|
|
104
|
+
}' > certificates.json
|
|
105
|
+
|
|
106
|
+
# For more than 50, fetch next page:
|
|
107
|
+
curl 'https://www.avanza.se/_api/market-certificate-filter/' \\
|
|
108
|
+
-H 'Content-Type: application/json' \\
|
|
109
|
+
--data-raw '{
|
|
110
|
+
"filter": {},
|
|
111
|
+
"offset": 50,
|
|
112
|
+
"limit": 50,
|
|
113
|
+
"sortBy": {"field": "name", "order": "asc"}
|
|
114
|
+
}' >> certificates.json
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
This fetches the data directly from Avanza's public API."
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Option 3: Provide a Shell Script for Multiple Items
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
User: "Get stock info for these 100 companies"
|
|
124
|
+
|
|
125
|
+
✅ GOOD Response:
|
|
126
|
+
"Here's a shell script to fetch data for all 100 stocks:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
#!/bin/bash
|
|
130
|
+
|
|
131
|
+
# Array of stock IDs
|
|
132
|
+
stock_ids=(5247 5361 5239 ...) # All 100 IDs
|
|
133
|
+
|
|
134
|
+
# Create output directory
|
|
135
|
+
mkdir -p stock_data
|
|
136
|
+
|
|
137
|
+
# Fetch each stock
|
|
138
|
+
for id in "${stock_ids[@]}"; do
|
|
139
|
+
echo "Fetching stock $id..."
|
|
140
|
+
curl -s "https://www.avanza.se/_api/market-guide/stock/$id" \\
|
|
141
|
+
> "stock_data/stock_$id.json"
|
|
142
|
+
sleep 0.5 # Be nice to the API
|
|
143
|
+
done
|
|
144
|
+
|
|
145
|
+
echo "Done! Data saved in stock_data/"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Run with: `chmod +x fetch_stocks.sh && ./fetch_stocks.sh`"
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## 📋 API Endpoint Reference (For Script Writing)
|
|
152
|
+
|
|
153
|
+
When instructing users to write scripts, these are the public endpoints:
|
|
154
|
+
|
|
155
|
+
### Search & Discovery
|
|
156
|
+
```bash
|
|
157
|
+
# Search instruments
|
|
158
|
+
curl 'https://www.avanza.se/_api/search/filtered-search' \\
|
|
159
|
+
-H 'Content-Type: application/json' \\
|
|
160
|
+
--data-raw '{"query": "Tesla", "instrumentTypes": ["STOCK"]}'
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Stock Data
|
|
164
|
+
```bash
|
|
165
|
+
# Stock info
|
|
166
|
+
curl 'https://www.avanza.se/_api/market-guide/stock/{id}'
|
|
167
|
+
|
|
168
|
+
# Stock quote
|
|
169
|
+
curl 'https://www.avanza.se/_api/market-guide/stock/{id}/quote'
|
|
170
|
+
|
|
171
|
+
# Stock chart
|
|
172
|
+
curl 'https://www.avanza.se/_api/price-chart/stock/{id}?timePeriod=one_month'
|
|
173
|
+
|
|
174
|
+
# Order book
|
|
175
|
+
curl 'https://www.avanza.se/_api/market-guide/stock/{id}/orderdepth'
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Filter Endpoints (Bulk Operations)
|
|
179
|
+
```bash
|
|
180
|
+
# Filter certificates (POST request)
|
|
181
|
+
curl 'https://www.avanza.se/_api/market-certificate-filter/' \\
|
|
182
|
+
-H 'Content-Type: application/json' \\
|
|
183
|
+
--data-raw '{
|
|
184
|
+
"filter": {"directions": ["long"]},
|
|
185
|
+
"offset": 0,
|
|
186
|
+
"limit": 100,
|
|
187
|
+
"sortBy": {"field": "name", "order": "asc"}
|
|
188
|
+
}'
|
|
189
|
+
|
|
190
|
+
# Filter ETFs (POST request)
|
|
191
|
+
curl 'https://www.avanza.se/_api/market-etf-filter/' \\
|
|
192
|
+
-H 'Content-Type: application/json' \\
|
|
193
|
+
--data-raw '{
|
|
194
|
+
"filter": {"exposures": ["usa"]},
|
|
195
|
+
"offset": 0,
|
|
196
|
+
"limit": 100,
|
|
197
|
+
"sortBy": {"field": "managementFee", "order": "asc"}
|
|
198
|
+
}'
|
|
199
|
+
|
|
200
|
+
# Filter warrants (POST request)
|
|
201
|
+
curl 'https://www.avanza.se/_api/market-warrant-filter/' \\
|
|
202
|
+
-H 'Content-Type: application/json' \\
|
|
203
|
+
--data-raw '{
|
|
204
|
+
"filter": {"subTypes": ["TURBO"]},
|
|
205
|
+
"offset": 0,
|
|
206
|
+
"limit": 100,
|
|
207
|
+
"sortBy": {"field": "name", "order": "asc"}
|
|
208
|
+
}'
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Fund Data
|
|
212
|
+
```bash
|
|
213
|
+
# Fund info
|
|
214
|
+
curl 'https://www.avanza.se/_api/fund-guide/guide/{id}'
|
|
215
|
+
|
|
216
|
+
# Fund chart
|
|
217
|
+
curl 'https://www.avanza.se/_api/fund-guide/chart/{id}/three_years'
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## 🔄 Decision Tree: Tool vs Script
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
User request → Count number of items needed
|
|
224
|
+
│
|
|
225
|
+
├─ 1-20 items? → Use MCP tools directly
|
|
226
|
+
│
|
|
227
|
+
├─ 20-50 items? → Ask user:
|
|
228
|
+
│ "This will require ~{count} API calls. Would you like me to:
|
|
229
|
+
│ 1. Proceed with MCP tools (slower, interactive)
|
|
230
|
+
│ 2. Provide a script for you to run (faster, bulk)"
|
|
231
|
+
│
|
|
232
|
+
└─ 50+ items? → ALWAYS provide script
|
|
233
|
+
│
|
|
234
|
+
├─ User is technical? → Python script with async
|
|
235
|
+
├─ User wants simple? → Bash script with curl
|
|
236
|
+
└─ User wants data file? → curl command + jq
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## 🎓 Examples of Correct Responses
|
|
240
|
+
|
|
241
|
+
### Example 1: Small Request (Use Tools)
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
User: "What's the current price of Volvo?"
|
|
245
|
+
|
|
246
|
+
✅ Response:
|
|
247
|
+
search_instruments(query="Volvo B", instrument_types=["STOCK"])
|
|
248
|
+
get_stock_quote(instrument_id="5247")
|
|
249
|
+
"Volvo B is currently trading at 265.40 SEK, up 1.2%"
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Example 2: Medium Request (Ask User)
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
User: "Compare these 30 ETFs"
|
|
256
|
+
|
|
257
|
+
✅ Response:
|
|
258
|
+
"Comparing 30 ETFs will require approximately 60 API calls through MCP tools.
|
|
259
|
+
I have two options for you:
|
|
260
|
+
|
|
261
|
+
1. **Use MCP Tools** (slower, ~2-3 minutes):
|
|
262
|
+
I'll fetch each ETF's data interactively. Good if you want to explore
|
|
263
|
+
the data step-by-step.
|
|
264
|
+
|
|
265
|
+
2. **Provide a Script** (faster, ~30 seconds):
|
|
266
|
+
I'll give you a Python script that fetches all 30 ETFs in parallel,
|
|
267
|
+
saves to JSON, and you can analyze the results.
|
|
268
|
+
|
|
269
|
+
Which would you prefer?"
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Example 3: Large Request (Provide Script)
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
User: "Analyze all Swedish stocks with market cap > 1B SEK"
|
|
276
|
+
|
|
277
|
+
✅ Response:
|
|
278
|
+
"To analyze 100+ stocks efficiently, you should fetch the data directly
|
|
279
|
+
rather than using MCP tools. Here's a Python script:
|
|
280
|
+
|
|
281
|
+
```python
|
|
282
|
+
import httpx
|
|
283
|
+
import asyncio
|
|
284
|
+
import pandas as pd
|
|
285
|
+
|
|
286
|
+
async def fetch_stock(client, stock_id):
|
|
287
|
+
try:
|
|
288
|
+
response = await client.get(
|
|
289
|
+
f"https://www.avanza.se/_api/market-guide/stock/{stock_id}"
|
|
290
|
+
)
|
|
291
|
+
return response.json()
|
|
292
|
+
except Exception as e:
|
|
293
|
+
print(f"Error fetching {stock_id}: {e}")
|
|
294
|
+
return None
|
|
295
|
+
|
|
296
|
+
async def main():
|
|
297
|
+
# First, get Swedish stock IDs (you'd need to search or have a list)
|
|
298
|
+
stock_ids = [...] # Your list of stock IDs
|
|
299
|
+
|
|
300
|
+
async with httpx.AsyncClient(timeout=30.0) as client:
|
|
301
|
+
tasks = [fetch_stock(client, sid) for sid in stock_ids]
|
|
302
|
+
results = await asyncio.gather(*tasks)
|
|
303
|
+
|
|
304
|
+
# Filter for market cap > 1B
|
|
305
|
+
large_caps = [
|
|
306
|
+
s for s in results
|
|
307
|
+
if s and s.get('company', {}).get('marketCapital', 0) > 1_000_000_000
|
|
308
|
+
]
|
|
309
|
+
|
|
310
|
+
# Convert to DataFrame for analysis
|
|
311
|
+
df = pd.DataFrame([{
|
|
312
|
+
'name': s['name'],
|
|
313
|
+
'price': s['quote']['last'],
|
|
314
|
+
'market_cap': s['company']['marketCapital'],
|
|
315
|
+
'pe_ratio': s.get('keyIndicators', {}).get('priceEarningsRatio'),
|
|
316
|
+
} for s in large_caps])
|
|
317
|
+
|
|
318
|
+
df.to_csv('large_cap_stocks.csv', index=False)
|
|
319
|
+
print(f"Analyzed {len(large_caps)} large-cap stocks")
|
|
320
|
+
print(df.head())
|
|
321
|
+
|
|
322
|
+
asyncio.run(main())
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Save this as `analyze_stocks.py` and run with:
|
|
326
|
+
```bash
|
|
327
|
+
pip install httpx pandas
|
|
328
|
+
python analyze_stocks.py
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
After running this, I can help you analyze the results in `large_cap_stocks.csv`."
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## 💡 Key Principles
|
|
335
|
+
|
|
336
|
+
1. **MCP tools = Interactive exploration** (1-20 items)
|
|
337
|
+
2. **Scripts = Bulk data processing** (50+ items)
|
|
338
|
+
3. **Always explain why** you're recommending a script over tools
|
|
339
|
+
4. **Provide working code** that users can run immediately
|
|
340
|
+
5. **Include error handling** in scripts (timeouts, retries)
|
|
341
|
+
6. **Be nice to the API** (rate limiting, delays)
|
|
342
|
+
|
|
343
|
+
## 🚀 Script Templates You Can Use
|
|
344
|
+
|
|
345
|
+
### Python: Async Bulk Fetcher
|
|
346
|
+
```python
|
|
347
|
+
import httpx
|
|
348
|
+
import asyncio
|
|
349
|
+
|
|
350
|
+
async def fetch_data(url):
|
|
351
|
+
async with httpx.AsyncClient() as client:
|
|
352
|
+
response = await client.get(url, timeout=30.0)
|
|
353
|
+
return response.json()
|
|
354
|
+
|
|
355
|
+
async def bulk_fetch(urls):
|
|
356
|
+
tasks = [fetch_data(url) for url in urls]
|
|
357
|
+
return await asyncio.gather(*tasks, return_exceptions=True)
|
|
358
|
+
|
|
359
|
+
# Usage
|
|
360
|
+
urls = [f"https://www.avanza.se/_api/market-guide/stock/{i}" for i in stock_ids]
|
|
361
|
+
results = asyncio.run(bulk_fetch(urls))
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Bash: Simple Sequential Fetcher
|
|
365
|
+
```bash
|
|
366
|
+
#!/bin/bash
|
|
367
|
+
for id in $(cat stock_ids.txt); do
|
|
368
|
+
curl -s "https://www.avanza.se/_api/market-guide/stock/$id" \\
|
|
369
|
+
> "data/stock_$id.json"
|
|
370
|
+
sleep 0.5
|
|
371
|
+
done
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### curl + jq: Filter and Extract
|
|
375
|
+
```bash
|
|
376
|
+
# Fetch and extract just the fields you need
|
|
377
|
+
curl -s 'https://www.avanza.se/_api/market-certificate-filter/' \\
|
|
378
|
+
-H 'Content-Type: application/json' \\
|
|
379
|
+
--data-raw '{"filter":{},"offset":0,"limit":100,"sortBy":{"field":"name","order":"asc"}}' \\
|
|
380
|
+
| jq '.certificates[] | {name, orderbookId, leverage, direction}'
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## ⚠️ Important Reminders
|
|
384
|
+
|
|
385
|
+
- **No authentication required** - All endpoints shown are public
|
|
386
|
+
- **Rate limiting** - Add delays (0.5-1s) between requests in loops
|
|
387
|
+
- **Timeout handling** - Use appropriate timeouts (10-30s)
|
|
388
|
+
- **Error handling** - Check for HTTP errors and null responses
|
|
389
|
+
- **Respect the API** - Don't hammer the servers with concurrent requests
|
|
390
|
+
|
|
391
|
+
## 📊 Summary
|
|
392
|
+
|
|
393
|
+
| Scenario | Items | Action |
|
|
394
|
+
|----------|-------|--------|
|
|
395
|
+
| Quick lookup | 1-5 | Use MCP tools |
|
|
396
|
+
| Comparison | 5-20 | Use MCP tools |
|
|
397
|
+
| Small screening | 20-50 | Ask user preference |
|
|
398
|
+
| Bulk screening | 50-200 | Provide script |
|
|
399
|
+
| Large analysis | 200+ | Provide script + pagination guide |
|
|
400
|
+
|
|
401
|
+
**Golden Rule**: If you're thinking about calling the same tool in a loop more than 20 times, provide a script instead.
|
|
402
|
+
"""
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
@mcp.resource("avanza://docs/usage")
|
|
406
|
+
async def get_usage_guide() -> str:
|
|
407
|
+
"""Get comprehensive usage guide for AI assistants.
|
|
408
|
+
|
|
409
|
+
URI: avanza://docs/usage
|
|
410
|
+
|
|
411
|
+
This resource provides critical guidance on:
|
|
412
|
+
- When to use MCP tools (small, interactive queries)
|
|
413
|
+
- When to provide scripts instead (bulk data fetching)
|
|
414
|
+
- How to write curl commands and Python scripts for users
|
|
415
|
+
- API endpoint reference for script writing
|
|
416
|
+
|
|
417
|
+
Returns:
|
|
418
|
+
Markdown-formatted usage guide
|
|
419
|
+
"""
|
|
420
|
+
return USAGE_GUIDE
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
@mcp.resource("avanza://docs/quick-start")
|
|
424
|
+
async def get_quick_start() -> str:
|
|
425
|
+
"""Get quick start guide focused on tool vs script decision.
|
|
426
|
+
|
|
427
|
+
URI: avanza://docs/quick-start
|
|
428
|
+
|
|
429
|
+
Returns:
|
|
430
|
+
Quick reference guide
|
|
431
|
+
"""
|
|
432
|
+
return """# Avanza MCP - Quick Decision Guide
|
|
433
|
+
|
|
434
|
+
## 🚦 When to Use What
|
|
435
|
+
|
|
436
|
+
### Use MCP Tools (✅)
|
|
437
|
+
- Single lookups: "What's Tesla's price?"
|
|
438
|
+
- Small comparisons: "Compare these 5 funds"
|
|
439
|
+
- Quick exploration: "Find ETFs with USA exposure"
|
|
440
|
+
- Interactive analysis: Step-by-step investigation
|
|
441
|
+
|
|
442
|
+
### Provide Script (📝)
|
|
443
|
+
- Bulk operations: "Analyze 100 stocks"
|
|
444
|
+
- Large screenings: "Get all certificates"
|
|
445
|
+
- Dataset building: "Fetch all Swedish funds"
|
|
446
|
+
- Repeated operations: "Daily price monitoring"
|
|
447
|
+
|
|
448
|
+
## 📏 The Rule
|
|
449
|
+
|
|
450
|
+
```
|
|
451
|
+
if items > 50:
|
|
452
|
+
provide_script()
|
|
453
|
+
elif items > 20:
|
|
454
|
+
ask_user_preference()
|
|
455
|
+
else:
|
|
456
|
+
use_mcp_tools()
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
## 🔧 Quick Script Templates
|
|
460
|
+
|
|
461
|
+
### Fetch Multiple Stocks (Python)
|
|
462
|
+
```python
|
|
463
|
+
import httpx
|
|
464
|
+
import asyncio
|
|
465
|
+
|
|
466
|
+
async def main():
|
|
467
|
+
stock_ids = ["5247", "5361", ...]
|
|
468
|
+
async with httpx.AsyncClient() as client:
|
|
469
|
+
for sid in stock_ids:
|
|
470
|
+
r = await client.get(f"https://www.avanza.se/_api/market-guide/stock/{sid}")
|
|
471
|
+
print(r.json()['name'], r.json()['quote']['last'])
|
|
472
|
+
|
|
473
|
+
asyncio.run(main())
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### Bulk Filter (curl)
|
|
477
|
+
```bash
|
|
478
|
+
curl 'https://www.avanza.se/_api/market-etf-filter/' \\
|
|
479
|
+
-H 'Content-Type: application/json' \\
|
|
480
|
+
--data-raw '{"filter":{},"offset":0,"limit":100,"sortBy":{"field":"name","order":"asc"}}'
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
## 💭 Example Responses
|
|
484
|
+
|
|
485
|
+
**User**: "Check Volvo stock"
|
|
486
|
+
**You**: ✅ Use `get_stock_quote("5247")`
|
|
487
|
+
|
|
488
|
+
**User**: "Compare 10 funds"
|
|
489
|
+
**You**: ✅ Use `get_fund_info()` for each
|
|
490
|
+
|
|
491
|
+
**User**: "Analyze 80 Swedish stocks"
|
|
492
|
+
**You**: 📝 "Here's a Python script to fetch all 80 stocks..."
|
|
493
|
+
|
|
494
|
+
**User**: "Screen all ETFs"
|
|
495
|
+
**You**: 📝 "Here's a curl command using filter_etfs endpoint..."
|
|
496
|
+
|
|
497
|
+
## 🎯 Remember
|
|
498
|
+
|
|
499
|
+
MCP = Interactive exploration (1-20 items)
|
|
500
|
+
Script = Bulk processing (50+ items)
|
|
501
|
+
|
|
502
|
+
Read full guide: `avanza://docs/usage`
|
|
503
|
+
"""
|