The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the MCP Jp Corporate Id listing page.
An MCP (Model Context Protocol) server that validates and normalizes Japanese corporate numbers (houjin bangou) and qualified invoice issuer registration numbers, and normalizes/matches company names across common notation variants.
No network access is used at all (v1 calls no external APIs). Every check is done with formulas and dictionary data embedded in the code.
calculate_check_digit always includes a caution about this in its response.| Tool | Description |
|---|---|
validate_corporate_number | Verifies the check digit of a 13-digit corporate number |
calculate_check_digit | Computes the check digit for a 12-digit company registration number and derives the 13-digit corporate number |
validate_invoice_number | Validates a qualified invoice registration number ("T" + 13 digits) |
parse_corporate_number | Breaks down the structure of a corporate number (category, registry office code, organization type, serial number) |
normalize_company_name | Normalizes company-name notation (株式会社/(株)/㈱ etc., prefix/suffix placement, legacy kanji forms) |
generate_matching_key | Generates a normalized key for company-name deduplication/matching |
compare_company_names | Judges whether two company names likely refer to the same entity (likely_different only under a strict, narrow condition; returns "unknown" whenever it cannot tell) |
Every tool's response includes the primary sources (sources) behind its logic.
Verifies whether the check digit of a 13-digit corporate number is correct. Accepts full-width digits, hyphens,
and whitespace, which are normalized before validation. If the normalized length isn't 13 digits, or the check
digit doesn't match, the tool returns valid: false rather than throwing.
Computes the check digit from a 12-digit company registration number (assigned based on commercial registry records) and derives the 13-digit corporate number. Throws if the normalized input isn't exactly 12 digits (no guessing or zero-padding).
Caution: a 12-digit number could just as easily be a My Number (individual number) as a company registration
number. Every response includes a caution field reminding callers never to submit a My Number. If the registry
office code portion falls outside the typical range (0100–5000) confirmed from primary sources, a note is added.
Validates a qualified invoice registration number ("T" + 13 digits).
entityType: "corporate".entityType: "individual_or_other",
validates format only, and explicitly states that mathematical verification isn't possible in this case.formatValid: false is returned (not an exception).Verifies the check digit of a 13-digit corporate number and then parses the structure of its 12-digit base number.
category: national_organ_legislative / national_organ_administrative / national_organ_judicial /
local_government / registered_corporation / unregistered_corporation_or_unincorporated_association /
unused_rangeregistered_corporation, returns registryOfficeCode (4 digits), organizationTypeCode (raw 2 digits),
and serialNumber (6 digits).Normalizes company-name notation and separates out the "body name" with the corporate form removed.
Dictionary limits: only major corporate forms and variant characters are covered. This is not exhaustive of every Japanese corporate form or notation variant; anything not in the dictionary is left unrecognized and stays in the body name as-is.
Uses normalize_company_name internally and strips whitespace from the body name to produce a matching key for
deduplication.
Normalizes both names and compares them, returning a verdict, a confidence level, and reasons.
Rather than hand-writing the verdict/confidence logic and the explanatory text separately, this tool derives both
from a single structured object, evidence, which is included as-is in the response:
| Field | Meaning |
|---|---|
scriptMismatch | Whether the body names differ so much in character type that comparison itself was judged meaningless |
bodyMatch | How the body names relate: "exact", "partial", or "none" |
commonTokens | The actual shared substring(s) found |
labelMatch | Whether the corporate-form label (株式会社/合同会社/etc.) matches (null when not applicable) |
positionMatch | Whether the prefix/suffix placement matches (null when not applicable) |
distinguishing | The common-token + distinguishing-element pair behind a likely_different verdict (null otherwise) |
The decision logic (evidence → verdict/confidence) and the explanation logic (evidence → reasons) are
two separate functions that both read only from this same evidence object. Changing the decision rules
automatically keeps the explanation in sync, so it's structurally impossible to end up with a confident verdict
whose reasons/notes say "cannot be determined."
If the two body names differ greatly in character type — one is Latin-only while the other contains Japanese
(hiragana/katakana/kanji) — comparing them as strings is meaningless in principle. For example, "日本電気株式会社"
(Nippon Electric Company) and "NEC" refer to the same company, yet their body-name strings share no characters at
all ("NEC" is an abbreviation that cannot be detected by string comparison). Whenever this script mismatch is
detected, the tool returns unknown (confidence: "low") immediately, before attempting any scoring.
likely_differentlikely_different is returned only when all of the following hold:
Example: "東京電力" (Tokyo Electric Power) vs. "東北電力" (Tohoku Electric Power) — they share the suffix "電力" ("Electric Power") as a common token, with "東京" (Tokyo) and "東北" (Tohoku) as the distinguishing elements. Because both names follow the same naming pattern but diverge on a clear, region-identifying element, this tool treats them as likely different companies.
When this condition is not met (no shared part at all, or one name simply being a substring of the other), there
is no positive evidence of being different companies, so the tool always returns unknown. The mere fact that
two strings don't match or overlap is never, by itself, grounds for likely_different — string non-overlap is
not evidence of being different entities. The reasons text distinguishes "no shared part at all" from "only a
partial match" rather than using the same wording for both.
medium, and stays consistent with the verdict by constructionconfidence has only two possible values: "medium" and "low". **"high" has been removed.** Since the 2006 enactment of the Companies Act abolished the similar-trade-name restriction, two unrelated companies can be registered under the same name as long as their head-office locations differ — so a match based on trade name alone can never justify strong confidence ("high"`) in principle.
The set of valid confidence values is constrained per verdict at the TypeScript type level: unknown can
only ever carry confidence: "low", and both likely_same and likely_different can only ever carry
confidence: "medium". It is structurally impossible for this tool to return unknown together with
confidence: "medium".
This tool never "hedges by lowering confidence." When something is inherently indeterminate — such as the
prefix/suffix placement mismatch below — the tool sets verdict itself to unknown rather than downgrading
likely_same to a lower confidence. This matters for callers that branch purely on verdict (e.g. a batch job
that auto-merges everything marked likely_same): such a caller would silently swallow the ambiguity if it were
only reflected in confidence.
reasons always states concretely why the tool reached its conclusion — or why it couldn't (script mismatch, no
shared token, partial overlap only, a mismatched corporate form or prefix/suffix placement, possibility of an
abbreviation/English name, etc.), generated directly from evidence. Every response also includes a fixed note
on the method's limitations:
This tool only performs text comparison based on notation normalization; it cannot judge whether an abbreviation, English name, or nickname refers to the same entity. A definitive identity check requires cross-referencing corporate numbers.
| Case | Example | verdict | confidence |
|---|---|---|---|
| Body name, corporate form, and prefix/suffix placement all match | "株式会社サンプル" vs. "㈱サンプル" | likely_same | medium (same trade name could still belong to a different company — cross-reference the corporate number) |
| Body name and corporate form match, but prefix/suffix placement differs (prefix vs. suffix) | "株式会社サンプル" vs. "サンプル(株)" | unknown | low (prefix/suffix placement is part of the trade name itself — legally a different trade name that could belong to a different company) |
| Body name matches, but the corporate form itself differs (株式会社 vs. 合同会社) | "株式会社サンプル" vs. "合同会社サンプル" | unknown | low (an organizational conversion — e.g. a stock company converting to an LLC — keeps the same corporate number, so the two records could just be the same entity at different points in time) |
| Script mismatch (one Latin-only, the other contains Japanese) | "日本電気株式会社" vs. "NEC" | unknown | low (guard fires before scoring) |
| Shared common token (≥2 chars) with clearly different distinguishing elements (≥2 chars each) | "東京電力" vs. "東北電力" | likely_different | medium |
| One body name is a substring of the other (doesn't meet the distinguishing-element condition) | "株式会社サンプル" vs. "株式会社サンプル商事" | unknown | low |
| No shared token at all | "株式会社あいうえお" vs. "株式会社かきくけこ" | unknown | low |
The only case where this tool returns likely_same (medium) is when the body name, corporate form, and
prefix/suffix placement all match. Even when the body name appears to match, a differing prefix/suffix
placement or a differing corporate form leaves a real possibility of a different entity that cannot be ruled out
in principle, so the tool returns unknown. likely_different is returned only when the strict "shared pattern
unknown. unknown does not mean
"probably different" — it means "this method cannot determine it." When a definitive identity check is required,
obtain each company's corporate number and cross-reference with validate_corporate_number or similar.The number-validation logic was implemented only after retrieving and reading the following primary sources directly (last checked: 2026-07-29):
parse_corporate_number returns only the raw 2-digit code with no interpretive label.On success, build/index.js is created.
Add the following to your Claude Desktop config file (claude_desktop_config.json):
Config file locations:
%APPDATA%\Claude\claude_desktop_config.json~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop afterward, and tools such as validate_corporate_number become available.
All tests should show ✔.
Other servers by the same author: