countryflags-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/dist/api.js +25 -0
- package/dist/index.js +4 -0
- package/dist/server.js +38 -0
- package/package.json +44 -0
- package/server.json +20 -0
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Country Flags MCP
|
|
2
|
+
|
|
3
|
+
Country flag image URLs and codes from the public Flagcdn API. No key required.
|
|
4
|
+
|
|
5
|
+
This file is self contained. It reads public data only and never writes to the machine. All output is bounded and honest about what could not be fetched.
|
|
6
|
+
|
|
7
|
+
## Tools
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
* `list` List flag codes.
|
|
11
|
+
* `flag` Flag URL for a country.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install
|
|
17
|
+
npm run build
|
|
18
|
+
node dist/index.js
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Data comes from the public Flagcdn API.
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const BASE = 'https://flagcdn.com';
|
|
2
|
+
export async function list(args = {}) {
|
|
3
|
+
const res = await fetch(`${BASE}/en/codes.json`, {
|
|
4
|
+
headers: { 'User-Agent': 'mrfentmen-countryflags-mcp/1.0', Accept: 'application/json' },
|
|
5
|
+
signal: AbortSignal.timeout(20000),
|
|
6
|
+
});
|
|
7
|
+
if (!res.ok)
|
|
8
|
+
throw new Error(`Flagcdn returned ${res.status}`);
|
|
9
|
+
const codes = (await res.json());
|
|
10
|
+
const entries = Object.entries(codes);
|
|
11
|
+
const q = (args.search ?? '').trim().toLowerCase();
|
|
12
|
+
const limit = Math.max(1, Math.min(args.limit ?? 20, 100));
|
|
13
|
+
const filtered = q ? entries.filter(([code, name]) => `${code} ${name}`.toLowerCase().includes(q)) : entries;
|
|
14
|
+
const shown = filtered.slice(0, limit);
|
|
15
|
+
if (!shown.length)
|
|
16
|
+
return `No countries match "${q}".`;
|
|
17
|
+
return `Country flags (${shown.length} shown):\n` +
|
|
18
|
+
shown.map(([code, name], i) => `${i + 1}. ${name} (${code}) | ${BASE}/${code}.png`).join('\n');
|
|
19
|
+
}
|
|
20
|
+
export async function flag(args) {
|
|
21
|
+
const code = (args.code ?? '').trim().toLowerCase();
|
|
22
|
+
if (!code)
|
|
23
|
+
return 'Provide a country code like us.';
|
|
24
|
+
return `${code.toUpperCase()}: ${BASE}/${code}.png (w160: ${BASE}/w160/${code}.png, w320: ${BASE}/w320/${code}.png)`;
|
|
25
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
2
|
+
import { createServer } from "./server.js";
|
|
3
|
+
const main = async () => { const server = createServer(); await server.connect(new StdioServerTransport()); };
|
|
4
|
+
main().catch((error) => { console.error("Fatal error:", error); process.exit(1); });
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { flag } from "./api.js";
|
|
4
|
+
import { list } from "./api.js";
|
|
5
|
+
const text = (value) => ({ content: [{ type: "text", text: value }] });
|
|
6
|
+
const textError = (t) => ({ content: [{ type: "text", text: t }], isError: true });
|
|
7
|
+
const READ_ONLY = { readOnlyHint: true, openWorldHint: true };
|
|
8
|
+
const error = (e) => `Error: ${e instanceof Error ? e.message : String(e)}`;
|
|
9
|
+
export function createServer() {
|
|
10
|
+
const server = new McpServer({ name: "countryflags-mcp", version: "1.0.0" });
|
|
11
|
+
server.registerTool("list", {
|
|
12
|
+
title: "List",
|
|
13
|
+
description: "List country flag codes.",
|
|
14
|
+
inputSchema: z.object({ search: z.string().describe("Optional search terms.").optional(), limit: z.number().describe("Max results.").optional() }),
|
|
15
|
+
annotations: READ_ONLY,
|
|
16
|
+
}, async (args) => {
|
|
17
|
+
try {
|
|
18
|
+
return text(await list(args));
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
return textError(error(e));
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
server.registerTool("flag", {
|
|
25
|
+
title: "Flag",
|
|
26
|
+
description: "Flag image URL for a country.",
|
|
27
|
+
inputSchema: z.object({ code: z.string().describe("Country code like us.") }),
|
|
28
|
+
annotations: READ_ONLY,
|
|
29
|
+
}, async (args) => {
|
|
30
|
+
try {
|
|
31
|
+
return text(await flag(args));
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
return textError(error(e));
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
return server;
|
|
38
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.0",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/mrfentmen/countryflags-mcp.git"
|
|
7
|
+
},
|
|
8
|
+
"bin": {
|
|
9
|
+
"countryflags-mcp": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"server.json",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc -p tsconfig.json",
|
|
19
|
+
"start": "node dist/index.js",
|
|
20
|
+
"dev": "npm run build && node dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
25
|
+
"zod": "^3.23.8"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "^22.0.0",
|
|
29
|
+
"typescript": "^5.6.0"
|
|
30
|
+
},
|
|
31
|
+
"name": "countryflags-mcp",
|
|
32
|
+
"description": "Country flag image URLs and codes. No key required.",
|
|
33
|
+
"mcpName": "io.github.mrfentmen/countryflags-mcp",
|
|
34
|
+
"keywords": [
|
|
35
|
+
"mcp",
|
|
36
|
+
"flags",
|
|
37
|
+
"countries",
|
|
38
|
+
"images",
|
|
39
|
+
"design"
|
|
40
|
+
],
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=20"
|
|
43
|
+
}
|
|
44
|
+
}
|
package/server.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "io.github.mrfentmen/countryflags-mcp",
|
|
4
|
+
"description": "Country flag image URLs and codes. No key required.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"url": "https://github.com/mrfentmen/countryflags-mcp",
|
|
7
|
+
"source": "github"
|
|
8
|
+
},
|
|
9
|
+
"version": "1.0.0",
|
|
10
|
+
"packages": [
|
|
11
|
+
{
|
|
12
|
+
"registryType": "npm",
|
|
13
|
+
"identifier": "countryflags-mcp",
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"transport": {
|
|
16
|
+
"type": "stdio"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|