adif-mcp
<!-- mcp-name: io.github.qso-graph/adif-mcp -->
# adif-mcp
[](https://pypi.org/project/adif-mcp/)
[](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.qso-graph/adif-mcp&version=latest)
MCP server for the [ADIF 3.1.7 specification](https://adif.org.uk/317/ADIF_317.htm): validate and parse ADIF records, search the spec's fields, enumerations and data types, and compute distance and heading between Maidenhead locators, through any MCP-compatible AI assistant.
Part of the [qso-graph](https://qso-graph.io/) project. **No authentication required** — the ADIF specification is bundled, so it works offline.
## Install
```bash
uvx adif-mcp # run it; nothing to install
```
## Tools
| Tool | Description | Key Parameters |
|------|-------------|----------------|
| `validate_adif_record` | Validate a raw ADIF record against the 3.1.7 spec | adif_string |
| `parse_adif` | Streaming parser for large ADIF files, with pagination | file_path, start_at, limit |
| `read_specification_resource` | Raw JSON for any spec module (band, mode, fields, ...) | resource_name |
| `list_enumerations` | All ADIF enumerations with entry counts | — |
| `search_enumerations` | Search enumeration records by keyword | search_term, enumeration |
| `calculate_distance` | Great-circle distance (km) between two Maidenhead locators | start, end |
| `calculate_heading` | Initial beam heading (azimuth) between two locators | start, end |
| `get_version_info` | Service version + upstream spec version (fleet identity attestation) | — |
## What is ADIF?
ADIF (Amateur Data Interchange Format) is the standard file format amateur radio logging programs use to exchange QSO records. adif-mcp is the specification package of qso-graph: it validates, parses and searches ADIF so an assistant can work with logs safely and accurately. Credentials are handled separately by [qso-graph-auth](https://pypi.org/project/qso-graph-auth/), and each logging service has its own MCP server (see [qso-graph.io](https://qso-graph.io/)).
## Quick Start
No credentials needed — just install and configure your MCP client.
### Configure your MCP client
adif-mcp works with any MCP-compatible client. Add the server config and restart. The tools appear automatically.
#### Claude Desktop
Add to `claude_desktop_config.json` (`~/Library/Application Support/Claude/` on macOS, `%APPDATA%\Claude\` on Windows):
```json
{
"mcpServers": {
"adif": {
"command": "uvx",
"args": ["adif-mcp"]
}
}
}
```
#### Claude Code
Add to `.claude/settings.json`:
```json
{
"mcpServers": {
"adif": {
"command": "uvx",
"args": ["adif-mcp"]
}
}
}
```
#### ChatGPT Desktop
Configure via Settings > Apps & Connectors, or in your agent definition:
```json
{
"mcpServers": {
"adif": {
"command": "uvx",
"args": ["adif-mcp"]
}
}
}
```
#### Cursor
Add to `.cursor/mcp.json` (project-level) or `~/.cursor/mcp.json` (global):
```json
{
"mcpServers": {
"adif": {
"command": "uvx",
"args": ["adif-mcp"]
}
}
}
```
#### VS Code / GitHub Copilot
Add to `.vscode/mcp.json` in your workspace:
```json
{
"servers": {
"adif": {
"command": "uvx",
"args": ["adif-mcp"]
}
}
}
```
#### Gemini CLI
Add to `~/.gemini/settings.json` (global) or `.gemini/settings.json` (project):
```json
{
"mcpServers": {
"adif": {
"command": "uvx",
"args": ["adif-mcp"]
}
}
}
```
### Ask questions
> "Is this ADIF record valid? <CALL:5>KI7MT<QSO_DATE:8>20260928<BAND:3>20m<MODE:3>SSB<EOR>"
> "What values does the ADIF MODE enumeration allow for digital modes?"
> "Parse my log file and show me the first 50 QSOs."
> "How far is it from DN13 to JN48, and what heading should I point the beam?"
## What the validator checks
adif-mcp ships ADIF 3.1.7 as ADIF publishes it: 186 fields, 25 enumerations and 28 data types.
`validate_adif_record` checks each field against its ADIF data type and, for enumerated fields,
against the enumeration:
- **Enumeration values** match regardless of case, so LoTW's `BAND=15M` is accepted as `15m`.
- **Import-only values** (42 of the Mode enumeration's 91 entries, for example) give a warning, not an
error: ADIF allows them on import but not in new records.
- **Compound values** such as `CREDIT_SUBMITTED` (a list of `Credit` or `Credit:Medium` entries) are
checked entry by entry.
- **SUBMODE** must be a valid Submode; one that belongs to a different MODE gives a warning. FT4, for
example, is `MODE=MFSK` with `SUBMODE=FT4`.
- **Structured types** are checked against the grammar ADIF states for them: grid squares (2, 4, 6 or
8 characters, any case) and their extensions and lists (VUCC needs two or four, each four or six
characters), `Location` (`XDDD MM.MMM`), `Boolean` (Y or N), and IOTA, WWFF, POTA and SOTA
references. What the grammar allows but cannot be right, such as a latitude over 90 degrees or
N/S on a longitude, is a warning, never an error.
The server also publishes the MCP resource `adif://system/version`: the service version and the ADIF
specification version it serves.
## MCP Inspector
```bash
adif-mcp --transport streamable-http --port 8003
```
Then open the MCP Inspector at `http://localhost:8003`.
## Development
```bash
git clone https://github.com/qso-graph/adif-mcp.git
cd adif-mcp
uv sync --group dev
uv run pytest
```
## License
adif-mcp's own code is GPL-3.0-or-later. See [LICENSE](LICENSE) for details.
**The ADIF specification files are not ours.** The package includes ADIF's published files for two versions, the previous and the current (3.1.6 and 3.1.7 today), unmodified: every file in ADIF's resource zip except its test material, in every format ADIF publishes (JSON, XML with `all.xml` and the XSD, CSV, TSV, XLSX, ODS), with a `MANIFEST.json` of their SHA-256s per version, from the [ADIF Developers Group](https://adif.org.uk/). They are ADIF's work, and our licence doesn't cover them. The only files in that folder that are ours are the derived Country enumeration and each version's `MANIFEST.json`. See [NOTICE](NOTICE).
TDQS
Scored across 8 tools
Most tools target distinct actions (parsing, validation, spec reading, geo math), and the list vs search enumeration pair is clarified by descriptions. The calculate_distance vs calculate_heading pair and read_specification_resource vs list_enumerations overlap slightly, but outputs are well differentiated.
All tools follow a consistent snake_case verb_noun pattern (get_version_info, calculate_distance, parse_adif, list_enumerations, search_enumerations, validate_adif_record). No mixed conventions.
Eight tools is well-scoped for an ADIF reference/validation server, with each tool covering a distinct capability (version, geo, parsing, spec, enumerations, validation). Nothing feels padded or missing for the stated purpose.
The read/validate/spec-reference surface is solid, covering parsing, validation, enumerations, and spec lookup. However, there is no write/export or record-modification tool, which is a noticeable but workable gap for an ADIF-focused server.