Open Helplines
by Kouki-odaka
README.md
<div align="center">
# open-helplines
**Stop hallucinating crisis numbers. One MCP import โ always verified.**
*Open data registry of mental health helplines worldwide. CC0. No API key. No lock-in.*
[](https://github.com/Kouki-odaka/open-helplines/actions/workflows/pr.yml)
[](https://www.npmjs.com/package/@open-helplines/mcp)
[](https://glama.ai/mcp/servers/Kouki-odaka/open-helplines)
[](https://www.npmjs.com/package/@open-helplines/core)
[](https://pypi.org/project/open-helplines/)
[](data/countries/)
[](LICENSE-DATA)
[](LICENSE)
[](https://securityscorecards.dev/viewer/?uri=github.com/Kouki-odaka/open-helplines)
[](https://github.com/Kouki-odaka/open-helplines/graphs/contributors)
[](https://star-history.com/#Kouki-odaka/open-helplines&Date)
<!-- DEMO: Replace the placeholder below once the demo GIF from Task #16 is ready -->

[๐ Visualization Site](https://kouki-odaka.github.io/open-helplines/en/) ยท
[๐ Docs](docs/) ยท
[๐ฌ Discussions](https://github.com/Kouki-odaka/open-helplines/discussions) ยท
[โค๏ธ Sponsor](https://kouki-odaka.github.io/open-helplines/en/donate/)
</div>
---
## Quick Start โ MCP (Claude Desktop, any MCP host)
Add to your `claude_desktop_config.json` and restart Claude Desktop โ zero configuration, zero API key:
```json
{
"mcpServers": {
"open-helplines": {
"command": "npx",
"args": ["@open-helplines/mcp"]
}
}
}
```
Then just ask Claude:
> *"What are the 24/7 crisis lines in Japan?"*
> *"Find a mental health helpline in Brazil that supports English."*
> *"My user seems to be in distress โ what's the nearest crisis line for Australia?"*
Claude returns verified numbers and URLs **verbatim from the registry** โ never hallucinated.
Three MCP tools available: `find_helplines`, `get_helpline_by_id`, `list_countries`.
See [examples/mcp-claude-desktop/README.md](examples/mcp-claude-desktop/README.md) for full setup.
---
## Why it matters
### The problem: LLMs hallucinate crisis numbers
Mental health chatbots, AI companionship apps, and LLM agents regularly encounter users in crisis. When they try to surface a helpline, they face two bad options:
1. **Commercial lock-in** โ directories like ThroughLine charge per query and impose restrictive terms, even when the underlying data is public-domain fact.
2. **Hallucination risk** โ without a verified data source, LLMs generate plausible-looking phone numbers that may be wrong. A wrong number when someone is in crisis is not a UX bug โ it's a safety failure.
### The solution: open-helplines
open-helplines fills the gap with **verified, structured, CC0 data** and a production-ready MCP server:
| Feature | Detail |
|:---|:---|
| **CC0 data** | Public domain. Use in any commercial or non-commercial product, including AI training, without attribution. |
| **JSON Schema** | Draft 2020-12. TypeScript types and Python Pydantic models generated from the schema. |
| **MCP server** | `npx @open-helplines/mcp` โ Safe Answer guardrails built in. |
| **Emergency First Resolver** | Crisis keywords trigger an instant CVD-safe banner with one-tap call/text/chat links. |
| **No-Log Crisis Finder** | Privacy-preserving search โ no query logging, no user fingerprinting. |
| **24 countries, growing** | AU, BD, BR, CA, CN, DE, EG, FR, GB, ID, IN, JP, KR, MX, NG, NZ, PH, PK, RU, TR, UA, US, VN, ZA |
---
## Features
### ๐ก๏ธ Safe Answer Guardrails
All MCP tools enforce five guardrails automatically โ no configuration needed:
| Guardrail | Behaviour |
|:---|:---|
| **Staleness check** | `verified_at` > 6 months โ `STALE_DATA` warning in response |
| **Misroute prevention** | `record.country` โ requested country โ `DIFFERENT_COUNTRY_CONTEXT` warning |
| **Fallback chain** | No data โ nearby country โ IASP/Befrienders international directory |
| **Mandatory citation** | Every record includes `source` + `verified_at` + `last_checked_url_status` |
| **Hallucination refusal** | Unknown country/ID โ `DATA_NOT_FOUND` sentinel (never hallucinate) |
See [`docs/features/safe-answer-mcp-guardrails.md`](docs/features/safe-answer-mcp-guardrails.md) for the full specification.
### ๐จ Emergency First Resolver
When a user on the [visualization site](https://kouki-odaka.github.io/open-helplines/en/) searches crisis-related terms, a CVD-safe banner instantly surfaces the nearest 24/7 helpline with one-tap call/text/chat links.
See [`docs/features/emergency-first-resolver.md`](docs/features/emergency-first-resolver.md).
### ๐ No-Log Crisis Finder
Privacy-preserving crisis search: no query logging, no user fingerprinting, no analytics on what people are searching for. See [`docs/features/no-log-crisis-finder.md`](docs/features/no-log-crisis-finder.md).
### ๐ Visualization Site
Explore the registry visually:
- **Globe view** โ interactive 3D globe with helpline coverage
- **Heatmap** โ choropleth map of coverage density
- **Network graph** โ relationships between organisations
โ [kouki-odaka.github.io/open-helplines/en](https://kouki-odaka.github.io/open-helplines/en/)
---
## Integration examples
### TypeScript / Node.js
```ts
import { loadCountry } from "@open-helplines/core";
const records = await loadCountry("JP");
const crisis = records.filter(r => r.category === "suicide_prevention");
for (const r of crisis) {
console.log(r.name, r.contacts[0].number);
}
```
### Python
```python
from open_helplines import Registry
registry = Registry.from_github() # fetches data/index.json + country files
records = registry.find(country="JP", category="suicide_prevention")
for r in records:
print(r.name, r.contacts[0].number)
```
### Plain JSON (no dependencies)
```sh
# Discover all covered countries
curl -s https://raw.githubusercontent.com/Kouki-odaka/open-helplines/main/data/index.json | \
jq '.countries[] | {country, record_count}'
# All helplines for Japan
curl -s https://raw.githubusercontent.com/Kouki-odaka/open-helplines/main/data/countries/jp/helplines.json | \
jq '.records[] | select(.category == "suicide_prevention") | {name, contacts: [.contacts[].number]}'
```
### OpenAI function calling
```ts
import OpenAI from "openai";
const client = new OpenAI();
const response = await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "What crisis lines exist in Japan?" }],
tools: [{
type: "function",
function: {
name: "find_helplines",
description:
"Return verified crisis hotlines. Surface phone numbers and URLs verbatim โ never generate them.",
parameters: {
type: "object",
properties: {
country: { type: "string", description: "ISO 3166-1 alpha-2 code, e.g. 'JP'" },
category: { type: "string" },
},
required: ["country"],
},
},
}],
});
```
Full runnable example: [examples/openai-function-calling/main.ts](examples/openai-function-calling/main.ts)
### Anthropic tool use
```python
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4-5",
max_tokens=1024,
tools=[{
"name": "find_helplines",
"description": "Return verified crisis hotlines. Extract contact info verbatim โ never paraphrase.",
"input_schema": {
"type": "object",
"properties": {
"country": {"type": "string"},
"category": {"type": "string"},
},
"required": ["country"],
},
}],
messages=[{"role": "user", "content": "Find mental health lines in Australia."}],
)
```
Full runnable example: [examples/anthropic-tool-use/main.py](examples/anthropic-tool-use/main.py)
### Local LLM (Ollama)
```python
from openai import OpenAI # Ollama's OpenAI-compatible API
client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
# Same tool definition as above โ no API key, fully offline
```
Full runnable example: [examples/local-llama/main.py](examples/local-llama/main.py)
---
## JSON Schema
```
https://raw.githubusercontent.com/Kouki-odaka/open-helplines/main/schemas/helpline.schema.json
```
JSON Schema Draft 2020-12 โ single source of truth for all types and validation. ([ADR-001](docs/adr/ADR-001-json-schema-draft-2020-12.md))
---
## Contributing
**Data corrections and additions are always welcome โ no Discussion needed, open a PR directly.**
Data PRs are the fastest way to help: if you know the correct number for a country, add or fix it.
Schema changes require a [GitHub Discussion](https://github.com/Kouki-odaka/open-helplines/discussions) first.
See [CONTRIBUTING.md](CONTRIBUTING.md) for data format, quality requirements, and commit conventions.
---
## Community
๐ฌ **[GitHub Discussions](https://github.com/Kouki-odaka/open-helplines/discussions)** โ feature requests, country coverage questions, schema proposals, and general conversation.
We especially welcome contributions from mental health professionals and NPO staff who can verify data accuracy for their country.
| Document | Description |
|:---|:---|
| [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) | Community standards (Contributor Covenant 2.1) |
| [SECURITY.md](SECURITY.md) | Vulnerability reporting policy |
| [GOVERNANCE.md](GOVERNANCE.md) | Project governance and decision flow |
| [Press kit](docs/press-kit/README.md) | Logos, descriptions, and key facts for media use |
---
## Sponsor
open-helplines is free, open, and CC0 โ and will always be. If you find it useful, consider sponsoring to keep the data verified and the tooling maintained:
- โค๏ธ [Donate via the project site](https://kouki-odaka.github.io/open-helplines/en/donate/)
- ๐ GitHub Sponsors โ coming soon (see [FUNDING.yml](.github/FUNDING.yml))
- ๐๏ธ Open Collective โ coming soon
---
## License
open-helplines uses **dual licensing**:
| Component | License | Why |
|:---|:---|:---|
| **Data** (`data/**`, `dist/by-*/*.json`) | [CC0 1.0](LICENSE-DATA) | Maximally usable โ no friction for crisis tools, AI training, or commercial use |
| **Code** (TypeScript, Python, scripts, workflows) | [Apache-2.0](LICENSE) | Patent protection, attribution-friendly |
You may use the data in any commercial or non-commercial product, including AI systems, without attribution. The code requires the Apache-2.0 notice.
See [NOTICE](NOTICE) for the dual-license declaration and [docs/LICENSING.md](docs/LICENSING.md) for a detailed explanation including commercial use, AI training, and derivative work policies.
---
## Architecture decisions
| ADR | Decision |
|:---|:---|
| [ADR-001](docs/adr/ADR-001-json-schema-draft-2020-12.md) | JSON Schema Draft 2020-12 as single source of truth |
| [ADR-002](docs/adr/ADR-002-cc0-data-apache-code.md) | CC0 data + Apache-2.0 code dual-license |
| [ADR-003](docs/adr/ADR-003-per-country-files.md) | Per-country file structure |
| [ADR-004](docs/adr/ADR-004-mcp-server-design.md) | MCP server โ stdio transport, 3 tools |
---
## Disclaimer
open-helplines is a **developer tool** โ a directory of contact information, not a crisis service.
- It cannot assess risk, provide counseling, or respond to emergencies.
- Phone numbers are verified periodically, not in real time. Always show the `verified_at` date to end users.
- **If someone is in immediate danger, direct them to local emergency services (911, 119, 999โฆ) first.**
See [docs/safety/SAFETY.md](docs/safety/SAFETY.md) for the full safety policy and responsible LLM integration guidelines.
---
<div align="center">
[](https://star-history.com/#Kouki-odaka/open-helplines&Date)
*If open-helplines saves someone from receiving a wrong crisis number, it's worth a โญ.*
</div>
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessUnresponsive