Skip to content
mongoosejsPublic

About

A Mongoose-native MongoDB UI with schema-aware autocomplete, AI-assisted queries, and dashboards that understand your models - not just your data.

Topics

Resources

Stars

26 stars

Watchers

1 watching

Forks

Latest commit

 

History

1,422 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mongoose Studio

An AI-Powered Data Workspace for MongoDB: Turn your MongoDB data into dashboards, maps, and interactive workflows - powered by your Mongoose models.

NPM Version

Getting Started

Mongoose Studio is meant to run as a sidecar to your Node.js application, using the same Mongoose connection config. If your app runs on acme.app, Mongoose Studio will be on acme.app/studio or whichever path you prefer. For local dev, if your app runs on localhost:3000, Mongoose Studio will be on localhost:3000/studio.

By default, Mongoose Studio does not provide any authentication or authorization. You can use Mongoose Studio for free for local development, but we recommend Mongoose Studio Pro for when you want to go into production. When you omit an API key, Mongoose Studio only accepts localhost connections by default.

First, npm install @mongoosejs/studio.

Express

Mongoose Studio can be mounted as Express middleware as follows.

const mongoose = require('mongoose');
const studio = require('@mongoosejs/studio/express');

// Mount Mongoose Studio on '/studio'
// If your models are registered on a different connection, pass in the connection instead of `mongoose`
app.use('/studio', await studio('/studio/api', mongoose));

If you have a Mongoose Studio Pro API key, you can set it as follows:

const opts = process.env.MONGOOSE_STUDIO_API_KEY ? { apiKey: process.env.MONGOOSE_STUDIO_API_KEY } : {};
// Optionally specify which ChatGPT model to use for chat messages
opts.model = 'gpt-4o-mini';
// Provide your own OpenAI, Anthropic, or Google Gemini API key to run chat completions locally
opts.openAIAPIKey = process.env.OPENAI_API_KEY;
opts.anthropicAPIKey = process.env.ANTHROPIC_API_KEY;
opts.googleGeminiAPIKey = process.env.GOOGLE_GEMINI_API_KEY;
// Apply a maximum execution time to all read operations, including reads in scripts.
// MongoDB does not support maxTimeMS for inserts and index operations.
// This is also a ceiling: a request may ask for a lower limit, never a higher one.
opts.maxTimeMS = 10000;

// Mount Mongoose Studio on '/studio'
app.use('/studio', await studio('/studio/api', mongoose, opts));

Without an API key, you can allow access from additional IP addresses with bindIp, similar to MongoDB's bindIp option. bindIp may be a comma-separated string or an array of exact IP addresses. Set bindIp to null to allow unauthenticated connections from anywhere.

app.use('/studio', await studio('/studio/api', mongoose, {
  bindIp: '127.0.0.1,192.168.0.10'
}));

Without an API key, the Express integration exposes a Streamable HTTP MCP endpoint at /studio/mcp by default. Set mcp: false to turn it off. It provides authorized Dashboard and Model actions, plus Script.createScript, as MCP tools. With a Pro API key, pass the logged-in Studio access token in the Authorization header (either directly or as a bearer token); tools receive that user's roles and permissions. Without workspace authentication, the MCP endpoint uses the same localhost and bindIp restrictions as the rest of Mongoose Studio.

Connecting ChatGPT or Claude with OAuth

With a Pro API key, MCP is disabled by default. Set mcp: true to expose /studio/mcp as an OAuth 2.1 protected resource so MCP clients such as ChatGPT and Claude can connect to it directly. Point the client at your /studio/mcp URL and it will discover the Mongoose Studio authorization server, walk the user through signing in and approving access, and receive a short-lived access token. Users review and revoke these connections from their Mongoose Studio account page, and the access an AI client gets can never exceed the access the user who approved it already has.

Mongoose Studio advertises itself to MCP clients using its externally reachable URL. When enabling MCP with a Pro API key, also set publicUrl to the URL where Mongoose Studio is mounted:

opts.publicUrl = 'https://app.example.com/studio';
opts.mcp = true;

Mongoose Studio finds the authorization server through the mothership it is already configured to use, so it needs no separate authorization server configuration.

