CJK Calendar Converter MCP Server
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., "@CJK Calendar Converter MCP ServerConvert 崇禎三年四月初三 to Gregorian"
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.
CJK Calendar Converter
A SQLite-backed historical calendar conversion system for Chinese, Japanese, Korean, and Vietnamese dates. Converts between traditional East Asian lunisolar calendars and the Gregorian/Julian calendar using Julian Day Numbers (JDN) as the universal pivot.
Designed for both human users (via REST API) and LLMs (via MCP server or API).
Disclaimer: This project has not been thoroughly tested against all historical sources. Calendar conversion for East Asian historical dates is inherently complex — different sources sometimes disagree on intercalary month placement, era boundaries, and calendar reform dates. There may be errors, especially for:
Dates during periods of dynastic transition or competing calendars
Vietnamese era year counts near era boundaries (±1 year offset possible)
Peripheral or short-lived dynasties not fully covered in the DILA dataset
Proleptic date ranges (hypothetical extensions before/after an era's actual use)
Always cross-reference with authoritative sources for scholarly or critical use.
How It Works
Every calendar date — whether Gregorian, Julian, Chinese lunisolar, Japanese imperial, Korean, or Vietnamese — can be mapped to a unique Julian Day Number (an integer counting days from January 1, 4713 BCE). This makes JDN the perfect intermediate representation:
崇禎三年四月初三 → JDN 2316539 → 1630-05-14 (Gregorian)
→ 寛永七年四月三日 (Japanese)
→ 天聰四年四月三日 (Later Jin/清前身)
→ 朝鮮七年四月三日 (Korean)
→ 後黎朝德隆元年四月三日 (Vietnamese)The database stores ~131,000 lunar month records with JDN ranges, covering:
Country | Coverage | Source |
China | ~220 BCE – 1912 CE | DILA Authority Database |
Japan | 593 – 1872 CE | DILA Authority Database |
Korea | 56 BCE – 1885 CE | DILA Authority Database |
Vietnam | ~544 – 1945 CE | Derived from Chinese lunar months + Vietnamese era data |
Related MCP server: shirabe-calendar-api
Quick Start
Prerequisites
uv (Python package manager)
Python 3.12+ (uv will install it automatically)
Setup
git clone https://github.com/kltng/calendar_converter.git
cd calendar_converter
# Install dependencies
uv sync --extra dev
# Download the DILA source data
mkdir -p data/raw
curl -L -o data/raw/authority_time.zip \
"https://authority.dila.edu.tw/downloads/authority_time.2012-02.zip"
cd data/raw && unzip authority_time.zip && cd ../..
# Build the SQLite database
uv run python -m data.scripts.build_db
uv run python -m data.scripts.add_vietnamese
# Run tests to verify
uv run pytestRun the API Server
uv run uvicorn src.calendar_converter.api:app --reload --port 8000Open http://localhost:8000/docs for the interactive Swagger UI.
Docker
docker build -t calendar-converter .
docker compose upThe SQLite database is embedded in the container image — no external database needed.
Usage
1. REST API
Convert a CJK date
curl "http://localhost:8000/convert?date=崇禎三年四月初三"Response:
{
"jdn": 2316539,
"gregorian": "1630-05-14",
"julian": null,
"ganzhi": {
"year": "庚午",
"month": "辛巳",
"day": "壬子"
},
"cjk_dates": [
{
"era_name": "崇禎",
"dynasty_name": "明",
"country": "chinese",
"year_in_era": 3,
"month": 4,
"month_name": "四",
"is_leap_month": false,
"day": 3
},
{
"era_name": "天聰",
"dynasty_name": "後金",
"country": "chinese",
"year_in_era": 4,
"month": 4,
"day": 3
},
{
"era_name": "寛永",
"dynasty_name": "江戸時代",
"country": "japanese",
"year_in_era": 7,
"month": 4,
"day": 3
}
]
}Convert by Julian Day Number
curl "http://localhost:8000/convert?jdn=2316539"Convert by Gregorian date
curl "http://localhost:8000/convert?gregorian=1630-05-14"Disambiguate with country hint
When an era name is shared across countries, use the country parameter:
curl "http://localhost:8000/convert?date=天保三年閏九月十五日&country=japanese"Disambiguate era names
Many era names were reused across dynasties. When the converter finds multiple matching eras, the response includes ambiguous: true and an other_candidates list showing all alternative interpretations:
curl "http://localhost:8000/convert?date=乾德二年正月初一"{
"jdn": 2057111,
"gregorian": "0920-01-29",
"ambiguous": true,
"other_candidates": [
{
"jdn": 2073191,
"gregorian": "0964-02-21",
"era_name": "乾德",
"dynasty_name": "吳越",
"emperor_name": "忠懿王",
"country": "chinese",
"year_in_era": 2,
"month": 1,
"day": 1
},
{
"jdn": 2073191,
"gregorian": "0964-02-21",
"era_name": "乾德",
"dynasty_name": "北宋",
"emperor_name": "太祖",
"country": "chinese",
"year_in_era": 2,
"month": 1,
"day": 1
}
],
"cjk_dates": [ ... ]
}Use dynasty or emperor hints to narrow to a specific era:
# Narrow to Northern Song dynasty
curl "http://localhost:8000/convert?date=乾德二年正月初一&dynasty=北宋"
# Narrow by emperor name
curl "http://localhost:8000/convert?date=上元二年正月初一&emperor=肅宗"
# Combine hints
curl "http://localhost:8000/convert?date=至元三年正月初一&dynasty=元&emperor=順帝"When hints resolve the ambiguity, ambiguous will be false and other_candidates will be empty.
Search eras
# By era name
curl "http://localhost:8000/eras?name=崇禎"
# By dynasty
curl "http://localhost:8000/eras?dynasty=明"
# By country
curl "http://localhost:8000/eras?country=vietnamese"Batch convert
curl -X POST http://localhost:8000/convert/batch \
-H "Content-Type: application/json" \
-d '["崇禎三年四月初三", "康熙元年正月初一", "嘉隆元年正月初一"]'Download the database
curl -o calendar.db http://localhost:8000/db/download2. Use the SQLite Database Directly
Download calendar.db and query it with any SQLite client:
-- Find all eras named 崇禎
SELECT * FROM era_summary WHERE era_name = '崇禎';
-- Find the lunar month containing a specific JDN
SELECT m.*, es.era_name, es.dynasty_name, es.country
FROM month m
JOIN era_summary es ON es.era_id = m.era_id
WHERE m.first_jdn <= 2316539 AND m.last_jdn >= 2316539;
-- List all Vietnamese eras
SELECT era_name, dynasty_name, start_jdn, end_jdn
FROM era_summary WHERE country = 'vietnamese'
ORDER BY start_jdn;
-- Find concurrent eras for a given year (JDN range)
SELECT es.era_name, es.dynasty_name, es.country
FROM era_summary es
WHERE es.start_jdn <= 2316539 AND es.end_jdn >= 2316539;3. MCP Server (LLM Integration)
The MCP server lets LLMs call calendar conversion as a tool via the Model Context Protocol. Three transports are supported:
Option A: Streamable HTTP (Remote)
The deployed API includes an MCP endpoint at /mcp/. Use this with any MCP client that supports Streamable HTTP transport — no local installation needed.
{
"mcpServers": {
"calendar": {
"type": "streamable-http",
"url": "https://calendar-converter.098484.xyz/mcp/"
}
}
}Option B: SSE (Remote)
For MCP clients that use SSE transport (e.g., LM Studio), connect to the /sse/ endpoint:
{
"mcpServers": {
"calendar": {
"type": "sse",
"url": "https://calendar-converter.098484.xyz/sse/"
}
}
}Option C: stdio (Local)
For local use, run the stdio-based MCP server directly:
{
"mcpServers": {
"calendar": {
"command": "uv",
"args": ["run", "python", "-m", "src.calendar_converter.mcp_server"],
"cwd": "/absolute/path/to/calendar_converter"
}
}
}The stdio server also supports SSE transport for local use with clients like LM Studio:
uv run python -m src.calendar_converter.mcp_server --transport sse --port 8001Available MCP Tools
Tool | Description | Required Parameters |
| Convert a CJK date string to JDN + all equivalents |
|
| Convert a Julian Day Number to all calendars |
|
| Convert YYYY-MM-DD to all calendars |
|
| Search era metadata |
|
All conversion tools accept optional disambiguation parameters: country ("chinese", "japanese", "korean", "vietnamese"), dynasty (e.g., "唐", "北宋"), and emperor (e.g., "肅宗"). When an era name matches multiple eras, the response includes ambiguous: true with other_candidates listing all alternatives — the LLM can then re-query with hints.
Supported Input Formats
CJK Date Strings
Format | Example | Parsed As |
Standard Chinese |
| 崇禎 era, year 3, month 4, day 3 |
With 日 suffix |
| 康熙 era, year 61, month 12, day 29 |
Leap month (閏) |
| 天保 era, year 3, leap month 9, day 15 |
Yuan year (元年) |
| 崇禎 era, year 1, month 1, day 1 |
Zheng month (正月) |
| 嘉隆 era, year 1, month 1, day 1 |
廿/卅 shorthands |
| 康熙 era, year 3, month 12, day 29 |
Year only |
| First month of that year |
Year+month only |
| First day of that month |
Ganzhi year |
| 嘉慶 era, year with ganzhi 甲子 |
Full ganzhi |
| Resolved via sexagenary cycle lookup |
Mixed ganzhi+numeric |
| Ganzhi year + numeric month/day |
Japanese Shorthand
Format | Example | Parsed As |
Meiji |
| 明治45年7月30日 |
Taisho |
| 大正15年12月25日 |
Showa |
| 昭和64年1月7日 |
Heisei |
| 平成26年6月8日 |
Reiwa |
| 令和1年5月1日 |
Database Schema
dynasty (id, type) -- 'chinese'|'japanese'|'korean'|'vietnamese'
dynasty_name (dynasty_id, name, ranking, language_id)
└─ emperor (id, dynasty_id)
emperor_name (emperor_id, name, ranking, language_id)
└─ era (id, emperor_id)
era_name (era_id, name, ranking, language_id)
└─ month (id, era_id, year, month, month_name, leap_month,
first_jdn, last_jdn, ganzhi, start_from, status, eclipse)
era_summary (VIEW) -- denormalized join for queries: era + emperor + dynasty + JDN range
period -- historical period spans
day_comment -- annotations for specific JDNs (historical events, eclipses)The month table is the core: each row represents one lunar month with its JDN range. Individual days are derived from first_jdn + (day - start_from).
Key Concepts
Julian Day Number (JDN): A continuous integer day count starting from noon GMT, January 1, 4713 BCE (Julian calendar). Every calendar date maps to exactly one JDN. This avoids needing pairwise conversion formulas between calendar systems.
Lunisolar Calendar: East Asian calendars track both lunar months (29–30 days) and solar years. When a lunar month contains no "major solar term" (中氣), it becomes an intercalary/leap month (閏月). This is determined astronomically, not by formula — historical data must be looked up.
Era Names (年號): Reign-period names that reset year counting. One emperor could use multiple era names. The same name can appear in different dynasties and countries (e.g., 太平 was used 10+ times). Always use dynasty or country for disambiguation.
Sexagenary Cycle (干支): A 60-unit cycle from 10 Heavenly Stems (天干) × 12 Earthly Branches (地支). Applied to years, months, days, and hours. Year ganzhi is stored in the database; month ganzhi is computed via the 五虎遁 formula; day ganzhi is computed from JDN.
Proleptic Dates: Dates marked status='P' extend a calendar system beyond its actual historical use (e.g., using an era name for dates after that era ended, because historical sources reference them that way).
Agent Skill (Claude Code / LLM Tool Use)
The skill/ directory contains a standalone agent skill — a self-contained, zero-dependency Python script with its own SQLite database that any LLM agent (Claude Code, etc.) can use for calendar conversion without needing the full API server.
What's Included
skill/
├── SKILL.md # Skill manifest and documentation
├── scripts/
│ ├── calendar_converter.py # Standalone converter (Python 3.10+, stdlib only)
│ └── .gitignore # Ignores downloaded calendar.db
└── references/
└── database_schema.md # SQLite schema and query patternsSetup
# Download the SQLite database (~14 MB) on first use
python3 skill/scripts/calendar_converter.py setupCLI Usage
# CJK date → Gregorian
python3 skill/scripts/calendar_converter.py convert "崇禎三年四月初三"
# Gregorian → all CJK calendars
python3 skill/scripts/calendar_converter.py gregorian 1644 3 19
# Julian Day Number → all calendars
python3 skill/scripts/calendar_converter.py jdn 2299161
# Search eras
python3 skill/scripts/calendar_converter.py eras --name 康熙
python3 skill/scripts/calendar_converter.py eras --dynasty 明 --country chineseAdding to a Skill Hub
Copy the skill/ directory (or symlink it) into your skill hub:
cp -r skill/ /path/to/your-skill-hub/cjk-calendarThe skill is fully self-contained: zero external dependencies, downloads its own database, and runs with Python 3.10+ stdlib only.
Development
# Run all tests (1416 tests)
uv run pytest
# Run a single test file
uv run pytest tests/test_parser.py
# Run a specific test
uv run pytest tests/test_converter.py::TestGanzhi::test_full_ganzhi_in_conversion -v
# Run CBDB verification tests only
uv run pytest tests/test_cbdb_verification.py -v
# Rebuild the database from scratch
uv run python -m data.scripts.build_db
uv run python -m data.scripts.add_vietnameseTest Suites
File | Tests | Description |
| 23 | CJK date string parsing |
| 39 | JDN conversion, ganzhi, disambiguation |
| 19 | FastAPI endpoint integration |
| 10 | MCP stdio server tools |
| 5 | DILA reference date verification |
| 1310 | Era name cross-validation against external dataset |
Data Sources and Acknowledgements
This project builds on the work of several institutions and individuals:
DILA Authority Database (Primary Source)
The core calendar data (Chinese, Japanese, Korean) comes from the Dharma Drum Institute of Liberal Arts (DILA) Time Authority Database, assembled between 2008–2010 by the Library and Information Center of Dharma Drum Buddhist College (法鼓佛教學院).
Website: https://authority.dila.edu.tw/
Download: https://authority.dila.edu.tw/docs/open_content/download.php
Author: Simon Wiles, DDBC
License: Creative Commons Attribution-ShareAlike 3.0 Unported
Japanese data builds upon data provided by Takashi SUGA
The DILA database uses Julian Day Numbers as the fundamental unit for date designation, with lunar months as the smallest stored entity. This elegant design inspired the architecture of this project.
CeJS (Colorless echo JavaScript)
The CeJS library by kanasimi provided reference data for Vietnamese calendar eras and validation of conversion results.
Repository: https://github.com/kanasimi/CeJS
Era Converter Demo: https://kanasimi.github.io/CeJS/_test%20suite/era.htm
Coverage: 246 BCE – 2100 CE across multiple calendar systems
CBDB (China Biographical Database)
The CBDB project at Harvard University provided nianhao (era name) verification data used for cross-validation testing.
Website: https://projects.iq.harvard.edu/cbdb
NIAN_HAO table: https://input.cbdb.fas.harvard.edu/codes/NIAN_HAO
Related NPM package (cn-era): https://www.npmjs.com/package/cn-era
Julian Day Number Algorithms
JDN ↔ Gregorian/Julian conversion algorithms are based on:
Jean Meeus, Astronomical Algorithms (Willmann-Bell, 1991)
E.G. Richards, "Calendars" in Explanatory Supplement to the Astronomical Almanac (2013)
Vietnamese Historical Data
Vietnamese dynasty and era information is derived from:
Đại Việt sử ký toàn thư (大越史記全書) — Complete Annals of Đại Việt
CeJS Vietnamese era data (see above)
Sexagenary Cycle (干支) Computation
Month ganzhi uses the traditional 五虎遁 (Five Tigers) formula. Day ganzhi is computed from JDN using a mod-60 cycle calibrated against known historical dates.
License
The DILA Authority Database data is licensed under CC BY-SA 3.0. The code in this repository is available under the MIT License. If you use the calendar data, please attribute the DILA Authority Database as required by their license.
Browser MCP clients
For browser or Chrome extension clients, set MCP_ALLOWED_ORIGINS to a
comma-separated list of exact origins, for example
chrome-extension://<extension-id>,https://your-client.example. Whitespace and
empty entries are ignored. Keep MCP_ALLOWED_HOST set to the server hostname.
Restart the service after changing these variables. An empty origin list rejects
requests with an Origin header; clients without one continue to work.
Available Tools
4 toolsconvert_cjk_dateA
Convert a CJK (Chinese/Japanese/Korean/Vietnamese) historical date to Julian Day Number and equivalent dates in all concurrent calendars.
Input examples: '崇禎三年四月初三', '康熙元年正月初一', '寛永七年四月初三', 'M45.7.30'. Returns JDN, Gregorian date, Julian date (pre-1582), ganzhi (干支), and all concurrent CJK era representations.
Args: date: CJK date string, e.g. '崇禎三年四月初三' or 'M45.7.30' country: Optional country hint to disambiguate era names (chinese, japanese, korean, vietnamese) dynasty: Optional dynasty hint to disambiguate era names, e.g. '唐', '元', '北宋' emperor: Optional emperor hint to disambiguate era names, e.g. '肅宗', '順帝'
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | ||
| country | No | ||
| dynasty | No | ||
| emperor | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden of behavioral disclosure. It explains exactly what the tool does, what it returns (JDN, Gregorian date, Julian date pre-1582, ganzhi, concurrent era representations), and provides representative input formats. No unexpected side effects or hidden behaviors are left unaddressed.
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-structured with a summary, input examples, return values, and per-argument details. It is front-loaded with the core purpose, and every sentence adds useful information without excessive verbosity.
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 complete for a converter tool with an output schema. It covers input syntax, optional ambiguity-resolution hints, and the nature of the returned conversions. An agent has everything needed to invoke the tool correctly and interpret the result.
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%, so the description must compensate. It does: each parameter is explained with concrete examples and purpose, and optional disambiguation hints (country, dynasty, emperor) are clearly described with valid values and sample inputs.
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 opens with a specific verb and resource: 'Convert a CJK ... historical date to Julian Day Number and equivalent dates in all concurrent calendars.' It clearly distinguishes the tool from siblings like convert_jdn and convert_gregorian_date by specifying the input type and output 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?
Usage context is implied clearly: use this when you have a CJK historical date string. Examples of valid inputs make the intended use concrete, but the description does not explicitly mention when to prefer sibling tools like convert_jdn or search_era, nor does it state exclusion conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
convert_gregorian_dateA
Convert a Gregorian date (YYYY-MM-DD) to Julian Day Number and all concurrent CJK era dates.
Args: date: Gregorian date in YYYY-MM-DD format
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It clearly says the conversion produces JDN and CJK era dates, but does not disclose behavior such as handling of invalid dates, supported date ranges, or whether the operation is purely stateless. The presence of an output schema covers return structure, but not edge-case behavior.
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 a single purposeful sentence followed by a one-line parameter note. It is front-loaded with the primary behavior and contains no filler or tangential information.
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?
With one simple parameter and an output schema present, the description gives the essential information needed to call the tool. Minor gaps remain around edge cases, date-range limits, and exactly which CJK calendars are included, but these do not block basic correct use.
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%, and the description compensates by specifying the exact format for the single parameter: 'Gregorian date in YYYY-MM-DD format'. This adds meaningful lexical and format guidance beyond the bare schema, though it omits any range, timezone, or validation constraints.
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 specific verb ('convert'), the input resource ('Gregorian date'), and the full output scope ('Julian Day Number and all concurrent CJK era dates'). This clearly distinguishes it from siblings like convert_jdn and convert_cjk_date, which cover only a subset of the outputs.
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 intended use is implied by the conversion target: an agent should pick this tool when needing both JDN and CJK era dates from a Gregorian input. However, it does not explicitly compare against siblings like convert_cjk_date or convert_jdn, nor state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
convert_jdnA
Convert a Julian Day Number to all calendar representations.
Returns Gregorian, Julian, ganzhi (干支), and all concurrent CJK era dates.
Args: jdn: Julian Day Number
| Name | Required | Description | Default |
|---|---|---|---|
| jdn | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the output types, but does not mention side effects, error handling, prerequisites, or authentication needs. For a conversion tool, this is minimal behavioral transparency.
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 concise and front-loaded, opening with the core action and resource, then detailing return types and the argument. Every sentence adds value with no redundancy or filler.
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?
For a simple conversion tool with one parameter and an output schema present, the description covers the essential purpose and return types. It is adequate but lacks discussion of edge cases, error behavior, or prerequisites, especially without annotations to fill in safety and permission details.
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?
The description defines the single parameter 'jdn' as a Julian Day Number, adding meaning beyond the schema's type-only definition. However, it lacks additional context like valid range or format, so it only partially compensates for the 0% schema description coverage.
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 clearly states the action 'Convert' and the resource 'Julian Day Number', and explicitly enumerates the output types (Gregorian, Julian, ganzhi, CJK era dates). This distinguishes it from siblings like convert_gregorian_date and convert_cjk_date, which are specific to one representation.
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 implies usage by stating it converts to 'all calendar representations', making it the natural choice for any JDN conversion. However, it does not explicitly mention when not to use it or compare it to alternatives like convert_gregorian_date, so the routing is clear but not fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_eraA
Search for era (年號) metadata by name, dynasty, or country.
Returns era name, dynasty, emperor, date range, and JDN range.
Args: name: Era name, e.g. '崇禎', '康熙', '寛永' dynasty: Dynasty name, e.g. '明', '清', '唐' country: Filter by country (chinese, japanese, korean, vietnamese)
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| country | No | ||
| dynasty | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries the burden. It discloses that the tool returns era metadata fields and mentions acceptable country values, but it does not explain match behavior (exact vs substring), how multiple filters combine, what happens when no arguments are provided, or any result limits.
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 structured: purpose first, then return fields, then parameter details. The Args section somewhat repeats the schema property names, but it earns its place by adding examples and allowed values, so the length is justified.
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?
An output schema exists, so return values do not need to be described in depth. However, the tool has three optional, nullable parameters and no required fields, yet the description never states whether at least one filter is expected or how omitted filters behave. It is adequate for simple lookups but leaves important invocation semantics unspecified.
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?
The schema has 0% description coverage, so the description must compensate. It does so by listing each parameter with concrete examples for name (e.g. '崇禎', '康熙') and explicit allowed values for country (chinese, japanese, korean, vietnamese). It does not clarify whether name/dynasty match exactly or partially, but it adds meaningful semantic detail.
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 opens with a specific verb and resource: 'Search for era (年號) metadata by name, dynasty, or country.' It clearly scopes the tool to era metadata lookup and distinguishes it from the sibling date-conversion tools, which have different purposes.
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 gives clear context for when the tool is appropriate: when you need era metadata such as era name, dynasty, emperor, date range, or JDN range. It does not explicitly name alternatives or exclusions, but the sibling tools are clearly date converters, so the use case is reasonably distinct.
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.
4 tool updates
v0.1.0- First observed
convert_cjk_date - First observed
convert_gregorian_date - First observed
convert_jdn - First observed
search_era
TDQS
Scored across 4 tools
Each tool has a clearly distinct purpose: converting from a CJK date, from a Julian Day Number, from a Gregorian date, and searching era metadata. There is no overlap or ambiguity between them.
All tools follow a consistent verb_noun pattern: convert_cjk_date, convert_jdn, convert_gregorian_date, and search_era. The naming convention is uniform and predictable.
Four tools is an appropriate, minimal set for a calendar converter server. Each tool covers a necessary conversion direction or lookup, and none are redundant or missing.
The server covers all major conversion paths: from CJK, JDN, and Gregorian dates, plus era searching. It returns all relevant calendar representations (Gregorian, Julian, ganzhi, CJK eras), so the surface is complete for its domain.
Maintenance
Related MCP Connectors
Deterministic calendars and cosmic date JSON for AI agents via MCP (Gregorian 1900-2100).
BaZi four pillars, Chinese zodiac, lunisolar calendar and almanac days for AI agents.
Read-only Bazi, True Solar Time, and Chinese almanac tools in English and Traditional Chinese.
China holidays and lunar calendar lookup, solar-to-lunar conversion and yearly schedule.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceProvides professional Chinese astrology calculations including Four Pillars, Five Elements, zodiac signs, and lunar calendar details. It allows users to perform accurate Bazi analysis with global timezone support directly within MCP-compatible clients.12 npm10MIT
- AlicenseNot gradedqualityDmaintenanceJapanese calendar API for AI agents. Provides Rokuyo, Rekichu, Eto, 24 Solar Terms, and fortune judgments. MCP + REST API.5 npmMIT
- FlicenseNot gradedqualityDmaintenanceEnables Korean lunar-solar birthday conversion, including leap month support, using a Streamable HTTP MCP server.-
- AlicenseAqualityBmaintenanceProvides MCP tools for Chinese metaphysics, including BaZi (Four Pillars) charting, Liu Yao hexagram casting, lunar conversion, and AI-powered destiny analysis.1027 npmMIT