First shot

This commit is contained in:
MatMoul 2025-07-07 03:51:37 +02:00
parent 6ad505a422
commit 9b8f36aeed
5 changed files with 1289 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
build

1089
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

25
package.json Normal file
View File

@ -0,0 +1,25 @@
{
"name": "mtm-news-mcp",
"version": "1.0.0",
"description": "",
"license": "ISC",
"author": "",
"type": "module",
"main": "index.js",
"bin": {
"mcp": "./build/index.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "node_modules/typescript/bin/tsc && chmod 755 build/index.js"
},
"files": ["build"],
"dependencies": {
"@modelcontextprotocol/sdk": "^1.13.0",
"zod": "^3.25.67"
},
"devDependencies": {
"@types/node": "^24.0.3",
"typescript": "^5.8.3"
}
}

10
run.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/bash
cd $(dirname "${0}")
if [ ! -f build/index.js ]; then
npm i
npm run build
fi
node build/index.js

163
src/index.ts Normal file
View File

@ -0,0 +1,163 @@
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
// import { z } from "zod"
// Need move source outside of the project for custom settings
const sources = [
{
name: '20 Minutes',
items: [
{
keys: ['swiss-french'],
name: 'Suisse romande',
url: 'https://www.20min.ch/fr/suisse-romande',
},
{
keys: ['swiss'],
name: 'Suisse',
url: 'https://www.20min.ch/fr/suisse',
},
{
keys: ['international'],
name: 'International',
url: 'https://www.20min.ch/fr/monde',
},
],
},
{
name: '24 Heures',
items: [
{
keys: ['swiss-french'],
name: 'Suisse romande',
url: 'https://www.24heures.ch/suisse-romande',
},
{
keys: ['swiss'],
name: 'Suisse',
url: 'https://www.24heures.ch/suisse',
},
{
keys: ['international'],
name: 'International',
url: 'https://www.24heures.ch/monde',
},
],
},
{
name: 'Blick',
items: [
{
keys: ['suisse'],
name: 'Suisse',
url: 'https://www.blick.ch/fr/suisse/',
},
{
keys: ['international'],
name: 'International',
url: 'https://www.blick.ch/fr/monde/',
},
],
},
{
name: 'Le Temps',
items: [
{
keys: ['swiss'],
name: 'Suisse',
url: 'https://www.letemps.ch/suisse',
},
{
keys: ['international'],
name: 'International',
url: 'https://www.letemps.ch/monde',
},
],
},
{
name: 'Watson',
items: [
{
keys: ['swiss'],
name: 'Suisse',
url: 'https://www.watson.ch/fr/suisse/',
},
{
keys: ['international'],
name: 'International',
url: 'https://www.watson.ch/fr/international/',
},
],
},
]
const layouts = [
{
name: 'switzerland',
use: ['swiss-french', 'swiss'],
},
{
name: 'international',
use: ['international'],
},
]
const categories = {}
const buildCategory = (use: Array<string>) => {
const result: Array<{ name: string, url: string }> = []
sources.forEach((source) => {
source.items.forEach((item) => {
use.forEach((key) => {
item.keys.forEach((itemKey) => {
let processed = false
if(processed == false && key === itemKey) {
result.push({
name: source.name + ' - ' + item.name,
url: item.url,
})
processed = true
}
})
})
})
})
}
layouts.forEach((layout) => {
categories[layout.name] = buildCategory(layout.use)
})
const server = new McpServer({
name: "mtm-news-mcp",
version: "1.0.0",
capabilities: {
resources: {},
tools: {},
},
})
server.tool(
"get-news",
"Get latest news title and link ",
{},
() => {
// Process
//
return {
content: [
{
type: "text",
text: "",
}
]
}
},
)
async function main() {
const transport = new StdioServerTransport()
await server.connect(transport)
console.error("MTM News MCP Server running on stdio")
}
main().catch((error) => {
console.error("Fatal error in main():", error)
process.exit(1)
})