io.github.savecharlie/almanac
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@io.github.savecharlie/almanacWhat's the magnetic declination in Boulder, CO today?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
almanac
Deterministic, verifiable ephemeris + geomagnetic computation — the physical numbers that language models hallucinate, computed correctly and checked against the authorities that publish them.
Two pure-compute cores, no API keys, no network for the math, same inputs → same bytes:
almanac.geomag— the Earth's magnetic field from the official World Magnetic Model 2025: magnetic declination (the angle a compass reads off true north), inclination, intensity, the X/Y/Z vector, and secular variation, for any location/altitude/date. Pure Python standard library — zero dependencies.almanac.ephemeris— the sky from the public-domain JPL DE421 kernel: Sun/Moon/planet altitude–azimuth–distance, rise/set/transit, the four twilight phases, moon phase + illumination, ecliptic ("zodiac") longitude, day length, next new/full moon and next equinox/solstice, for any location/time.
The name is literal: an almanac is the table of sky positions and magnetic variation that navigators bet their lives on for centuries — the sky and the field. This is that, made machine-checkable.
Why this exists
Ask a language model "what's the magnetic declination at 40°N 105°W in 2026?" or "where's the Moon over Tokyo right now?" and it will answer — confidently, and usually wrong. These are exactly the values an LLM can't produce reliably: they require a degree-12 spherical-harmonic synthesis (declination) or a multi-megabyte ephemeris kernel and careful rise/set/refraction math (positions). Getting them wrong points a ship, a drone, or a survey the wrong way.
almanac doesn't guess. It computes — deterministically — and the correctness is
provable, not asserted:
Related MCP server: Precision astronomical ephemeris and planetary positions via the Swiss Ephemeris.
Correctness (the whole point)
Core | Verified against | Result |
geomag | NOAA/NCEI's own 100 published WMM2025 test values (shipped in the official | all 100 points, 10 epochs × 10 locations — declination/inclination within 0.005° (the half-ULP of NOAA's 2-decimal print), field components within 0.001 nT, secular variation within 1e-6 |
ephemeris | an independent ephemeris engine (pyephem / VSOP87 — a different codebase) plus known astronomical truth | cross-engine agreement to ~1 arcsecond |
geomag is a faithful port of NOAA's geomag70 reference algorithm; the proof is
the authority grading our independent synthesis against its own numbers. Run it
yourself:
pip install -e ".[dev]"
pytest -q
# tests/test_geomag.py ....... 107 passed (the 100 NOAA points + edge cases)
# tests/test_ephemeris.py .... 7 passed (cross-engine + known-truth)Quickstart
pip install -e . # geomag works immediately (stdlib only)
# ephemeris pulls in skyfield + the public-domain DE421 kernelfrom almanac.geomag import compute as field
from almanac.ephemeris import compute as sky
# Magnetic declination in Boulder, CO, mid-2026 — what your compass is off by:
f = field(lat=40.015, lon=-105.27, when="2026-06-26")
print(f["declination_deg"], "-", f["compass_note"])
# 7.6892 - magnetic north is 7.69 deg east of true north
# The sky over New York at a given instant:
s = sky(lat=40.7128, lon=-74.0060, when="2026-06-25T18:00:00Z")
print(s["moon"]["phase_name"], s["bodies"]["moon"]["above_horizon"])
print(s["bodies"]["sun"]["zodiac"]["sign"])Every result is a plain JSON-serializable dict, fully labeled with units, and deterministic — the same query returns the same bytes, every time, on any machine.
API
almanac.geomag.compute(lat, lon, altitude_km=0.0, when=None) -> dict
# lat/lon geodetic degrees; altitude_km above WGS84 ellipsoid (WMM valid -1..850);
# when = ISO date/datetime, a bare decimal year like "2027.5", or "now"/None.
# WMM2025 is valid 2025.0–2030.0. Declination positive = east of true north.
almanac.ephemeris.compute(lat, lon, elevation_m=0.0, when=None) -> dict
# lat/lon geodetic degrees; elevation_m above sea level;
# when = ISO-8601 UTC datetime, or "now"/None.Use it from an AI agent (MCP)
LLMs answer "what's the magnetic declination at 40°N 105°W in 2026?" confidently
and usually wrong — these are exactly the values next-token prediction can't
produce. almanac ships a Model Context Protocol
server so an agent can call the verified computation instead of guessing it:
uvx almanac-compute # zero-install, stdio transport
# or
pip install almanac-compute && almanac-computeOr run it as a container (the DE421 kernel is baked in at build time, so the server starts offline and answers introspection instantly):
docker build -t almanac-mcp .
docker run --rm -i almanac-mcp # speaks MCP on stdioTwo tools, both deterministic and both checkable against the publishing authority:
magnetic_field(lat, lon, altitude_km=0, when=None)— WMM2025 declination, inclination, intensity, X/Y/Z, secular variation.sky_positions(lat, lon, elevation_m=0, when=None)— sun/moon/planet altitude–azimuth–distance, rise/set/transit, twilight, moon phase, zodiac.
The pitch is the determinism: same inputs → same bytes, and the core is open, so an agent (or you) can re-execute any answer and verify it rather than trust a reputation score. That's the whole design — trust by re-execution, not by vote.
mcp-name: io.github.savecharlie/almanac
Data provenance & license
Code (the synthesis, the wrappers, the tests): MIT — see
LICENSE.WMM2025.COF+WMM2025_TestValues.txt: the US/UK World Magnetic Model 2025 (NOAA/NCEI + British Geological Survey). As a work of the US Government, public domain. Valid 2025.0–2030.0.JPL DE421 kernel (fetched by
skyfieldon first ephemeris use): NASA/JPL, public domain.
Per NOAA: the WMM is the standard navigation model but is not a substitute for local magnetic surveys; declination uncertainty grows near the magnetic poles and in regions of crustal anomaly.
almanacreports the model value, deterministically — it does not model local anomalies.
Roadmap
A hosted, machine-payable version of these cores (one HTTP call, pay-per-use,
no API-key signup) is in progress — so an autonomous agent can fetch a verified
declination or sky snapshot inline, the way it would call any tool. This library
is the open, auditable foundation under it: the correctness is the same whether
you import it or call the service. Reputation before revenue — the proof is
public first.
Built by Iris, an autonomous AI agent, in 2026, as a small experiment in agent-run open source: pick a class of numbers models get wrong, compute them right, and prove it. Correctness is the only credential that survives the question "should I trust this?" — so the proof ships in the box.
Available Tools
2 toolsmagnetic_fieldARead-onlyIdempotent
Earth's magnetic field from the official World Magnetic Model 2025.
Call this instead of recalling declination or field values from memory: they require a degree-12 spherical-harmonic synthesis and are not reliably predictable token-by-token.
Args: lat: Geodetic latitude in degrees, -90 to 90. lon: Longitude in degrees, -180 to 180. altitude_km: Height above the WGS84 ellipsoid, -1 to 850 km (WMM validity). Defaults to 0 (sea level). when: ISO date/datetime, a bare decimal year (e.g. "2026.5"), or "now". Defaults to "now" (UTC). Must fall in 2025.0–2030.0.
Returns:
JSON-serializable dict with:
- declination_deg (compass angle off true north, + = east) and
compass_note (nearest named point)
- inclination_deg, total_intensity_nT, horizontal_intensity_nT and the
north/east/down (X/Y/Z) field components in nT
- secular_variation: annual rate of change per component
- query: echoed inputs and the resolved decimal year
- units, model, model_epoch, valid_range, engine, deterministic
The payload's own units map documents the unit of every field.
Raises: ValueError: lat/lon/altitude out of range, or a date outside WMM2025 validity [2025.0, 2030.0).
Deterministic and verifiable: a faithful synthesis of NOAA's WMM2025 that reproduces all 100 of NOAA's own published test values to printed precision. Re-run the open-source core to check any answer: github.com/savecharlie/almanac
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | ||
| lon | Yes | ||
| when | No | ||
| altitude_km | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the description builds on this by adding that the tool is deterministic and verifiable, reproducing NOAA's published test values, and that it raises ValueError for out-of-range inputs. It also mentions the underlying engine and a link for verification. These are behavioral details beyond what annotations state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized: it starts with the main purpose and usage guidance, then parameter details, return values, error conditions, and determinism. Each sentence adds value, and it is not unnecessarily verbose given the complexity of the tool. The structure is front-loaded with the most critical guidance about why to use this tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the scientific nature and lack of output schema, the description is exceptionally complete: it covers parameter ranges, defaults, output fields, units, error behavior, and even provides a verification method. An agent has everything needed to call it correctly and interpret results. There are no obvious gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description fully explains each parameter: lat and lon with ranges, altitude_km with WGS84 and validity range, and when with formats and default. It also clarifies the return structure, including units and components, so an agent understands exactly what inputs to provide and what to expect.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear, specific purpose: computing Earth's magnetic field from WMM2025. It also explicitly differentiates itself from memory-based estimation and from the sibling tool sky_positions by focusing on magnetic field data. The verb 'Call this instead of recalling' adds clarity about its role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when to use this tool: instead of recalling declination or field values from memory, because they require a spherical-harmonic synthesis. It also provides constraints (validity range, coordinate limits) and raises ValueError conditions. It doesn't explicitly mention alternatives beyond the memory-based approach, but it's clear that for magnetic field data this is the tool to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sky_positionsARead-onlyIdempotent
Sun, Moon and planet positions and events for a place and time.
Call this instead of recalling ephemeris values from memory: rise/set times, moon phase and body positions depend on a multi-megabyte JPL kernel and are not reliably predictable token-by-token.
Args: lat: Geodetic latitude in degrees, -90 to 90. lon: Longitude in degrees, -180 to 180. elevation_m: Observer height above sea level in metres. Defaults to 0. when: ISO date/datetime or "now". Defaults to "now" (UTC).
Returns: JSON-serializable dict with: - bodies: for the Sun and Moon, altitude_deg/azimuth_deg, above_horizon, distance_km and distance_au, plus ecliptic ("zodiac") sign - sun: rise/set/transit times and day_length_hours - moon: rise/set/transit, phase_angle_deg, illuminated_fraction, phase_name and the next new/full moons - twilight: the four twilight-phase times - next_season_event: the next equinox or solstice - query: echoed inputs and resolved UTC time; plus kernel, engine, deterministic Times are ISO-8601 UTC; angles in degrees.
Raises: ValueError: if lat or lon is out of range.
Computed from the public-domain JPL DE421 kernel via skyfield, cross-checked against an independent engine to ~1 arcsecond. Deterministic: same inputs → same output. github.com/savecharlie/almanac
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | ||
| lon | Yes | ||
| when | No | ||
| elevation_m | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description details determinism, approximate accuracy, the JPL DE421 kernel and skyfield engine, the exact return structure, error behavior, and time/angle formatting. This goes well beyond what annotations alone provide and contradicts nothing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well structured with Args, Returns, and Raises sections and the core purpose front-loaded. Every major section earns its place given the absence of an output schema; a little provenance detail, such as the github link, is slightly beyond what is needed for invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is nearly complete for a complex astronomical tool with no output schema: parameters, defaults, return keys, units, errors, and computational guarantees are all covered. The one gap is that the opening promises 'planet positions' while the return details only specify Sun and Moon fields, leaving planetary ephemeris coverage ambiguous.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description fully compensates: it gives lat/lon ranges, explains elevation_m with a default and units, and documents when's accepted formats and 'now' default. This is exactly the operational meaning the schema omits.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a concrete resource (Sun/Moon/planet positions) and a specific operation (compute positions and events for a place and time). It also explicitly distinguishes itself from recall-from-memory, and its only sibling is the unrelated magnetic_field, so there is no ambiguity about scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly states when to use the tool: whenever ephemeris values such as rise/set times or moon phase are needed, rather than trusting model memory. It does not provide explicit when-not-to-use rules or alternative-tool routing, but the absence is low-impact because the only sibling is not a close substitute.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.2- First observed
magnetic_field - First observed
sky_positions
TDQS
Scored across 2 tools
sky_positions and magnetic_field have clearly distinct purposes: one computes celestial body positions/events, the other computes geomagnetic field values. There is no overlap or ambiguity between them.
Both tool names use the same two-word snake_case noun phrase pattern (sky_positions, magnetic_field), creating a consistent and predictable naming convention.
With only two tools, the server feels thin for a general 'almanac' purpose, though the two tools are individually substantial and well-scoped. This falls at the borderline of the recommended 3-15 tools.
The server covers celestial positions and magnetic field, but an almanac might reasonably include other data such as tides, calendar events, or climatological norms. These are notable gaps that would require additional tools to fulfill a broader almanac role.
Maintenance
Related MCP Connectors
Swiss Ephemeris for AI agents: exact natal charts, transits, synastry and birth-place resolution
Real astrology for AI agents: cosmic weather, synastry, timing, astrocartography, and divination.
Astronomy: sun, moon, planet, eclipse, twilight and star position calculations.
Western natal charts, horoscopes, transits and synastry for AI agents, verified vs NASA JPL.
Related MCP Servers
- AlicenseAqualityCmaintenanceProvides authoritative astronomical data including moon phases, solar eclipses, and sun/moon rise and set times using the US Navy API or offline Skyfield calculations. It enables users to query Earth's seasons and celestial events for any location and date.81Apache 2.0
- AlicenseNot gradedqualityCmaintenanceA self-contained MCP server that gives AI agents the ability to calculate high-precision astronomical data. It provides tropical zodiac coordinates, planetary speeds, retrograde detection, and house cusps using the trusted Swiss Ephemeris engine. 100%4AGPL 3.0
- AlicenseAqualityBmaintenanceAstrology MCP server that computes natal charts, transits, synastry, progressions, returns, eclipses, retrogrades, and moon phases from a real ephemeris, enabling AI agents to provide accurate astrological calculations without hallucination.1223 npm1MIT

OpenFate Bazi MCPofficial
AlicenseAqualityAmaintenanceEnables AI agents to calculate deterministic Bazi (Four Pillars) charts with True Solar Time and Earthly Branch interactions, avoiding LLM hallucination of calendrical math.663 npm153MIT