First shot
This commit is contained in:
parent
6ad505a422
commit
9b8f36aeed
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
build
|
1089
package-lock.json
generated
Normal file
1089
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
25
package.json
Normal file
25
package.json
Normal 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
10
run.sh
Executable 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
163
src/index.ts
Normal 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)
|
||||||
|
})
|
Loading…
x
Reference in New Issue
Block a user