@mongoosejs/studio 0.6.1 → 0.7.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/CHANGELOG.md +58 -0
- package/README.md +85 -4
- package/backend/next.js +24 -0
- package/backend/vercel/checkBindIp.js +25 -0
- package/backend/vercel/index.js +3 -0
- package/backend/vercel/mcpConfig.js +28 -0
- package/backend/vercel/vercelMCP.js +152 -0
- package/backend/vercel/vercelMCPRouteHandler.js +19 -0
- package/docs/mcp-oauth.md +1 -1
- package/express.js +1 -1
- package/frontend/index.js +24 -2
- package/frontend/public/app.js +263 -111
- package/frontend/src/mcp/mcp.js +5 -2
- package/next.js +35 -8
- package/package.json +1 -1
- package/vercel.d.ts +14 -1
- package/vercel.js +1 -0
- package/backend/vercel.js +0 -3
package/frontend/src/mcp/mcp.js
CHANGED
|
@@ -8,13 +8,16 @@ module.exports = {
|
|
|
8
8
|
mcpUrl() {
|
|
9
9
|
const configuredUrl = window.MONGOOSE_STUDIO_CONFIG.mcpUrl;
|
|
10
10
|
if (configuredUrl) {
|
|
11
|
-
|
|
11
|
+
if (/^https?:\/\//i.test(configuredUrl)) {
|
|
12
|
+
return configuredUrl;
|
|
13
|
+
}
|
|
14
|
+
return new URL(configuredUrl, window.location.href).toString();
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
const url = new URL(window.location.href);
|
|
15
18
|
url.hash = '';
|
|
16
19
|
url.search = '';
|
|
17
|
-
url.pathname = `${url.pathname.replace(/\/+$/, '')}/mcp`;
|
|
20
|
+
url.pathname = `${url.pathname.replace(/\/index\.html$/, '').replace(/\/+$/, '')}/mcp`;
|
|
18
21
|
return url.toString();
|
|
19
22
|
}
|
|
20
23
|
},
|
package/next.js
CHANGED
|
@@ -11,14 +11,24 @@ module.exports = withMongooseStudio;
|
|
|
11
11
|
*
|
|
12
12
|
* @param {object} nextConfig - Existing Next.js config
|
|
13
13
|
* @param {object} [options]
|
|
14
|
-
* @param {string} [options.
|
|
14
|
+
* @param {string} [options.apiKey] - Mongoose Studio Pro API key, only used to pick the `mcp` default
|
|
15
|
+
* @param {boolean} [options.mcp] - Whether to show MCP in the frontend. Defaults to true without an API key, false with one.
|
|
16
|
+
* @param {string} [options.publicUrl] - Externally reachable Studio URL
|
|
15
17
|
*/
|
|
16
|
-
function withMongooseStudio(nextConfig = {}) {
|
|
18
|
+
function withMongooseStudio(nextConfig = {}, options = {}) {
|
|
17
19
|
const studioPath = normalizeBasePath(nextConfig.studioPath || '/studio');
|
|
18
20
|
|
|
19
21
|
try {
|
|
22
|
+
// With only frontend options, frontend() writes config.js before its first
|
|
23
|
+
// await. Copy that config together with the other static assets. Don't
|
|
24
|
+
// pass apiKey through, because that makes frontend() fetch the workspace first.
|
|
25
|
+
const frontendPromise = frontend('/api/studio', true, {
|
|
26
|
+
mcp: options.mcp ?? !options.apiKey,
|
|
27
|
+
publicUrl: options.publicUrl,
|
|
28
|
+
_mcpPath: 'mcp'
|
|
29
|
+
});
|
|
20
30
|
copyStudioFrontend(studioPath);
|
|
21
|
-
|
|
31
|
+
frontendPromise
|
|
22
32
|
.then(() => console.log(`✅ Mongoose Studio: copied frontend+config to public${studioPath}`))
|
|
23
33
|
.catch(err => console.error(`❌ Mongoose Studio: failed to copy frontend`, err));
|
|
24
34
|
} catch (err) {
|
|
@@ -28,6 +38,27 @@ function withMongooseStudio(nextConfig = {}) {
|
|
|
28
38
|
return {
|
|
29
39
|
...nextConfig,
|
|
30
40
|
|
|
41
|
+
async rewrites() {
|
|
42
|
+
const userRewrites = typeof nextConfig.rewrites === 'function'
|
|
43
|
+
? await nextConfig.rewrites()
|
|
44
|
+
: nextConfig.rewrites || [];
|
|
45
|
+
const studioRewrites = [
|
|
46
|
+
{ source: `${studioPath}/mcp`, destination: '/api/studio/mcp' },
|
|
47
|
+
{
|
|
48
|
+
source: `${studioPath}/\\.well-known/oauth-protected-resource`,
|
|
49
|
+
destination: '/api/studio/.well-known/oauth-protected-resource'
|
|
50
|
+
}
|
|
51
|
+
];
|
|
52
|
+
if (Array.isArray(userRewrites)) {
|
|
53
|
+
return { beforeFiles: studioRewrites, afterFiles: userRewrites, fallback: [] };
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
beforeFiles: [...studioRewrites, ...(userRewrites.beforeFiles || [])],
|
|
57
|
+
afterFiles: userRewrites.afterFiles || [],
|
|
58
|
+
fallback: userRewrites.fallback || []
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
|
|
31
62
|
async redirects() {
|
|
32
63
|
const userRedirects =
|
|
33
64
|
typeof nextConfig.redirects === 'function'
|
|
@@ -54,11 +85,7 @@ function normalizeBasePath(p) {
|
|
|
54
85
|
|
|
55
86
|
/** Copies all built frontend assets into /public/{studioPath} */
|
|
56
87
|
function copyStudioFrontend(studioPath) {
|
|
57
|
-
const src = path.join(
|
|
58
|
-
path.dirname(require.resolve('@mongoosejs/studio/package.json')),
|
|
59
|
-
'frontend',
|
|
60
|
-
'public'
|
|
61
|
-
);
|
|
88
|
+
const src = path.join(__dirname, 'frontend', 'public');
|
|
62
89
|
const dest = path.join(process.cwd(), 'public', studioPath.replace(/^\//, ''));
|
|
63
90
|
|
|
64
91
|
if (!fs.existsSync(src)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mongoosejs/studio",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "AI-Powered Data Workspace for MongoDB: Turn your MongoDB data into dashboards, maps, and interactive workflows - powered by your Mongoose models and AI.",
|
|
5
5
|
"homepage": "https://mongoosestudio.app/",
|
|
6
6
|
"repository": {
|
package/vercel.d.ts
CHANGED
|
@@ -4,6 +4,12 @@ declare module '@mongoosejs/studio/vercel' {
|
|
|
4
4
|
export interface VercelAPIRouteHandlerOptions {
|
|
5
5
|
/** Mongoose Studio Pro API key. When set, requests must be authorized. */
|
|
6
6
|
apiKey?: string;
|
|
7
|
+
/** Enable /studio/mcp; defaults to true without an API key, false with one. */
|
|
8
|
+
mcp?: boolean;
|
|
9
|
+
/** Public /studio URL. Required when MCP is enabled with an API key. */
|
|
10
|
+
publicUrl?: string;
|
|
11
|
+
/** Without an API key, restrict access to these exact client IPs. Defaults to localhost; null allows any IP. */
|
|
12
|
+
bindIp?: string | string[] | null;
|
|
7
13
|
/** Separate connection for Studio's own collections (dashboards, chat threads). */
|
|
8
14
|
studioConnection?: Connection;
|
|
9
15
|
/** Watch the connection for changes and stream them to the Studio frontend. */
|
|
@@ -40,11 +46,18 @@ declare module '@mongoosejs/studio/vercel' {
|
|
|
40
46
|
|
|
41
47
|
/**
|
|
42
48
|
* Creates a Mongoose Studio API handler for Next.js Pages Router API routes
|
|
43
|
-
* (`pages/api/studio.js`)
|
|
49
|
+
* (`pages/api/studio/[[...studioRoute]].js`) or standalone Vercel Studio
|
|
50
|
+
* actions (`api/studio.js`).
|
|
44
51
|
* Pass `null` to use the default Mongoose global.
|
|
45
52
|
*/
|
|
46
53
|
export function vercelAPIRouteHandler(
|
|
47
54
|
conn?: Connection | Mongoose | null,
|
|
48
55
|
options?: VercelAPIRouteHandlerOptions
|
|
49
56
|
): (req: VercelAPIRouteHandlerRequest, res: VercelAPIRouteHandlerResponse) => Promise<any>;
|
|
57
|
+
|
|
58
|
+
/** Creates a standalone /api/studio-mcp Vercel Function handler. */
|
|
59
|
+
export function vercelMCPRouteHandler(
|
|
60
|
+
conn?: Connection | Mongoose | null,
|
|
61
|
+
options?: VercelAPIRouteHandlerOptions
|
|
62
|
+
): (req: VercelAPIRouteHandlerRequest, res: VercelAPIRouteHandlerResponse) => Promise<any>;
|
|
50
63
|
}
|
package/vercel.js
CHANGED
package/backend/vercel.js
DELETED