DNS Server Landscape for Go + SQLite + MCP Management
This report surveys DNS server software suitable for hosting on a VPS, with emphasis on Go implementations and SQLite zone storage, and evaluates their fit for MCP-based management.
---
Requirements Recap
- Language: Go (for easy compilation, static binary, minimal runtime).
- Zone storage: SQLite (file-based, no separate DB process).
- Management interface: MCP (Model Context Protocol) tools to manipulate zones and records.
- Target use: Dynamic, automation-friendly DNS for a VPS, potentially for internal services or small public zones.
- Ops: Should run as a systemd service or Docker container; easy to reload config without downtime.
---
Candidate DNS Servers
1. CoreDNS
Description: CoreDNS is a flexible, extensible DNS server written in Go. It’s a Cloud Native Computing Foundation (CNCF) project and is widely used (e.g., Kubernetes DNS). It’s plugin-based; the core handles DNS protocol and delegates to middleware plugins.
Go: Yes.
Zone storage:
- CoreDNS does not have a built-in SQLite backend. It primarily uses the `file` plugin (loads zone files) or `auto` for reverse zones.
- There are community plugins that add SQLite storage, e.g., `github.com/threefoldtech/coredns-sqlite` or `github.com/coredns/sqlite` (if it exists). However, these are not part of the official distribution and may be unmaintained.
- Alternatively, we could write a custom plugin that reads zones from SQLite and implements the `Middleware` and `Handler` interfaces. This is feasible but requires Go coding.
MCP integration:
- CoreDNS itself does not speak MCP. However, we could build a separate MCP control server that writes to the same SQLite database and signals CoreDNS to reload (e.g., by sending `SIGHUP` or via an HTTP endpoint if we add one). Or we could embed MCP directly as a CoreDNS plugin (exposing a Unix socket for MCP stdio). That would be more advanced.
Maturity: Very high. CoreDNS is battle‑tested, supports modern features (DNS over TLS, gRPC health checks, etc.), and has excellent documentation.
Operational:
- Single binary; config file (Corefile) defines plugins.
- Can run as systemd service; reload by sending `SIGHUP` or using `coredns - reload`.
- Logging to stdout.
Verdict: Strong candidate if we are willing to either adopt an existing SQLite plugin (research needed) or write a custom plugin. The plugin architecture makes it relatively clean to add MCP management as an additional plugin that exposes tools while sharing the same in‑memory zone data. However, the need for a custom SQLite plugin may add development time.
2. Custom Server using miekg/dns
Description: `github.com/miekg/dns` is the premier Go library for DNS protocol handling. Many DNS servers and tools are built on it (including CoreDNS originally). We could build a minimal authoritative server tailored to our needs.
Go: Yes (library).
Zone storage: We design a simple SQLite schema: tables `zones` (id, name, soa, ttl) and `records` (zone_id, name, type, value, ttl). The server loads zones into memory on startup (or on reload). We implement AXFR? Not needed initially; just serve queries from memory. Updates go through MCP tools, which write to SQLite and trigger an in‑memory reload.
MCP integration: Directly embed an MCP server in the same binary as a separate goroutine listening on stdin/stdout (stdio mode). The MCP tools call into the zone manager to add/delete zones/records, update SQLite, and then refresh in‑memory state. This yields a tightly integrated, single‑binary solution.
Development effort: Moderate. Building a correct, performant DNS server from scratch is non‑trivial, but `miekg/dns` handles protocol details, caching, and concurrency. We’d need to implement zone loading, query routing (match zone by name), record selection, and response generation. This is a ~1000‑2000 line program. Manageable for a small team in 2‑3 weeks.
Maturity: As a custom build, it would be less proven than CoreDNS, but we control the code. We can start minimal and add features (e.g., DNSSEC, TSIG) as needed.
Operational:
- Single static binary; no external deps.
- systemd service file straightforward.
- Reload: send `SIGHUP` or use MCP tool to trigger reload.
Verdict: Very promising. It meets all constraints exactly: Go, SQLite, MCP-native. Development time is acceptable for an MVP, and we avoid reliance on third‑party plugins that may be abandoned.
3. NSD (Not Go)
Description: NSD (Name Server Daemon) is a high‑performance authoritative DNS server written in C. It uses zone files, not SQLite. While extremely solid, it doesn’t meet the Go requirement.
Verdict: Out.
4. Knot DNS (Not Go)
Description: Knot DNS is another fast authoritative server in C. Supports SQLite via a zone database module? Actually Knot can use a zone database in Berkeley DB or lmdb; not sure about SQLite. Not Go.
Verdict: Out.
5. PowerDNS (C++ with Go bindings?)
Description: PowerDNS is a popular DNS server with multiple backends (SQL, LDAP, etc.). It’s written in C++. There is a Go version? No. It can use SQLite via its `gsqlite` backend (MySQL, PostgreSQL, SQLite). However, it’s not Go, and MCP integration would be external.
Verdict: Not Go, so not preferred.
6. Other Go DNS servers
- `github.com/facebookgo/dns` – not a server.
- `github.com/armon/circbuf`? not relevant.
- `github.com/leverly/go-dnssec` – library.
- No other full‑featured Go DNS server with SQLite integration is widely known.
---
Comparative Summary
| Server | Language | SQLite Support | MCP Integration Potential | Maturity | Effort to MVP |
|-----------------|----------|----------------|---------------------------|----------|---------------|
| CoreDNS | Go | Plugin (community, may need custom) | Plugin or external process | High | Medium (plugin dev) |
| Custom (miekg/dns) | Go | Native (we design) | Built‑in (native) | Medium (custom) | Medium (2–3 weeks) |
| NSD | C | No | External only | Very High| N/A (not Go) |
| PowerDNS | C++ | Yes (gsqlite) | External | High | N/A (not Go) |
---
Recommended Approach
Build a custom lightweight authoritative DNS server using `miekg/dns` with SQLite backend and embedded MCP interface.
Why:
- Exactly matches constraints: Go, SQLite, MCP-native.
- Full control over features and codebase; no dependency on unmaintained plugins.
- Simpler mental model: single binary does both DNS serving and management.
- Development effort is reasonable (2–3 weeks for MVP).
- We can design a clean MCP tool set that directly manipulates zones.
- Future enhancements (e.g., TSIG, DNSSEC, dynamic updates) can be added as needed.
Architecture sketch:
+---------------------+ +------------------+
| MCP Client (stdio) | <->| MCP Server | (tools: add_zone, add_record, ...)
+---------------------+ +------------------+
|
v
+---------------------+ +------------------+
| DNS Server (miekg/dns) | <->| Zone Manager | (in‑memory cache + SQLite writer)
+---------------------+ +------------------+
The server loads all zones from SQLite into memory on startup. Queries are answered from memory. MCP tools modify SQLite and then trigger an in‑memory reload (or atomic swap). This provides fast query performance and simple consistency.
SQLite schema:
sql
CREATE TABLE zones (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL UNIQUE, -- e.g., "example.com."
origin TEXT NOT NULL, -- same as name usually
ttl INTEGER DEFAULT 3600
);
CREATE TABLE records (
id INTEGER PRIMARY KEY,
zone_id INTEGER NOT NULL,
name TEXT NOT NULL, -- relative name or full?
rtype TEXT NOT NULL, -- "A", "AAAA", "CNAME", "MX", "TXT", "NS"
value TEXT NOT NULL, -- formatted as needed (e.g., "1.2.3.4" for A, "mail.example.com." for MX? Actually MX needs preference and host)
ttl INTEGER,
FOREIGN KEY(zone_id) REFERENCES zones(id)
);
-- Possibly separate table for different record types if needed.
MCP tools will handle formatting values appropriately.
Next: Write Report 2 (Architecture & MCP Spec) and Report 3 (Implementation Plan).
---
Word count: ~1,150