@skemacms/mcp-server 1.1.0
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 +206 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +130 -0
- package/dist/skema-client.d.ts +78 -0
- package/dist/skema-client.js +116 -0
- package/dist/tools.d.ts +6 -0
- package/dist/tools.js +235 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Skema MCP Server
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@skemacms/mcp-server)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
Serveur MCP (Model Context Protocol) officiel pour **Skema CMS**.
|
|
7
|
+
Connectez Claude Desktop, Cursor, Windsurf ou tout client MCP compatible à vos données Skema.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g @skemacms/mcp-server
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Configuration
|
|
16
|
+
|
|
17
|
+
### Claude Desktop
|
|
18
|
+
|
|
19
|
+
Ajoutez dans votre fichier `claude_desktop_config.json` :
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"mcpServers": {
|
|
24
|
+
"skema-cms": {
|
|
25
|
+
"command": "skema-mcp",
|
|
26
|
+
"env": {
|
|
27
|
+
"SKEMA_API_KEY": "pk_live_votre_cle_api",
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Windsurf / Cursor
|
|
35
|
+
|
|
36
|
+
Ajoutez dans vos paramètres MCP :
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"skema-cms": {
|
|
41
|
+
"command": "npx",
|
|
42
|
+
"args": ["-y", "@skemacms/mcp-server"],
|
|
43
|
+
"env": {
|
|
44
|
+
"SKEMA_API_KEY": "pk_live_votre_cle_api",
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Variables d'environnement
|
|
51
|
+
|
|
52
|
+
| Variable | Description | Requis |
|
|
53
|
+
| ---------------- | ------------------------------------------------------- | ------ |
|
|
54
|
+
| `SKEMA_API_KEY` | Clé API Skema (format `pk_live_xxx`) | Oui |
|
|
55
|
+
| `SKEMA_BASE_URL` | URL de l'API Skema (défaut: `https://api.skemacms.com`) | Non |
|
|
56
|
+
|
|
57
|
+
## Outils disponibles (11 outils)
|
|
58
|
+
|
|
59
|
+
### Lecture
|
|
60
|
+
|
|
61
|
+
| Outil | Description |
|
|
62
|
+
| ------------------------- | -------------------------------------------------------------- |
|
|
63
|
+
| `get_collections` | Liste toutes les collections accessibles |
|
|
64
|
+
| `get_collection` | Récupère le schéma d'une collection (champs, types, relations) |
|
|
65
|
+
| `get_collection_items` | Liste les items avec pagination, tri, filtres et populate |
|
|
66
|
+
| `get_collection_item` | Récupère un item par son ID avec ses relations |
|
|
67
|
+
| `search_collection_items` | Recherche textuelle dans une collection |
|
|
68
|
+
| `count_collection_items` | Compte les items avec filtres optionnels |
|
|
69
|
+
|
|
70
|
+
### Écriture
|
|
71
|
+
|
|
72
|
+
| Outil | Description |
|
|
73
|
+
| ------------------------ | ----------------------------------------------- |
|
|
74
|
+
| `create_collection_item` | Crée un nouvel item |
|
|
75
|
+
| `update_collection_item` | Met à jour un item existant (merge partiel) |
|
|
76
|
+
| `delete_collection_item` | Supprime un item |
|
|
77
|
+
| `batch_create_items` | Crée plusieurs items en une seule requête |
|
|
78
|
+
| `batch_update_items` | Met à jour plusieurs items en une seule requête |
|
|
79
|
+
|
|
80
|
+
## Exemples d'utilisation
|
|
81
|
+
|
|
82
|
+
### Lister les collections
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
Quelles collections sont disponibles dans mon CMS ?
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Récupérer des items avec relations
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
Liste les 10 derniers articles avec leurs auteurs et catégories
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Créer un item
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Crée un nouvel article avec le titre "Mon article" et le statut "draft"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Recherche
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
Recherche les produits contenant "smartphone" dans le titre
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Opérations en masse
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
Mets à jour le statut de tous les articles de la catégorie "news" en "published"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## API HTTP (alternative)
|
|
113
|
+
|
|
114
|
+
Vous pouvez aussi utiliser l'API MCP directement via HTTP :
|
|
115
|
+
|
|
116
|
+
**Endpoint :** `POST https://api.skemacms.com/mcp`
|
|
117
|
+
|
|
118
|
+
**Headers :**
|
|
119
|
+
|
|
120
|
+
- `Authorization: Bearer <API_KEY>`
|
|
121
|
+
- `Content-Type: application/json`
|
|
122
|
+
|
|
123
|
+
### Exemple cURL
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
curl -X POST https://api.skemacms.com/mcp \
|
|
127
|
+
-H "Authorization: Bearer pk_live_xxx" \
|
|
128
|
+
-H "Content-Type: application/json" \
|
|
129
|
+
-d '{
|
|
130
|
+
"jsonrpc": "2.0",
|
|
131
|
+
"id": 1,
|
|
132
|
+
"method": "tools/call",
|
|
133
|
+
"params": {
|
|
134
|
+
"name": "get_collection_items",
|
|
135
|
+
"arguments": {
|
|
136
|
+
"collection": "articles",
|
|
137
|
+
"page": 1,
|
|
138
|
+
"perPage": 10,
|
|
139
|
+
"populate": "author,category"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}'
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Exemple Python
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
import requests
|
|
149
|
+
|
|
150
|
+
API_KEY = "pk_live_xxx"
|
|
151
|
+
MCP_URL = "https://api.skemacms.com/mcp"
|
|
152
|
+
|
|
153
|
+
headers = {
|
|
154
|
+
"Authorization": f"Bearer {API_KEY}",
|
|
155
|
+
"Content-Type": "application/json"
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
response = requests.post(MCP_URL, headers=headers, json={
|
|
159
|
+
"jsonrpc": "2.0",
|
|
160
|
+
"id": 1,
|
|
161
|
+
"method": "tools/call",
|
|
162
|
+
"params": {
|
|
163
|
+
"name": "get_collection_items",
|
|
164
|
+
"arguments": {"collection": "articles", "populate": "author"}
|
|
165
|
+
}
|
|
166
|
+
})
|
|
167
|
+
print(response.json())
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Méthodes JSON-RPC
|
|
171
|
+
|
|
172
|
+
| Méthode | Description |
|
|
173
|
+
| ------------ | ----------------------------------- |
|
|
174
|
+
| `initialize` | Initialise la connexion MCP |
|
|
175
|
+
| `tools/list` | Liste tous les outils disponibles |
|
|
176
|
+
| `tools/call` | Exécute un outil avec ses arguments |
|
|
177
|
+
|
|
178
|
+
## Permissions
|
|
179
|
+
|
|
180
|
+
Les outils disponibles dépendent des permissions de votre clé API :
|
|
181
|
+
|
|
182
|
+
| Permission | Outils autorisés |
|
|
183
|
+
| ---------- | ------------------------------ |
|
|
184
|
+
| `read` | `get_*`, `search_*`, `count_*` |
|
|
185
|
+
| `create` | `create_*`, `batch_create_*` |
|
|
186
|
+
| `update` | `update_*`, `batch_update_*` |
|
|
187
|
+
| `delete` | `delete_*` |
|
|
188
|
+
|
|
189
|
+
## Développement local
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
git clone https://github.com/skemacms/mcp-server.git
|
|
193
|
+
cd mcp-server
|
|
194
|
+
npm install
|
|
195
|
+
npm run dev
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Liens utiles
|
|
199
|
+
|
|
200
|
+
- [Documentation Skema CMS](https://docs.skemacms.com)
|
|
201
|
+
- [Guide MCP](https://docs.skemacms.com/guide/mcp)
|
|
202
|
+
- [Créer une clé API](https://app.skemacms.com)
|
|
203
|
+
|
|
204
|
+
## Licence
|
|
205
|
+
|
|
206
|
+
MIT - Skema CMS
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Serveur MCP pour Skema CMS
|
|
4
|
+
* Expose les fonctionnalités de gestion de contenu via le protocole MCP
|
|
5
|
+
*/
|
|
6
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
7
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
8
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
9
|
+
import { tools } from "./tools.js";
|
|
10
|
+
import * as skema from "./skema-client.js";
|
|
11
|
+
const server = new Server({
|
|
12
|
+
name: "skema-cms",
|
|
13
|
+
version: "1.0.0",
|
|
14
|
+
}, {
|
|
15
|
+
capabilities: {
|
|
16
|
+
tools: {},
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
// Liste des outils disponibles
|
|
20
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
21
|
+
tools,
|
|
22
|
+
}));
|
|
23
|
+
// Execution des outils
|
|
24
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
25
|
+
const { name, arguments: args } = request.params;
|
|
26
|
+
try {
|
|
27
|
+
let result;
|
|
28
|
+
switch (name) {
|
|
29
|
+
// Collections
|
|
30
|
+
case "get_collections": {
|
|
31
|
+
result = await skema.getCollections();
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
case "get_collection": {
|
|
35
|
+
const { collection } = args;
|
|
36
|
+
result = await skema.getCollection(collection);
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
// Content CRUD
|
|
40
|
+
case "get_collection_items": {
|
|
41
|
+
const { collection, page, perPage, sort, populate, filters } = args;
|
|
42
|
+
result = await skema.getItems(collection, {
|
|
43
|
+
page,
|
|
44
|
+
perPage,
|
|
45
|
+
sort,
|
|
46
|
+
populate,
|
|
47
|
+
filters,
|
|
48
|
+
});
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
case "get_collection_item": {
|
|
52
|
+
const { collection, id, populate } = args;
|
|
53
|
+
result = await skema.getItem(collection, id, { populate });
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case "create_collection_item": {
|
|
57
|
+
const { collection, data } = args;
|
|
58
|
+
result = await skema.createItem(collection, data);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
case "update_collection_item": {
|
|
62
|
+
const { collection, id, data } = args;
|
|
63
|
+
result = await skema.updateItem(collection, id, data);
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case "delete_collection_item": {
|
|
67
|
+
const { collection, id } = args;
|
|
68
|
+
result = await skema.deleteItem(collection, id);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
case "search_collection_items": {
|
|
72
|
+
const { collection, query, fields, page, perPage } = args;
|
|
73
|
+
result = await skema.searchItems(collection, query, {
|
|
74
|
+
fields,
|
|
75
|
+
page,
|
|
76
|
+
perPage,
|
|
77
|
+
});
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
case "count_collection_items": {
|
|
81
|
+
const { collection, filters } = args;
|
|
82
|
+
result = await skema.countItems(collection, filters);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
case "batch_create_items": {
|
|
86
|
+
const { collection, items } = args;
|
|
87
|
+
result = await skema.batchCreate(collection, items);
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
case "batch_update_items": {
|
|
91
|
+
const { collection, items } = args;
|
|
92
|
+
result = await skema.batchUpdate(collection, items);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
default:
|
|
96
|
+
throw new Error(`Outil inconnu: ${name}`);
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
content: [
|
|
100
|
+
{
|
|
101
|
+
type: "text",
|
|
102
|
+
text: JSON.stringify(result, null, 2),
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
109
|
+
console.error(`Erreur outil ${name}:`, message);
|
|
110
|
+
return {
|
|
111
|
+
content: [
|
|
112
|
+
{
|
|
113
|
+
type: "text",
|
|
114
|
+
text: `Erreur: ${message}`,
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
isError: true,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
// Démarrage du serveur
|
|
122
|
+
const main = async () => {
|
|
123
|
+
const transport = new StdioServerTransport();
|
|
124
|
+
await server.connect(transport);
|
|
125
|
+
console.error("Serveur MCP Skema démarre");
|
|
126
|
+
};
|
|
127
|
+
main().catch((error) => {
|
|
128
|
+
console.error("Erreur fatale:", error);
|
|
129
|
+
process.exit(1);
|
|
130
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client HTTP pour communiquer avec l'API publique Skema
|
|
3
|
+
*/
|
|
4
|
+
export interface SkemaResponse<T = unknown> {
|
|
5
|
+
data: T;
|
|
6
|
+
count?: number;
|
|
7
|
+
page?: number;
|
|
8
|
+
totalPages?: number;
|
|
9
|
+
message: string;
|
|
10
|
+
statusCode: number;
|
|
11
|
+
}
|
|
12
|
+
export interface FetchOptions {
|
|
13
|
+
method?: "GET" | "POST" | "PUT" | "DELETE";
|
|
14
|
+
body?: unknown;
|
|
15
|
+
params?: Record<string, string | number | boolean | undefined>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Effectue une requete vers l'API Skema
|
|
19
|
+
*/
|
|
20
|
+
export declare const skemaFetch: <T = unknown>(path: string, options?: FetchOptions) => Promise<SkemaResponse<T>>;
|
|
21
|
+
/**
|
|
22
|
+
* Recupere la liste des collections
|
|
23
|
+
*/
|
|
24
|
+
export declare const getCollections: () => Promise<SkemaResponse<unknown>>;
|
|
25
|
+
/**
|
|
26
|
+
* Recupere le schema d'une collection
|
|
27
|
+
*/
|
|
28
|
+
export declare const getCollection: (name: string) => Promise<SkemaResponse<unknown>>;
|
|
29
|
+
/**
|
|
30
|
+
* Liste les items d'une collection
|
|
31
|
+
*/
|
|
32
|
+
export declare const getItems: (collection: string, options?: {
|
|
33
|
+
page?: number;
|
|
34
|
+
perPage?: number;
|
|
35
|
+
sort?: string;
|
|
36
|
+
populate?: string;
|
|
37
|
+
filters?: Record<string, unknown>;
|
|
38
|
+
}) => Promise<SkemaResponse<unknown>>;
|
|
39
|
+
/**
|
|
40
|
+
* Recupere un item par son ID
|
|
41
|
+
*/
|
|
42
|
+
export declare const getItem: (collection: string, id: string, options?: {
|
|
43
|
+
populate?: string;
|
|
44
|
+
}) => Promise<SkemaResponse<unknown>>;
|
|
45
|
+
/**
|
|
46
|
+
* Cree un nouvel item
|
|
47
|
+
*/
|
|
48
|
+
export declare const createItem: (collection: string, data: Record<string, unknown>) => Promise<SkemaResponse<unknown>>;
|
|
49
|
+
/**
|
|
50
|
+
* Met a jour un item
|
|
51
|
+
*/
|
|
52
|
+
export declare const updateItem: (collection: string, id: string, data: Record<string, unknown>) => Promise<SkemaResponse<unknown>>;
|
|
53
|
+
/**
|
|
54
|
+
* Supprime un item
|
|
55
|
+
*/
|
|
56
|
+
export declare const deleteItem: (collection: string, id: string) => Promise<SkemaResponse<unknown>>;
|
|
57
|
+
/**
|
|
58
|
+
* Recherche dans une collection
|
|
59
|
+
*/
|
|
60
|
+
export declare const searchItems: (collection: string, query: string, options?: {
|
|
61
|
+
fields?: string;
|
|
62
|
+
page?: number;
|
|
63
|
+
perPage?: number;
|
|
64
|
+
}) => Promise<SkemaResponse<unknown>>;
|
|
65
|
+
/**
|
|
66
|
+
* Compte les items d'une collection
|
|
67
|
+
*/
|
|
68
|
+
export declare const countItems: (collection: string, filters?: Record<string, unknown>) => Promise<SkemaResponse<unknown>>;
|
|
69
|
+
/**
|
|
70
|
+
* Cree plusieurs items en une seule requete
|
|
71
|
+
*/
|
|
72
|
+
export declare const batchCreate: (collection: string, items: Record<string, unknown>[]) => Promise<SkemaResponse<unknown>>;
|
|
73
|
+
/**
|
|
74
|
+
* Met a jour plusieurs items en une seule requete
|
|
75
|
+
*/
|
|
76
|
+
export declare const batchUpdate: (collection: string, items: Array<{
|
|
77
|
+
id: string;
|
|
78
|
+
} & Record<string, unknown>>) => Promise<SkemaResponse<unknown>>;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client HTTP pour communiquer avec l'API publique Skema
|
|
3
|
+
*/
|
|
4
|
+
const API_KEY = process.env.SKEMA_API_KEY || "";
|
|
5
|
+
const BASE_URL = process.env.SKEMA_BASE_URL || "https://api.skemacms.com";
|
|
6
|
+
/**
|
|
7
|
+
* Effectue une requete vers l'API Skema
|
|
8
|
+
*/
|
|
9
|
+
export const skemaFetch = async (path, options = {}) => {
|
|
10
|
+
const { method = "GET", body, params } = options;
|
|
11
|
+
let url = `${BASE_URL}${path}`;
|
|
12
|
+
if (params) {
|
|
13
|
+
const searchParams = new URLSearchParams();
|
|
14
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
15
|
+
if (value !== undefined) {
|
|
16
|
+
searchParams.append(key, String(value));
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const queryString = searchParams.toString();
|
|
20
|
+
if (queryString) {
|
|
21
|
+
url += `?${queryString}`;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const response = await fetch(url, {
|
|
25
|
+
method,
|
|
26
|
+
headers: {
|
|
27
|
+
"X-API-Key": API_KEY,
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
},
|
|
30
|
+
...(body ? { body: JSON.stringify(body) } : {}),
|
|
31
|
+
});
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
const error = await response
|
|
34
|
+
.json()
|
|
35
|
+
.catch(() => ({ message: "Erreur inconnue" }));
|
|
36
|
+
throw new Error(error.message || `Erreur HTTP ${response.status}`);
|
|
37
|
+
}
|
|
38
|
+
return response.json();
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Recupere la liste des collections
|
|
42
|
+
*/
|
|
43
|
+
export const getCollections = () => skemaFetch("/public/collections");
|
|
44
|
+
/**
|
|
45
|
+
* Recupere le schema d'une collection
|
|
46
|
+
*/
|
|
47
|
+
export const getCollection = (name) => skemaFetch(`/public/collections/${name}`);
|
|
48
|
+
/**
|
|
49
|
+
* Liste les items d'une collection
|
|
50
|
+
*/
|
|
51
|
+
export const getItems = (collection, options) => skemaFetch(`/public/${collection}`, {
|
|
52
|
+
params: {
|
|
53
|
+
page: options?.page,
|
|
54
|
+
perPage: options?.perPage,
|
|
55
|
+
sort: options?.sort,
|
|
56
|
+
populate: options?.populate,
|
|
57
|
+
...(options?.filters && { filters: JSON.stringify(options.filters) }),
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
/**
|
|
61
|
+
* Recupere un item par son ID
|
|
62
|
+
*/
|
|
63
|
+
export const getItem = (collection, id, options) => skemaFetch(`/public/${collection}/${id}`, {
|
|
64
|
+
params: { populate: options?.populate },
|
|
65
|
+
});
|
|
66
|
+
/**
|
|
67
|
+
* Cree un nouvel item
|
|
68
|
+
*/
|
|
69
|
+
export const createItem = (collection, data) => skemaFetch(`/public/${collection}`, {
|
|
70
|
+
method: "POST",
|
|
71
|
+
body: data,
|
|
72
|
+
});
|
|
73
|
+
/**
|
|
74
|
+
* Met a jour un item
|
|
75
|
+
*/
|
|
76
|
+
export const updateItem = (collection, id, data) => skemaFetch(`/public/${collection}/${id}`, {
|
|
77
|
+
method: "PUT",
|
|
78
|
+
body: data,
|
|
79
|
+
});
|
|
80
|
+
/**
|
|
81
|
+
* Supprime un item
|
|
82
|
+
*/
|
|
83
|
+
export const deleteItem = (collection, id) => skemaFetch(`/public/${collection}/${id}`, {
|
|
84
|
+
method: "DELETE",
|
|
85
|
+
});
|
|
86
|
+
/**
|
|
87
|
+
* Recherche dans une collection
|
|
88
|
+
*/
|
|
89
|
+
export const searchItems = (collection, query, options) => skemaFetch(`/public/${collection}/search`, {
|
|
90
|
+
params: {
|
|
91
|
+
q: query,
|
|
92
|
+
fields: options?.fields,
|
|
93
|
+
page: options?.page,
|
|
94
|
+
perPage: options?.perPage,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
/**
|
|
98
|
+
* Compte les items d'une collection
|
|
99
|
+
*/
|
|
100
|
+
export const countItems = (collection, filters) => skemaFetch(`/public/${collection}/count`, {
|
|
101
|
+
params: filters ? { filters: JSON.stringify(filters) } : undefined,
|
|
102
|
+
});
|
|
103
|
+
/**
|
|
104
|
+
* Cree plusieurs items en une seule requete
|
|
105
|
+
*/
|
|
106
|
+
export const batchCreate = (collection, items) => skemaFetch(`/public/${collection}/batch`, {
|
|
107
|
+
method: "POST",
|
|
108
|
+
body: items,
|
|
109
|
+
});
|
|
110
|
+
/**
|
|
111
|
+
* Met a jour plusieurs items en une seule requete
|
|
112
|
+
*/
|
|
113
|
+
export const batchUpdate = (collection, items) => skemaFetch(`/public/${collection}/batch`, {
|
|
114
|
+
method: "PUT",
|
|
115
|
+
body: items,
|
|
116
|
+
});
|
package/dist/tools.d.ts
ADDED
package/dist/tools.js
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Définition des outils MCP pour Skema
|
|
3
|
+
* Version 2 : 11 outils (sans get_related_items, on utilise populate)
|
|
4
|
+
*/
|
|
5
|
+
export const tools = [
|
|
6
|
+
{
|
|
7
|
+
name: "get_collections",
|
|
8
|
+
description: "Liste toutes les collections accessibles avec la clé API configurée",
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: "object",
|
|
11
|
+
properties: {},
|
|
12
|
+
required: [],
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: "get_collection",
|
|
17
|
+
description: "Récupère le schéma complet d'une collection (champs, types, relations)",
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
collection: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "Nom de la collection",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
required: ["collection"],
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "get_collection_items",
|
|
31
|
+
description: "Liste les items d'une collection avec pagination, tri, filtres et populate",
|
|
32
|
+
inputSchema: {
|
|
33
|
+
type: "object",
|
|
34
|
+
properties: {
|
|
35
|
+
collection: {
|
|
36
|
+
type: "string",
|
|
37
|
+
description: "Nom de la collection",
|
|
38
|
+
},
|
|
39
|
+
page: {
|
|
40
|
+
type: "number",
|
|
41
|
+
description: "Numéro de page (défaut: 1)",
|
|
42
|
+
},
|
|
43
|
+
perPage: {
|
|
44
|
+
type: "number",
|
|
45
|
+
description: "Items par page (défaut: 20, max: 100)",
|
|
46
|
+
},
|
|
47
|
+
sort: {
|
|
48
|
+
type: "string",
|
|
49
|
+
description: "Champ de tri. Préfixe - pour descendant (ex: -created_at)",
|
|
50
|
+
},
|
|
51
|
+
populate: {
|
|
52
|
+
type: "string",
|
|
53
|
+
description: "Relations à inclure, séparées par des virgules (ex: author,category)",
|
|
54
|
+
},
|
|
55
|
+
filters: {
|
|
56
|
+
type: "object",
|
|
57
|
+
description: "Filtres JSON (ex: { status: 'active' })",
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
required: ["collection"],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: "get_collection_item",
|
|
65
|
+
description: "Récupère un item spécifique par son ID avec ses relations (populate)",
|
|
66
|
+
inputSchema: {
|
|
67
|
+
type: "object",
|
|
68
|
+
properties: {
|
|
69
|
+
collection: {
|
|
70
|
+
type: "string",
|
|
71
|
+
description: "Nom de la collection",
|
|
72
|
+
},
|
|
73
|
+
id: {
|
|
74
|
+
type: "string",
|
|
75
|
+
description: "ID de l'item (UUID)",
|
|
76
|
+
},
|
|
77
|
+
populate: {
|
|
78
|
+
type: "string",
|
|
79
|
+
description: "Relations à inclure, séparées par des virgules",
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
required: ["collection", "id"],
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: "create_collection_item",
|
|
87
|
+
description: "Crée un nouvel item dans une collection",
|
|
88
|
+
inputSchema: {
|
|
89
|
+
type: "object",
|
|
90
|
+
properties: {
|
|
91
|
+
collection: {
|
|
92
|
+
type: "string",
|
|
93
|
+
description: "Nom de la collection",
|
|
94
|
+
},
|
|
95
|
+
data: {
|
|
96
|
+
type: "object",
|
|
97
|
+
description: "Données de l'item à créer",
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
required: ["collection", "data"],
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: "update_collection_item",
|
|
105
|
+
description: "Met à jour un item existant (merge partiel)",
|
|
106
|
+
inputSchema: {
|
|
107
|
+
type: "object",
|
|
108
|
+
properties: {
|
|
109
|
+
collection: {
|
|
110
|
+
type: "string",
|
|
111
|
+
description: "Nom de la collection",
|
|
112
|
+
},
|
|
113
|
+
id: {
|
|
114
|
+
type: "string",
|
|
115
|
+
description: "ID de l'item à modifier",
|
|
116
|
+
},
|
|
117
|
+
data: {
|
|
118
|
+
type: "object",
|
|
119
|
+
description: "Données à mettre à jour",
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
required: ["collection", "id", "data"],
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "delete_collection_item",
|
|
127
|
+
description: "Supprime un item d'une collection",
|
|
128
|
+
inputSchema: {
|
|
129
|
+
type: "object",
|
|
130
|
+
properties: {
|
|
131
|
+
collection: {
|
|
132
|
+
type: "string",
|
|
133
|
+
description: "Nom de la collection",
|
|
134
|
+
},
|
|
135
|
+
id: {
|
|
136
|
+
type: "string",
|
|
137
|
+
description: "ID de l'item à supprimer",
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
required: ["collection", "id"],
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: "search_collection_items",
|
|
145
|
+
description: "Recherche textuelle dans une collection",
|
|
146
|
+
inputSchema: {
|
|
147
|
+
type: "object",
|
|
148
|
+
properties: {
|
|
149
|
+
collection: {
|
|
150
|
+
type: "string",
|
|
151
|
+
description: "Nom de la collection",
|
|
152
|
+
},
|
|
153
|
+
query: {
|
|
154
|
+
type: "string",
|
|
155
|
+
description: "Terme de recherche",
|
|
156
|
+
},
|
|
157
|
+
fields: {
|
|
158
|
+
type: "string",
|
|
159
|
+
description: "Champs où chercher, séparés par des virgules (ex: title,description)",
|
|
160
|
+
},
|
|
161
|
+
page: {
|
|
162
|
+
type: "number",
|
|
163
|
+
description: "Numéro de page",
|
|
164
|
+
},
|
|
165
|
+
perPage: {
|
|
166
|
+
type: "number",
|
|
167
|
+
description: "Items par page",
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
required: ["collection", "query"],
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: "count_collection_items",
|
|
175
|
+
description: "Compte le nombre d'items dans une collection avec filtres optionnels",
|
|
176
|
+
inputSchema: {
|
|
177
|
+
type: "object",
|
|
178
|
+
properties: {
|
|
179
|
+
collection: {
|
|
180
|
+
type: "string",
|
|
181
|
+
description: "Nom de la collection",
|
|
182
|
+
},
|
|
183
|
+
filters: {
|
|
184
|
+
type: "object",
|
|
185
|
+
description: "Filtres JSON optionnels",
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
required: ["collection"],
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: "batch_create_items",
|
|
193
|
+
description: "Crée plusieurs items en une seule requête",
|
|
194
|
+
inputSchema: {
|
|
195
|
+
type: "object",
|
|
196
|
+
properties: {
|
|
197
|
+
collection: {
|
|
198
|
+
type: "string",
|
|
199
|
+
description: "Nom de la collection",
|
|
200
|
+
},
|
|
201
|
+
items: {
|
|
202
|
+
type: "array",
|
|
203
|
+
items: { type: "object" },
|
|
204
|
+
description: "Tableau d'items à créer",
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
required: ["collection", "items"],
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: "batch_update_items",
|
|
212
|
+
description: "Met à jour plusieurs items en une seule requête",
|
|
213
|
+
inputSchema: {
|
|
214
|
+
type: "object",
|
|
215
|
+
properties: {
|
|
216
|
+
collection: {
|
|
217
|
+
type: "string",
|
|
218
|
+
description: "Nom de la collection",
|
|
219
|
+
},
|
|
220
|
+
items: {
|
|
221
|
+
type: "array",
|
|
222
|
+
items: {
|
|
223
|
+
type: "object",
|
|
224
|
+
properties: {
|
|
225
|
+
id: { type: "string" },
|
|
226
|
+
},
|
|
227
|
+
required: ["id"],
|
|
228
|
+
},
|
|
229
|
+
description: "Tableau d'items avec leur ID et les données à modifier",
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
required: ["collection", "items"],
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
];
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@skemacms/mcp-server",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Serveur MCP officiel pour Skema CMS - Connectez Claude Desktop a vos donnees",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"skema-mcp": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/index.js",
|
|
13
|
+
"dev": "tsx src/index.ts",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"keywords": ["mcp", "skema", "cms", "headless", "claude", "ai", "model-context-protocol"],
|
|
17
|
+
"author": "Skema <contact@skemacms.com>",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/skemacms/mcp-server.git"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://docs.skemacms.com/guide/mcp",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/skemacms/mcp-server/issues"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18.0.0"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"README.md"
|
|
33
|
+
],
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^25.0.9",
|
|
39
|
+
"tsx": "^4.7.0",
|
|
40
|
+
"typescript": "^5.3.0"
|
|
41
|
+
}
|
|
42
|
+
}
|