See docs/mcp-oauth.md for how the flow and the delegated access policy work.

Next.js

First, add withMongooseStudio to your next.config.js file:

import withMongooseStudio from '@mongoosejs/studio/next';

// Mount Mongoose Studio frontend on /studio
export default withMongooseStudio({
  // Your Next.js config here
  reactStrictMode: true,
}, {
  mcp: true,
  publicUrl: process.env.MONGOOSE_STUDIO_PUBLIC_URL
});

Add pages/api/studio/[[...studioRoute]].js to your Next.js project to host both the Mongoose Studio API and MCP. If you already have pages/api/studio.js, move its handler into the new file and remove the old file. The optional catch-all keeps /api/studio working for existing Studio actions and also accepts /api/studio/mcp and the OAuth metadata path.

// pages/api/studio/[[...studioRoute]].js
// Make sure to import the database connection
import db from '../../../src/db';
import { vercelAPIRouteHandler } from '@mongoosejs/studio/vercel';

const handler = vercelAPIRouteHandler(
  db, // Mongoose connection or Mongoose global. Or null to use `import mongoose`.
  {
    apiKey: process.env.MONGOOSE_STUDIO_API_KEY, // optional
    connection: db, // Optional: Connection or Mongoose global. If omitted, will use `import mongoose`
    connectToDB: async () => { /* connection logic here */ }, // Optional: if you need to call a function to connect to the database put it here
    mcp: true, // Also enabled by default without an API key
    publicUrl: process.env.MONGOOSE_STUDIO_PUBLIC_URL // Required with an API key; e.g. https://app.example.com/studio
  }
);

export default handler;

With mcp: true, the same API function handles Streamable HTTP at /studio/mcp. With an API key, it also serves OAuth discovery at /studio/.well-known/oauth-protected-resource. withMongooseStudio installs rewrites from those public URLs to the catch-all API route and shows /studio/mcp in the frontend. No additional API function or mcpUrl setting is needed. The rewrites are needed to keep the public URL at /studio/mcp; the catch-all file itself lives under /api/studio. A Pro API key is required for OAuth-based Vercel MCP. Without an API key, MCP is enabled by default and is limited to localhost unless bindIp is configured. Set bindIp to an IP address or an array of IP addresses to permit other clients; set it to null to allow access from any IP. The same restriction applies to Studio API actions. With an API key, set publicUrl to the externally reachable /studio URL. The OAuth resource URL is derived from it, even if the workspace's baseUrl differs.

The handler is stateless and returns a JSON response for each POST. No Redis, sticky sessions, or long-lived SSE connection is needed. Tool calls still count against Vercel Function duration and payload limits, so set an appropriate maxDuration for longer database operations and keep results reasonably sized.

Standalone Vercel Functions

If your project uses api/studio.js rather than Next.js, keep it for Studio actions and add a separate api/studio-mcp.js function for MCP. Next.js optional catch-all filenames such as [[...studioRoute]].js do not apply to standalone Vercel Functions:

// api/studio-mcp.js
// Make sure to import the database connection
import db from '../../../src/db';
const { vercelMCPRouteHandler } = require('@mongoosejs/studio/vercel');

module.exports = vercelMCPRouteHandler(db, {
  apiKey: process.env.MONGOOSE_STUDIO_API_KEY,
  publicUrl: process.env.MONGOOSE_STUDIO_PUBLIC_URL
});

Set MONGOOSE_STUDIO_PUBLIC_URL to the externally reachable Studio URL, for example https://app.example.com/studio, when using an API key. Without an API key, MCP is enabled by default and follows the same localhost and bindIp restriction described above. Connect MCP clients to /api/studio-mcp; no rewrite is required.

For OAuth, the protected resource metadata is generated in the Studio frontend by the same frontend() call used to write config.js. It registers the MCP resource before the returned promise resolves, so copy the frontend after that promise resolves. Existing publicUrl fallbacks can stay as they are; the copy source must include hidden files:

