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,21 @@
export default defineMcpResource({
title: 'Arthur Danjou - Contact Information & Social Media Links',
description: 'Contact information and social media links for Arthur Danjou, including email, LinkedIn, GitHub, Twitter, Discord, and personal websites',
uri: 'resource://artmcp/contact',
cache: '1 hour',
handler: async (uri: URL) => {
const event = useEvent()
const result = await queryCollection(event, 'contact')
.where('extension', '=', 'json')
.first()
return {
contents: [{
uri: uri.toString(),
mimeType: 'text/json',
text: JSON.stringify(result.body, null, 2)
}]
}
}
})

View File

@@ -0,0 +1,29 @@
export default defineMcpResource({
title: 'Arthur Danjou - Education & Academic Background',
description: 'Arthur Danjou\'s educational background, including degrees, institutions, and academic achievements',
uri: 'resource://artmcp/education',
cache: '1 hour',
handler: async (uri: URL) => {
const event = useEvent()
const result = await queryCollection(event, 'education')
.where('extension', '=', 'md')
.select([
'degree',
'institution',
'startDate',
'endDate',
'location'
])
.orderBy('startDate', 'desc')
.all()
return {
contents: [{
uri: uri.toString(),
mimeType: 'text/json',
text: JSON.stringify(result)
}]
}
}
})

View File

@@ -0,0 +1,31 @@
export default defineMcpResource({
title: 'Arthur Danjou - Experiences',
description: 'A detailed list of Arthur Danjou\'s professional work experiences, including roles, companies, and responsibilities',
uri: 'resource://artmcp/experiences',
cache: '1 hour',
handler: async (uri: URL) => {
const event = useEvent()
const result = await queryCollection(event, 'experiences')
.where('extension', '=', 'md')
.select([
'title',
'company',
'companyUrl',
'startDate',
'endDate',
'location',
'description'
])
.orderBy('startDate', 'desc')
.all()
return {
contents: [{
uri: uri.toString(),
mimeType: 'text/json',
text: JSON.stringify(result)
}]
}
}
})

View File

@@ -0,0 +1,21 @@
export default defineMcpResource({
title: 'Arthur Danjou - Hobbies & Interests',
description: 'Arthur Danjou\'s personal hobbies, interests, and passions outside of professional work',
uri: 'resource://artmcp/hobbies',
cache: '1 hour',
handler: async (uri: URL) => {
const event = useEvent()
const result = await queryCollection(event, 'hobbies')
.where('extension', '=', 'md')
.first()
return {
contents: [{
uri: uri.toString(),
mimeType: 'text/json',
text: JSON.stringify(result.body, null, 2)
}]
}
}
})

View File

@@ -0,0 +1,21 @@
export default defineMcpResource({
title: 'Arthur Danjou - Spoken Languages & Proficiency Levels',
description: 'Languages spoken by Arthur Danjou with detailed proficiency levels for each language',
uri: 'resource://artmcp/languages',
cache: '1 hour',
handler: async (uri: URL) => {
const event = useEvent()
const result = await queryCollection(event, 'languages')
.where('extension', '=', 'json')
.first()
return {
contents: [{
uri: uri.toString(),
mimeType: 'text/json',
text: JSON.stringify(result.body, null, 2)
}]
}
}
})

View File

@@ -0,0 +1,21 @@
export default defineMcpResource({
title: 'Arthur Danjou - Professional Profile',
description: 'Comprehensive professional profile of Arthur Danjou, including biography, location, availability status, career goals, and work preferences',
uri: 'resource://artmcp/profile',
cache: '1 hour',
handler: async (uri: URL) => {
const event = useEvent()
const result = await queryCollection(event, 'profile')
.where('extension', '=', 'md')
.first()
return {
contents: [{
uri: uri.toString(),
mimeType: 'text/json',
text: JSON.stringify(result)
}]
}
}
})

View File

@@ -0,0 +1,21 @@
export default defineMcpResource({
title: 'Arthur Danjou - Projects Portfolio',
description: 'A comprehensive collection of projects developed by Arthur Danjou, showcasing technical skills and achievements',
uri: 'resource://artmcp/projects',
cache: '1 hour',
handler: async (uri: URL) => {
const event = useEvent()
const result = await queryCollection(event, 'projects')
.where('extension', '=', 'md')
.all()
return {
contents: [{
uri: uri.toString(),
mimeType: 'text/json',
text: JSON.stringify(result)
}]
}
}
})

View File

@@ -0,0 +1,21 @@
export default defineMcpResource({
title: 'Arthur Danjou - Skills',
description: 'A comprehensive list of technical skills, programming languages, frameworks, and tools mastered by Arthur Danjou',
cache: '1 hour',
uri: 'resource://artmcp/skills',
handler: async () => {
const event = useEvent()
const result = await queryCollection(event, 'skills')
.where('extension', '=', 'json')
.first()
return {
contents: [{
uri: result.path,
mimeType: 'text/json',
text: JSON.stringify(result.body, null, 2)
}]
}
}
})

View File

@@ -0,0 +1,31 @@
export default defineMcpResource({
title: 'Arthur Danjou - Tech Stack & Tools',
description: 'A curated list of tools, software, and hardware used by Arthur Danjou, organized by categories (homelab, IDE, hardware, software)',
uri: 'resource://artmcp/uses',
cache: '1 hour',
handler: async (uri: URL) => {
const event = useEvent()
const categories = await queryCollection(event, 'usesCategories').where('extension', '=', 'md').all()
const uses = await queryCollection(event, 'uses')
.where('extension', '=', 'md')
.all()
const uses_by_categories = []
for (const category of categories) {
uses_by_categories.push({
category: category,
uses: uses.filter((use: { category: unknown }) => use.category === category.slug)
})
}
return {
contents: [{
uri: uri.toString(),
mimeType: 'text/json',
text: JSON.stringify(uses_by_categories, null, 2)
}]
}
}
})