Refactor MCP API: Remove deprecated endpoints and add new resource handlers

- Deleted old API endpoints for contact, education, experiences, hobbies, languages, profile, projects, skills, and uses.
- Introduced new resource handlers for contact, education, experiences, hobbies, languages, profile, projects, skills, and uses with structured responses.
- Added new MCP prompts for real-time activity, contact information, hobbies, languages, profile, projects, skills, stats, and status page.
- Implemented tools for fetching real-time activity, resume links, coding stats, and weather information.
- Removed legacy MCP server route and replaced it with a modular approach for better maintainability.
This commit is contained in:
2025-11-30 14:54:37 +01:00
parent ebcc2aa821
commit 2a1c6369f3
41 changed files with 717 additions and 12081 deletions

View File

@@ -0,0 +1,12 @@
export default defineMcpTool({
description: 'Real-time current activity and status of Arthur Danjou, including what he\'s currently working on',
handler: async () => {
const result = await $fetch('/api/activity')
return {
content: [{
type: 'text',
text: JSON.stringify(result, null, 2)
}]
}
}
})

View File

@@ -0,0 +1,15 @@
import z from 'zod'
export default defineMcpTool({
description: 'Retrieves a direct download link to Arthur Danjou\'s professional resume in the specified language. Supports both English and French versions.',
inputSchema: {
lang: z.enum(['en', 'fr']).describe('The language for the resume: \'en\' for English or \'fr\' for French.')
},
handler: async ({ lang }) => {
const base_url = import.meta.dev ? 'http://localhost:3000/api' : 'https://mcp.arthurdanjou.fr/api'
const url = `${base_url}/resumes/${lang}`
return {
content: [{ type: 'text', text: JSON.stringify(url, null, 2) }]
}
}
})

12
server/mcp/tools/stats.ts Normal file
View File

@@ -0,0 +1,12 @@
export default defineMcpTool({
description: 'Detailed coding statistics and analytics from WakaTime, including programming languages, time spent coding, and productivity metrics',
handler: async () => {
const result = await $fetch('/api/wakatime')
return {
content: [{
type: 'text',
text: JSON.stringify(result, null, 2)
}]
}
}
})

View File

@@ -0,0 +1,12 @@
export default defineMcpTool({
description: 'Real-time status, uptime monitoring, and incident reports for Arthur Danjou\'s homelab infrastructure, powered by UptimeKuma',
handler: async () => {
const result = await $fetch('/api/status-page')
return {
content: [{
type: 'text',
text: JSON.stringify(result, null, 2)
}]
}
}
})

View File

@@ -0,0 +1,21 @@
import z from 'zod'
export default defineMcpTool({
description: 'Retrieves a filtered list of tools, software, and hardware used by Arthur Danjou based on a specific category. Available categories: homelab, IDE, hardware, and software.',
inputSchema: {
categoryName: z.enum(['homelab', 'ide', 'hardware', 'software']).describe('The category to filter by: \'homelab\', \'ide\', \'hardware\', or \'software\'.')
},
handler: async ({ categoryName }) => {
const event = useEvent()
const result = await queryCollection(event, 'uses')
.where('extension', '=', 'md')
.where('category', '=', categoryName)
.all()
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
structuredContent: result as { [key: string]: unknown }
}
}
})

View File

@@ -0,0 +1,30 @@
import { z } from 'zod'
export default defineMcpTool({
description: 'Get current weather for a city',
inputSchema: {
city: z.string().describe('City name')
},
cache: '15m',
handler: async ({ city }) => {
try {
const data = await $fetch(`https://wttr.in/${city}?format=j1`)
return {
content: [{
type: 'text',
text: JSON.stringify(data, null, 2)
}]
}
}
catch (error) {
return {
content: [{
type: 'text',
text: `Error: ${error instanceof Error ? error.message : String(error)}`
}],
isError: true
}
}
}
})