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 have clearly distinct purposes: version info, distance/heading calculations, parsing, validation, spec reading, and enumeration listing/searching. The only mild overlap is between list_enumerations and search_enumerations, and read_specification_resource could partially duplicate enumeration data, but the descriptions clarify the boundaries.
All tool names use snake_case and follow a verb_noun pattern (get_version_info, calculate_distance, parse_adif, list_enumerations, validate_adif_record). The convention is consistent across the entire set.
Eight tools is well-scoped for an ADIF support server covering reference lookup, validation, parsing, and Maidenhead calculations. No tool feels redundant, and the set does not appear artificially inflated or thin.
The surface covers reading, parsing, validating, spec/enumeration lookup, and calculations, but lacks any tool to create, write, or export ADIF records. This is a notable gap if the server is meant to support full ADIF lifecycle workflows.