const { execSync } = require('child_process');
const opts = {
  apiKey: process.env.MONGOOSE_STUDIO_API_KEY,
  mcp: true,
  publicUrl: process.env.MONGOOSE_STUDIO_PUBLIC_URL
};
require('@mongoosejs/studio/frontend')('/api/studio', true, opts).then(() => {
  execSync('mkdir -p ./public/studio && cp -r ./node_modules/@mongoosejs/studio/frontend/public/. ./public/studio/');
});

The /. source copies hidden directories such as .well-known; a /* source does not. This places public/studio/.well-known/oauth-protected-resource and registers /api/studio-mcp with the authorization server. The metadata is needed only with an API key. Set Content-Type: application/json and Access-Control-Allow-Origin: * for that static path, as in the standalone Vercel example. Its build script shows the complete asset copy and metadata generation sequence.

Nest.js

Add MongooseStudioModule to your app module as follows. Use getConnectionToken() so Mongoose Studio uses the same connection that MongooseModule.forRoot() creates.

import { Module } from '@nestjs/common';
import { MongooseModule, getConnectionToken } from '@nestjs/mongoose';
import { MongooseStudioModule } from '@mongoosejs/studio/nest';

@Module({
  imports: [
    MongooseModule.forRoot(process.env.MONGODB_URI),
    MongooseStudioModule.forRoot({
      connectionToken: getConnectionToken(),
      apiKey: process.env.MONGOOSE_STUDIO_API_KEY // optional
    })
  ]
})
export class AppModule {}

With this setup, Mongoose Studio is available at /studio. If you mount Mongoose Studio on a different path, update the path option as follows.

MongooseStudioModule.forRoot({
  path: '/__studio', // Serve on `/__studio` rather than `/studio`
  connectionToken: getConnectionToken()
})

Netlify

Here is a full example of how to add Mongoose Studio to a Netlify repo.

  1. Copy the Mongoose Studio frontend into public/studio automatically in npm run build.
const { execSync } = require('child_process');

// Sign up for Mongoose Studio Pro to get an API key, or omit `apiKey` for local dev.
const opts = {
  apiKey: process.env.MONGOOSE_STUDIO_API_KEY,
  // Optionally specify which ChatGPT model to use for chat messages
  model: 'gpt-4o-mini',
  // Provide your own OpenAI, Anthropic, or Google Gemini API key to run chat completions locally
  openAIAPIKey: process.env.OPENAI_API_KEY,
  anthropicAPIKey: process.env.ANTHROPIC_API_KEY,
  googleGeminiAPIKey: process.env.GOOGLE_GEMINI_API_KEY
};
console.log('Creating Mongoose studio', opts);
require('@mongoosejs/studio/frontend')(`/.netlify/functions/studio`, true, opts).then(() => {
  execSync(`
  mkdir -p ./public/imdb
  cp -r ./node_modules/@mongoosejs/studio/frontend/public/* ./public/imdb/
  `);
});
  1. Create a /studio Netlify function in netlify/functions/studio.js, or wherever your Netlify functions directory is. The function path should match the /.netlify/functions/studio parameter in the build script above.
const mongoose = require('mongoose');

const handler = require('@mongoosejs/studio/backend/netlify')({
  apiKey: process.env.MONGOOSE_STUDIO_API_KEY,
  model: 'gpt-4o-mini',
  openAIAPIKey: process.env.OPENAI_API_KEY,
  anthropicAPIKey: process.env.ANTHROPIC_API_KEY,
  googleGeminiAPIKey: process.env.GOOGLE_GEMINI_API_KEY
}).handler;

let conn = null;

module.exports = {
  handler: async function studioHandler(params) {
    if (conn == null) {
      conn = await mongoose.connect(process.env.MONGODB_CONNECTION_STRING, { serverSelectionTimeoutMS: 3000 });
    }

    return handler.apply(null, arguments);
  }
};
  1. Redeploy and you're live!

Try our IMDB demo for an example of Mongoose Studio running on Netlify, or check out the studio.mongoosejs.io GitHub repo for the full source code.

About

A Mongoose-native MongoDB UI with schema-aware autocomplete, AI-assisted queries, and dashboards that understand your models - not just your data.

Topics

Resources

Stars

26 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages