@enokdev/springdocs-mcp 1.2.0 → 1.2.2
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 +42 -1
- package/build/debug.d.ts +3 -0
- package/build/debug.d.ts.map +1 -0
- package/build/debug.js +292 -0
- package/build/debug.js.map +1 -0
- package/build/index.js +16 -10
- package/build/index.js.map +1 -1
- package/build/services/springboot-docs.d.ts.map +1 -1
- package/build/services/springboot-docs.js +174 -15
- package/build/services/springboot-docs.js.map +1 -1
- package/package.json +11 -3
- package/.github/workflows/publish.yml +0 -64
- package/CHANGELOG.md +0 -82
- package/CHANGELOG_v1.2.0.md +0 -71
- package/CONTRIBUTING.md +0 -215
- package/EXAMPLES.md +0 -186
- package/EXAMPLES_FR.md +0 -186
- package/INSTALL.md +0 -123
- package/INSTALL_FR.md +0 -123
- package/JETBRAINS_SETUP.md +0 -171
- package/README_FR.md +0 -219
- package/RELEASE_NOTES_v1.1.0.md +0 -106
- package/RELEASE_NOTES_v1.2.0.md +0 -138
- package/TROUBLESHOOTING.md +0 -163
- package/claude_desktop_config.json +0 -7
- package/diagnostic.sh +0 -55
- package/docs/index.html +0 -147
- package/guid.md +0 -92
- package/publish.sh +0 -130
- package/setup-jetbrains.sh +0 -164
- package/src/index.ts +0 -287
- package/src/services/springboot-docs.ts +0 -615
- package/src/tools/index.ts +0 -144
- package/test-jetbrains.sh +0 -125
- package/test.sh +0 -64
- package/tsconfig.json +0 -24
package/publish.sh
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Script de publication automatique pour @enokdev/springdocs-mcp
|
|
4
|
-
# Auteur: EnokDev (https://github.com/tky0065)
|
|
5
|
-
|
|
6
|
-
set -e
|
|
7
|
-
|
|
8
|
-
echo "🌱 Publication de Spring Documentation MCP Server"
|
|
9
|
-
echo "=================================================="
|
|
10
|
-
echo ""
|
|
11
|
-
|
|
12
|
-
# Vérifications préliminaires
|
|
13
|
-
echo "🔍 Vérifications pré-publication..."
|
|
14
|
-
|
|
15
|
-
# Vérifier que nous sommes connectés à npm
|
|
16
|
-
NPM_USER=$(npm whoami 2>/dev/null || echo "")
|
|
17
|
-
if [ "$NPM_USER" != "enokdev" ]; then
|
|
18
|
-
echo "❌ Erreur: Vous devez être connecté à npm en tant qu'enokdev"
|
|
19
|
-
echo "Exécutez: npm login"
|
|
20
|
-
exit 1
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
echo "✅ Connecté à npm en tant que: $NPM_USER"
|
|
24
|
-
|
|
25
|
-
# Vérifier que le build fonctionne
|
|
26
|
-
echo "🔨 Compilation du projet..."
|
|
27
|
-
npm run build
|
|
28
|
-
|
|
29
|
-
# Exécuter les tests
|
|
30
|
-
echo "🧪 Exécution des tests..."
|
|
31
|
-
npm test
|
|
32
|
-
|
|
33
|
-
# Vérifier la configuration Git
|
|
34
|
-
if ! git remote get-url origin | grep -q "tky0065/springdocs-mcp"; then
|
|
35
|
-
echo "⚠️ Attention: L'origin Git ne semble pas pointer vers tky0065/springdocs-mcp"
|
|
36
|
-
echo "Origin actuel: $(git remote get-url origin)"
|
|
37
|
-
read -p "Continuer quand même? (y/N): " -n 1 -r
|
|
38
|
-
echo
|
|
39
|
-
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
40
|
-
exit 1
|
|
41
|
-
fi
|
|
42
|
-
fi
|
|
43
|
-
|
|
44
|
-
# Afficher la version actuelle
|
|
45
|
-
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
46
|
-
echo "📦 Version actuelle: $CURRENT_VERSION"
|
|
47
|
-
|
|
48
|
-
# Demander le type de mise à jour
|
|
49
|
-
echo ""
|
|
50
|
-
echo "Type de mise à jour:"
|
|
51
|
-
echo "1) patch (1.1.0 -> 1.1.1) - Corrections de bugs"
|
|
52
|
-
echo "2) minor (1.1.0 -> 1.2.0) - Nouvelles fonctionnalités"
|
|
53
|
-
echo "3) major (1.1.0 -> 2.0.0) - Changements incompatibles"
|
|
54
|
-
echo "4) Garder la version actuelle"
|
|
55
|
-
|
|
56
|
-
read -p "Votre choix (1-4): " -n 1 -r
|
|
57
|
-
echo
|
|
58
|
-
|
|
59
|
-
case $REPLY in
|
|
60
|
-
1) VERSION_TYPE="patch" ;;
|
|
61
|
-
2) VERSION_TYPE="minor" ;;
|
|
62
|
-
3) VERSION_TYPE="major" ;;
|
|
63
|
-
4) VERSION_TYPE="" ;;
|
|
64
|
-
*) echo "❌ Choix invalide"; exit 1 ;;
|
|
65
|
-
esac
|
|
66
|
-
|
|
67
|
-
# Mise à jour de version si nécessaire
|
|
68
|
-
if [ ! -z "$VERSION_TYPE" ]; then
|
|
69
|
-
echo "📝 Mise à jour de version ($VERSION_TYPE)..."
|
|
70
|
-
npm version $VERSION_TYPE --no-git-tag-version
|
|
71
|
-
NEW_VERSION=$(node -p "require('./package.json').version")
|
|
72
|
-
echo "✅ Nouvelle version: $NEW_VERSION"
|
|
73
|
-
else
|
|
74
|
-
NEW_VERSION=$CURRENT_VERSION
|
|
75
|
-
echo "📌 Conservation de la version: $NEW_VERSION"
|
|
76
|
-
fi
|
|
77
|
-
|
|
78
|
-
# Test final du package
|
|
79
|
-
echo "🔍 Test final du package..."
|
|
80
|
-
npm pack --dry-run > /dev/null
|
|
81
|
-
|
|
82
|
-
# Confirmation finale
|
|
83
|
-
echo ""
|
|
84
|
-
echo "🚀 Prêt pour la publication:"
|
|
85
|
-
echo " Package: @enokdev/springdocs-mcp@$NEW_VERSION"
|
|
86
|
-
echo " Registry: https://www.npmjs.com/package/@enokdev/springdocs-mcp"
|
|
87
|
-
echo " Repository: https://github.com/tky0065/springdocs-mcp"
|
|
88
|
-
echo ""
|
|
89
|
-
|
|
90
|
-
read -p "Confirmer la publication? (y/N): " -n 1 -r
|
|
91
|
-
echo
|
|
92
|
-
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
93
|
-
echo "❌ Publication annulée"
|
|
94
|
-
exit 1
|
|
95
|
-
fi
|
|
96
|
-
|
|
97
|
-
# Git commit et push
|
|
98
|
-
if [ ! -z "$VERSION_TYPE" ]; then
|
|
99
|
-
echo "📤 Envoi vers GitHub..."
|
|
100
|
-
git add .
|
|
101
|
-
git commit -m "Release v$NEW_VERSION"
|
|
102
|
-
git tag "v$NEW_VERSION"
|
|
103
|
-
git push origin main --tags
|
|
104
|
-
echo "✅ Code envoyé vers GitHub avec tag v$NEW_VERSION"
|
|
105
|
-
fi
|
|
106
|
-
|
|
107
|
-
# Publication npm
|
|
108
|
-
echo "📦 Publication sur npm..."
|
|
109
|
-
npm publish --access public
|
|
110
|
-
|
|
111
|
-
echo ""
|
|
112
|
-
echo "🎉 Publication réussie!"
|
|
113
|
-
echo ""
|
|
114
|
-
echo "📋 Informations de publication:"
|
|
115
|
-
echo " 📦 Package: https://www.npmjs.com/package/@enokdev/springdocs-mcp"
|
|
116
|
-
echo " 🐙 GitHub: https://github.com/tky0065/springdocs-mcp"
|
|
117
|
-
echo " 📊 Stats: https://npm-stat.com/charts.html?package=@enokdev/springdocs-mcp"
|
|
118
|
-
echo ""
|
|
119
|
-
echo "📥 Installation pour les utilisateurs:"
|
|
120
|
-
echo " npm install -g @enokdev/springdocs-mcp"
|
|
121
|
-
echo ""
|
|
122
|
-
echo "🔧 Configuration Claude Desktop:"
|
|
123
|
-
echo ' {"mcpServers": {"spring-docs": {"command": "springdocs-mcp"}}}'
|
|
124
|
-
echo ""
|
|
125
|
-
echo "🌟 N'oubliez pas de:"
|
|
126
|
-
echo " • Annoncer sur les réseaux sociaux"
|
|
127
|
-
echo " • Mettre à jour la documentation si nécessaire"
|
|
128
|
-
echo " • Répondre aux issues GitHub"
|
|
129
|
-
echo ""
|
|
130
|
-
echo "Merci d'avoir publié un outil utile pour la communauté Spring! 🌱"
|
package/setup-jetbrains.sh
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
echo "🚀 Configuration automatique du serveur MCP Spring pour IDEs JetBrains"
|
|
4
|
-
echo "======================================================================"
|
|
5
|
-
echo
|
|
6
|
-
|
|
7
|
-
# Couleurs pour l'affichage
|
|
8
|
-
GREEN='\033[0;32m'
|
|
9
|
-
YELLOW='\033[1;33m'
|
|
10
|
-
BLUE='\033[0;34m'
|
|
11
|
-
RED='\033[0;31m'
|
|
12
|
-
NC='\033[0m' # No Color
|
|
13
|
-
|
|
14
|
-
# Vérifier si springdocs-mcp est installé
|
|
15
|
-
if ! command -v springdocs-mcp &> /dev/null; then
|
|
16
|
-
echo -e "${RED}❌ springdocs-mcp n'est pas installé globalement${NC}"
|
|
17
|
-
echo "Exécutez: npm install -g @enokdev/springdocs-mcp"
|
|
18
|
-
exit 1
|
|
19
|
-
fi
|
|
20
|
-
|
|
21
|
-
echo -e "${GREEN}✅ springdocs-mcp trouvé: $(which springdocs-mcp)${NC}"
|
|
22
|
-
echo
|
|
23
|
-
|
|
24
|
-
# Configuration MCP standard
|
|
25
|
-
MCP_CONFIG='{
|
|
26
|
-
"spring-docs": {
|
|
27
|
-
"command": "/opt/homebrew/bin/springdocs-mcp",
|
|
28
|
-
"description": "Spring Documentation MCP Server - Access to complete Spring ecosystem",
|
|
29
|
-
"timeout": 30000
|
|
30
|
-
}
|
|
31
|
-
}'
|
|
32
|
-
|
|
33
|
-
# Fonction pour créer la configuration Claude générique
|
|
34
|
-
create_claude_config() {
|
|
35
|
-
local config_dir="$1"
|
|
36
|
-
local config_file="$config_dir/claude_mcp_config.json"
|
|
37
|
-
|
|
38
|
-
if [ ! -d "$config_dir" ]; then
|
|
39
|
-
mkdir -p "$config_dir"
|
|
40
|
-
echo -e "${BLUE}📁 Créé le dossier: $config_dir${NC}"
|
|
41
|
-
fi
|
|
42
|
-
|
|
43
|
-
cat > "$config_file" << EOF
|
|
44
|
-
{
|
|
45
|
-
"mcpServers": $MCP_CONFIG
|
|
46
|
-
}
|
|
47
|
-
EOF
|
|
48
|
-
|
|
49
|
-
echo -e "${GREEN}✅ Configuration créée: $config_file${NC}"
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
# Fonction pour créer la configuration XML JetBrains
|
|
53
|
-
create_jetbrains_xml() {
|
|
54
|
-
local ide_config_dir="$1"
|
|
55
|
-
local options_dir="$ide_config_dir/options"
|
|
56
|
-
local claude_xml="$options_dir/claude.xml"
|
|
57
|
-
|
|
58
|
-
if [ ! -d "$options_dir" ]; then
|
|
59
|
-
mkdir -p "$options_dir"
|
|
60
|
-
echo -e "${BLUE}📁 Créé le dossier: $options_dir${NC}"
|
|
61
|
-
fi
|
|
62
|
-
|
|
63
|
-
cat > "$claude_xml" << 'EOF'
|
|
64
|
-
<application>
|
|
65
|
-
<component name="ClaudeSettings">
|
|
66
|
-
<option name="mcpServers">
|
|
67
|
-
<map>
|
|
68
|
-
<entry key="spring-docs">
|
|
69
|
-
<value>
|
|
70
|
-
<MCPServerConfig>
|
|
71
|
-
<option name="command" value="/opt/homebrew/bin/springdocs-mcp" />
|
|
72
|
-
<option name="description" value="Spring Documentation MCP Server" />
|
|
73
|
-
<option name="timeout" value="30000" />
|
|
74
|
-
</MCPServerConfig>
|
|
75
|
-
</value>
|
|
76
|
-
</entry>
|
|
77
|
-
</map>
|
|
78
|
-
</option>
|
|
79
|
-
</component>
|
|
80
|
-
</application>
|
|
81
|
-
EOF
|
|
82
|
-
|
|
83
|
-
echo -e "${GREEN}✅ Configuration XML créée: $claude_xml${NC}"
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
echo -e "${YELLOW}🔧 Configuration des IDEs JetBrains...${NC}"
|
|
87
|
-
echo
|
|
88
|
-
|
|
89
|
-
# Détecter le système d'exploitation
|
|
90
|
-
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
91
|
-
# macOS
|
|
92
|
-
JETBRAINS_BASE="$HOME/Library/Application Support/JetBrains"
|
|
93
|
-
CONFIG_BASE="$HOME/.jetbrains"
|
|
94
|
-
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
|
95
|
-
# Linux
|
|
96
|
-
JETBRAINS_BASE="$HOME/.config/JetBrains"
|
|
97
|
-
CONFIG_BASE="$HOME/.jetbrains"
|
|
98
|
-
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" ]]; then
|
|
99
|
-
# Windows
|
|
100
|
-
JETBRAINS_BASE="$APPDATA/JetBrains"
|
|
101
|
-
CONFIG_BASE="$HOME/.jetbrains"
|
|
102
|
-
else
|
|
103
|
-
echo -e "${RED}❌ Système d'exploitation non supporté: $OSTYPE${NC}"
|
|
104
|
-
exit 1
|
|
105
|
-
fi
|
|
106
|
-
|
|
107
|
-
echo -e "${BLUE}📍 Dossier JetBrains détecté: $JETBRAINS_BASE${NC}"
|
|
108
|
-
echo
|
|
109
|
-
|
|
110
|
-
# Créer la configuration générique
|
|
111
|
-
echo -e "${YELLOW}📝 Création de la configuration générique...${NC}"
|
|
112
|
-
create_claude_config "$CONFIG_BASE"
|
|
113
|
-
echo
|
|
114
|
-
|
|
115
|
-
# Liste des IDEs JetBrains à configurer
|
|
116
|
-
JETBRAINS_IDES=(
|
|
117
|
-
"IntelliJIdea"
|
|
118
|
-
"WebStorm"
|
|
119
|
-
"PyCharm"
|
|
120
|
-
"PhpStorm"
|
|
121
|
-
"RubyMine"
|
|
122
|
-
"CLion"
|
|
123
|
-
"GoLand"
|
|
124
|
-
"Rider"
|
|
125
|
-
"DataGrip"
|
|
126
|
-
"AndroidStudio"
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
echo -e "${YELLOW}🎯 Configuration des IDEs spécifiques...${NC}"
|
|
130
|
-
|
|
131
|
-
for ide in "${JETBRAINS_IDES[@]}"; do
|
|
132
|
-
# Chercher les versions installées de l'IDE
|
|
133
|
-
if [ -d "$JETBRAINS_BASE" ]; then
|
|
134
|
-
ide_dirs=$(find "$JETBRAINS_BASE" -maxdepth 1 -type d -name "${ide}*" 2>/dev/null)
|
|
135
|
-
|
|
136
|
-
if [ -n "$ide_dirs" ]; then
|
|
137
|
-
echo -e "${BLUE}🔍 Trouvé $ide:${NC}"
|
|
138
|
-
echo "$ide_dirs" | while read -r ide_dir; do
|
|
139
|
-
echo -e " 📁 $(basename "$ide_dir")"
|
|
140
|
-
create_jetbrains_xml "$ide_dir"
|
|
141
|
-
done
|
|
142
|
-
else
|
|
143
|
-
echo -e "${YELLOW}⚠️ $ide non installé ou non trouvé${NC}"
|
|
144
|
-
fi
|
|
145
|
-
fi
|
|
146
|
-
done
|
|
147
|
-
|
|
148
|
-
echo
|
|
149
|
-
echo -e "${GREEN}🎉 Configuration terminée !${NC}"
|
|
150
|
-
echo
|
|
151
|
-
echo -e "${YELLOW}📋 Prochaines étapes:${NC}"
|
|
152
|
-
echo "1. 🔄 Redémarrer vos IDEs JetBrains"
|
|
153
|
-
echo "2. 🔌 Installer le plugin Claude (si pas déjà fait)"
|
|
154
|
-
echo "3. ⚙️ Vérifier les paramètres Claude dans Settings → Tools → Claude"
|
|
155
|
-
echo "4. 🧪 Tester avec une question Spring dans le chat Claude"
|
|
156
|
-
echo
|
|
157
|
-
echo -e "${BLUE}💡 Exemple de test:${NC}"
|
|
158
|
-
echo "Demandez à Claude dans votre IDE: 'Quels sont les projets Spring pour la sécurité ?'"
|
|
159
|
-
echo
|
|
160
|
-
echo -e "${YELLOW}🔧 En cas de problème:${NC}"
|
|
161
|
-
echo "- Vérifiez que springdocs-mcp fonctionne: echo '{\"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"tools/list\", \"params\": {}}' | springdocs-mcp"
|
|
162
|
-
echo "- Consultez TROUBLESHOOTING.md pour plus d'aide"
|
|
163
|
-
echo
|
|
164
|
-
echo -e "${GREEN}✨ Votre serveur MCP Spring Documentation est maintenant disponible dans tous vos IDEs JetBrains !${NC}"
|
package/src/index.ts
DELETED
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
-
import { CallToolRequestSchema, ListToolsRequestSchema, CallToolRequest, ListToolsRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
6
|
-
import { SpringBootDocsService } from "./services/springboot-docs.js";
|
|
7
|
-
import { ToolDefinitions } from "./tools/index.js";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Serveur MCP pour accéder à la documentation Spring Boot
|
|
11
|
-
*/
|
|
12
|
-
class SpringBootMCPServer {
|
|
13
|
-
private server: Server;
|
|
14
|
-
private docsService: SpringBootDocsService;
|
|
15
|
-
|
|
16
|
-
constructor() {
|
|
17
|
-
this.server = new Server(
|
|
18
|
-
{
|
|
19
|
-
name: "springboot-mcp-server",
|
|
20
|
-
version: "1.1.0",
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
capabilities: {
|
|
24
|
-
tools: {},
|
|
25
|
-
},
|
|
26
|
-
}
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
this.docsService = new SpringBootDocsService();
|
|
30
|
-
this.setupToolHandlers();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
private setupToolHandlers() {
|
|
34
|
-
// Gestionnaire pour lister les outils disponibles
|
|
35
|
-
this.server.setRequestHandler(ListToolsRequestSchema, async (request: ListToolsRequest) => {
|
|
36
|
-
return {
|
|
37
|
-
tools: ToolDefinitions.getToolList(),
|
|
38
|
-
};
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
// Gestionnaire pour exécuter un outil
|
|
42
|
-
this.server.setRequestHandler(CallToolRequestSchema, async (request: CallToolRequest) => {
|
|
43
|
-
const { name, arguments: args } = request.params;
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
switch (name) {
|
|
47
|
-
case "search_spring_docs":
|
|
48
|
-
return await this.handleSearchDocs(args);
|
|
49
|
-
|
|
50
|
-
case "search_spring_projects":
|
|
51
|
-
return await this.handleSearchProjects(args);
|
|
52
|
-
|
|
53
|
-
case "get_spring_project":
|
|
54
|
-
return await this.handleGetProject(args);
|
|
55
|
-
|
|
56
|
-
case "get_all_spring_guides":
|
|
57
|
-
return await this.handleGetAllGuides(args);
|
|
58
|
-
|
|
59
|
-
case "get_spring_guide":
|
|
60
|
-
return await this.handleGetGuide(args);
|
|
61
|
-
|
|
62
|
-
case "get_spring_reference":
|
|
63
|
-
return await this.handleGetReference(args);
|
|
64
|
-
|
|
65
|
-
case "search_spring_concepts":
|
|
66
|
-
return await this.handleSearchConcepts(args);
|
|
67
|
-
|
|
68
|
-
default:
|
|
69
|
-
throw new Error(`Outil inconnu: ${name}`);
|
|
70
|
-
}
|
|
71
|
-
} catch (error) {
|
|
72
|
-
const errorMessage = error instanceof Error ? error.message : "Erreur inconnue";
|
|
73
|
-
return {
|
|
74
|
-
content: [
|
|
75
|
-
{
|
|
76
|
-
type: "text",
|
|
77
|
-
text: `Erreur lors de l'exécution de l'outil ${name}: ${errorMessage}`,
|
|
78
|
-
},
|
|
79
|
-
],
|
|
80
|
-
isError: true,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
private async handleSearchProjects(args: any) {
|
|
87
|
-
const { query, limit = 10 } = args;
|
|
88
|
-
|
|
89
|
-
if (!query || typeof query !== "string") {
|
|
90
|
-
throw new Error("Le paramètre 'query' est requis et doit être une chaîne de caractères");
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const results = await this.docsService.searchSpringProjects(query, limit);
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
content: [
|
|
97
|
-
{
|
|
98
|
-
type: "text",
|
|
99
|
-
text: `Projets Spring trouvés pour "${query}":\n\n${this.formatSearchResults(results)}`,
|
|
100
|
-
},
|
|
101
|
-
],
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
private async handleGetProject(args: any) {
|
|
106
|
-
const { projectName } = args;
|
|
107
|
-
|
|
108
|
-
if (!projectName || typeof projectName !== "string") {
|
|
109
|
-
throw new Error("Le paramètre 'projectName' est requis et doit être une chaîne de caractères");
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const project = await this.docsService.getSpringProject(projectName);
|
|
113
|
-
|
|
114
|
-
return {
|
|
115
|
-
content: [
|
|
116
|
-
{
|
|
117
|
-
type: "text",
|
|
118
|
-
text: project,
|
|
119
|
-
},
|
|
120
|
-
],
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
private async handleGetAllGuides(args: any) {
|
|
125
|
-
const { category, limit = 20 } = args;
|
|
126
|
-
|
|
127
|
-
const results = await this.docsService.getAllSpringGuides(category, limit);
|
|
128
|
-
|
|
129
|
-
return {
|
|
130
|
-
content: [
|
|
131
|
-
{
|
|
132
|
-
type: "text",
|
|
133
|
-
text: `Guides Spring disponibles${category ? ` dans la catégorie "${category}"` : ""}:\n\n${this.formatSearchResults(results)}`,
|
|
134
|
-
},
|
|
135
|
-
],
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
private async handleSearchDocs(args: any) {
|
|
140
|
-
const { query, docType = "all", limit = 10 } = args;
|
|
141
|
-
|
|
142
|
-
if (!query || typeof query !== "string") {
|
|
143
|
-
throw new Error("Le paramètre 'query' est requis et doit être une chaîne de caractères");
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const results = await this.docsService.searchDocumentation(query, docType, limit);
|
|
147
|
-
|
|
148
|
-
return {
|
|
149
|
-
content: [
|
|
150
|
-
{
|
|
151
|
-
type: "text",
|
|
152
|
-
text: `Résultats de recherche pour "${query}":\n\n${this.formatSearchResults(results)}`,
|
|
153
|
-
},
|
|
154
|
-
],
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
private async handleGetGuide(args: any) {
|
|
159
|
-
const { guideId } = args;
|
|
160
|
-
|
|
161
|
-
if (!guideId || typeof guideId !== "string") {
|
|
162
|
-
throw new Error("Le paramètre 'guideId' est requis et doit être une chaîne de caractères");
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const guide = await this.docsService.getGuide(guideId);
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
content: [
|
|
169
|
-
{
|
|
170
|
-
type: "text",
|
|
171
|
-
text: guide,
|
|
172
|
-
},
|
|
173
|
-
],
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
private async handleGetReference(args: any) {
|
|
178
|
-
const { section, subsection } = args;
|
|
179
|
-
|
|
180
|
-
if (!section || typeof section !== "string") {
|
|
181
|
-
throw new Error("Le paramètre 'section' est requis et doit être une chaîne de caractères");
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const reference = await this.docsService.getReference(section, subsection);
|
|
185
|
-
|
|
186
|
-
return {
|
|
187
|
-
content: [
|
|
188
|
-
{
|
|
189
|
-
type: "text",
|
|
190
|
-
text: reference,
|
|
191
|
-
},
|
|
192
|
-
],
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
private async handleSearchConcepts(args: any) {
|
|
197
|
-
const { concept, category } = args;
|
|
198
|
-
|
|
199
|
-
if (!concept || typeof concept !== "string") {
|
|
200
|
-
throw new Error("Le paramètre 'concept' est requis et doit être une chaîne de caractères");
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const results = await this.docsService.searchConcepts(concept, category);
|
|
204
|
-
|
|
205
|
-
return {
|
|
206
|
-
content: [
|
|
207
|
-
{
|
|
208
|
-
type: "text",
|
|
209
|
-
text: this.formatConceptResults(results),
|
|
210
|
-
},
|
|
211
|
-
],
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
private formatSearchResults(results: any[]): string {
|
|
216
|
-
if (results.length === 0) {
|
|
217
|
-
return "Aucun résultat trouvé.";
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
return results
|
|
221
|
-
.map((result, index) => {
|
|
222
|
-
return `${index + 1}. **${result.title}**
|
|
223
|
-
Type: ${result.type}
|
|
224
|
-
URL: ${result.url}
|
|
225
|
-
Description: ${result.description || "Aucune description disponible"}
|
|
226
|
-
|
|
227
|
-
`;
|
|
228
|
-
})
|
|
229
|
-
.join("\n");
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
private formatConceptResults(results: any): string {
|
|
233
|
-
if (!results || Object.keys(results).length === 0) {
|
|
234
|
-
return "Aucun concept trouvé.";
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
let formatted = `# Concepts Spring Boot\n\n`;
|
|
238
|
-
|
|
239
|
-
for (const [category, concepts] of Object.entries(results)) {
|
|
240
|
-
formatted += `## ${category}\n\n`;
|
|
241
|
-
|
|
242
|
-
if (Array.isArray(concepts)) {
|
|
243
|
-
concepts.forEach((concept: any) => {
|
|
244
|
-
formatted += `- **${concept.name}**: ${concept.description}\n`;
|
|
245
|
-
if (concept.examples && concept.examples.length > 0) {
|
|
246
|
-
formatted += ` Exemples: ${concept.examples.join(", ")}\n`;
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
formatted += "\n";
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
return formatted;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
async run() {
|
|
258
|
-
const transport = new StdioServerTransport();
|
|
259
|
-
await this.server.connect(transport);
|
|
260
|
-
console.error("Serveur MCP Spring Boot démarré sur stdio");
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Point d'entrée principal
|
|
265
|
-
async function main() {
|
|
266
|
-
const server = new SpringBootMCPServer();
|
|
267
|
-
await server.run();
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Gestion des erreurs
|
|
271
|
-
process.on("SIGINT", async () => {
|
|
272
|
-
console.error("Arrêt du serveur...");
|
|
273
|
-
process.exit(0);
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
process.on("unhandledRejection", (reason: any, promise: Promise<any>) => {
|
|
277
|
-
console.error("Rejet de promesse non géré:", reason);
|
|
278
|
-
process.exit(1);
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
// Démarrage du serveur
|
|
282
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
283
|
-
main().catch((error) => {
|
|
284
|
-
console.error("Erreur fatale:", error);
|
|
285
|
-
process.exit(1);
|
|
286
|
-
});
|
|
287
|
-
}
|