@enfyra/mcp-server 0.0.78 → 0.0.80

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
@@ -219,6 +219,16 @@ When an LLM builds a Nuxt, Next, or other SSR frontend for Enfyra, follow the sa
219
219
  - Socket.IO browser clients use a same-origin bridge too. Connect to the namespace, e.g. `io("/chat", { path: "/socket.io", withCredentials: true })`, and proxy `/socket.io/**` to the Enfyra app bridge `/ws/socket.io/**`. The backend gateway metadata path remains `/chat`.
220
220
  - Use token-query OAuth callback pages only for non-SSR/manual-token apps.
221
221
 
222
+ ### OAuth provider setup checklist
223
+
224
+ OAuth provider setup has three distinct URLs:
225
+
226
+ - Provider callback URL: Enfyra handles this at `{ENFYRA_API_URL}/auth/{provider}/callback`. If the app proxy base is `http://localhost:3000/api`, the Google callback URL is `http://localhost:3000/api/auth/google/callback`.
227
+ - Enfyra OAuth config: `oauth_config_definition.redirectUri` must exactly match the provider callback URL registered in Google, Facebook, or GitHub. The same row stores the provider client id/secret and enabled state.
228
+ - App return URL: the frontend sends this as the `redirect` query when starting OAuth, for example `/enfyra/auth/google?redirect=https%3A%2F%2Fapp.example.com%2Fchat&cookieBridgePrefix=/enfyra`.
229
+
230
+ Do not confuse `redirectUri` with `redirect`. `redirectUri` is the provider-to-Enfyra callback. `redirect` is where Enfyra sends the browser after cookies are set. `appCallbackUrl` is only for manual-token apps that intentionally read token query parameters instead of using proxy-owned cookies.
231
+
222
232
  ---
223
233
 
224
234
  ## Tools (summary)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enfyra/mcp-server",
3
- "version": "0.0.78",
3
+ "version": "0.0.80",
4
4
  "description": "MCP server for Enfyra - manage your Enfyra instance via Claude Code",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -153,6 +153,26 @@ onUnmounted(() => {
153
153
  'Disconnect the singleton socket when the current user/session clears.',
154
154
  ],
155
155
  },
156
+ {
157
+ name: 'OAuth provider setup values',
158
+ code: `// Enfyra OAuth config row, stored in oauth_config_definition.
159
+ {
160
+ "provider": "google",
161
+ "clientId": "<google-client-id>",
162
+ "clientSecret": "<google-client-secret>",
163
+ "redirectUri": "http://localhost:3000/api/auth/google/callback",
164
+ "isEnabled": true
165
+ }
166
+
167
+ // Google Cloud Console -> Authorized redirect URIs:
168
+ // http://localhost:3000/api/auth/google/callback`,
169
+ notes: [
170
+ 'redirectUri is the Enfyra callback URL: {ENFYRA_API_URL}/auth/google/callback.',
171
+ 'The provider console callback URL and oauth_config_definition.redirectUri must match exactly.',
172
+ 'This callback URL is not the app return page; the app return page is sent as the redirect query when starting OAuth.',
173
+ 'Use appCallbackUrl only for manual-token apps that intentionally read token query parameters.',
174
+ ],
175
+ },
156
176
  {
157
177
  name: 'Google OAuth button',
158
178
  code: `const redirect = new URL("/chat", window.location.origin)
@@ -164,6 +184,7 @@ window.location.href = url.toString()`,
164
184
  'redirect must be absolute and must include the app origin.',
165
185
  'cookieBridgePrefix is the app proxy prefix that forwards to Enfyra API routes.',
166
186
  'Enfyra redirects through {redirect.origin}{cookieBridgePrefix}/auth/set-cookies before returning to redirect.',
187
+ 'After returning, call /enfyra/me to load the authenticated user; do not parse tokens from the URL in proxy-cookie mode.',
167
188
  ],
168
189
  },
169
190
  ],
@@ -513,6 +513,8 @@ function scriptRecordLabel(tableName, record) {
513
513
  const method = record.method?.name || record.method?.method || null;
514
514
  const route = record.route?.path || null;
515
515
  const flow = record.flow?.name || null;
516
+ const gateway = record.gateway?.path || null;
517
+ const gqlTable = record.table?.name || null;
516
518
  return {
517
519
  tableName,
518
520
  id: getId(record),
@@ -520,9 +522,26 @@ function scriptRecordLabel(tableName, record) {
520
522
  route,
521
523
  method,
522
524
  flow,
525
+ gateway,
526
+ gqlTable,
523
527
  };
524
528
  }
525
529
 
530
+ function scriptTraceFields(tableName) {
531
+ const common = 'id,_id,name,key,eventName,sourceCode,handlerScript,connectionHandlerScript,code,scriptLanguage';
532
+ const byTable = {
533
+ route_handler_definition: `${common},route.id,route.path,method.id,method.name`,
534
+ pre_hook_definition: `${common},route.id,route.path,methods.id,methods.name,isGlobal`,
535
+ post_hook_definition: `${common},route.id,route.path,methods.id,methods.name,isGlobal`,
536
+ flow_step_definition: `${common},flow.id,flow.name`,
537
+ websocket_event_definition: `${common},gateway.id,gateway.path`,
538
+ websocket_definition: `${common},path`,
539
+ gql_definition: `${common},table.id,table.name`,
540
+ bootstrap_script_definition: common,
541
+ };
542
+ return byTable[tableName] || '*';
543
+ }
544
+
526
545
  async function findMethodRecordByName(method) {
527
546
  const filter = encodeURIComponent(JSON.stringify({ name: { _eq: method } }));
528
547
  const result = await fetchAPI(ENFYRA_API_URL, `/method_definition?filter=${filter}&limit=1&fields=id,_id,name,buttonColor,textColor,isSystem`);
@@ -1874,7 +1893,11 @@ server.tool(
1874
1893
  const sourceContains = (record) => getRecordSource(record).sourceCode.toLowerCase().includes(lower);
1875
1894
 
1876
1895
  const scriptTableResults = await Promise.all(SCRIPT_BACKED_TABLES.map(async (tableName) => {
1877
- const result = await fetchAPI(ENFYRA_API_URL, `/${tableName}?limit=1000&fields=*`).catch((error) => ({ error }));
1896
+ const fields = scriptTraceFields(tableName);
1897
+ let result = await fetchAPI(ENFYRA_API_URL, `/${tableName}?limit=1000&fields=${encodeURIComponent(fields)}`).catch((error) => ({ error }));
1898
+ if (result?.error && fields !== '*') {
1899
+ result = await fetchAPI(ENFYRA_API_URL, `/${tableName}?limit=1000&fields=*`).catch((error) => ({ error }));
1900
+ }
1878
1901
  return { tableName, records: unwrapData(result), error: result?.error?.message || null };
1879
1902
  }));
1880
1903
  const scriptMatches = [];