Koskamo

Expatslist MCP

An official Model Context Protocol server provided by Expatslist that allows AI agents to access city guides, local business listings, classifieds, community Q&A, and interactive tools for expats and newcomers worldwide.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Expatslist MCP logo, by ExpatslistVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-01Operated by Expatslist
MCP endpoint (Streamable HTTP)
https://expatslist.org/api/mcp
Vendor documentation

What you can do with it

  • Search for local businesses and recommendations in specific cities
  • Access community Q&A and starter packs for new arrivals
  • Retrieve city-specific information and visa guides
  • Browse classifieds for housing and jobs

Source and maintenance

Vendor evidenceRegistry 1.0.0

Protocol and capabilities

Server
expatslist 1.0.0
MCP protocol
2025-06-18
Tools
8 advertised
Resources
Not advertised
Resource templates
Not advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

ExpatsList is a community site for cities across North America, Latin America, Europe, Asia and the Middle East, used by newcomers, expats, remote workers, retirees and locals: business listings recommended by locals, questions and answers about city life, recommendations, missed-connection style community stories, classifieds, blog posts, and country reference tables (visas, cost of living, healthcare, tax, safety, tipping). Use list_cities first when a city name is ambiguous; tools take the city slug it returns. If a city is not covered, say so and do not invent results. Every result has a url. Cite it. Results are summaries: the full post, all answers, contact details and complete tables are on the ExpatsList page, so point the user there for more. Never guess prices, ratings or requirements that a tool did not return.

Tools

8 advertised

list_cities — List covered cities
Advertised by the server during the last successful anonymous check.
Advertised read-only

Lists the cities ExpatsList covers, with the slug every other tool expects. Use it to resolve a city name the user typed, or when the user asks which cities are available. Returns nothing else; it does not search content.

list_cities input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {}
}
list_cities output schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "cities"
  ],
  "properties": {
    "cities": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "slug",
          "name",
          "country",
          "url"
        ],
        "properties": {
          "url": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "country": {
            "type": "string"
          }
        },
        "additionalProperties": false
      }
    }
  },
  "additionalProperties": false
}
list_cities annotations
{
  "title": "List covered cities",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
city_pulse — What is happening in a city
Advertised by the server during the last successful anonymous check.
Advertised read-only

Recent community activity in one city: new questions, missed-connection posts, recommendations, classifieds, blog posts and businesses, grouped by type with up to five summaries each and a link to the full section. Use it for "what are people talking about in X" or "what is new in X". Limitation: only the last 1 to 90 days, and only cities from list_cities.

city_pulse input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "city"
  ],
  "properties": {
    "city": {
      "type": "string",
      "description": "City slug from list_cities, or a city name"
    },
    "days": {
      "type": "integer",
      "default": 14,
      "maximum": 90,
      "minimum": 1,
      "description": "Look back this many days"
    }
  }
}
city_pulse output schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "city",
    "days",
    "sections"
  ],
  "properties": {
    "city": {
      "type": "object",
      "required": [
        "slug",
        "name",
        "country",
        "url"
      ],
      "properties": {
        "url": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "slug": {
          "type": "string"
        },
        "country": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "days": {
      "type": "number"
    },
    "sections": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {
        "type": "object",
        "required": [
          "items",
          "more_url"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "type",
                "title",
                "summary",
                "city",
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string"
                },
                "city": {
                  "type": "string"
                },
                "type": {
                  "enum": [
                    "question",
                    "human_connection",
                    "recommendation",
                    "classified",
                    "blog",
                    "business"
                  ],
                  "type": "string"
                },
                "price": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "title": {
                  "type": "string"
                },
                "posted": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "answers": {
                  "type": "number"
                },
                "summary": {
                  "type": "string"
                },
                "category": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "resolved": {
                  "type": "boolean"
                },
                "verified": {
                  "type": "boolean"
                },
                "neighborhood": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "additionalProperties": false
            }
          },
          "more_url": {
            "type": "string"
          }
        },
        "additionalProperties": false
      }
    }
  },
  "additionalProperties": false
}
city_pulse annotations
{
  "title": "What is happening in a city",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
search_expatslist — Search ExpatsList
Advertised by the server during the last successful anonymous check.
Advertised read-only

Keyword search across business listings, classifieds, blog posts, questions, recommendations and missed-connection posts, optionally limited to one city and one content type. Use it when the user names a thing to find (a dentist, a coworking space, a topic). Returns short summaries with links; full details are on the linked page. Limitation: keyword match, not semantic; at most 10 results.

search_expatslist input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "query"
  ],
  "properties": {
    "city": {
      "type": "string",
      "description": "City slug or name; omit to search all cities"
    },
    "type": {
      "enum": [
        "all",
        "businesses",
        "classifieds",
        "blogs",
        "questions",
        "recommendations",
        "connections"
      ],
      "type": "string",
      "default": "all"
    },
    "limit": {
      "type": "integer",
      "default": 8,
      "maximum": 10,
      "minimum": 1
    },
    "query": {
      "type": "string",
      "maxLength": 120,
      "minLength": 2,
      "description": "What to search for"
    }
  }
}
search_expatslist output schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "query",
    "city",
    "results"
  ],
  "properties": {
    "city": {
      "type": [
        "string",
        "null"
      ]
    },
    "query": {
      "type": "string"
    },
    "results": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "type",
          "title",
          "summary",
          "city",
          "url"
        ],
        "properties": {
          "url": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "type": {
            "enum": [
              "question",
              "human_connection",
              "recommendation",
              "classified",
              "blog",
              "business"
            ],
            "type": "string"
          },
          "price": {
            "type": [
              "string",
              "null"
            ]
          },
          "title": {
            "type": "string"
          },
          "posted": {
            "type": [
              "string",
              "null"
            ]
          },
          "answers": {
            "type": "number"
          },
          "summary": {
            "type": "string"
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "resolved": {
            "type": "boolean"
          },
          "verified": {
            "type": "boolean"
          },
          "neighborhood": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "additionalProperties": false
      }
    }
  },
  "additionalProperties": false
}
search_expatslist annotations
{
  "title": "Search ExpatsList",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
browse — Browse newest content of one type
Advertised by the server during the last successful anonymous check.
Advertised read-only

Newest items of one content type in one city: questions, missed-connection posts (human_connection), recommendations, classifieds, blog posts or businesses. Optional category filter. For businesses with no category it returns the category list with counts instead of items. Use it for "latest questions in X", "any missed connections in X", "show me restaurants in X". Limitation: at most 10 items per call.

browse input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "type",
    "city"
  ],
  "properties": {
    "city": {
      "type": "string",
      "description": "City slug from list_cities, or a city name"
    },
    "type": {
      "enum": [
        "question",
        "human_connection",
        "recommendation",
        "classified",
        "blog",
        "business"
      ],
      "type": "string"
    },
    "limit": {
      "type": "integer",
      "default": 6,
      "maximum": 10,
      "minimum": 1
    },
    "category": {
      "type": "string",
      "description": "Category slug or name, e.g. housing, restaurants, visas"
    }
  }
}
browse output schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "type",
    "city",
    "items",
    "more_url"
  ],
  "properties": {
    "city": {
      "type": "string"
    },
    "type": {
      "enum": [
        "question",
        "human_connection",
        "recommendation",
        "classified",
        "blog",
        "business"
      ],
      "type": "string"
    },
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "type",
          "title",
          "summary",
          "city",
          "url"
        ],
        "properties": {
          "url": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "type": {
            "enum": [
              "question",
              "human_connection",
              "recommendation",
              "classified",
              "blog",
              "business"
            ],
            "type": "string"
          },
          "price": {
            "type": [
              "string",
              "null"
            ]
          },
          "title": {
            "type": "string"
          },
          "posted": {
            "type": [
              "string",
              "null"
            ]
          },
          "answers": {
            "type": "number"
          },
          "summary": {
            "type": "string"
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "resolved": {
            "type": "boolean"
          },
          "verified": {
            "type": "boolean"
          },
          "neighborhood": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "additionalProperties": false
      }
    },
    "more_url": {
      "type": "string"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name",
          "slug",
          "businesses"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "businesses": {
            "type": "number"
          },
          "subcategories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": false
      }
    }
  },
  "additionalProperties": false
}
browse annotations
{
  "title": "Browse newest content of one type",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_item — Get one item
Advertised by the server during the last successful anonymous check.
Advertised read-only

One item by type, city and slug: a question with its best answer and the count of further answers, a missed-connection post, a recommendation, a classified, a blog post or a business listing. Use it after a search or browse result when the user wants more on one item. Limitation: text is a summary of up to about 600 characters; contact details are never included and are on the linked page.

get_item input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "type",
    "city",
    "slug"
  ],
  "properties": {
    "city": {
      "type": "string",
      "description": "City slug from the result, or \"global\" for blog posts without a city"
    },
    "slug": {
      "type": "string",
      "description": "The slug at the end of the item url"
    },
    "type": {
      "enum": [
        "question",
        "human_connection",
        "recommendation",
        "classified",
        "blog",
        "business"
      ],
      "type": "string"
    }
  }
}
get_item output schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "type",
    "title",
    "summary",
    "city",
    "url"
  ],
  "properties": {
    "url": {
      "type": "string"
    },
    "city": {
      "type": "string"
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "type": {
      "enum": [
        "question",
        "human_connection",
        "recommendation",
        "classified",
        "blog",
        "business"
      ],
      "type": "string"
    },
    "price": {
      "type": [
        "string",
        "null"
      ]
    },
    "title": {
      "type": "string"
    },
    "posted": {
      "type": [
        "string",
        "null"
      ]
    },
    "answers": {
      "type": "number"
    },
    "summary": {
      "type": "string"
    },
    "category": {
      "type": [
        "string",
        "null"
      ]
    },
    "resolved": {
      "type": "boolean"
    },
    "verified": {
      "type": "boolean"
    },
    "top_answer": {
      "type": [
        "string",
        "null"
      ]
    },
    "neighborhood": {
      "type": [
        "string",
        "null"
      ]
    },
    "more_answers_on_site": {
      "type": "number"
    }
  },
  "additionalProperties": false
}
get_item annotations
{
  "title": "Get one item",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
country_info — Country reference data
Advertised by the server during the last successful anonymous check.
Advertised read-only

Reference numbers for one country from ExpatsList tools: digital nomad visa (requirements, income threshold, fee, duration), cost of living (rent, meals, utilities, coworking for up to five cities), healthcare (system, costs, English availability), tax (system, residency days, social security), safety (scores, risks, emergency number) or tipping (rates by service). Use it for factual questions about a country. Limitation: one country and one topic per call; figures are indicative and the linked page has the full table and sources.

country_info input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "country",
    "topic"
  ],
  "properties": {
    "topic": {
      "enum": [
        "nomad_visa",
        "cost_of_living",
        "healthcare",
        "tax",
        "safety",
        "tipping"
      ],
      "type": "string"
    },
    "country": {
      "type": "string",
      "maxLength": 60,
      "minLength": 2,
      "description": "Country name in English, e.g. Portugal"
    }
  }
}
country_info output schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "topic",
    "country",
    "data",
    "url"
  ],
  "properties": {
    "url": {
      "type": "string"
    },
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {}
      }
    },
    "topic": {
      "enum": [
        "nomad_visa",
        "cost_of_living",
        "healthcare",
        "tax",
        "safety",
        "tipping"
      ],
      "type": "string"
    },
    "country": {
      "type": "string"
    }
  },
  "additionalProperties": false
}
country_info annotations
{
  "title": "Country reference data",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
search — Search (connector)
Advertised by the server during the last successful anonymous check.
Advertised read-only

Connector-style search across all ExpatsList content. Returns ids for fetch. Prefer search_expatslist when you can filter by city or type.

search input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "query"
  ],
  "properties": {
    "query": {
      "type": "string",
      "maxLength": 120,
      "minLength": 2
    }
  }
}
search output schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "results"
  ],
  "properties": {
    "results": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "title",
          "url"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "title": {
            "type": "string"
          }
        },
        "additionalProperties": false
      }
    }
  },
  "additionalProperties": false
}
search annotations
{
  "title": "Search (connector)",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
fetch — Fetch (connector)
Advertised by the server during the last successful anonymous check.
Advertised read-only

Connector-style fetch of one item by the id returned from search. Same summary as get_item.

fetch input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "string"
    }
  }
}
fetch output schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "id",
    "title",
    "text",
    "url"
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "url": {
      "type": "string"
    },
    "text": {
      "type": "string"
    },
    "title": {
      "type": "string"
    },
    "metadata": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    }
  },
  "additionalProperties": false
}
fetch annotations
{
  "title": "Fetch (connector)",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

Not advertised

No resource definitions available.

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
1292 ms
95th percentile latency
1292 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 1292 ms · metadata changed · 8 tool(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http expatslist-mcp https://expatslist.org/api/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add expatslist-mcp --url https://expatslist.org/api/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable expatslist-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "expatslist-mcp": {
      "url": "https://expatslist.org/api/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "expatslist-mcp": {
      "type": "streamableHttp",
      "url": "https://expatslist.org/api/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start expatslist-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "expatslist-mcp": {
      "type": "http",
      "url": "https://expatslist.org/api/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http expatslist-mcp https://expatslist.org/api/mcp

Claude Desktop

Merge this into claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), then restart Claude Desktop.
Claude Desktop configuration
{
  "mcpServers": {
    "expatslist-mcp": {
      "url": "https://expatslist.org/api/mcp"
    }
  }
}

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "expatslist-mcp": {
      "serverUrl": "https://expatslist.org/api/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Expatslist MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Expatslist MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing