country-state-city
Click on "Install 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., "@country-state-citysearch for cities named Paris"
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.
Country State City
About
Country State City provides a versioned dataset of 250 countries and territories, 4,963 administrative areas, 147,739 populated-place records, and 922 Türkiye districts as an NPM package, an MCP server for AI assistants, and an interactive web app.
Related MCP server: OpenStreetMap MCP Server
Features
Versioned location data — 250 countries and territories, 4,963 administrative areas, and 147,739 places
Immutable public identity — Namespaced
csc:country|state|city|district:{id}values, source-ID collision gates, and version-pair migration downloadsNormalized display labels — CLDR-style country names and separated administrative categories across subdivision and place records without changing canonical source names
Reproducible artifacts — one canonical country/state/city source generates optimized data, browser shards, and package copies with byte-level CI drift checks
Multiple Formats — JSON, CSV, XML, YAML output
MCP Server — Connect to Claude Desktop and AI assistants
TypeScript — Full type definitions included
Dual Entry Points — Separate browser (ESM) and Node.js (CJS/ESM) builds
Search — Filter countries, states, and cities by name
Ranked location search — Canonical names, aliases, transliterations, typo tolerance, match reasons, and stable IDs
Nearest-centre lookup — Lazy spatial indexes, batch queries, antimeridian handling, distance, and confidence metadata
Timezone utilities — Observe IANA timezone offsets for a specific instant instead of relying on stale stored offsets
Explicit Türkiye districts — 922 current districts with province parents, legacy aliases, open source IDs, and centre-coordinate review status
Optional boundary layers — Versioned Türkiye admin-1/admin-2 GeoJSON downloads and a lazy overview TopoJSON export
Auditable quality — Machine-readable coverage, provenance, normalization, package-budget, and migration reports
Interactive Playground — Test the API at the live demo
Quick Start
npm install @tansuasici/country-state-cityimport { CountryStateCity, toPublicId } from '@tansuasici/country-state-city';
const countries = CountryStateCity.getAllCountries();
const turkey = CountryStateCity.getCountryByIso2('TR');
const states = CountryStateCity.getStatesByCountryId(225);
const cities = CountryStateCity.getCitiesByStateId(2170);
const districts = CountryStateCity.getDistrictsByCountryCode('TR');
const currentAdmin1 = CountryStateCity.getAdministrativeAreas({ level: 1 });
const settlements = CountryStateCity.getSettlements({ countryCode: 'TR' });
const stableCityId = toPublicId('city', cities[0].id);
const stableDistrictId = toPublicId('district', districts[0].id);
// Search
const results = CountryStateCity.searchLocations('İstanbull', {
countryCode: 'TR',
entityTypes: ['state'],
});
// Optional Türkiye boundary asset — not loaded with the core API
const { default: turkeyOverview } = await import(
'@tansuasici/country-state-city/data/boundaries/tr/overview.json',
{ with: { type: 'json' } }
);
// Different formats
const csv = CountryStateCity.getAllCountries('csv');
const xml = CountryStateCity.getStatesByCountryId(231, 'xml');
const yaml = CountryStateCity.getCitiesByStateId(1416, 'yaml');Hosted REST and GraphQL API
The optional hosted API exposes the same canonical data snapshot under /api/v1 and includes the immutable data version and source attribution in every response.
curl 'https://countrystatecity.tansuasici.com/api/v1/countries?limit=3&fields=id,name,iso2' \
-H 'x-api-key: YOUR_API_KEY'REST supports search, pagination, field selection, ETag caching, and per-key rate limits. Read-only GraphQL is available at /api/graphql; the OpenAPI contract and operating policy live at /api/openapi.json and /api/policy.json. See the hosted API documentation and interactive playground.
Offline nearest-centre lookup uses a lazy 3D KD-tree, handles the antimeridian, and returns distance, confidence, and the immutable data version:
const nearest = CountryStateCity.nearestCenters(
{ latitude: 40.9811, longitude: 29.0651 },
{ entityTypes: ['country', 'state', 'city'], countryCode: 'TR' }
);
// Ranked multilingual/alias search with canonical identity and match reason
const matches = CountryStateCity.searchLocations('München', {
countryCode: 'DE',
entityTypes: ['city'],
});For polygon containment, import a compatible GeoJSON boundary and use PolygonLookupIndex; current versioned coverage is Türkiye admin-1/admin-2. Nearest centres are not treated as proof of administrative containment.
MCP Integration
Use location data directly in Claude Desktop and other MCP-compatible AI assistants.
Add to your claude_desktop_config.json:
{
"mcpServers": {
"country-state-city": {
"command": "npx",
"args": ["-y", "@tansuasici/country-state-city"]
}
}
}11 Tools — search_countries, get_country, get_countries_by_region, get_states, search_states, get_cities, search_cities, get_stats, get_regions, get_timezones, get_currencies
6 Resources — ://countries, ://countries/{iso2}, ://countries/{iso2}/states, ://states/{id}/cities, ://stats, ://snapshot
The exact production identity policy and version-pair migration index are published as package exports:
import identityPolicy from '@tansuasici/country-state-city/data/identity-policy.json';
import migrationIndex from '@tansuasici/country-state-city/data/migrations/index.json';
import coveragePolicy from '@tansuasici/country-state-city/data/coverage-policy.json';
import coverageReport from '@tansuasici/country-state-city/data/coverage-report.json';
import stateCoordinatePolicy from '@tansuasici/country-state-city/data/geography/state-coordinate-policy.json';
import schemaNormalizationPolicy from '@tansuasici/country-state-city/data/schema-normalization-policy.json';API Reference
Country Methods
CountryStateCity.getAllCountries(format?: 'json' | 'csv' | 'xml' | 'yaml');
CountryStateCity.getCountryById(id: number);
CountryStateCity.getCountryByIso2(iso2: string);
CountryStateCity.getCountryByIso3(iso3: string);
CountryStateCity.searchCountries(query: string);
CountryStateCity.getCountriesByRegion(region: string);
CountryStateCity.getCountriesBySubregion(subregion: string);
CountryStateCity.getCountryTranslation(countryCode, locale);
CountryStateCity.getCoverageReport();
CountryStateCity.getCountryCoverage(countryCode: string);State Methods
CountryStateCity.getAllStates(format?: 'json' | 'csv' | 'xml' | 'yaml');
CountryStateCity.getStateById(id: number);
CountryStateCity.getStatesByCountryId(countryId: number, format?: string);
CountryStateCity.getStatesByCountryCode(countryCode: string, format?: string);
CountryStateCity.searchStates(query: string, countryId?: number);City Methods
CountryStateCity.getAllCities(format?: 'json' | 'csv' | 'xml' | 'yaml');
CountryStateCity.getCityById(id: number);
CountryStateCity.getCitiesByStateId(stateId: number, format?: string);
CountryStateCity.getCitiesByCountryId(countryId: number, format?: string);
CountryStateCity.searchCities(query: string, stateId?: number, countryId?: number);Canonical Entity Methods
The legacy state/city methods retain the imported collections. For comparable administrative levels and a clean settlement layer, use:
CountryStateCity.getAdministrativeAreas({
countryCode?: string,
level?: number, // defaults to 1
lifecycleStatus?: 'current' | 'historical' | 'review-required' | 'all',
sourceLayer?: 'state' | 'city' | 'all', // defaults to state
});
CountryStateCity.getSettlements({
countryCode?: string,
stateId?: number,
lifecycleStatus?: 'current' | 'historical' | 'review-required' | 'all',
});Every state/city row has explicit entity, level, parent, place type, lifecycle, validity, confidence, and policy-source fields. The migration contract and country mappings are exported as data/entity-level-policy.json.
District Methods
The district layer currently covers Türkiye. Legacy city records remain available for backward compatibility; use these methods when the administrative district grain is required.
CountryStateCity.getAllDistricts(format?: 'json' | 'csv' | 'xml' | 'yaml');
CountryStateCity.getDistrictById(id: number);
CountryStateCity.getDistrictByPublicId(publicId: string);
CountryStateCity.getDistrictsByStateId(stateId: number, format?: string);
CountryStateCity.getDistrictsByCountryCode(countryCode: string);
CountryStateCity.searchDistricts(query: string, stateId?: number);csc:district:* IDs belong to CountryStateCity. Türkiye's public validation source does not publish an authoritative district code, so the dataset keeps officialDistrictCode: null instead of inventing one.
Utility Methods
CountryStateCity.getStats();
CountryStateCity.getCoverageReport();
CountryStateCity.getCountryCoverage(countryCode: string);
CountryStateCity.getAllRegions();
CountryStateCity.getAllSubregions();
CountryStateCity.getAllTimezones();
CountryStateCity.getTimezoneOffset(zoneName, at?);
CountryStateCity.getAllCurrencies();
CountryStateCity.searchLocations(query, options?);
CountryStateCity.nearestCenters(point, options?);
CountryStateCity.nearestCentersBatch(points, options?);
CountryStateCity.exportData(dataType, format, options?);nearestCenters() compares a coordinate with representative centre points. It does not prove that a point is inside an administrative area. For containment, supply compatible GeoJSON to PolygonLookupIndex or locatePointInPolygons(). Versioned polygon coverage currently includes Türkiye admin-1/admin-2 only.
Direct Data Exports
Use package exports instead of repository-relative paths:
import countries from '@tansuasici/country-state-city/data/countries.json' with { type: 'json' };
import states from '@tansuasici/country-state-city/data/states.json' with { type: 'json' };
import compactCities from '@tansuasici/country-state-city/data/cities.optimized.json' with { type: 'json' };
import turkeyDistricts from '@tansuasici/country-state-city/data/districts/tr.json' with { type: 'json' };The compact city keys are i (ID), n (name), s (state ID), c (country ID), la/lo (coordinates), and optional w (Wikidata QID). Use the class API when full City objects are preferred.
TypeScript
import { CountryStateCity } from '@tansuasici/country-state-city';
import type {
Country,
State,
City,
District,
DataFormat,
FormatOptions,
} from '@tansuasici/country-state-city';Migrating to v3
Version 3 keeps the familiar country/state/city methods while tightening the data contract and adding canonical administrative, search, district, timezone, and spatial APIs.
@tansuasici/country-state-city/data/cities.jsonwas removed. Use the class API ordata/cities.optimized.json.Country and state coordinates can be
nullwhen no trustworthy value is available.Country translations are normalized to typed locale keys and values can be
nullwhen a translation is unavailable.State and city records now include explicit entity classification, administrative level, lifecycle, parent, and source fields.
Centre-based reverse geocoding and polygon containment are deliberately separate APIs.
Review nullable fields when upgrading TypeScript consumers and prefer immutable csc:* public IDs for persisted references.
Development
# Install dependencies
npm install
# Start dev server
npm run dev
# Build NPM package
npm run build:lib
# Build MCP server
npm run build:mcp
# Run tests
npm test
# Validate the pinned data source and patch manifests
npm run test:data-sync
# Validate immutable public IDs and versioned migration contracts
npm run test:identity
# Check whether a newer upstream release exists
npm run data:check-freshness
# Build and validate a reproducible candidate dataset (does not modify production data)
npm run data:sync -- --check --verify-reproducible
# Regenerate non-destructive subdivision display names and types
npm run data:display-metadataContributing
Contributions are welcome! Please read CONTRIBUTING.md for guidelines.
License
Source code is licensed under the MIT License.
The country, state, and city database is a derivative database made available under the Open Database License (ODbL) v1.0.
The data is derived from Countries States Cities Database. Attribution is required. Machine-readable source and version details are in data/provenance.json.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceA geospatial MCP server that provides tools for geocoding, routing, elevation profiles, and spatial analysis. It enables AI agents to process GIS file formats like GeoJSON and Shapefiles while performing complex coordinate transformations and distance calculations.4MIT
- AlicenseBqualityDmaintenanceA comprehensive MCP server providing 30 tools for geocoding, routing, and OpenStreetMap data analysis. It enables AI assistants to search for locations, calculate travel routes, and perform quality assurance checks on map data.303MIT
- AlicenseAqualityDmaintenanceMCP server providing structured geographic data for AI agents. Access 261 countries and millions of cities via Bamwor API.5732MIT
- AlicenseNot gradedqualityDmaintenanceMCP Server that gives AI assistants access to comprehensive country data from 250+ countries.1MIT
Related MCP Connectors
MCP server for Japan geodata: cadastral lot numbers (chiban) and reverse geocoding, for AI agents.
Free GeoNames MCP: countries, cities, POIs, distance & nearby. Remote HTTP + agent token signup.
MCP server for Mireye Earth — federal-source-cited geospatial data for any MCP-aware agent.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/tansuasici/CountryStateCity'
If you have feedback or need assistance with the MCP directory API, please join our Discord server