gnomon — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited gnomon (Plugin) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
<!-- mcp-name: io.github.lihtness/gnomon-mcp -->
The pointer on a sundial that turns shadow into time.
A small MCP server for the boring-but-essential utilities every model needs: dates, calendars, arithmetic, unit conversion. Use it so your assistant stops "next-token guessing" math and date math.
LLMs are bad at arithmetic and date math by default. They produce plausible answers that are often wrong by a small amount — exactly the kind of mistake that's hard to notice in a long response. gnomon-mcp exposes deterministic Python implementations through MCP so your model can compute instead of guess.
Anywhere the next plausible token is not the right answer. Concretely:
calc.now for a snapshot; calendar with until/since/diff for elapsed time; parse for natural-language dates ("next thursday").calendar with add / business_days.calc_convert. Never eyeball "kg → lb" or "°C → °F".calendar, calc) take a list and return a list in order. One call, N results.The rule of thumb: if you'd ask a colleague to "just double-check that number," call gnomon instead.
Time and math already have several MCP servers — the official Time reference (timezone-only), mcp-time and mcp-datetime (date formatting / timezone), calculator-server (math + units, no dates), and bundles like agent-utils-mcp (regex / hashing / JWT). gnomon's lane is narrower:
calendar(ops) and calc(expressions) take lists; one tool call covers a whole table column instead of N calls.is_weekend, … — instead of just {iso, tz}."next thursday", "in 3 hours") without a separate NLP server.If you only need timezone conversion, the official Time server is enough. If you want a broad utility bundle (regex, hashing, encoding, JWT), agent-utils-mcp is a better fit. gnomon is for the boring date-arithmetic-and-arithmetic core, batched.
Two tools:
`now(tz?)` returns:
{
"iso": "2026-05-25T14:30:45+00:00",
"date": "2026-05-25",
"time": "14:30:45",
"unix": 1779345045,
"tz": "UTC",
"year": 2026, "month": 5, "month_name": "May", "day": 25,
"weekday": "Monday", "weekday_num": 0, # 0=Monday
"day_of_year": 145, "week_of_year": 22, # ISO week
"quarter": 2, "fiscal_year_us_gov": 2026, # FY starts Oct 1
"hour": 14, "minute": 30, "second": 45,
"is_weekend": False,
}`calendar(ops)` operations:
| Op | Params | Returns | |||
|---|---|---|---|---|---|
diff | start, end, unit | end - start — time elapsed between two known dates | |||
until | target, unit, tz? | target - now — time left to a future point (negative if past) | |||
since | source, unit, tz? | now - source — time elapsed since a past point (negative if future) | |||
add | date, n, unit | ISO of date + n units (`seconds\ | ...\ | weeks, plus months\ | years` calendar-aware) |
weekday | date | "Monday".."Sunday" | |||
business_days | start, end | count of Mon-Fri days (start inclusive, end exclusive) | |||
parse | natural, tz? | ISO from natural language ("next thursday", "in 3 hours") | |||
format | date, fmt | strftime-formatted string |
Units for diff/until/since: seconds, minutes, hours, days, weeks.
Example — compute several things in one call:
calendar([
{"op": "until", "target": "2026-12-31", "unit": "days"}, # days left in year
{"op": "since", "source": "2026-01-01", "unit": "days"}, # days elapsed in year
{"op": "diff", "start": "2026-01-01", "end": "2026-12-31", "unit": "days"},
{"op": "weekday", "date": "2026-05-25"}, # "Monday"
{"op": "add", "date": "2026-05-25", "n": 1, "unit": "months"},
{"op": "parse", "natural": "next thursday", "tz": "America/Los_Angeles"},
])| Tool | Purpose |
|---|---|
calc(expressions) | Evaluate a list of Python expressions and return a list of results. Math (sqrt, sin, log, pi, e, ...), stats (mean, median, stdev, variance), and useful builtins (abs, round, min, max, sum, range, sorted, ...) are pre-loaded. Batch in / batch out, order preserved. |
calc_convert(value, from_unit, to_unit) | Unit conversion via Pint (meter → foot, kg → lb, degC → degF, etc.). |
Examples:
calc(["2 + 3 * 4"]) # [14]
calc(["sqrt(16)", "sin(pi/2)"]) # [4.0, 1.0]
calc(["mean([1, 2, 3, 4])"]) # [2.5]
calc(["sum(range(101))"]) # [5050]
calc(["(25 / 100) * 100"]) # [25.0]The same logic — if the model is likely to bluff it, expose a deterministic version — points at several more primitives worth building. None of these are implemented yet; they are candidates, listed roughly in order of bang-for-buck:
count(text, unit) for chars / words / lines / sentences / LLM tokens. Agents constantly miscount "how long is this" and "will this fit in the context window."regex_find(pattern, text) and regex_sub(pattern, repl, text). Models hallucinate which substrings match a regex; a real engine ends the argument.jq(path, json) / jsonpath(path, json). Reading values out of a nested blob by path, without typos.hash(text, algo) (sha256, md5, blake2), encode(text, scheme) / decode(text, scheme) (base64, hex, url, jwt-payload). All things models confidently invent wrong.money(expr) evaluated under Python's Decimal with explicit rounding. calc is float-based and quietly unsafe for currency.calendar.business_days with a country (or calendar) parameter so US/UK/IN holidays are excluded. The current implementation only knows weekends.cron_describe("0 9 * * 1-5") → human English; cron_next(expr, n) → next N firing times. Models routinely misread cron fields.count_tokens(text, model) via tiktoken / Anthropic tokenizer. Lets an agent budget its own prompts and outputs instead of guessing.If you want one of these, open an issue (or a PR — each is a small self-contained module that fits the existing tools/ layout).
Recommended: no install — run on demand via uv:
uvx gnomon-mcp # serves stdio MCP, ready for any client
uvx gnomon-mcp --demo # call every tool once and print the results (no MCP client needed)Or install globally:
pip install gnomon-mcpAll recipes assume uvx gnomon-mcp. If you prefer a pinned install, swap the command for gnomon-mcp (with no uvx).
claude mcp add gnomon -- uvx gnomon-mcpOr edit ~/.claude.json / a project .mcp.json:
{
"mcpServers": {
"gnomon": { "command": "uvx", "args": ["gnomon-mcp"] }
}
}claude_desktop_config.json:
{
"mcpServers": {
"gnomon": { "command": "uvx", "args": ["gnomon-mcp"] }
}
}~/.cursor/mcp.json (or .cursor/mcp.json in a project):
{
"mcpServers": {
"gnomon": { "command": "uvx", "args": ["gnomon-mcp"] }
}
}~/.continue/config.yaml:
mcpServers:
- name: gnomon
command: uvx
args: ["gnomon-mcp"]Spawn uvx gnomon-mcp as a subprocess and speak MCP over stdin/stdout. That is the entire integration.
For team-shared instances or agents that can't spawn a local subprocess:
uvx gnomon-mcp --transport streamable-http --host 0.0.0.0 --port 8000
# also supported: --transport sseThen point your MCP client at http://<host>:8000/mcp (or /sse for the SSE transport).
The MCP tool descriptions are intentionally terse to keep persistent context cost minimal (~150 tokens for all four tools). The richer "when to reach for gnomon" guidance lives in a Claude Code skill that loads on demand.
The plugin wires both the MCP server and the skill in one shot. Inside Claude Code:
/plugin marketplace add lihtness/gnomon-mcp
/plugin install gnomon@gnomon-mcpThat registers gnomon as an MCP server (auto-starts via uvx) and installs the on-demand skill. Skill body loads only when the task triggers it — persistent context stays ~150 tokens for the four tool descriptions plus ~40 tokens for the skill's name + summary.
If you've already wired the MCP server with claude mcp add gnomon -- uvx gnomon-mcp and only want the skill:
mkdir -p ~/.claude/skills/gnomon
curl -fsSL https://raw.githubusercontent.com/lihtness/gnomon-mcp/main/skills/gnomon/SKILL.md \
-o ~/.claude/skills/gnomon/SKILL.mdFor agents without skill support, paste this short version into your system prompt or CLAUDE.md:
You have gnomon: deterministic tools for dates and math. Use them instead
of guessing.
- `now` — current moment (your training cutoff isn't today).
- `calendar(ops)` — batch date math: diff/until/since/add/weekday/
business_days/parse (natural language)/format.
- `calc(expressions)` — batch Python eval; math + statistics + common
builtins pre-loaded.
- `calc_convert(value, from, to)` — unit conversion via Pint.
Both batch tools take a list and return a list. Prefer one batched call
over many small ones.git clone https://github.com/lihtness/gnomon-mcp
cd gnomon-mcp
pip install -e ".[dev]"
pytestMIT
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.