avios-cli 0.5.0__tar.gz → 0.6.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.
- {avios_cli-0.5.0 → avios_cli-0.6.0}/CHANGELOG.md +26 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/PKG-INFO +45 -7
- {avios_cli-0.5.0 → avios_cli-0.6.0}/README.md +40 -4
- {avios_cli-0.5.0 → avios_cli-0.6.0}/pyproject.toml +13 -3
- avios_cli-0.6.0/src/avios/__init__.py +7 -0
- avios_cli-0.6.0/src/avios/mcp_entry.py +36 -0
- avios_cli-0.6.0/src/avios/mcp_server.py +675 -0
- avios_cli-0.6.0/tests/test_mcp_server.py +623 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/uv.lock +671 -2
- avios_cli-0.5.0/src/avios/__init__.py +0 -6
- {avios_cli-0.5.0 → avios_cli-0.6.0}/.editorconfig +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/.github/dependabot.yml +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/.github/workflows/ci.yml +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/.github/workflows/publish.yml +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/.gitignore +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/.pre-commit-config.yaml +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/.python-version +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/CONTRIBUTING.md +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/LICENSE +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/SECURITY.md +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/docs/dashboard.svg +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/docs/reward-flights.svg +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/scripts/screenshot.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/accounts.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/aggregate.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/auth.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/cli.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/client.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/config.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/endpoints.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/finnair.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/models.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/programmes.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/rewards.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/session.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/tui/__init__.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/tui/app.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/tui/art.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/tui/rewards.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/tui/styles.tcss +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/src/avios/tui/widgets.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/tests/conftest.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/tests/fixtures/balance.json +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/tests/fixtures/reward_search.rsc +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/tests/fixtures/transactions.json +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/tests/test_accounts.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/tests/test_aggregate.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/tests/test_auth.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/tests/test_cli.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/tests/test_client.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/tests/test_finnair.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/tests/test_models.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/tests/test_rewards.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/tests/test_session.py +0 -0
- {avios_cli-0.5.0 → avios_cli-0.6.0}/tests/test_tui.py +0 -0
|
@@ -6,6 +6,32 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.6.0] - 2026-08-11
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **MCP server (`avios-mcp`).** Exposes your Avios accounts and British Airways
|
|
13
|
+
reward availability to Claude and any other MCP client over stdio. Install with
|
|
14
|
+
`uv tool install 'avios-cli[mcp]'`; sessions come from `avios login`, so the
|
|
15
|
+
server never performs a login itself. Closes #45.
|
|
16
|
+
|
|
17
|
+
Tools: `list_accounts`, `get_balance`, `get_transactions`,
|
|
18
|
+
`get_pending_transactions`, `whoami`, `search_reward_flights`.
|
|
19
|
+
|
|
20
|
+
Design constraints worth stating, because they are what make it safe to point an
|
|
21
|
+
agent at:
|
|
22
|
+
|
|
23
|
+
- **Read-only.** Nothing books, spends, or mutates a session.
|
|
24
|
+
- **No credentials in output.** Every tool returns an explicit response model
|
|
25
|
+
rather than a raw API payload, so cookies, API keys and the `whoami` id token
|
|
26
|
+
never leave the process.
|
|
27
|
+
- **Reward search is batched and rate-limited.** BA blocks by IP address, so an
|
|
28
|
+
agent fanning out over routes could lock you out of the site. A whole return
|
|
29
|
+
trip goes through one batched, single-browser-session search; the server
|
|
30
|
+
enforces a cooldown between searches; and a block is reported as terminal and
|
|
31
|
+
explicitly not retryable.
|
|
32
|
+
- **MCP is an optional extra**, so a plain CLI install does not pull in the SDK's
|
|
33
|
+
web stack.
|
|
34
|
+
|
|
9
35
|
## [0.5.0] - 2026-08-11
|
|
10
36
|
|
|
11
37
|
### Fixed
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: avios-cli
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: A CLI and
|
|
3
|
+
Version: 0.6.0
|
|
4
|
+
Summary: A CLI, TUI and MCP server for Avios balances, transactions, and BA reward-flight availability.
|
|
5
5
|
Project-URL: Homepage, https://github.com/alexechoi/avios-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/alexechoi/avios-cli
|
|
7
7
|
Project-URL: Issues, https://github.com/alexechoi/avios-cli/issues
|
|
8
8
|
Author: Alex Choi
|
|
9
9
|
License-Expression: MIT
|
|
10
10
|
License-File: LICENSE
|
|
11
|
-
Keywords: avios,british-airways,cli,loyalty,terminal,tui
|
|
11
|
+
Keywords: avios,british-airways,cli,loyalty,mcp,terminal,tui
|
|
12
12
|
Classifier: Development Status :: 3 - Alpha
|
|
13
13
|
Classifier: Environment :: Console
|
|
14
14
|
Classifier: Intended Audience :: End Users/Desktop
|
|
@@ -31,6 +31,8 @@ Requires-Dist: rich>=13.7
|
|
|
31
31
|
Requires-Dist: textual>=0.80
|
|
32
32
|
Requires-Dist: typer>=0.12
|
|
33
33
|
Provides-Extra: login
|
|
34
|
+
Provides-Extra: mcp
|
|
35
|
+
Requires-Dist: mcp<3,>=2.0; extra == 'mcp'
|
|
34
36
|
Description-Content-Type: text/markdown
|
|
35
37
|
|
|
36
38
|
# avios-cli
|
|
@@ -39,10 +41,10 @@ Description-Content-Type: text/markdown
|
|
|
39
41
|
[](LICENSE)
|
|
40
42
|
[](https://www.python.org/)
|
|
41
43
|
|
|
42
|
-
A **CLI and
|
|
43
|
-
and search British Airways reward-flight availability without leaving
|
|
44
|
-
|
|
45
|
-
own OAuth and loyalty API.
|
|
44
|
+
A **CLI, TUI and MCP server for your Avios programmes** — check balances, browse
|
|
45
|
+
transactions, and search British Airways reward-flight availability without leaving
|
|
46
|
+
the terminal, or hand the same data to an AI agent. British Airways, Iberia, and
|
|
47
|
+
Aer Lingus use avios.com; Finnair Plus uses Finnair's own OAuth and loyalty API.
|
|
46
48
|
|
|
47
49
|
> ⚠️ **Unofficial.** This project is not affiliated with, authorised by, or endorsed by
|
|
48
50
|
> Avios, British Airways, Finnair or IAG Loyalty. It drives the same private endpoints
|
|
@@ -178,6 +180,41 @@ A tabbed full-screen application:
|
|
|
178
180
|
Press `r` to refresh the dashboard and `q` to quit. Reward searches run only when
|
|
179
181
|
you press Search or Enter.
|
|
180
182
|
|
|
183
|
+
## MCP server
|
|
184
|
+
|
|
185
|
+
Expose your accounts to Claude and other MCP clients, read-only:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
uv tool install 'avios-cli[mcp]'
|
|
189
|
+
avios login ba # sessions come from the CLI; the server never logs in
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
```jsonc
|
|
193
|
+
// Claude Desktop: claude_desktop_config.json
|
|
194
|
+
{
|
|
195
|
+
"mcpServers": {
|
|
196
|
+
"avios": { "command": "avios-mcp" }
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Or, for Claude Code:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
claude mcp add avios -- uvx --from 'avios-cli[mcp]' avios-mcp
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Tools: `list_accounts`, `get_balance`, `get_transactions`,
|
|
208
|
+
`get_pending_transactions`, `whoami`, `search_reward_flights`.
|
|
209
|
+
|
|
210
|
+
Every tool is read-only — nothing books, spends, or changes a session — and no
|
|
211
|
+
cookie or token is ever returned. `search_reward_flights` searches a whole return
|
|
212
|
+
trip in one call and is rate-limited server-side, because it drives a real browser
|
|
213
|
+
and British Airways blocks by IP address; an agent looping over routes could get
|
|
214
|
+
you locked out of the site.
|
|
215
|
+
|
|
216
|
+
## Notes on reward search
|
|
217
|
+
|
|
181
218
|
Reward search is an unofficial view of BA's own flight finder. It supports direct
|
|
182
219
|
BA flights, three-letter airport/city codes, and seat counts by cabin. Searching
|
|
183
220
|
an exact `--date` also fetches the Avios price per cabin for your party; calendar
|
|
@@ -197,6 +234,7 @@ one-way searches sharing one browser session.
|
|
|
197
234
|
- [x] Multiple accounts (BA, Iberia, Aer Lingus, Finnair) with combined views
|
|
198
235
|
- [x] British Airways reward-flight **availability** search (CLI + TUI)
|
|
199
236
|
- [x] Avios pricing per cabin for an exact date
|
|
237
|
+
- [x] MCP server (`avios-mcp`) for AI agents
|
|
200
238
|
|
|
201
239
|
## Development
|
|
202
240
|
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://www.python.org/)
|
|
6
6
|
|
|
7
|
-
A **CLI and
|
|
8
|
-
and search British Airways reward-flight availability without leaving
|
|
9
|
-
|
|
10
|
-
own OAuth and loyalty API.
|
|
7
|
+
A **CLI, TUI and MCP server for your Avios programmes** — check balances, browse
|
|
8
|
+
transactions, and search British Airways reward-flight availability without leaving
|
|
9
|
+
the terminal, or hand the same data to an AI agent. British Airways, Iberia, and
|
|
10
|
+
Aer Lingus use avios.com; Finnair Plus uses Finnair's own OAuth and loyalty API.
|
|
11
11
|
|
|
12
12
|
> ⚠️ **Unofficial.** This project is not affiliated with, authorised by, or endorsed by
|
|
13
13
|
> Avios, British Airways, Finnair or IAG Loyalty. It drives the same private endpoints
|
|
@@ -143,6 +143,41 @@ A tabbed full-screen application:
|
|
|
143
143
|
Press `r` to refresh the dashboard and `q` to quit. Reward searches run only when
|
|
144
144
|
you press Search or Enter.
|
|
145
145
|
|
|
146
|
+
## MCP server
|
|
147
|
+
|
|
148
|
+
Expose your accounts to Claude and other MCP clients, read-only:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
uv tool install 'avios-cli[mcp]'
|
|
152
|
+
avios login ba # sessions come from the CLI; the server never logs in
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
```jsonc
|
|
156
|
+
// Claude Desktop: claude_desktop_config.json
|
|
157
|
+
{
|
|
158
|
+
"mcpServers": {
|
|
159
|
+
"avios": { "command": "avios-mcp" }
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Or, for Claude Code:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
claude mcp add avios -- uvx --from 'avios-cli[mcp]' avios-mcp
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Tools: `list_accounts`, `get_balance`, `get_transactions`,
|
|
171
|
+
`get_pending_transactions`, `whoami`, `search_reward_flights`.
|
|
172
|
+
|
|
173
|
+
Every tool is read-only — nothing books, spends, or changes a session — and no
|
|
174
|
+
cookie or token is ever returned. `search_reward_flights` searches a whole return
|
|
175
|
+
trip in one call and is rate-limited server-side, because it drives a real browser
|
|
176
|
+
and British Airways blocks by IP address; an agent looping over routes could get
|
|
177
|
+
you locked out of the site.
|
|
178
|
+
|
|
179
|
+
## Notes on reward search
|
|
180
|
+
|
|
146
181
|
Reward search is an unofficial view of BA's own flight finder. It supports direct
|
|
147
182
|
BA flights, three-letter airport/city codes, and seat counts by cabin. Searching
|
|
148
183
|
an exact `--date` also fetches the Avios price per cabin for your party; calendar
|
|
@@ -162,6 +197,7 @@ one-way searches sharing one browser session.
|
|
|
162
197
|
- [x] Multiple accounts (BA, Iberia, Aer Lingus, Finnair) with combined views
|
|
163
198
|
- [x] British Airways reward-flight **availability** search (CLI + TUI)
|
|
164
199
|
- [x] Avios pricing per cabin for an exact date
|
|
200
|
+
- [x] MCP server (`avios-mcp`) for AI agents
|
|
165
201
|
|
|
166
202
|
## Development
|
|
167
203
|
|
|
@@ -4,13 +4,13 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "avios-cli"
|
|
7
|
-
description = "A CLI and
|
|
7
|
+
description = "A CLI, TUI and MCP server for Avios balances, transactions, and BA reward-flight availability."
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
license = "MIT"
|
|
10
10
|
license-files = ["LICENSE"]
|
|
11
11
|
requires-python = ">=3.10"
|
|
12
12
|
authors = [{ name = "Alex Choi" }]
|
|
13
|
-
keywords = ["avios", "british-airways", "cli", "tui", "loyalty", "terminal"]
|
|
13
|
+
keywords = ["avios", "british-airways", "cli", "tui", "loyalty", "terminal", "mcp"]
|
|
14
14
|
classifiers = [
|
|
15
15
|
"Development Status :: 3 - Alpha",
|
|
16
16
|
"Environment :: Console",
|
|
@@ -45,6 +45,10 @@ dependencies = [
|
|
|
45
45
|
# base package, so `avios-cli[login]` resolves to the same thing as `avios-cli`.
|
|
46
46
|
login = []
|
|
47
47
|
|
|
48
|
+
# MCP server (`avios-mcp`). Optional so a plain CLI install stays small; the SDK
|
|
49
|
+
# pulls in a web stack the terminal app has no use for.
|
|
50
|
+
mcp = ["mcp>=2.0,<3"]
|
|
51
|
+
|
|
48
52
|
# Dev tooling lives in a PEP 735 dependency-group (not an extra) so that `uv sync`
|
|
49
53
|
# and `uv run` install it by default — an extra would be pruned by `uv run`.
|
|
50
54
|
[dependency-groups]
|
|
@@ -56,12 +60,18 @@ dev = [
|
|
|
56
60
|
"ruff>=0.6",
|
|
57
61
|
"mypy>=1.10",
|
|
58
62
|
"types-PyYAML",
|
|
63
|
+
# In the dev group, not just the `mcp` extra, so CI type-checks and tests the
|
|
64
|
+
# MCP server rather than skipping it.
|
|
65
|
+
"mcp>=2.0,<3",
|
|
59
66
|
]
|
|
60
67
|
|
|
61
68
|
[project.scripts]
|
|
62
69
|
avios = "avios.cli:app"
|
|
63
70
|
# Alias so `uvx avios-cli` (matching the package name) works too.
|
|
64
71
|
avios-cli = "avios.cli:app"
|
|
72
|
+
# MCP server over stdio; needs the `mcp` extra. The wrapper module reports a
|
|
73
|
+
# missing extra as one readable line rather than an import traceback.
|
|
74
|
+
avios-mcp = "avios.mcp_entry:main"
|
|
65
75
|
|
|
66
76
|
[project.urls]
|
|
67
77
|
Homepage = "https://github.com/alexechoi/avios-cli"
|
|
@@ -99,5 +109,5 @@ mypy_path = "src"
|
|
|
99
109
|
plugins = ["pydantic.mypy"]
|
|
100
110
|
|
|
101
111
|
[[tool.mypy.overrides]]
|
|
102
|
-
module = ["browser_cookie3.*", "playwright.*"]
|
|
112
|
+
module = ["browser_cookie3.*", "playwright.*", "mcp.*"]
|
|
103
113
|
ignore_missing_imports = true
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Console-script wrapper for ``avios-mcp``.
|
|
2
|
+
|
|
3
|
+
Kept separate from :mod:`avios.mcp_server` so that a missing ``mcp`` extra produces
|
|
4
|
+
one actionable line on stderr instead of an ``ImportError`` traceback — the server
|
|
5
|
+
is normally launched by an MCP client, which shows the user very little.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import sys
|
|
11
|
+
from importlib.util import find_spec
|
|
12
|
+
|
|
13
|
+
INSTALL_HINT = (
|
|
14
|
+
"avios-mcp needs the `mcp` extra, which is not installed.\n"
|
|
15
|
+
"\n"
|
|
16
|
+
" uv tool install 'avios-cli[mcp]'\n"
|
|
17
|
+
"\n"
|
|
18
|
+
"or run it without installing:\n"
|
|
19
|
+
"\n"
|
|
20
|
+
" uvx --from 'avios-cli[mcp]' avios-mcp"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def main() -> None:
|
|
25
|
+
"""Serve the Avios MCP server over stdio."""
|
|
26
|
+
if find_spec("mcp") is None:
|
|
27
|
+
print(INSTALL_HINT, file=sys.stderr)
|
|
28
|
+
raise SystemExit(1)
|
|
29
|
+
|
|
30
|
+
from avios.mcp_server import mcp
|
|
31
|
+
|
|
32
|
+
mcp.run(transport="stdio")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
if __name__ == "__main__":
|
|
36
|
+
main()
|