avanza-mcp 1.0.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.
- avanza_mcp-1.0.0/.github/PUBLISHING.md +58 -0
- avanza_mcp-1.0.0/.github/workflows/ci.yml +40 -0
- avanza_mcp-1.0.0/.github/workflows/publish.yml +34 -0
- avanza_mcp-1.0.0/.gitignore +13 -0
- avanza_mcp-1.0.0/.python-version +1 -0
- avanza_mcp-1.0.0/CLAUDE.md +123 -0
- avanza_mcp-1.0.0/DEVELOPMENT.md +125 -0
- avanza_mcp-1.0.0/LICENSE.md +21 -0
- avanza_mcp-1.0.0/PKG-INFO +99 -0
- avanza_mcp-1.0.0/README.md +83 -0
- avanza_mcp-1.0.0/justfile +81 -0
- avanza_mcp-1.0.0/pyproject.toml +40 -0
- avanza_mcp-1.0.0/src/avanza_mcp/__init__.py +29 -0
- avanza_mcp-1.0.0/src/avanza_mcp/client/__init__.py +25 -0
- avanza_mcp-1.0.0/src/avanza_mcp/client/base.py +375 -0
- avanza_mcp-1.0.0/src/avanza_mcp/client/endpoints.py +41 -0
- avanza_mcp-1.0.0/src/avanza_mcp/client/exceptions.py +66 -0
- avanza_mcp-1.0.0/src/avanza_mcp/models/__init__.py +41 -0
- avanza_mcp-1.0.0/src/avanza_mcp/models/common.py +50 -0
- avanza_mcp-1.0.0/src/avanza_mcp/models/fund.py +246 -0
- avanza_mcp-1.0.0/src/avanza_mcp/models/search.py +123 -0
- avanza_mcp-1.0.0/src/avanza_mcp/models/stock.py +268 -0
- avanza_mcp-1.0.0/src/avanza_mcp/prompts/__init__.py +6 -0
- avanza_mcp-1.0.0/src/avanza_mcp/prompts/analysis.py +116 -0
- avanza_mcp-1.0.0/src/avanza_mcp/resources/__init__.py +6 -0
- avanza_mcp-1.0.0/src/avanza_mcp/resources/instruments.py +127 -0
- avanza_mcp-1.0.0/src/avanza_mcp/services/__init__.py +6 -0
- avanza_mcp-1.0.0/src/avanza_mcp/services/market_data_service.py +298 -0
- avanza_mcp-1.0.0/src/avanza_mcp/services/search_service.py +64 -0
- avanza_mcp-1.0.0/src/avanza_mcp/tools/__init__.py +8 -0
- avanza_mcp-1.0.0/src/avanza_mcp/tools/funds.py +267 -0
- avanza_mcp-1.0.0/src/avanza_mcp/tools/market_data.py +508 -0
- avanza_mcp-1.0.0/src/avanza_mcp/tools/search.py +119 -0
- avanza_mcp-1.0.0/tests/__init__.py +1 -0
- avanza_mcp-1.0.0/tests/conftest.py +17 -0
- avanza_mcp-1.0.0/tests/integration/__init__.py +1 -0
- avanza_mcp-1.0.0/tests/integration/test_tools.py +270 -0
- avanza_mcp-1.0.0/tests/unit/__init__.py +1 -0
- avanza_mcp-1.0.0/tests/unit/test_client.py +225 -0
- avanza_mcp-1.0.0/tests/unit/test_models.py +344 -0
- avanza_mcp-1.0.0/uv.lock +1372 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Publishing to PyPI
|
|
2
|
+
|
|
3
|
+
## Setup (One-time)
|
|
4
|
+
|
|
5
|
+
### 1. Configure PyPI Trusted Publishing
|
|
6
|
+
|
|
7
|
+
1. Go to https://pypi.org/manage/account/publishing/
|
|
8
|
+
2. Add a new publisher:
|
|
9
|
+
- **PyPI Project Name**: `avanza-mcp`
|
|
10
|
+
- **Owner**: `antewall`
|
|
11
|
+
- **Repository**: `avanza-mcp`
|
|
12
|
+
- **Workflow**: `publish.yml`
|
|
13
|
+
- **Environment**: `pypi`
|
|
14
|
+
|
|
15
|
+
### 2. Create GitHub Environment
|
|
16
|
+
|
|
17
|
+
1. Go to repository Settings → Environments
|
|
18
|
+
2. Create environment: `pypi`
|
|
19
|
+
|
|
20
|
+
## Publishing a Release
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Patch release (1.0.0 -> 1.0.1)
|
|
24
|
+
just release-patch
|
|
25
|
+
|
|
26
|
+
# Minor release (1.0.0 -> 1.1.0)
|
|
27
|
+
just release-minor
|
|
28
|
+
|
|
29
|
+
# Major release (1.0.0 -> 2.0.0)
|
|
30
|
+
just release-major
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This will:
|
|
34
|
+
1. Bump `__version__` in `src/avanza_mcp/__init__.py`
|
|
35
|
+
2. Commit changes
|
|
36
|
+
3. Create and push git tag
|
|
37
|
+
4. Trigger CI to build and publish to PyPI
|
|
38
|
+
|
|
39
|
+
## Version Management
|
|
40
|
+
|
|
41
|
+
Version is defined in **one place**: `src/avanza_mcp/__init__.py`
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
__version__ = "1.0.0"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
All other files read from this:
|
|
48
|
+
- `pyproject.toml` uses dynamic versioning
|
|
49
|
+
- `src/avanza_mcp/client/base.py` imports and uses `__version__`
|
|
50
|
+
|
|
51
|
+
## CI Workflow
|
|
52
|
+
|
|
53
|
+
GitHub Actions automatically:
|
|
54
|
+
1. Installs uv
|
|
55
|
+
2. Builds package with `uv build`
|
|
56
|
+
3. Publishes to PyPI with `uv publish` (using trusted publishing)
|
|
57
|
+
|
|
58
|
+
Monitor at: https://github.com/antewall/avanza-mcp/actions
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master, main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master, main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Test on Python ${{ matrix.python-version }}
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.12", "3.13"]
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python-version }}
|
|
23
|
+
|
|
24
|
+
- name: Install uv
|
|
25
|
+
uses: astral-sh/setup-uv@v4
|
|
26
|
+
with:
|
|
27
|
+
enable-cache: true
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: uv sync --all-extras
|
|
31
|
+
|
|
32
|
+
- name: Verify imports
|
|
33
|
+
run: uv run python -c "from avanza_mcp import mcp; print('✓ Import successful')"
|
|
34
|
+
|
|
35
|
+
- name: Build package
|
|
36
|
+
run: uv build
|
|
37
|
+
|
|
38
|
+
- name: Check package
|
|
39
|
+
run: |
|
|
40
|
+
uv tool run twine check dist/*
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Build and Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
publish:
|
|
14
|
+
name: Build and publish to PyPI
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
environment:
|
|
17
|
+
name: pypi
|
|
18
|
+
url: https://pypi.org/p/avanza-mcp
|
|
19
|
+
permissions:
|
|
20
|
+
id-token: write
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- name: Install uv
|
|
25
|
+
uses: astral-sh/setup-uv@v4
|
|
26
|
+
|
|
27
|
+
- name: Set up Python
|
|
28
|
+
run: uv python install 3.12
|
|
29
|
+
|
|
30
|
+
- name: Build package
|
|
31
|
+
run: uv build
|
|
32
|
+
|
|
33
|
+
- name: Publish to PyPI
|
|
34
|
+
run: uv publish
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Persona
|
|
6
|
+
|
|
7
|
+
You are a senior Python developer with deep expertise in MCP (Model Context Protocol) and the FastMCP framework. You write clean, idiomatic Python code following modern best practices. You understand async patterns, type hints, and API design principles.
|
|
8
|
+
|
|
9
|
+
## FastMCP Documentation
|
|
10
|
+
|
|
11
|
+
For comprehensive FastMCP documentation, reference: https://gofastmcp.com/llms-full.txt
|
|
12
|
+
|
|
13
|
+
Key FastMCP concepts:
|
|
14
|
+
- **Tools**: Functions exposed to LLMs via `@mcp.tool` decorator
|
|
15
|
+
- **Resources**: Data exposed via `@mcp.resource` decorator
|
|
16
|
+
- **Prompts**: Reusable prompt templates via `@mcp.prompt` decorator
|
|
17
|
+
- **Context**: Access request context via `Context` parameter for logging, progress, and state
|
|
18
|
+
- **Client**: `fastmcp.Client` for connecting to MCP servers programmatically
|
|
19
|
+
|
|
20
|
+
## Project Overview
|
|
21
|
+
|
|
22
|
+
This is an MCP (Model Context Protocol) server for Avanza built with FastMCP 3.0.0b1 and Python 3.12. It provides 18 tools for accessing Swedish market data (stocks, funds) without authentication.
|
|
23
|
+
|
|
24
|
+
## Commands
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Install dependencies (uses uv)
|
|
28
|
+
uv sync
|
|
29
|
+
|
|
30
|
+
# Install with dev dependencies (for testing)
|
|
31
|
+
uv sync --all-extras
|
|
32
|
+
|
|
33
|
+
# Run the MCP server locally
|
|
34
|
+
uv run avanza-mcp
|
|
35
|
+
|
|
36
|
+
# Run all tests
|
|
37
|
+
uv run pytest tests/
|
|
38
|
+
|
|
39
|
+
# Run unit tests only (fast, mocked)
|
|
40
|
+
uv run pytest tests/unit -v
|
|
41
|
+
|
|
42
|
+
# Run integration tests (hits real API)
|
|
43
|
+
uv run pytest tests/integration -v
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Installation for MCP Clients
|
|
47
|
+
|
|
48
|
+
For Claude Desktop or other MCP clients, add to your MCP config:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"mcpServers": {
|
|
53
|
+
"avanza": {
|
|
54
|
+
"command": "uvx",
|
|
55
|
+
"args": ["avanza-mcp"]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Architecture
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
src/avanza_mcp/
|
|
65
|
+
├── __init__.py # FastMCP server instance, entry point
|
|
66
|
+
├── client/
|
|
67
|
+
│ ├── base.py # Async httpx client with retry logic & connection pooling
|
|
68
|
+
│ ├── endpoints.py # API endpoint URL definitions
|
|
69
|
+
│ └── exceptions.py # Custom exceptions (AvanzaAPIError, etc.)
|
|
70
|
+
├── services/
|
|
71
|
+
│ ├── market_data_service.py # Stock & fund data operations
|
|
72
|
+
│ └── search_service.py # Search operations
|
|
73
|
+
├── tools/
|
|
74
|
+
│ ├── market_data.py # Stock tools (get_stock_info, get_dividends, etc.)
|
|
75
|
+
│ ├── funds.py # Fund tools (get_fund_info, get_fund_holdings, etc.)
|
|
76
|
+
│ └── search.py # Search tools
|
|
77
|
+
├── models/
|
|
78
|
+
│ ├── stock.py # Stock Pydantic models (Quote, StockInfo, etc.)
|
|
79
|
+
│ ├── fund.py # Fund Pydantic models (FundInfo, FundSustainability, etc.)
|
|
80
|
+
│ ├── search.py # Search response models
|
|
81
|
+
│ └── common.py # Shared enums (InstrumentType, TimePeriod)
|
|
82
|
+
├── resources/ # MCP resources
|
|
83
|
+
└── prompts/ # MCP prompts
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Key Design Patterns
|
|
87
|
+
|
|
88
|
+
### HTTP Client with Retry
|
|
89
|
+
The client uses tenacity for automatic retries on transient failures:
|
|
90
|
+
- Retries on: timeouts, network errors, 5xx server errors
|
|
91
|
+
- Does NOT retry on: 4xx client errors (400, 404, etc.)
|
|
92
|
+
- Exponential backoff: 2-10 seconds between retries, max 3 attempts
|
|
93
|
+
|
|
94
|
+
### Pydantic Models
|
|
95
|
+
All models use consistent ConfigDict:
|
|
96
|
+
```python
|
|
97
|
+
MODEL_CONFIG = ConfigDict(
|
|
98
|
+
populate_by_name=True, # Support both camelCase and snake_case
|
|
99
|
+
str_strip_whitespace=True, # Clean string inputs
|
|
100
|
+
validate_assignment=True, # Validate on assignment
|
|
101
|
+
extra="allow", # Don't fail on unknown API fields
|
|
102
|
+
)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Tool Pattern
|
|
106
|
+
Tools follow this pattern:
|
|
107
|
+
```python
|
|
108
|
+
@mcp.tool()
|
|
109
|
+
async def get_something(ctx: Context, instrument_id: str) -> dict:
|
|
110
|
+
ctx.info(f"Fetching data for ID: {instrument_id}")
|
|
111
|
+
async with AvanzaClient() as client:
|
|
112
|
+
service = MarketDataService(client)
|
|
113
|
+
result = await service.get_something(instrument_id)
|
|
114
|
+
return result.model_dump(by_alias=True, exclude_none=True)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Available Tools
|
|
118
|
+
|
|
119
|
+
**Search:** search_instruments, get_instrument_by_order_book_id
|
|
120
|
+
|
|
121
|
+
**Stocks:** get_stock_info, get_stock_quote, get_stock_analysis, get_stock_chart, get_orderbook, get_marketplace_info, get_recent_trades, get_broker_trade_summary, get_dividends, get_company_financials
|
|
122
|
+
|
|
123
|
+
**Funds:** get_fund_info, get_fund_sustainability, get_fund_chart, get_fund_chart_periods, get_fund_description, get_fund_holdings
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Development Guide - Avanza MCP Server
|
|
2
|
+
|
|
3
|
+
This guide explains how to develop and test the Avanza MCP server locally, including integration with Claude Desktop.
|
|
4
|
+
|
|
5
|
+
## 🚀 Quick Start
|
|
6
|
+
|
|
7
|
+
### Prerequisites
|
|
8
|
+
|
|
9
|
+
- Python 3.12 or higher
|
|
10
|
+
- [uv](https://github.com/astral-sh/uv) package manager
|
|
11
|
+
- [Claude Desktop](https://claude.ai/download) (optional, for MCP testing)
|
|
12
|
+
|
|
13
|
+
### Initial Setup
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Clone the repository
|
|
17
|
+
git clone https://github.com/yourusername/avanza-mcp.git
|
|
18
|
+
cd avanza-mcp
|
|
19
|
+
|
|
20
|
+
# Install dependencies
|
|
21
|
+
uv sync
|
|
22
|
+
|
|
23
|
+
# Verify installation
|
|
24
|
+
uv run python -c "from avanza_mcp import mcp; print('✓ Import successful')"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Test with Claude Desktop
|
|
28
|
+
|
|
29
|
+
This is the **recommended way** to test the full MCP integration.
|
|
30
|
+
|
|
31
|
+
#### Step 1: Configure Claude Desktop for Local Development
|
|
32
|
+
|
|
33
|
+
Edit your Claude Desktop configuration file:
|
|
34
|
+
|
|
35
|
+
**Linux:** `~/.claude.json`
|
|
36
|
+
|
|
37
|
+
Add the local development configuration:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"mcpServers": {
|
|
42
|
+
"avanza-dev": {
|
|
43
|
+
"command": "uv",
|
|
44
|
+
"args": [
|
|
45
|
+
"--directory",
|
|
46
|
+
"/absolute/path/to/avanza-mcp",
|
|
47
|
+
"run",
|
|
48
|
+
"avanza-mcp"
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Replace `/absolute/path/to/avanza-mcp`** with your actual project path:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Get the absolute path
|
|
59
|
+
pwd
|
|
60
|
+
# Example: /Users/username/projects/avanza-mcp
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### Step 2: Restart Claude Desktop
|
|
64
|
+
|
|
65
|
+
1. Quit Claude Desktop completely
|
|
66
|
+
2. Start Claude Desktop again
|
|
67
|
+
3. The MCP server will be loaded automatically
|
|
68
|
+
|
|
69
|
+
#### Step 3: Verify Connection
|
|
70
|
+
|
|
71
|
+
In Claude Desktop, ask:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
Can you list the available MCP tools?
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
You should see all Avanza tools listed.
|
|
78
|
+
|
|
79
|
+
#### Step 4: Test Tools
|
|
80
|
+
|
|
81
|
+
Try these queries in Claude Desktop:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
# Search for stocks
|
|
85
|
+
Search for Volvo stock on Avanza
|
|
86
|
+
|
|
87
|
+
# Get stock quote
|
|
88
|
+
Get the current stock quote for Volvo B (ID: 5269)
|
|
89
|
+
|
|
90
|
+
# Get historical chart
|
|
91
|
+
Show me a 3-month price chart for Ericsson (ID: 5286)
|
|
92
|
+
|
|
93
|
+
# Get fund sustainability
|
|
94
|
+
What's the ESG score for Avanza Zero fund (ID: 41567)?
|
|
95
|
+
|
|
96
|
+
# Get order book
|
|
97
|
+
Show me the order book depth for H&M (ID: 5364)
|
|
98
|
+
|
|
99
|
+
# Get dividends (new)
|
|
100
|
+
What dividends has SEB paid over the years?
|
|
101
|
+
|
|
102
|
+
# Get fund holdings (new)
|
|
103
|
+
Show me the portfolio allocation for Avanza Global fund
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 🧪 Running Tests
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Install dev dependencies
|
|
110
|
+
uv sync --all-extras
|
|
111
|
+
|
|
112
|
+
# Run all tests
|
|
113
|
+
uv run pytest tests/
|
|
114
|
+
|
|
115
|
+
# Run unit tests only (fast, no API calls)
|
|
116
|
+
uv run pytest tests/unit -v
|
|
117
|
+
|
|
118
|
+
# Run integration tests (hits real API, use sparingly)
|
|
119
|
+
uv run pytest tests/integration -v --tb=short
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Test Coverage
|
|
123
|
+
|
|
124
|
+
- **Unit tests** (`tests/unit/`): Test client, models, and error handling with mocked responses
|
|
125
|
+
- **Integration tests** (`tests/integration/`): Test all 18 tools against the real Avanza API
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ante Wall
|
|
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.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: avanza-mcp
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: MCP server for Avanza public market data API - Swedish stocks, funds, and more
|
|
5
|
+
License-File: LICENSE.md
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Requires-Dist: fastmcp==3.0.0b1
|
|
8
|
+
Requires-Dist: httpx>=0.27.0
|
|
9
|
+
Requires-Dist: pydantic>=2.0.0
|
|
10
|
+
Requires-Dist: tenacity>=9.0.0
|
|
11
|
+
Provides-Extra: dev
|
|
12
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
13
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
14
|
+
Requires-Dist: respx>=0.21.0; extra == 'dev'
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# Avanza MCP Server
|
|
18
|
+
|
|
19
|
+
A Model Context Protocol (MCP) server providing access to Avanza's public API. Get real-time Swedish stock quotes, fund information, charts, and comprehensive market data.
|
|
20
|
+
|
|
21
|
+
## ⚠️ Disclaimer
|
|
22
|
+
|
|
23
|
+
This is an unofficial API client/MCP Server. Not affiliated with Avanza Bank AB. The underlying API can be taken down or changed without warning at any point in time.
|
|
24
|
+
|
|
25
|
+
The author of this software is not responsible for any indirect damages (foreseeable or unforeseeable), such as, if necessary, loss or alteration of or fraudulent access to data, accidental transmission of viruses or of any other harmful element, loss of profits or opportunities, the cost of replacement goods and services or the attitude and behavior of a third party.
|
|
26
|
+
|
|
27
|
+
## 🛠️ MCP Tools
|
|
28
|
+
|
|
29
|
+
### Search & Discovery
|
|
30
|
+
| Tool | Description |
|
|
31
|
+
|------|-------------|
|
|
32
|
+
| `search_instruments` | Find stocks, funds, ETFs by name or symbol |
|
|
33
|
+
| `get_instrument_by_order_book_id` | Look up instruments by order book ID |
|
|
34
|
+
|
|
35
|
+
### Stock Analysis
|
|
36
|
+
| Tool | Description |
|
|
37
|
+
|------|-------------|
|
|
38
|
+
| `get_stock_info` | Complete stock information with fundamentals |
|
|
39
|
+
| `get_stock_quote` | Real-time price and volume data |
|
|
40
|
+
| `get_stock_analysis` | Financial ratios by year and quarter |
|
|
41
|
+
| `get_stock_chart` | Historical OHLC price data |
|
|
42
|
+
| `get_orderbook` | Order book depth with bid/ask levels |
|
|
43
|
+
| `get_marketplace_info` | Trading hours and market status |
|
|
44
|
+
| `get_recent_trades` | Latest executed trades |
|
|
45
|
+
| `get_broker_trade_summary` | Broker buy/sell activity |
|
|
46
|
+
| `get_dividends` | Historical dividend data |
|
|
47
|
+
| `get_company_financials` | Annual and quarterly financial statements |
|
|
48
|
+
|
|
49
|
+
### Fund Analysis
|
|
50
|
+
| Tool | Description |
|
|
51
|
+
|------|-------------|
|
|
52
|
+
| `get_fund_info` | Complete fund information with performance |
|
|
53
|
+
| `get_fund_sustainability` | ESG scores and sustainability metrics |
|
|
54
|
+
| `get_fund_chart` | Historical performance charts |
|
|
55
|
+
| `get_fund_chart_periods` | Performance across all time periods |
|
|
56
|
+
| `get_fund_description` | Detailed fund description |
|
|
57
|
+
| `get_fund_holdings` | Portfolio allocation (country, sector, top holdings) |
|
|
58
|
+
|
|
59
|
+
## 💡 MCP Prompts
|
|
60
|
+
|
|
61
|
+
- `analyze_stock` - Comprehensive stock analysis workflow
|
|
62
|
+
- `compare_funds` - Multi-fund comparison template
|
|
63
|
+
- `screen_dividend_stocks` - Dividend stock screening
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
### Configuration for MCP Clients
|
|
67
|
+
|
|
68
|
+
For Claude Desktop or other MCP clients, add to your configuration:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"mcpServers": {
|
|
73
|
+
"avanza": {
|
|
74
|
+
"command": "uvx",
|
|
75
|
+
"args": ["avanza-mcp"]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Usage in Claude Desktop
|
|
82
|
+
|
|
83
|
+
Once configured, you can ask Claude:
|
|
84
|
+
|
|
85
|
+
- "Search for Volvo stock on Avanza"
|
|
86
|
+
- "Get the latest stock quote for Ericsson"
|
|
87
|
+
- "Show me sustainable Swedish funds"
|
|
88
|
+
- "What's in the order book for H&M?"
|
|
89
|
+
- "Compare the performance of these three funds"
|
|
90
|
+
- "What dividends has SEB paid over the years?"
|
|
91
|
+
- "Show me the portfolio holdings for Avanza Global fund"
|
|
92
|
+
|
|
93
|
+
## 📄 License
|
|
94
|
+
|
|
95
|
+
MIT License - See [LICENSE.md](LICENSE.md) for details.
|
|
96
|
+
|
|
97
|
+
## 🤝 Contributing
|
|
98
|
+
|
|
99
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Avanza MCP Server
|
|
2
|
+
|
|
3
|
+
A Model Context Protocol (MCP) server providing access to Avanza's public API. Get real-time Swedish stock quotes, fund information, charts, and comprehensive market data.
|
|
4
|
+
|
|
5
|
+
## ⚠️ Disclaimer
|
|
6
|
+
|
|
7
|
+
This is an unofficial API client/MCP Server. Not affiliated with Avanza Bank AB. The underlying API can be taken down or changed without warning at any point in time.
|
|
8
|
+
|
|
9
|
+
The author of this software is not responsible for any indirect damages (foreseeable or unforeseeable), such as, if necessary, loss or alteration of or fraudulent access to data, accidental transmission of viruses or of any other harmful element, loss of profits or opportunities, the cost of replacement goods and services or the attitude and behavior of a third party.
|
|
10
|
+
|
|
11
|
+
## 🛠️ MCP Tools
|
|
12
|
+
|
|
13
|
+
### Search & Discovery
|
|
14
|
+
| Tool | Description |
|
|
15
|
+
|------|-------------|
|
|
16
|
+
| `search_instruments` | Find stocks, funds, ETFs by name or symbol |
|
|
17
|
+
| `get_instrument_by_order_book_id` | Look up instruments by order book ID |
|
|
18
|
+
|
|
19
|
+
### Stock Analysis
|
|
20
|
+
| Tool | Description |
|
|
21
|
+
|------|-------------|
|
|
22
|
+
| `get_stock_info` | Complete stock information with fundamentals |
|
|
23
|
+
| `get_stock_quote` | Real-time price and volume data |
|
|
24
|
+
| `get_stock_analysis` | Financial ratios by year and quarter |
|
|
25
|
+
| `get_stock_chart` | Historical OHLC price data |
|
|
26
|
+
| `get_orderbook` | Order book depth with bid/ask levels |
|
|
27
|
+
| `get_marketplace_info` | Trading hours and market status |
|
|
28
|
+
| `get_recent_trades` | Latest executed trades |
|
|
29
|
+
| `get_broker_trade_summary` | Broker buy/sell activity |
|
|
30
|
+
| `get_dividends` | Historical dividend data |
|
|
31
|
+
| `get_company_financials` | Annual and quarterly financial statements |
|
|
32
|
+
|
|
33
|
+
### Fund Analysis
|
|
34
|
+
| Tool | Description |
|
|
35
|
+
|------|-------------|
|
|
36
|
+
| `get_fund_info` | Complete fund information with performance |
|
|
37
|
+
| `get_fund_sustainability` | ESG scores and sustainability metrics |
|
|
38
|
+
| `get_fund_chart` | Historical performance charts |
|
|
39
|
+
| `get_fund_chart_periods` | Performance across all time periods |
|
|
40
|
+
| `get_fund_description` | Detailed fund description |
|
|
41
|
+
| `get_fund_holdings` | Portfolio allocation (country, sector, top holdings) |
|
|
42
|
+
|
|
43
|
+
## 💡 MCP Prompts
|
|
44
|
+
|
|
45
|
+
- `analyze_stock` - Comprehensive stock analysis workflow
|
|
46
|
+
- `compare_funds` - Multi-fund comparison template
|
|
47
|
+
- `screen_dividend_stocks` - Dividend stock screening
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### Configuration for MCP Clients
|
|
51
|
+
|
|
52
|
+
For Claude Desktop or other MCP clients, add to your configuration:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"mcpServers": {
|
|
57
|
+
"avanza": {
|
|
58
|
+
"command": "uvx",
|
|
59
|
+
"args": ["avanza-mcp"]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Usage in Claude Desktop
|
|
66
|
+
|
|
67
|
+
Once configured, you can ask Claude:
|
|
68
|
+
|
|
69
|
+
- "Search for Volvo stock on Avanza"
|
|
70
|
+
- "Get the latest stock quote for Ericsson"
|
|
71
|
+
- "Show me sustainable Swedish funds"
|
|
72
|
+
- "What's in the order book for H&M?"
|
|
73
|
+
- "Compare the performance of these three funds"
|
|
74
|
+
- "What dividends has SEB paid over the years?"
|
|
75
|
+
- "Show me the portfolio holdings for Avanza Global fund"
|
|
76
|
+
|
|
77
|
+
## 📄 License
|
|
78
|
+
|
|
79
|
+
MIT License - See [LICENSE.md](LICENSE.md) for details.
|
|
80
|
+
|
|
81
|
+
## 🤝 Contributing
|
|
82
|
+
|
|
83
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Avanza MCP Server
|
|
2
|
+
|
|
3
|
+
# Show all commands
|
|
4
|
+
default:
|
|
5
|
+
@just --list
|
|
6
|
+
|
|
7
|
+
# Install dependencies
|
|
8
|
+
install:
|
|
9
|
+
uv sync
|
|
10
|
+
|
|
11
|
+
# Run the MCP server
|
|
12
|
+
run:
|
|
13
|
+
uv run avanza-mcp
|
|
14
|
+
|
|
15
|
+
# Build the package
|
|
16
|
+
build:
|
|
17
|
+
uv build
|
|
18
|
+
|
|
19
|
+
# Clean build artifacts
|
|
20
|
+
clean:
|
|
21
|
+
rm -rf dist/ build/ *.egg-info
|
|
22
|
+
find . -type d -name __pycache__ -exec rm -rf {} +
|
|
23
|
+
|
|
24
|
+
# Get current version
|
|
25
|
+
version:
|
|
26
|
+
@grep '^__version__ = ' src/avanza_mcp/__init__.py | cut -d'"' -f2
|
|
27
|
+
|
|
28
|
+
# Bump version and trigger CI publish
|
|
29
|
+
release version_part="patch":
|
|
30
|
+
#!/usr/bin/env bash
|
|
31
|
+
set -euo pipefail
|
|
32
|
+
|
|
33
|
+
# Check for uncommitted changes
|
|
34
|
+
if [[ -n $(git status -s) ]]; then
|
|
35
|
+
echo "Error: Uncommitted changes detected"
|
|
36
|
+
git status -s
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# Get current version
|
|
41
|
+
current=$(grep '^__version__ = ' src/avanza_mcp/__init__.py | cut -d'"' -f2)
|
|
42
|
+
echo "Current: $current"
|
|
43
|
+
|
|
44
|
+
# Bump version
|
|
45
|
+
IFS='.' read -r major minor patch <<< "$current"
|
|
46
|
+
case "{{version_part}}" in
|
|
47
|
+
major) major=$((major + 1)); minor=0; patch=0 ;;
|
|
48
|
+
minor) minor=$((minor + 1)); patch=0 ;;
|
|
49
|
+
patch) patch=$((patch + 1)) ;;
|
|
50
|
+
*) echo "Error: Use major, minor, or patch"; exit 1 ;;
|
|
51
|
+
esac
|
|
52
|
+
|
|
53
|
+
new_version="$major.$minor.$patch"
|
|
54
|
+
echo "New: $new_version"
|
|
55
|
+
|
|
56
|
+
# Update version in __init__.py
|
|
57
|
+
sed -i "s/^__version__ = \".*\"/__version__ = \"$new_version\"/" src/avanza_mcp/__init__.py
|
|
58
|
+
|
|
59
|
+
# Show diff
|
|
60
|
+
git diff src/avanza_mcp/__init__.py
|
|
61
|
+
|
|
62
|
+
# Commit and tag
|
|
63
|
+
git add src/avanza_mcp/__init__.py
|
|
64
|
+
git commit -m "Bump version to $new_version"
|
|
65
|
+
git tag "v$new_version"
|
|
66
|
+
git push origin master
|
|
67
|
+
git push origin "v$new_version"
|
|
68
|
+
|
|
69
|
+
echo ""
|
|
70
|
+
echo "✓ Released $new_version"
|
|
71
|
+
echo "✓ CI will build and publish to PyPI"
|
|
72
|
+
echo "✓ https://github.com/antewall/avanza-mcp/actions"
|
|
73
|
+
|
|
74
|
+
# Release shortcuts
|
|
75
|
+
release-patch: (release "patch")
|
|
76
|
+
release-minor: (release "minor")
|
|
77
|
+
release-major: (release "major")
|
|
78
|
+
|
|
79
|
+
# Test imports
|
|
80
|
+
test:
|
|
81
|
+
uv run python -c "from avanza_mcp import mcp, __version__; print(f'v{__version__}')"
|