@daylight-labs/sharedb-mcp 0.1.3 → 0.1.5

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.
Files changed (2) hide show
  1. package/dist/tools/auth.js +80 -0
  2. package/package.json +1 -1
@@ -4,6 +4,22 @@ async function getPostgRESTUrl(databaseId) {
4
4
  const info = await api.databases.postgrest(databaseId);
5
5
  return info.postgrestUrl;
6
6
  }
7
+ async function getEmailIntegrationInfo(appId) {
8
+ try {
9
+ const response = await fetch(`${config.adminApiUrl}/admin/apps/${appId}/integrations/email`, {
10
+ headers: {
11
+ 'Content-Type': 'application/json',
12
+ Authorization: `Bearer ${config.token}`,
13
+ },
14
+ });
15
+ if (!response.ok)
16
+ return null;
17
+ return response.json();
18
+ }
19
+ catch {
20
+ return null;
21
+ }
22
+ }
7
23
  export const authTools = [
8
24
  {
9
25
  name: 'get_api_endpoints',
@@ -37,6 +53,8 @@ export async function handleAuthTool(name, args) {
37
53
  let tableEndpoints = {};
38
54
  let tableList = [];
39
55
  let postgrestUrl = '<PostgREST URL - specify database_id to get actual URL>';
56
+ let appId;
57
+ let appName;
40
58
  if (databaseId) {
41
59
  try {
42
60
  const [schema, url] = await Promise.all([
@@ -54,11 +72,69 @@ export async function handleAuthTool(name, args) {
54
72
  delete: `DELETE ${postgrestUrl}/${tableName}?id=eq.<uuid>`,
55
73
  };
56
74
  }
75
+ const dbInfo = await api.databases.get(databaseId);
76
+ if (dbInfo.database) {
77
+ const dbName = dbInfo.database.name;
78
+ const match = dbName.match(/^sharedb_(.+?)_(staging|production)$/);
79
+ if (match) {
80
+ appName = match[1];
81
+ try {
82
+ const { app } = await api.apps.get(appName);
83
+ appId = app.id;
84
+ }
85
+ catch {
86
+ // App lookup failed, continue without email info
87
+ }
88
+ }
89
+ }
57
90
  }
58
91
  catch {
59
92
  // Database might not have tables yet
60
93
  }
61
94
  }
95
+ let emailSection;
96
+ if (appId && appName) {
97
+ const emailInfo = await getEmailIntegrationInfo(appId);
98
+ if (emailInfo) {
99
+ const enabled = emailInfo.integration?.enabled ?? false;
100
+ emailSection = {
101
+ description: 'Send transactional emails via AWS SES',
102
+ status: enabled ? 'enabled' : 'disabled',
103
+ endpoint: `POST ${config.adminApiUrl}/admin/apps/${appId}/integrations/email/send`,
104
+ authentication: 'Include admin API token: Authorization: Bearer <token>',
105
+ fromAddress: emailInfo.fromAddress,
106
+ rateLimit: `1 email per ${emailInfo.rateLimitSeconds} seconds per app`,
107
+ requestBody: {
108
+ to: 'string (required) - recipient email address',
109
+ subject: 'string (required) - email subject line',
110
+ body: 'string (required) - plain text email body',
111
+ html: 'string (optional) - HTML email body',
112
+ },
113
+ example: `fetch('${config.adminApiUrl}/admin/apps/${appId}/integrations/email/send', {
114
+ method: 'POST',
115
+ headers: {
116
+ 'Content-Type': 'application/json',
117
+ 'Authorization': 'Bearer <your-api-token>'
118
+ },
119
+ body: JSON.stringify({
120
+ to: 'user@example.com',
121
+ subject: 'Welcome to ${appName}!',
122
+ body: 'Thanks for signing up.',
123
+ html: '<h1>Welcome!</h1><p>Thanks for signing up.</p>'
124
+ })
125
+ })`,
126
+ importantNotes: [
127
+ enabled
128
+ ? 'Email integration is ENABLED for this app'
129
+ : 'Email integration is DISABLED - enable it in the Admin UI before sending',
130
+ 'Rate limited to 1 email per minute to prevent spam',
131
+ 'Returns HTTP 429 with retryAfter seconds if rate limit exceeded',
132
+ 'Returns HTTP 403 if email integration is not enabled',
133
+ `Emails are sent from: ${emailInfo.fromAddress}`,
134
+ ],
135
+ };
136
+ }
137
+ }
62
138
  const endpoints = {
63
139
  auth: {
64
140
  baseUrl: config.authApiUrl,
@@ -72,6 +148,7 @@ export async function handleAuthTool(name, args) {
72
148
  importantNotes: [
73
149
  'After login, store the accessToken and user object (contains user.id)',
74
150
  'Include accessToken in all API requests: Authorization: Bearer <accessToken>',
151
+ 'Persist accessToken to localStorage to keep users logged in across page refreshes',
75
152
  'Use GET /auth/me to fetch current user if needed (returns { user: { id, email, name } })',
76
153
  ],
77
154
  },
@@ -120,6 +197,9 @@ export async function handleAuthTool(name, args) {
120
197
  recommendation: 'Add to your global error handler (window.onerror, React error boundaries) during development to catch unhandled errors.',
121
198
  },
122
199
  };
200
+ if (emailSection) {
201
+ endpoints.email = emailSection;
202
+ }
123
203
  return {
124
204
  content: [
125
205
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@daylight-labs/sharedb-mcp",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "MCP server for ShareDB schema management and development",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",