@dalcontak/blogger-mcp-server 1.0.0 → 1.0.1

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.
@@ -6,6 +6,7 @@ on:
6
6
  - 'release/**'
7
7
 
8
8
  permissions:
9
+ contents: read
9
10
  id-token: write
10
11
 
11
12
  jobs:
@@ -32,3 +33,5 @@ jobs:
32
33
 
33
34
  - name: Publish to npm
34
35
  run: npm publish --provenance --access public
36
+ env:
37
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/AGENTS.md CHANGED
@@ -6,7 +6,7 @@ MCP (Model Context Protocol) server for Google's Blogger API. Allows AI models t
6
6
  interact with Blogger blogs via stdio or HTTP transport. Includes an optional web dashboard
7
7
  (Express + Socket.IO) on a separate port when `UI_PORT` is set. Written in TypeScript, targeting Node.js 20.
8
8
 
9
- Package: `@mcproadev/blogger-mcp-server` (v1.0.4)
9
+ Package: `@dalcontak/blogger-mcp-server` (v1.0.4)
10
10
 
11
11
  ## Build / Run / Test Commands
12
12
 
@@ -47,6 +47,7 @@ src/
47
47
  config.ts # Environment-based configuration object
48
48
  types.ts # Shared interfaces and type definitions
49
49
  ui-manager.ts # Express + Socket.IO web dashboard
50
+ *.test.ts # Unit tests (Jest) alongside source files
50
51
  public/ # Static web UI assets (HTML/JS/CSS)
51
52
  dist/ # Compiled output (committed to repo)
52
53
  ```
@@ -146,7 +147,6 @@ dist/ # Compiled output (committed to repo)
146
147
  ## Known Issues / Gotchas
147
148
 
148
149
  - `dist/` directory is committed to the repo -- rebuild before committing if you change source
149
- - README.md has an unresolved merge conflict marker at line 171
150
150
  - HTTP mode in `index.ts` has a manual tool-routing switch that duplicates `server.ts` logic
151
151
 
152
152
  ## Deployment
package/README.md CHANGED
@@ -1,169 +1,264 @@
1
- # blogger-mcp-server
2
- =======
3
- # Serveur MCP pour Blogger
1
+ # Blogger MCP Server
4
2
 
5
- Un serveur MCP (Model Context Protocol) qui permet aux modèles d'intelligence artificielle comme Claude d'interagir directement avec l'API Blogger de Google.
3
+ MCP (Model Context Protocol) server for Google's Blogger API. Allows AI models like Claude to interact with Blogger blogs.
6
4
 
7
- ## À propos
5
+ ## Features
8
6
 
9
- Ce projet implémente un serveur compatible avec le protocole MCP (Model Context Protocol) pour l'API Blogger de Google. Il permet aux modèles d'IA comme Claude d'interagir avec les blogs Blogger pour :
7
+ - **List and retrieve blogs** Get blog details by ID or URL
8
+ - **Posts management** — List, search, retrieve, create, update, delete posts
9
+ - **Labels management** — List and retrieve labels
10
+ - **Dual authentication**:
11
+ - **API Key** (read-only) — Access public blogs
12
+ - **OAuth2** (full access) — Create, update, delete posts, list your blogs
13
+ - **Native search** — Uses Blogger's `posts/search` endpoint (not client-side filtering)
14
+ - **Blog discovery** — `get_blog_by_url` tool to find blog ID from URL
15
+ - **Optional Web UI** — Express + Socket.IO dashboard (enable with `UI_PORT`)
10
16
 
11
- * Lister et récupérer des blogs
12
- * Lister, rechercher, récupérer, créer, mettre à jour et supprimer des posts
13
- * Lister et récupérer des labels
14
-
15
- > **Note importante** : L'API Blogger de Google ne permet pas de créer de nouveaux blogs via API. Cette limitation est documentée par Google. Les blogs doivent être créés manuellement via l'interface web de Blogger.
16
-
17
- ## Prérequis
18
-
19
- * Node.js (version 16 ou supérieure)
20
- * Une clé API Blogger de Google
17
+ > **Note:** The Blogger API does not allow creating new blogs. Blogs must be created manually via the Blogger web interface.
21
18
 
22
19
  ## Installation
23
20
 
24
- ### Installation depuis npm
21
+ ### From npm
25
22
 
26
23
  ```bash
