Skip to content

Commit 35f4694

Browse files
KI7MTclaude
andcommitted
Add adif-mcp foundation, architecture, testing, and llms.txt
- adif-mcp Foundation page: 7 tools, validation coverage, credential setup - Architecture page: system overview, credential flow, design principles - Testing & Validation page: 60 security tests across 10 packages, ADIF 3.1.6 official test corpus (6,191 records), KI7MT forensic tests - llms.txt: AI-discoverable site index - Updated nav: Foundation/Logbook/Public server grouping - Updated homepage: 10 packages, 51 tools Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent eda943b commit 35f4694

7 files changed

Lines changed: 762 additions & 21 deletions

File tree

docs/architecture.md

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# Architecture
2+
3+
**How qso-graph servers work together — one foundation, ten packages, zero cloud dependencies.**
4+
5+
---
6+
7+
## System Overview
8+
9+
```
10+
┌─────────────────────────────────────────────────────────┐
11+
│ AI Assistant │
12+
│ Claude · ChatGPT · Cursor · Gemini │
13+
└────────────────────┬────────────────────────────────────┘
14+
│ MCP Protocol (stdio)
15+
16+
┌─────────────────────────────────────────────────────────┐
17+
│ MCP Servers (local) │
18+
│ │
19+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
20+
│ │ eqsl-mcp │ │ qrz-mcp │ │ lotw-mcp │ │ pota-mcp │ │
21+
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
22+
│ │ │ │ │ │
23+
│ ┌────┴─────────────┴────────────┴─────────────┘ │
24+
│ │ │
25+
│ │ adif-mcp (foundation) │
26+
│ │ ├── PersonaManager → OS Keyring │
27+
│ │ ├── ADIF 3.1.6 Spec (186 fields, 25 enums) │
28+
│ │ ├── Validation Engine │
29+
│ │ └── Geospatial (distance, heading) │
30+
│ │ │
31+
│ └──────────────────────────────────────────────────────┘
32+
│ │
33+
└─────────────────────────────────────────────────────────┘
34+
│ HTTPS only
35+
36+
┌─────────────────────────────────────────────────────────┐
37+
│ External Services │
38+
│ │
39+
│ eQSL.cc · QRZ.com · LoTW · Club Log · HamQTH │
40+
│ POTA · SOTA · NOAA SWPC · WSPR Network │
41+
└─────────────────────────────────────────────────────────┘
42+
```
43+
44+
---
45+
46+
## Foundation: adif-mcp
47+
48+
adif-mcp provides three capabilities that all other servers depend on:
49+
50+
### 1. Persona Management
51+
52+
Named identities with credentials stored in the OS keyring. One persona serves all services:
53+
54+
```
55+
Persona: "ki7mt"
56+
├── eqsl → password in OS keyring
57+
├── lotw → password in OS keyring
58+
├── qrz → password in OS keyring
59+
└── hamqth → password in OS keyring
60+
```
61+
62+
When a server needs credentials, it calls `adif-mcp` which reads them from the keyring at runtime. Credentials never exist in config files, environment variables, or MCP protocol messages.
63+
64+
### 2. ADIF 3.1.6 Specification
65+
66+
The complete ADIF 3.1.6 spec bundled as JSON:
67+
68+
- **186 fields** with data types, valid ranges, and descriptions
69+
- **25 enumerations** with 4,427 records (Mode, Band, DXCC, Contest_ID, etc.)
70+
- **28 data types** (Number, String, Date, GridSquare, etc.)
71+
72+
All servers share this spec for consistent parsing and validation.
73+
74+
### 3. Validation Engine
75+
76+
Record validation against the full spec:
77+
78+
- Field name recognition (186 fields)
79+
- Data type checking (Number, Date, etc.)
80+
- Enum membership checking (43 enum-typed fields across 25 enumerations)
81+
- Compound format parsing (CreditList, multi-medium)
82+
- Conditional validation (Submode depends on Mode)
83+
- Import-only detection (warn, don't reject historical data)
84+
85+
---
86+
87+
## Server Architecture
88+
89+
Each MCP server follows the same pattern:
90+
91+
```
92+
MCP Client Request
93+
94+
95+
Input Validation ──── Regex on all user strings
96+
97+
98+
Rate Limiter ──────── Per-service throttle (prevents account bans)
99+
100+
101+
Credential Lookup ─── OS keyring via adif-mcp (authenticated servers only)
102+
103+
104+
API Call ──────────── HTTPS only, response parsed
105+
106+
107+
Response Cache ────── In-memory TTL cache
108+
109+
110+
Safe Return ───────── No credentials in results, errors, or logs
111+
```
112+
113+
### Common Properties
114+
115+
| Property | Value |
116+
|----------|-------|
117+
| Transport | stdio (default) or `--transport streamable-http` for MCP Inspector |
118+
| Framework | FastMCP 3.x |
119+
| Python | 3.10+ |
120+
| License | GPL-3.0-or-later |
121+
| Mock mode | `<NAME>_MCP_MOCK=1` for testing without credentials |
122+
123+
### Rate Limiting
124+
125+
Each server implements rate limiting appropriate for its service:
126+
127+
| Server | Min Delay | Max Rate | Notes |
128+
|--------|-----------|----------|-------|
129+
| eqsl-mcp | 500ms || Respectful crawl |
130+
| qrz-mcp | 500ms | 35/min | IP ban risk above 35/min |
131+
| clublog-mcp | 500ms | 30/min | API key rate limit |
132+
| lotw-mcp | 500ms || Respectful crawl |
133+
| hamqth-mcp | 500ms || XML session rate limit |
134+
| pota-mcp | 100ms || Public API |
135+
| sota-mcp | 200ms || Public API |
136+
| solar-mcp | 200ms || NOAA public data |
137+
| wspr-mcp | 200ms || Public API |
138+
139+
---
140+
141+
## Credential Flow
142+
143+
Credentials take one path and never deviate:
144+
145+
```
146+
User ──── adif-mcp creds set ──── OS Keyring (encrypted)
147+
148+
MCP Server ──── adif-mcp read ─────────┘
149+
│ (in-process, never serialized)
150+
151+
HTTPS Request ──── credential in Authorization header
152+
153+
154+
Response ──── parsed, credential stripped
155+
156+
157+
MCP Tool Result ──── data only, no credentials
158+
```
159+
160+
**What gets persisted:** Nothing. Credentials exist in memory only during the API call. The OS keyring handles encryption at rest.
161+
162+
**What the AI sees:** Tool parameters (`persona`, `callsign`, `band`) and tool results (lookup data, QSO records). Never passwords, API keys, or session tokens.
163+
164+
---
165+
166+
## Package Independence
167+
168+
Each server is a standalone `pip install`:
169+
170+
```bash
171+
pip install eqsl-mcp # just eqsl-mcp + its dependencies
172+
pip install pota-mcp # just pota-mcp, no auth needed
173+
```
174+
175+
Servers don't depend on each other. You can install one or all ten.
176+
177+
Authenticated servers depend on `adif-mcp` for credential management. Public servers (POTA, SOTA, Solar, WSPR) have no dependency on adif-mcp.
178+
179+
---
180+
181+
## MCP Client Configuration
182+
183+
All servers work with any MCP client. Example for Claude Desktop:
184+
185+
```json
186+
{
187+
"mcpServers": {
188+
"adif": {
189+
"command": "adif-mcp"
190+
},
191+
"eqsl": {
192+
"command": "eqsl-mcp"
193+
},
194+
"pota": {
195+
"command": "pota-mcp"
196+
}
197+
}
198+
}
199+
```
200+
201+
For Claude Code, add to `~/.claude/settings.json`:
202+
203+
```json
204+
{
205+
"mcpServers": {
206+
"adif": { "command": "adif-mcp", "args": [] },
207+
"eqsl": { "command": "eqsl-mcp", "args": [] }
208+
}
209+
}
210+
```
211+
212+
See [Getting Started](getting-started.md) for configuration for all 6 supported MCP clients.
213+
214+
---
215+
216+
## Design Principles
217+
218+
### Good Neighbor Policy
219+
220+
qso-graph servers **wrap** external APIs — they don't replicate them. Rate limiting is built in to prevent account bans. If a service goes down, the server fails gracefully.
221+
222+
### Read-Only Security Model
223+
224+
No qso-graph server writes to external services. All operations are read-only: lookups, downloads, queries. No log uploads, no QSO submissions, no account modifications.
225+
226+
### Validate Before Upload
227+
228+
adif-mcp's validation engine catches data defects at the source. A busted QSO is not a confirmation — and a rare DXpedition contact may be irreplaceable. Validate before uploading to LoTW, eQSL, or Club Log.
229+
230+
### Pip Install and Go
231+
232+
Every server is one `pip install` away. No Docker, no containers, no config files (except MCP client config). Credentials go in the OS keyring, not YAML files.

docs/index.md

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,15 @@ Ask your AI assistant to look up a callsign, check your LoTW confirmations, find
66

77
---
88

9-
## 9 Packages, 44 Tools
9+
## 10 Packages, 51 Tools
10+
11+
### Foundation
12+
13+
| Package | Tools | What It Does |
14+
|---------|:-----:|--------------|
15+
| [adif-mcp](servers/adif-mcp.md) | 7 | ADIF 3.1.6 spec engine, validation, persona management, keyring credentials |
16+
17+
### Logbook Services (Authenticated)
1018

1119
| Package | Tools | Auth | What It Does |
1220
|---------|:-----:|------|--------------|
@@ -15,20 +23,28 @@ Ask your AI assistant to look up a callsign, check your LoTW confirmations, find
1523
| [clublog-mcp](servers/clublog.md) | 6 | API key | DXCC resolution, expedition logs, Most Wanted |
1624
| [lotw-mcp](servers/lotw.md) | 4 | Persona | LoTW confirmations, QSOs, DXCC credits |
1725
| [hamqth-mcp](servers/hamqth.md) | 4 | Persona | Free callsign lookup, DXCC, bio, activity |
18-
| [pota-mcp](servers/pota.md) | 6 | None | Live spots, park info, stats, schedules |
19-
| [sota-mcp](servers/sota.md) | 5 | None | Spots, alerts, summit info, nearby search |
20-
| [solar-mcp](servers/solar.md) | 6 | None | SFI, Kp, solar wind, X-ray, band outlook |
21-
| [wspr-mcp](servers/wspr.md) | 5 | None | Beacon spots, band activity, propagation |
26+
27+
### Public Services (No Auth Required)
28+
29+
| Package | Tools | What It Does |
30+
|---------|:-----:|--------------|
31+
| [pota-mcp](servers/pota.md) | 6 | Live spots, park info, stats, schedules |
32+
| [sota-mcp](servers/sota.md) | 5 | Spots, alerts, summit info, nearby search |
33+
| [solar-mcp](servers/solar.md) | 6 | SFI, Kp, solar wind, X-ray, band outlook |
34+
| [wspr-mcp](servers/wspr.md) | 5 | Beacon spots, band activity, propagation |
2235

2336
---
2437

2538
## Quick Install
2639

2740
```bash
28-
# Install any package
29-
pip install eqsl-mcp qrz-mcp clublog-mcp lotw-mcp
41+
# Foundation (credential management + ADIF validation)
42+
pip install adif-mcp
43+
44+
# Logbook services (authenticated)
45+
pip install eqsl-mcp qrz-mcp clublog-mcp lotw-mcp hamqth-mcp
3046

31-
# Public-only packages (no credentials needed)
47+
# Public services (no credentials needed)
3248
pip install pota-mcp sota-mcp solar-mcp wspr-mcp
3349
```
3450

@@ -90,5 +106,6 @@ Dashboard, physics lab, DXCC progress, path analyzer, and log viewer — all pow
90106
- **Demo**: [qso-graph-demo.vercel.app](https://qso-graph-demo.vercel.app/)
91107
- **GitHub**: [github.com/qso-graph](https://github.com/qso-graph)
92108
- **PyPI**: [eqsl-mcp](https://pypi.org/project/eqsl-mcp/) · [qrz-mcp](https://pypi.org/project/qrz-mcp/) · [clublog-mcp](https://pypi.org/project/clublog-mcp/) · [lotw-mcp](https://pypi.org/project/lotw-mcp/)
93-
- **Foundation**: [adif-mcp](https://pypi.org/project/adif-mcp/) — ADIF parsing + credential management
109+
- **Foundation**: [adif-mcp](servers/adif-mcp.md) — ADIF 3.1.6 spec engine + credential management ([PyPI](https://pypi.org/project/adif-mcp/))
110+
- **Testing**: [48/48 PASS](testing.md) — security audit + ADIF 3.1.6 official test corpus + forensic validation
94111
- **Related**: [IONIS](https://ionis-ai.com/) — HF propagation prediction from 14B amateur radio observations

docs/llms.txt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# qso-graph — MCP Servers for Amateur Radio
2+
3+
> Open-source Model Context Protocol servers connecting AI assistants to amateur radio services. 10 packages, 51 tools, secure by design.
4+
5+
## Foundation
6+
7+
- [adif-mcp](https://qso-graph.io/servers/adif-mcp/): ADIF 3.1.6 spec engine, validation, persona management, OS keyring credentials. 8 tools. Foundation for all authenticated servers.
8+
9+
## Logbook Services (Authenticated)
10+
11+
- [eqsl-mcp](https://qso-graph.io/servers/eqsl/): eQSL.cc — inbox download, QSO verification, AG status, last upload. 4 tools.
12+
- [qrz-mcp](https://qso-graph.io/servers/qrz/): QRZ.com — callsign lookup, DXCC resolution, logbook access. 4 tools.
13+
- [clublog-mcp](https://qso-graph.io/servers/clublog/): Club Log — DXCC, log search, propagation activity, Most Wanted, expeditions. 6 tools.
14+
- [lotw-mcp](https://qso-graph.io/servers/lotw/): LoTW (ARRL) — confirmations, QSOs, DXCC credits, user activity. 4 tools.
15+
- [hamqth-mcp](https://qso-graph.io/servers/hamqth/): HamQTH — callsign lookup, DXCC, bio, activity. 4 tools.
16+
17+
## Public Services (No Auth Required)
18+
19+
- [pota-mcp](https://qso-graph.io/servers/pota/): Parks on the Air — live spots, park info, stats, schedules, location search. 6 tools.
20+
- [sota-mcp](https://qso-graph.io/servers/sota/): Summits on the Air — spots, alerts, summit info, nearby search, activator stats. 5 tools.
21+
- [solar-mcp](https://qso-graph.io/servers/solar/): NOAA SWPC — SFI, Kp, solar wind, X-ray flux, band outlook, alerts. 6 tools.
22+
- [wspr-mcp](https://qso-graph.io/servers/wspr/): WSPR network — beacon spots, band activity, propagation paths, TX power. 5 tools.
23+
24+
## Documentation
25+
26+
- [Getting Started](https://qso-graph.io/getting-started/): Installation, credential setup, MCP client configuration for Claude Desktop, Claude Code, ChatGPT, Cursor, VS Code, and Gemini CLI.
27+
- [Architecture](https://qso-graph.io/architecture/): System design — foundation layer, credential flow, rate limiting, read-only security model.
28+
- [Testing & Validation](https://qso-graph.io/testing/): 60 security tests across 10 packages, ADIF 3.1.6 official test corpus validation, forensic tests from real operator data.
29+
- [Security](https://qso-graph.io/security/): 10 non-negotiable security guarantees, credential architecture, forbidden patterns, release process, incident response.
30+
31+
## Key Facts
32+
33+
- All credentials stored in OS keyring (macOS Keychain, Windows Credential Manager, Linux Secret Service)
34+
- All external connections HTTPS only
35+
- No subprocess, no shell=True, no eval/exec in any package
36+
- Every package requires security audit before PyPI publication
37+
- Read-only — no server writes to external services
38+
- License: GPL-3.0-or-later
39+
- Author: Greg Beam, KI7MT
40+
41+
## Links
42+
43+
- GitHub: https://github.com/qso-graph
44+
- Documentation: https://qso-graph.io
45+
- Demo: https://qso-graph-demo.vercel.app
46+
- Related: https://ionis-ai.com (HF propagation prediction from 14B amateur radio observations)

0 commit comments

Comments
 (0)