strapi-oauth-mcp-manager 0.1.0 → 0.1.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 CHANGED
@@ -31,11 +31,144 @@ export default () => ({
31
31
  'yt-transcript-strapi-plugin': {
32
32
  enabled: true,
33
33
  },
34
+ 'strapi-content-mcp': {
35
+ enabled: true,
36
+ },
34
37
  });
35
38
  ```
36
39
 
40
+ ---
41
+
42
+ ## Quick Start: ChatGPT Setup
43
+
44
+ ### Step 1: Create a Strapi API Token
45
+
46
+ 1. Go to **Strapi Admin** → **Settings** → **API Tokens**
47
+ 2. Click **Create new API Token**
48
+ 3. Configure:
49
+ - **Name**: `ChatGPT MCP Access`
50
+ - **Token type**: `Full access` (or custom with specific permissions)
51
+ - **Token duration**: `Unlimited` (recommended) or set expiry
52
+ 4. Click **Save** and **copy the token** (you won't see it again)
53
+
54
+ ### Step 2: Create an OAuth Client in Strapi
55
+
56
+ 1. Go to **Strapi Admin** → **Content Manager** → **MCP OAuth Client**
57
+ 2. Click **Create new entry**
58
+ 3. Fill in the fields:
59
+
60
+ | Field | Value |
61
+ |-------|-------|
62
+ | **name** | `ChatGPT` |
63
+ | **clientId** | `chatgpt` |
64
+ | **clientSecret** | Choose a secure secret (e.g., `my-super-secret-key-123`) |
65
+ | **redirectUris** | `https://chatgpt.com/connector_platform_oauth_redirect` |
66
+ | **strapiApiToken** | Paste the API token from Step 1 |
67
+ | **active** | `true` |
68
+
69
+ 4. Click **Save**
70
+
71
+ ### Step 3: Configure ChatGPT
72
+
73
+ 1. Go to [ChatGPT](https://chatgpt.com)
74
+ 2. Click your profile → **Settings** → **Connected Apps** → **Add App**
75
+ 3. Fill in the form:
76
+
77
+ | Field | Value |
78
+ |-------|-------|
79
+ | **Name** | `Your App Name` (e.g., "YT Transcripts") |
80
+ | **Description** | What the app does |
81
+ | **MCP Server URL** | `https://your-strapi-domain.com/api/yt-transcript-strapi-plugin/mcp` |
82
+ | **Authentication** | `OAuth` |
83
+ | **Client ID** | `chatgpt` (from Step 2) |
84
+ | **Client Secret** | Your secret from Step 2 |
85
+
86
+ 4. Click **Save**
87
+
88
+ ### Step 4: Authorize
89
+
90
+ When you first use the MCP tools in ChatGPT, it will redirect you to Strapi to authorize. Click **Authorize** to complete the OAuth flow.
91
+
92
+ ---
93
+
94
+ ## Quick Start: Claude Desktop Setup
95
+
96
+ Claude Desktop uses direct Strapi API tokens (no OAuth flow needed).
97
+
98
+ ### Step 1: Create a Strapi API Token
99
+
100
+ Same as ChatGPT Step 1 above.
101
+
102
+ ### Step 2: Configure Claude Desktop
103
+
104
+ Edit your Claude Desktop config file:
105
+
106
+ **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
107
+ **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
108
+
109
+ ```json
110
+ {
111
+ "mcpServers": {
112
+ "yt-transcript": {
113
+ "command": "npx",
114
+ "args": [
115
+ "mcp-remote",
116
+ "https://your-strapi-domain.com/api/yt-transcript-strapi-plugin/mcp",
117
+ "--header",
118
+ "Authorization: Bearer YOUR_STRAPI_API_TOKEN"
119
+ ]
120
+ },
121
+ "strapi-content": {
122
+ "command": "npx",
123
+ "args": [
124
+ "mcp-remote",
125
+ "https://your-strapi-domain.com/api/strapi-content-mcp/mcp",
126
+ "--header",
127
+ "Authorization: Bearer YOUR_STRAPI_API_TOKEN"
128
+ ]
129
+ }
130
+ }
131
+ }
132
+ ```
133
+
134
+ Replace:
135
+ - `your-strapi-domain.com` with your actual Strapi URL
136
+ - `YOUR_STRAPI_API_TOKEN` with the token from Step 1
137
+
138
+ ### Step 3: Restart Claude Desktop
139
+
140
+ Quit and reopen Claude Desktop to load the new configuration.
141
+
142
+ ---
143
+
37
144
  ## How It Works
38
145
 
146
+ ### Architecture
147
+
148
+ ```
149
+ ┌─────────────────────────────────────────────────────────────┐
150
+ │ Strapi Application │
151
+ │ │
152
+ │ ┌─────────────────────────────────────────────────────┐ │
153
+ │ │ strapi-oauth-mcp-manager │ │
154
+ │ │ ┌───────────────┐ ┌───────────────────────────┐ │ │
155
+ │ │ │ OAuth │ │ Global Auth Middleware │ │ │
156
+ │ │ │ Endpoints │ │ (protects all registered │ │ │
157
+ │ │ │ /authorize │ │ MCP endpoints) │ │ │
158
+ │ │ │ /token │ └───────────────────────────┘ │ │
159
+ │ │ └───────────────┘ │ │
160
+ │ └─────────────────────────────────────────────────────┘ │
161
+ │ │ │
162
+ │ ┌──────────────────┼──────────────────┐ │
163
+ │ ▼ ▼ ▼ │
164
+ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
165
+ │ │ MCP Plugin │ │ MCP Plugin │ │ MCP Plugin │ │
166
+ │ │ A │ │ B │ │ C │ │
167
+ │ │ (registers) │ │ (registers) │ │ (registers) │ │
168
+ │ └─────────────┘ └─────────────┘ └─────────────┘ │
169
+ └─────────────────────────────────────────────────────────────┘
170
+ ```
171
+
39
172
  ### For MCP Plugin Developers
40
173
 
41
174
  MCP plugins register with the OAuth manager to gain authentication support:
@@ -54,17 +187,40 @@ if (oauthPlugin) {
54
187
  }
55
188
  ```
56
189
 
57
- ### For Users
190
+ ### Authentication Flow
58
191
 
59
- 1. **Create an OAuth Client** in Strapi Admin:
60
- - Go to Content Manager > MCP OAuth Client
61
- - Add client name, ID, secret, and redirect URIs
62
- - Link to a Strapi API token
192
+ ```
193
+ ChatGPT/OAuth Client Strapi
194
+ │ │
195
+ 1. Request MCP endpoint │
196
+ │ ─────────────────────────────────>│
197
+ │ │
198
+ │ 2. 401 + WWW-Authenticate header │
199
+ │ <─────────────────────────────────│
200
+ │ │
201
+ │ 3. Discover OAuth via .well-known │
202
+ │ ─────────────────────────────────>│
203
+ │ │
204
+ │ 4. Redirect to /authorize │
205
+ │ ─────────────────────────────────>│
206
+ │ │
207
+ │ 5. User authorizes, get code │
208
+ │ <─────────────────────────────────│
209
+ │ │
210
+ │ 6. Exchange code for token │
211
+ │ ─────────────────────────────────>│
212
+ │ │
213
+ │ 7. Access token returned │
214
+ │ <─────────────────────────────────│
215
+ │ │
216
+ │ 8. MCP requests with Bearer token │
217
+ │ ─────────────────────────────────>│
218
+ │ │
219
+ │ 9. MCP response │
220
+ │ <─────────────────────────────────│
221
+ ```
63
222
 
64
- 2. **Configure ChatGPT**:
65
- - MCP Server URL: `https://your-domain/api/your-mcp-plugin/mcp`
66
- - OAuth Client ID: From Strapi admin
67
- - OAuth Client Secret: From Strapi admin
223
+ ---
68
224
 
69
225
  ## OAuth Endpoints
70
226
 
@@ -75,6 +231,8 @@ if (oauthPlugin) {
75
231
  | Discovery (RFC 8414) | `/api/strapi-oauth-mcp-manager/.well-known/oauth-authorization-server` |
76
232
  | Protected Resource (RFC 9728) | `/api/strapi-oauth-mcp-manager/.well-known/oauth-protected-resource` |
77
233
 
234
+ ---
235
+
78
236
  ## Content Types
79
237
 
80
238
  The plugin creates these content types:
@@ -86,52 +244,70 @@ The plugin creates these content types:
86
244
  | `mcp-oauth-token` | Access and refresh tokens |
87
245
  | `mcp-endpoint` | Registered MCP endpoints |
88
246
 
89
- ## Creating an OAuth Client for ChatGPT
247
+ ---
90
248
 
91
- In Strapi Admin > Content Manager > MCP OAuth Client:
249
+ ## OAuth Client Configuration
92
250
 
93
- ```json
94
- {
95
- "name": "ChatGPT",
96
- "clientId": "chatgpt",
97
- "clientSecret": "your-secure-secret",
98
- "redirectUris": ["https://chatgpt.com/connector_platform_oauth_redirect"],
99
- "strapiApiToken": "your-strapi-api-token",
100
- "active": true
101
- }
102
- ```
251
+ ### Required Fields
252
+
253
+ | Field | Type | Description |
254
+ |-------|------|-------------|
255
+ | `name` | string | Display name for the client |
256
+ | `clientId` | string | Unique identifier (e.g., `chatgpt`) |
257
+ | `clientSecret` | string | Secret for token exchange |
258
+ | `redirectUris` | string[] | Allowed redirect URIs after authorization |
259
+ | `strapiApiToken` | string | Strapi API token to use for authenticated requests |
260
+ | `active` | boolean | Whether the client is active |
261
+
262
+ ### Redirect URIs
263
+
264
+ Common redirect URIs:
265
+
266
+ | Client | Redirect URI |
267
+ |--------|--------------|
268
+ | ChatGPT | `https://chatgpt.com/connector_platform_oauth_redirect` |
269
+ | Custom OAuth | Your app's callback URL |
270
+
271
+ Wildcard patterns are supported (e.g., `https://*.example.com/callback`).
272
+
273
+ ---
274
+
275
+ ## Troubleshooting
103
276
 
104
- ## Authentication Flow
277
+ ### "Invalid redirect_uri" Error
105
278
 
279
+ Make sure the redirect URI in your OAuth client exactly matches what the client sends. For ChatGPT, use:
106
280
  ```
107
- 1. Client hits MCP endpoint without auth
108
- 2. Returns 401 with WWW-Authenticate header
109
- 3. Client discovers OAuth endpoints via .well-known
110
- 4. Client completes OAuth authorization code flow
111
- 5. Client receives access token
112
- 6. Client makes MCP requests with Bearer token
113
- 7. OAuth manager validates and forwards to MCP plugin
281
+ https://chatgpt.com/connector_platform_oauth_redirect
114
282
  ```
115
283
 
116
- ## Claude Desktop (API Token)
284
+ ### "Session expired" Error
117
285
 
118
- For Claude Desktop, use direct Strapi API tokens:
286
+ Sessions expire after 4 hours. The client should automatically reinitialize the connection.
119
287
 
120
- ```json
121
- {
122
- "mcpServers": {
123
- "your-mcp": {
124
- "command": "npx",
125
- "args": [
126
- "mcp-remote",
127
- "https://your-domain/api/your-mcp-plugin/mcp",
128
- "--header",
129
- "Authorization: Bearer YOUR_STRAPI_API_TOKEN"
130
- ]
131
- }
132
- }
133
- }
134
- ```
288
+ ### Claude Desktop Not Connecting
289
+
290
+ 1. Check that `mcp-remote` is installed: `npx mcp-remote --version`
291
+ 2. Verify your API token is valid in Strapi Admin
292
+ 3. Check the Strapi logs for authentication errors
293
+ 4. Ensure your Strapi instance is accessible from your machine
294
+
295
+ ### OAuth Flow Not Starting
296
+
297
+ 1. Verify the OAuth client is set to `active: true`
298
+ 2. Check that the `strapiApiToken` in the OAuth client is valid
299
+ 3. Look at Strapi logs for detailed error messages
300
+
301
+ ---
302
+
303
+ ## Compatible MCP Plugins
304
+
305
+ These plugins support `strapi-oauth-mcp-manager`:
306
+
307
+ - [yt-transcript-strapi-plugin](https://www.npmjs.com/package/yt-transcript-strapi-plugin) - YouTube transcript tools
308
+ - [strapi-content-mcp](https://www.npmjs.com/package/strapi-content-mcp) - Strapi content management tools
309
+
310
+ ---
135
311
 
136
312
  ## Requirements
137
313
 
@@ -417,7 +417,18 @@ const oauthController = ({ strapi }) => ({
417
417
  ctx.body = { error: "invalid_client", error_description: "Unknown client_id" };
418
418
  return;
419
419
  }
420
- const allowedRedirects = client.redirectUris;
420
+ let allowedRedirects = [];
421
+ if (Array.isArray(client.redirectUris)) {
422
+ allowedRedirects = client.redirectUris;
423
+ } else if (typeof client.redirectUris === "string") {
424
+ try {
425
+ allowedRedirects = JSON.parse(client.redirectUris);
426
+ } catch {
427
+ allowedRedirects = [client.redirectUris];
428
+ }
429
+ }
430
+ strapi.log.debug(`[${PLUGIN_ID}] Checking redirect_uri: ${redirect_uri}`);
431
+ strapi.log.debug(`[${PLUGIN_ID}] Allowed redirects (${typeof client.redirectUris}): ${JSON.stringify(allowedRedirects)}`);
421
432
  if (!matchRedirectUri(redirect_uri, allowedRedirects)) {
422
433
  strapi.log.warn(`[${PLUGIN_ID}] Invalid redirect_uri: ${redirect_uri}`);
423
434
  strapi.log.warn(`[${PLUGIN_ID}] Allowed patterns: ${allowedRedirects.join(", ")}`);
@@ -416,7 +416,18 @@ const oauthController = ({ strapi }) => ({
416
416
  ctx.body = { error: "invalid_client", error_description: "Unknown client_id" };
417
417
  return;
418
418
  }
419
- const allowedRedirects = client.redirectUris;
419
+ let allowedRedirects = [];
420
+ if (Array.isArray(client.redirectUris)) {
421
+ allowedRedirects = client.redirectUris;
422
+ } else if (typeof client.redirectUris === "string") {
423
+ try {
424
+ allowedRedirects = JSON.parse(client.redirectUris);
425
+ } catch {
426
+ allowedRedirects = [client.redirectUris];
427
+ }
428
+ }
429
+ strapi.log.debug(`[${PLUGIN_ID}] Checking redirect_uri: ${redirect_uri}`);
430
+ strapi.log.debug(`[${PLUGIN_ID}] Allowed redirects (${typeof client.redirectUris}): ${JSON.stringify(allowedRedirects)}`);
420
431
  if (!matchRedirectUri(redirect_uri, allowedRedirects)) {
421
432
  strapi.log.warn(`[${PLUGIN_ID}] Invalid redirect_uri: ${redirect_uri}`);
422
433
  strapi.log.warn(`[${PLUGIN_ID}] Allowed patterns: ${allowedRedirects.join(", ")}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-oauth-mcp-manager",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Centralized OAuth 2.0 authentication manager for Strapi MCP plugins. Supports ChatGPT, Claude, and custom OAuth clients.",
5
5
  "keywords": [
6
6
  "strapi",