27
- npm install -g @mcproadev/blogger-mcp-server
24
+ npm install -g @dalcontak/blogger-mcp-server
28
25
  ```
29
26
 
30
- ### Installation depuis le code source
27
+ ### From source
31
28
 
32
29
  ```bash
33
- git clone https://github.com/niyonabil/blogger-mcp-server.git
30
+ git clone https://github.com/dalcontak/blogger-mcp-server.git
34
31
  cd blogger-mcp-server
35
32
  npm install
36
33
  npm run build
37
34
  ```
38
- if error install :
35
+
36
+ ## Authentication
37
+
38
+ ### Option 1: API Key (Read-only)
39
+
40
+ Access public blogs only.
41
+
42
+ 1. Go to [Google Cloud Console](https://console.cloud.google.com/)
43
+ 2. Create/select a project or existing one
44
+ 3. Enable the **Blogger API v3**
45
+ 4. Create an **API Key**
46
+ 5. Set the environment variable:
47
+
48
+ ```bash
49
+ export BLOGGER_API_KEY=your_api_key_here
50
+ ```
51
+
52
+ Works for: `get_blog`, `get_blog_by_url`, `list_posts`, `get_post`, `search_posts`, `list_labels`, `get_label`
53
+
54
+ ### Option 2: OAuth2 (Full Access)
55
+
56
+ Required for: `list_blogs`, `create_post`, `update_post`, `delete_post`
57
+
58
+ 1. Go to [Google Cloud Console](https://console.cloud.google.com/)
59
+ 2. Navigate to **Credentials** > **Create Credentials**
60
+ 3. Select **OAuth client ID**
61
+ 4. Application type: **Web application** or **Desktop app**
62
+ 5. Name: Your app name
63
+ 6. Authorized redirect URI: `http://localhost` (or your actual redirect)
64
+ 7. Scopes: Select **`https://www.googleapis.com/auth/blogger`**
65
+ 8. Create credentials and note the **Client ID** and **Client Secret**
66
+
67
+ To obtain a refresh token (one-time setup):
68
+ - Use the [OAuth Playground](https://developers.google.com/oauthplayground/)
69
+ - Select **Blogger API v3**
70
+ - Choose `https://www.googleapis.com/auth/blogger` scope
71
+ - Authorize and copy the **refresh token**
72
+
73
+ Set environment variables:
39
74
 
40
75
  ```bash
41
- npm install --save-dev @types/express
76
+ export GOOGLE_CLIENT_ID=your_client_id
77
+ export GOOGLE_CLIENT_SECRET=your_client_secret
78
+ export GOOGLE_REFRESH_TOKEN=your_refresh_token
42
79
  ```
43
- ## Configuration
44
80
 
45
- ### Obtenir une clé API Blogger
81
+ > **Note:** If both authentication methods are configured, OAuth2 is used (it covers all operations).
82
+
83
+ ## Usage
46
84
 
47
- 1. Accédez à la [Console Google Cloud](https://console.cloud.google.com/)
48
- 2. Créez un nouveau projet ou sélectionnez un projet existant
49
- 3. Activez l'API Blogger v3
50
- 4. Créez une clé API
51
- 5. Notez cette clé pour l'utiliser dans la configuration
85
+ ### Local Development
52
86
 
53
- ### Configuration du serveur MCP
87
+ ```bash
88
+ # Using npm package
89
+ npm start
54
90
 
55
- Créez un fichier de configuration pour votre client MCP. Voici un exemple pour Claude Desktop :
91
+ # Or from source (after build)
92
+ node dist/index.js
93
+
94
+ # Development mode with ts-node
95
+ npm run dev
96
+ ```
97
+
98
+ ### With MCP Client (Claude Desktop)
99
+
100
+ Create or edit your Claude Desktop config file:
101
+
102
+ **Linux:** `~/.config/Claude/claude_desktop_config.json`
103
+ **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
104
+ **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
56
105
 
57
106
  ```json
58
107
  {
59
108
  "mcpServers": {
60
109
  "blogger": {
61
- "command": "npx",
62
- "args": [
63
- "-y",
64
- "@mcproadev/blogger-mcp-server"
65
- ],
110
+ "command": "node",
111
+ "args": ["/home/dalcon/dev/ai/blogger-mcp-server/dist/index.js"],
66
112
  "env": {
67
- "BLOGGER_API_KEY": "VOTRE_CLE_API_ICI"
113
+ "BLOGGER_API_KEY": "your_api_key_here"
68
114
  }
69
115
  }
70
116
  }
71
117
  }
72
118
  ```
73
119
 
74
- Remplacez `VOTRE_CLE_API_ICI` par la clé API que vous avez obtenue.
120
+ Replace `/home/dalcon/dev/ai/blogger-mcp-server/dist/index.js` with your actual path, and set your API key or OAuth2 credentials.
75
121
 
76
- ## Utilisation
122
+ ### Example Commands
77
123
 
78
- ### Démarrage local
124
+ ```json
125
+ // List all your blogs (requires OAuth2)
126
+ {"tool": "list_blogs", "params": {}}
79
127
 
80
- Le projet inclut deux scripts pour faciliter le démarrage du serveur :
128
+ // Get blog details by ID
129
+ {"tool": "get_blog", "params": {"blogId": "123456789"}}
81
130
 
82
- #### Mode développement
131
+ // Find blog ID from URL (useful when you don't know the ID)
132
+ {"tool": "get_blog_by_url", "params": {"url": "https://yourblog.blogspot.com"}}
83
133
 
84
- ```bash
85
- export BLOGGER_API_KEY=votre_cle_api
86
- ./start-dev.sh
87
- ```
134
+ // List posts
135
+ {"tool": "list_posts", "params": {"blogId": "123456789", "maxResults": 10}}
88
136
 
89
- Ce script vérifie la présence de la clé API, installe les dépendances si nécessaire, compile le projet si nécessaire, puis démarre le serveur en mode développement.
137
+ // Search posts
138
+ {"tool": "search_posts", "params": {"blogId": "123456789", "query": "technology"}}
90
139
 
91
- #### Mode production
140
+ // Create a new post (requires OAuth2)
141
+ {"tool": "create_post", "params": {"blogId": "123456789", "title": "My Post", "content": "Content here", "labels": ["tech", "nodejs"]}}
92
142
 
93
- ```bash
94
- export BLOGGER_API_KEY=votre_cle_api
95
- npm run build
96
- ./start-prod.sh
143
+ // Update a post (requires OAuth2)
144
+ {"tool": "update_post", "params": {"blogId": "123456789", "postId": "789012", "title": "Updated Title"}}
145
+
146
+ // Delete a post (requires OAuth2)
147
+ {"tool": "delete_post", "params": {"blogId": "123456789", "postId": "789012"}}
148
+
149
+ // List labels
150
+ {"tool": "list_labels", "params": {"blogId": "123456789"}}
151
+
152
+ // Get label details
153
+ {"tool": "get_label", "params": {"blogId": "123456789", "labelName": "technology"}}
97
154
  ```
98
155
 
99
- Ce script vérifie la présence de la clé API et que le projet est compilé, puis démarre le serveur en mode production.
156
+ ## Available Tools
157
+
158
+ | Tool | Description | Auth Required |
159
+ |-------|-------------|---------------|
160
+ | `list_blogs` | Lists all your blogs | OAuth2 |
161
+ | `get_blog` | Retrieves blog details by ID | None |
162
+ | `get_blog_by_url` | Finds blog ID from URL | None |
163
+ | `list_posts` | Lists posts from a blog | None |
164
+ | `search_posts` | Searches posts (uses native API) | None |
165
+ | `get_post` | Retrieves post details | None |
166
+ | `create_post` | Creates a new post | OAuth2 |
167
+ | `update_post` | Updates an existing post | OAuth2 |
168
+ | `delete_post` | Deletes a post | OAuth2 |
169
+ | `list_labels` | Lists all labels from a blog | None |
170
+ | `get_label` | Retrieves label details | None |
171
+
172
+ ## Environment Variables
173
+
174
+ | Variable | Default | Description |
175
+ |----------|---------|-------------|
176
+ | `BLOGGER_API_KEY` | (optional) | Google Blogger API key (read-only) |
177
+ | `GOOGLE_CLIENT_ID` | (optional) | OAuth2 client ID (for full access) |
178
+ | `GOOGLE_CLIENT_SECRET` | (optional) | OAuth2 client secret |
179
+ | `GOOGLE_REFRESH_TOKEN` | (optional) | OAuth2 refresh token |
180
+ | `MCP_MODE` | `stdio` | Transport: `stdio` or `http` |
181
+ | `MCP_HTTP_HOST` | `0.0.0.0` | HTTP host (HTTP mode) |
182
+ | `MCP_HTTP_PORT` | `3000` | HTTP port (HTTP mode) |
183
+ | `BLOGGER_MAX_RESULTS` | `10` | Max results per query |
184
+ | `BLOGGER_API_TIMEOUT` | `30000` | API timeout (ms) |
185
+ | `LOG_LEVEL` | `info` | Logging level |
186
+ | `UI_PORT` | (disabled) | Web UI port (set to enable) |
187
+
188
+ **At least one auth method is required** — Either API key OR OAuth2 credentials.
189
+
190
+ ## Project Structure
100
191
 
101
- ### Utilisation avec un client MCP
192
+ ```
193
+ src/
194
+ index.ts # Entry point, main() function, HTTP mode routing
195
+ server.ts # MCP server tool registration (initMCPServer)
196
+ bloggerService.ts # Google Blogger API wrapper (BloggerService class)
197
+ config.ts # Environment-based configuration object
198
+ types.ts # Shared interfaces and type definitions
199
+ ui-manager.ts # Express + Socket.IO web dashboard
200
+ tests/ # Unit tests (Jest)
201
+ .github/workflows/ # GitHub Actions CI/CD
202
+ public/ # Static web UI assets (HTML/JS/CSS)
203
+ dist/ # Compiled output
204
+ ```
102
205
 
103
- Une fois configuré, vous pouvez utiliser le serveur MCP pour Blogger avec n'importe quel client MCP compatible, comme Claude Desktop.
206
+ ## Development
104
207
 
105
- Exemples de commandes :
208
+ ```bash
209
+ # Install dependencies
210
+ npm install
106
211
 
107
- * "Liste tous mes blogs Blogger"
108
- * "Crée un nouveau post sur mon blog avec l'ID 123456 avec le titre 'Mon nouveau post' et le contenu 'Voici le contenu de mon post'"
109
- * "Recherche des posts contenant le mot 'technologie' dans mon blog"
110
- * "Mets à jour le post avec l'ID 789012 pour changer son titre en 'Nouveau titre'"
212
+ # Run development (stdio mode, auto-compiles with ts-node)
213
+ npm run dev
111
214
 
112
- ## Options de déploiement
215
+ # Run in HTTP mode (useful for manual testing with curl)
216
+ MCP_MODE=http BLOGGER_API_KEY=your_key npm run dev
113
217
 
114
- ### Déploiement sur Vercel
218
+ # Run tests
219
+ npm test
115
220
 
116
- Le projet inclut un fichier `vercel.json` pour faciliter le déploiement sur Vercel :
221
+ # Build for production
222
+ npm run build
223
+ ```
117
224
 
118
- 1. Créez un compte sur [Vercel](https://vercel.com/) si vous n'en avez pas déjà un
119
- 2. Installez l'outil CLI Vercel : `npm install -g vercel`
120
- 3. Connectez-vous à votre compte Vercel : `vercel login`
121
- 4. Configurez votre variable d'environnement secrète : `vercel secrets add blogger_api_key "VOTRE_CLE_API_ICI"`
122
- 5. Déployez le projet : `vercel`
225
+ ## Deployment
123
226
 
124
- ### Déploiement avec Docker
227
+ ### Vercel
125
228
 
126
- Le projet inclut un Dockerfile pour faciliter le déploiement dans un conteneur Docker :
229
+ The project includes `vercel.json` for Vercel deployment:
127
230
 
128
- 1. Construisez l'image Docker :
129
- ```bash
130
- docker build -t blogger-mcp-server .
131
- ```
231
+ 1. Install Vercel CLI: `npm install -g vercel`
232
+ 2. Login: `vercel login`
233
+ 3. Deploy: `vercel`
132
234
 
133
- 2. Exécutez le conteneur :
134
- ```bash
135
- docker run -p 3000:3000 -e BLOGGER_API_KEY=votre_cle_api blogger-mcp-server
136
- ```
235
+ ### Docker
137
236
 
138
- ### Autres options de déploiement
237
+ Build and run:
139
238
 
140
- Le serveur peut également être déployé sur d'autres plateformes compatibles avec Node.js :
239
+ ```bash
240
+ docker build -t blogger-mcp-server .
241
+ docker run -p 3000:3000 -e BLOGGER_API_KEY=your_key blogger-mcp-server
242
+ ```
141
243
 
142
- 1. **Heroku** : Utilisez un Procfile et les variables d'environnement Heroku
143
- 2. **AWS Lambda** : Utilisez un adaptateur comme Serverless Framework
144
- 3. **Google Cloud Run** : Utilisez le Dockerfile inclus
244
+ ### Other Platforms
145
245
 
146
- ## Structure du projet
246
+ The server can be deployed to any Node.js-compatible platform (Heroku, AWS Lambda, Google Cloud Run, etc.).
147
247
 
148
- Le serveur MCP pour Blogger est composé de plusieurs modules :
248
+ ## Release Process
149
249
 
150
- * `index.ts` : Point d'entrée principal
151
- * `server.ts` : Configuration du serveur MCP
152
- * `bloggerService.ts` : Service d'interaction avec l'API Blogger
153
- * `config.ts` : Configuration du serveur
154
- * `types.ts` : Définition des types et interfaces
250
+ For publishing new versions to npm, see [RELEASE.md](./RELEASE.md).
155
251
 
156
- ## Limitations connues
252
+ ## Contributing
157
253
 
158
- * **Création de blogs** : L'API Blogger de Google ne permet pas de créer de nouveaux blogs via API. Les blogs doivent être créés manuellement via l'interface web de Blogger.
159
- * **Recherche de posts** : La recherche utilise l'endpoint natif `posts/search?q=` de l'API Blogger v3.
160
- * **Gestion des labels** : L'API Blogger ne fournit pas d'endpoints directs pour la gestion des labels. Cette fonctionnalité est implémentée en extrayant les labels des posts.
161
- * **Authentification** : Le serveur supporte l'authentification par clé API (lecture seule, blogs publics) et OAuth2 (accès complet en lecture/écriture). OAuth2 est requis pour `list_blogs`, `create_post`, `update_post`, `delete_post`.
254
+ Contributions are welcome! Feel free to open an issue or pull request.
162
255
 
163
- ## Contribution
256
+ ## License
164
257
 
165
- Les contributions sont les bienvenues ! N'hésitez pas à ouvrir une issue ou une pull request.
258
+ MIT
166
259
 
167
- ## Licence
260
+ ## Acknowledgments
168
261
 
169
- Ce projet est sous licence MIT.
262
+ - Built with [TypeScript](https://www.typescriptlang.org/)
263
+ - Uses [googleapis](https://github.com/googleapis/google-api-nodejs-client) for Google APIs
264
+ - MCP SDK by [Model Context Protocol](https://modelcontextprotocol.io/)
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "@dalcontak/blogger-mcp-server",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "private": false,
5
5
  "description": "MCP Server for Blogger API",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/dalcontak/blogger-mcp-server.git"
9
+ },
6
10
  "main": "dist/index.js",
7
11
  "types": "dist/index.d.ts",
8
12
  "scripts": {
@@ -1,57 +0,0 @@
1
- /**
2
- * Mock du SDK MCP pour éviter les problèmes de dépendances
3
- * Cette implémentation simplifiée fournit les fonctionnalités essentielles
4
- * du SDK MCP sans dépendre de la version exacte du package
5
- */
6
- import { z } from 'zod';
7
- import { ServerMode } from './types';
8
- export interface MCPTool<T extends z.ZodType> {
9
- name: string;
10
- description: string;
11
- parameters: T;
12
- handler: (params: z.infer<T>) => Promise<any>;
13
- }
14
- export interface MCPServerOptions {
15
- name: string;
16
- version: string;
17
- mode: ServerMode;
18
- }
19
- export interface ServerTransport {
20
- start: () => Promise<void>;
21
- stop: () => Promise<void>;
22
- onRequest?: (handler: (request: any) => Promise<any>) => void;
23
- }
24
- export declare class MCPServer {
25
- private options;
26
- private tools;
27
- private transport;
28
- constructor(options: MCPServerOptions);
29
- addTool<T extends z.ZodType>(tool: MCPTool<T>): void;
30
- connect(transport: ServerTransport): Promise<void>;
31
- start(): Promise<void>;
32
- stop(): Promise<void>;
33
- }
34
- export declare class StdioServerTransport implements ServerTransport {
35
- private requestHandler;
36
- start(): Promise<void>;
37
- stop(): Promise<void>;
38
- onRequest(handler: (request: any) => Promise<any>): void;
39
- }
40
- export declare class HttpServerTransport implements ServerTransport {
41
- private server;
42
- private requestHandler;
43
- private host;
44
- private port;
45
- constructor(options: {
46
- host: string;
47
- port: number;
48
- });
49
- start(): Promise<void>;
50
- stop(): Promise<void>;
51
- onRequest(handler: (request: any) => Promise<any>): void;
52
- }
53
- export declare class ResourceTemplate<T> {
54
- private resource;
55
- constructor(resource: T);
56
- get(): T;
57
- }
@@ -1,227 +0,0 @@
1
- "use strict";
2
- /**
3
- * Mock du SDK MCP pour éviter les problèmes de dépendances
4
- * Cette implémentation simplifiée fournit les fonctionnalités essentielles
5
- * du SDK MCP sans dépendre de la version exacte du package
6
- */
7
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
- if (k2 === undefined) k2 = k;
9
- var desc = Object.getOwnPropertyDescriptor(m, k);
10
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
- desc = { enumerable: true, get: function() { return m[k]; } };
12
- }
13
- Object.defineProperty(o, k2, desc);
14
- }) : (function(o, m, k, k2) {
15
- if (k2 === undefined) k2 = k;
16
- o[k2] = m[k];
17
- }));
18
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
- Object.defineProperty(o, "default", { enumerable: true, value: v });
20
- }) : function(o, v) {
21
- o["default"] = v;
22
- });
23
- var __importStar = (this && this.__importStar) || (function () {
24
- var ownKeys = function(o) {
25
- ownKeys = Object.getOwnPropertyNames || function (o) {
26
- var ar = [];
27
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
- return ar;
29
- };
30
- return ownKeys(o);
31
- };
32
- return function (mod) {
33
- if (mod && mod.__esModule) return mod;
34
- var result = {};
35
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
- __setModuleDefault(result, mod);
37
- return result;
38
- };
39
- })();
40
- Object.defineProperty(exports, "__esModule", { value: true });
41
- exports.ResourceTemplate = exports.HttpServerTransport = exports.StdioServerTransport = exports.MCPServer = void 0;
42
- const zod_1 = require("zod");
43
- const http = __importStar(require("http"));
44
- // Classe principale du serveur MCP
45
- class MCPServer {
46
- constructor(options) {
47
- this.tools = new Map();
48
- this.transport = null;
49
- this.options = options;
50
- }
51
- // Ajoute un outil au serveur
52
- addTool(tool) {
53
- this.tools.set(tool.name, tool);
54
- }
55
- // Connecte le serveur à un transport
56
- async connect(transport) {
57
- this.transport = transport;
58
- if (this.transport.onRequest) {
59
- this.transport.onRequest(async (request) => {
60
- try {
61
- const { tool, params } = request;
62
- if (!this.tools.has(tool)) {
63
- return {
64
- error: `Outil non trouvé: ${tool}`
65
- };
66
- }
67
- const mcpTool = this.tools.get(tool);
68
- try {
69
- const validatedParams = mcpTool.parameters.parse(params);
70
- const result = await mcpTool.handler(validatedParams);
71
- return result;
72
- }
73
- catch (error) {
74
- if (error instanceof zod_1.z.ZodError) {
75
- return {
76
- error: `Paramètres invalides: ${error.message}`
77
- };
78
- }
79
- return {
80
- error: `Erreur lors de l'exécution de l'outil: ${error}`
81
- };
82
- }
83
- }
84
- catch (error) {
85
- return {
86
- error: `Erreur interne du serveur: ${error}`
87
- };
88
- }
89
- });
90
- }
91
- }
92
- // Démarre le serveur
93
- async start() {
94
- if (!this.transport) {
95
- throw new Error('Le serveur doit être connecté à un transport avant de démarrer');
96
- }
97
- await this.transport.start();
98
- }
99
- // Arrête le serveur
100
- async stop() {
101
- if (this.transport) {
102
- await this.transport.stop();
103
- }
104
- }
105
- }
106
- exports.MCPServer = MCPServer;
107
- // Transport pour le mode stdio
108
- class StdioServerTransport {
109
- constructor() {
110
- this.requestHandler = null;
111
- }
112
- async start() {
113
- process.stdin.setEncoding('utf-8');
114
- process.stdin.on('data', async (data) => {
115
- try {
116
- const request = JSON.parse(data.toString());
117
- if (this.requestHandler) {
118
- const response = await this.requestHandler(request);
119
- process.stdout.write(JSON.stringify(response) + '\n');
120
- }
121
- }
122
- catch (error) {
123
- process.stdout.write(JSON.stringify({ error: `Erreur de parsing: ${error}` }) + '\n');
124
- }
125
- });
126
- }
127
- async stop() {
128
- // Rien à faire pour le mode stdio
129
- }
130
- onRequest(handler) {
131
- this.requestHandler = handler;
132
- }
133
- }
134
- exports.StdioServerTransport = StdioServerTransport;
135
- // Transport pour le mode HTTP
136
- class HttpServerTransport {
137
- constructor(options) {
138
- this.server = null;
139
- this.requestHandler = null;
140
- this.host = options.host;
141
- this.port = options.port;
142
- }
143
- async start() {
144
- this.server = http.createServer(async (req, res) => {
145
- res.setHeader('Content-Type', 'application/json');
146
- res.setHeader('Access-Control-Allow-Origin', '*');
147
- res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
148
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
149
- if (req.method === 'OPTIONS') {
150
- res.statusCode = 200;
151
- res.end();
152
- return;
153
- }
154
- if (req.method !== 'POST') {
155
- res.statusCode = 405;
156
- res.end(JSON.stringify({ error: 'Méthode non autorisée' }));
157
- return;
158
- }
159
- try {
160
- let body = '';
161
- req.on('data', (chunk) => {
162
- body += chunk.toString();
163
- });
164
- req.on('end', async () => {
165
- try {
166
- const request = JSON.parse(body);
167
- if (this.requestHandler) {
168
- const response = await this.requestHandler(request);
169
- res.statusCode = 200;
170
- res.end(JSON.stringify(response));
171
- }
172
- else {
173
- res.statusCode = 500;
174
- res.end(JSON.stringify({ error: 'Gestionnaire de requêtes non configuré' }));
175
- }
176
- }
177
- catch (error) {
178
- res.statusCode = 400;
179
- res.end(JSON.stringify({ error: `Erreur de parsing: ${error}` }));
180
- }
181
- });
182
- }
183
- catch (error) {
184
- res.statusCode = 500;
185
- res.end(JSON.stringify({ error: `Erreur interne du serveur: ${error}` }));
186
- }
187
- });
188
- return new Promise((resolve) => {
189
- if (this.server) {
190
- this.server.listen(this.port, this.host, () => {
191
- resolve();
192
- });
193
- }
194
- });
195
- }
196
- async stop() {
197
- return new Promise((resolve, reject) => {
198
- if (this.server) {
199
- this.server.close((err) => {
200
- if (err) {
201
- reject(err);
202
- }
203
- else {
204
- resolve();
205
- }
206
- });
207
- }
208
- else {
209
- resolve();
210
- }
211
- });
212
- }
213
- onRequest(handler) {
214
- this.requestHandler = handler;
215
- }
216
- }
217
- exports.HttpServerTransport = HttpServerTransport;
218
- // Classe pour les templates de ressources
219
- class ResourceTemplate {
220
- constructor(resource) {
221
- this.resource = resource;
222
- }
223
- get() {
224
- return this.resource;
225
- }
226
- }
227
- exports.ResourceTemplate = ResourceTemplate;