Skip to main content
Glama

kaigo_mcp

An MCP server that exposes Japan's long-term care supply-demand data as tools that AI agents can use.

When connected from Claude Code or Claude Desktop, it can answer questions like "Does this city have enough special nursing homes (tokuyo)?" based on public data.

Status: Phase 1 (server itself) is working. The agent itself and the eval are not yet started.

What it does

MCP (Model Context Protocol) is a standard for giving LLMs tools. This repository builds the tool side and does not include the LLM itself. The server alone makes no API calls and incurs no charges.

[考える側]                    [このリポジトリ]
Claude Code / 自作エージェント  ←stdio→  kaigo-gap サーバー
「どの道具を使うか」を判断              呼ばれたらデータを返す

Tools

Tool

Purpose

get_national_baseline

National baseline values. The premise for evaluating individual figures

lookup_insurer

Look up supply-demand by municipality name or insurer name

rank_insurers

Rank insurers by tokuyo shortage (or sufficiency) order

The primary indicator is the number of tokuyo beds per 100 certified people with care level 3 or higher (national: 24.6, median: 26.7). Definitions and sources are on the kaigo_gap_analysis side.

We don't write the aggregation here

The data is written out by Proposal 4 (kaigo_gap_analysis) via export_web.py, and we use the same insurers.json that the public dashboard serves, by copying it. We don't rewrite the division here.

If the indicator definition lived in two places, then when the agent's answer and the dashboard's numbers disagreed, it would be impossible to determine which was correct. Proposal 4's dataset.py is written with a "one definition in one place" policy, and we maintain that across the boundary. Update with python scripts/sync_data.py.

What we were careful about in tool design

Returning just a number doesn't let you make a judgment. Even if you hand an LLM "12.4," it can't tell whether that's high or low, so we include the national rank and the national value in the tool's description text.

We don't hard-code same-name municipalities to a single entry. "Fuchu City" exists in both Tokyo and Hiroshima Prefecture. We return both candidates and leave the narrowing down to the caller.

We don't let a tokuyo bed count of 0 be read as "worst in the nation." There are 90 insurers in this situation, and all of them would tie for first place. We always attach the number of tied entries, and also add a note that "this is not uncommon in small municipalities, and residents often use facilities in neighboring municipalities." Without this, rank_insurers results would lead to the false conclusion that "Shingo Village is the worst region in the country."

If domain knowledge isn't embedded in the tool's responses, the same misreading recurs every time the calling model is changed. That's why we put it on the tool side rather than in the prompt.

Usage

pip install -r requirements.txt
python scripts/sync_data.py     # 案4からデータを取り込む
python scripts/smoke_test.py    # 通信の疎通確認

To use it from Claude Code, launching it in this directory will read .mcp.json. Settings for registering it with other clients:

{
  "mcpServers": {
    "kaigo-gap": {
      "command": "python",
      "args": ["-m", "kaigo_mcp"],
      "cwd": "C:\projects\kaigo_mcp"
    }
  }
}

Agent (Phase 2, up to verification)

python -m kaigo_mcp.agent --list
python -m kaigo_mcp.agent "尼崎市は特養が足りてる?" --verbose

Tools are called over the MCP server (we don't import the functions directly). If we just imported them, it wouldn't be going through MCP, and the claim "we built an MCP server" wouldn't be verified.

The 4 columns being compared

Column

Model

Location

Cost per question

A

qwen2.5:7b

Main machine (CPU)

0 yen

B

Qwen3.5 9B

RTX 5050 8GB

0 yen

C

Qwen3-235B

DeepInfra

approx. 0.11 yen

D

Claude Haiku 4.5

Anthropic

approx. 1.7 yen

B and C are both from the Qwen family. This way, the B→C difference reads as "the effect of model size alone," C→D as "the difference in model lineage," and A→B as "the effect of hardware and generation."

We only write one loop. If one side uses only the SDK's tool runner and the other side is hand-written, you can no longer separate whether the difference between columns is due to the model or to the loop implementation. The backend is responsible only for history conversion.

Measured results (Columns A and B)

Measured 6 times each with python scripts/probe_tool_calling.py.

Column A qwen2.5:7b (CPU)

Column B qwen3.5:9b (RTX 5050 8GB)

Tool call success rate (default temperature)

4/6 = 67%

6/6 = 100%

Tool call success rate (temperature 0)

6/6 = 100%

6/6 = 100%

Instruction following (whether the baseline was fetched first)

0/6 = 0%

6/6 = 100%

Time per run (after warm-up)

7.6 seconds

needs re-measurement

Temperature 0 being needed was specific to 7B

With qwen2.5:7b at the default temperature, the opening tag of <tool_call> breaks (a few characters like olith or pering get prepended), the ollama parser can't recognize it, and the call leaks into the body text. The telltale sign is that only the closing tag </tool_call> remains. Temperature 0 resolves it.

With qwen3.5:9b, it was 6/6 even at the default temperature. This breakage isn't a general problem with local execution; it was specific to this model's generation and size.

The bigger difference is "whether it follows instructions"

The system prompt instructs: "Before answering, check the national baseline with get_national_baseline." The 9B followed 6/6 times, and the 7B never followed, 0/6. Moreover, the 9B calls two tools in parallel in a single step.

The 7B was able to produce correct answers because it picked up the national value (24.6) embedded in the tool descriptions, but it didn't follow the instructed procedure. This is a difference in instruction following, not stability, and it matters more as the number of tools grows.

Limitations of this comparison

Since A→B changes both hardware and model generation at the same time, we can't separate whether the improvement comes from the GPU or from the 9B. To separate them, we'd need to run qwen2.5:7b on the GPU machine too (free, takes a few minutes).

The seconds are also inflated by the first-time model load. In the Column A measurements, the first run took 102.6 seconds, subsequent runs 7.6 seconds (average 23.4 seconds). The script was fixed to report the median and the first run separately, but the Column B figures were taken with the old script, so a re-measurement is needed.

Next steps

  • Re-measure Column B (re-take the seconds with the improved script)

  • Run qwen2.5:7b on the GPU machine to separate the effects of hardware and model generation

  • Columns C and D not yet run (they incur charges, so we'll run them once, after the columns are aligned)

  • Phase 3: the eval itself (correct answer rate and completion rate across multiple questions × multiple runs)

  • kaigo_matching — Structured extraction of care records (Proposal 1)

  • kaigo_gap_analysis — Supply-demand gap analysis by insurer (Proposal 4, the source of this data)

-
license - not tested
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Raw Japanese regulatory data for AI agents: pension, gazette, gBizINFO. x402-metered (USDC).

  • Verified Polish open data for AI agents: debt, budget, 460 MPs, votings, judiciary search, RAG.

  • Machine-readable utilities and datasets for AI agents.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ossudesu-lab/kaigo_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server