@interface-db/mcp 1.0.67
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/LICENSE.md +202 -0
- package/NOTICE +4 -0
- package/README.md +105 -0
- package/dist/crypto.d.ts +16 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +45 -0
- package/dist/crypto.js.map +1 -0
- package/dist/db/instant.perms.d.ts +9 -0
- package/dist/db/instant.perms.d.ts.map +1 -0
- package/dist/db/instant.perms.js +10 -0
- package/dist/db/instant.perms.js.map +1 -0
- package/dist/db/instant.schema.d.ts +162 -0
- package/dist/db/instant.schema.d.ts.map +1 -0
- package/dist/db/instant.schema.js +167 -0
- package/dist/db/instant.schema.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.html.d.ts +3 -0
- package/dist/index.html.d.ts.map +1 -0
- package/dist/index.html.js +111 -0
- package/dist/index.html.js.map +1 -0
- package/dist/index.js +456 -0
- package/dist/index.js.map +1 -0
- package/dist/oauth-service-provider.d.ts +37 -0
- package/dist/oauth-service-provider.d.ts.map +1 -0
- package/dist/oauth-service-provider.js +603 -0
- package/dist/oauth-service-provider.js.map +1 -0
- package/dist/schema.d.ts +29 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +52 -0
- package/dist/schema.js.map +1 -0
- package/dist/tools.d.ts +12 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +72 -0
- package/dist/tools.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-service-provider.js","sourceRoot":"","sources":["../src/oauth-service-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Express,\n NextFunction,\n Request,\n RequestHandler,\n Response,\n urlencoded,\n} from 'express';\nimport crypto from 'crypto';\nimport {\n id,\n InstantAdminDatabase,\n InstaQLEntity,\n InstaQLResult,\n lookup,\n} from '@interface-db/admin';\nimport { AppSchema } from './db/instant.schema.ts';\nimport {\n AuthorizationParams,\n OAuthServerProvider,\n} from '@modelcontextprotocol/sdk/server/auth/provider.js';\nimport { OAuthRegisteredClientsStore } from '@modelcontextprotocol/sdk/server/auth/clients.js';\nimport {\n OAuthClientInformationFull,\n OAuthTokenRevocationRequest,\n OAuthTokens,\n} from '@modelcontextprotocol/sdk/shared/auth.js';\nimport { decrypt, encrypt, hash, KeyConfig } from './crypto.ts';\nimport { exchangeCodeForToken } from '@interface-db/platform';\nimport { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';\nimport { PlatformApiAuth } from '../../platform/dist/esm/api.js';\nimport { PlatformApi } from '@interface-db/platform';\nimport cookieParser from 'cookie-parser';\nimport {\n InvalidRequestError,\n InvalidTokenError,\n} from '@modelcontextprotocol/sdk/server/auth/errors.js';\n\nexport type OAuthConfig = {\n clientId: string;\n clientSecret: string;\n serverOrigin: string;\n};\n\nexport async function tokensOfBearerToken(\n db: InstantAdminDatabase<AppSchema>,\n token: string,\n): Promise<{\n mcpToken: InstaQLResult<\n AppSchema,\n { mcpTokens: { client: {}; instantToken: {} } }\n >['mcpTokens'][number];\n instantToken: InstaQLEntity<AppSchema, 'instantTokens'>;\n}> {\n const queryRes = await db.query({\n mcpTokens: {\n $: {\n where: {\n tokenHash: hash(token),\n },\n },\n client: {},\n instantToken: {},\n },\n });\n\n const tokenEnt = queryRes.mcpTokens[0];\n if (!tokenEnt) {\n throw new InvalidTokenError('Token not found.');\n }\n\n return { mcpToken: tokenEnt, instantToken: tokenEnt.instantToken! };\n}\n\nexport function makeApiAuth(\n oauthConfig: OAuthConfig,\n key: KeyConfig,\n db: InstantAdminDatabase<AppSchema>,\n instantTokenEnt: InstaQLEntity<AppSchema, 'instantTokens'>,\n): PlatformApiAuth {\n return {\n accessToken: decrypt({\n key,\n enc: instantTokenEnt.accessToken,\n aad: instantTokenEnt.id,\n }),\n refreshToken: decrypt({\n key,\n enc: instantTokenEnt.refreshToken,\n aad: instantTokenEnt.id,\n }),\n clientId: oauthConfig.clientId,\n clientSecret: oauthConfig.clientSecret,\n onRefresh: async ({ accessToken, expiresAt }) => {\n await db.transact(\n db.tx.instantTokens[instantTokenEnt.id].update({\n accessToken: encrypt({\n key,\n aad: instantTokenEnt.id,\n plaintext: accessToken,\n }),\n expiresAt: expiresAt.getTime(),\n }),\n );\n },\n };\n}\n\nfunction patchClientForScopes(\n client: OAuthClientInformationFull,\n): OAuthClientInformationFull {\n if (\n !client.scope ||\n // https://github.com/modelcontextprotocol/modelcontextprotocol/issues/653\n // Anthropic says it's fixed, but it doesn't seem like it\n client.scope?.includes('claudeai') ||\n // Fix for mcp-remote. Unclear why it can't find the scopes\n // and falls back to its default\n client.scope === 'openid email profile'\n ) {\n return { ...client, scope: 'apps-read apps-write' };\n }\n return client;\n}\n\nexport class ServiceProvider implements OAuthServerProvider {\n #db: InstantAdminDatabase<AppSchema>;\n #oauthConfig: OAuthConfig;\n #keyConfig: KeyConfig;\n\n constructor(\n db: InstantAdminDatabase<AppSchema>,\n oauthConfig: OAuthConfig,\n keyConfig: KeyConfig,\n ) {\n this.#db = db;\n this.#oauthConfig = oauthConfig;\n this.#keyConfig = keyConfig;\n }\n\n get clientsStore(): OAuthRegisteredClientsStore {\n return {\n getClient: async (clientId: string) => {\n const res = await this.#db.query({\n clients: { $: { where: { client_id: clientId } } },\n });\n const client = res.clients[0];\n if (!client) {\n return undefined;\n }\n\n return {\n ...client,\n ...(client.client_secret\n ? {\n client_secret: decrypt({\n key: this.#keyConfig,\n enc: client.client_secret,\n aad: client.client_id,\n }),\n }\n : {}),\n } as OAuthClientInformationFull;\n },\n\n registerClient: async (rawClient: OAuthClientInformationFull) => {\n const client = {\n ...patchClientForScopes(rawClient),\n };\n\n await this.#db.transact(\n this.#db.tx.clients[id()].update({\n ...client,\n ...(client.client_secret\n ? {\n client_secret: encrypt({\n key: this.#keyConfig,\n aad: client.client_id,\n plaintext: client.client_secret,\n }),\n }\n : {}),\n }),\n );\n return client;\n },\n };\n }\n async authorize(\n client: OAuthClientInformationFull,\n params: AuthorizationParams,\n res: Response,\n ): Promise<void> {\n // Tag the cookie with a prefix in case multiple have the same key\n const cookie = `_imcp_${crypto.randomUUID()}`;\n const cookieHash = hash(cookie);\n const state = crypto.randomUUID();\n\n await this.#db.transact(\n this.#db.tx.redirects[id()]\n .update({\n cookieHash,\n authParams: params,\n state,\n clientToken: crypto.randomUUID(),\n expiresAt: new Date(Date.now() + 1000 * 60 * 10).getTime(),\n })\n .link({ client: lookup('client_id', client.client_id) }),\n );\n res\n .cookie('__session', cookie, {\n httpOnly: true,\n secure: this.#oauthConfig.serverOrigin.startsWith('https'),\n sameSite: 'lax',\n path: '/oauth',\n expires: new Date(Date.now() + 1000 * 60 * 5),\n })\n .redirect('/oauth/start');\n }\n\n async challengeForAuthorizationCode(\n _client: OAuthClientInformationFull,\n authorizationCode: string,\n ): Promise<string> {\n const mcpCodeHash = hash(authorizationCode);\n\n const queryRes = await this.#db.query({\n redirects: { $: { where: { mcpCodeHash } } },\n });\n\n const redirect = queryRes.redirects[0];\n\n if (!redirect) {\n throw new Error('Could not find OAuth request.');\n }\n\n if (!redirect.exchangedForInstantCode) {\n throw new Error(\n 'OAuth flow is in an invalid state. Expected to exchange a code for a token first.',\n );\n }\n\n return redirect.authParams.codeChallenge;\n }\n\n async exchangeAuthorizationCode(\n client: OAuthClientInformationFull,\n authorizationCode: string,\n // Already checked in `challengeForAuthorizationCode`\n _codeVerifier?: string,\n redirectUri?: string,\n ): Promise<OAuthTokens> {\n const mcpCodeHash = hash(authorizationCode);\n\n const queryRes = await this.#db.query({\n redirects: { $: { where: { mcpCodeHash } } },\n });\n\n const redirect = queryRes.redirects[0];\n\n if (!redirect) {\n throw new InvalidRequestError('Could not find OAuth request.');\n }\n\n await this.#db.transact(this.#db.tx.redirects[redirect.id].delete());\n\n const originalRedirectUri = redirect.authParams.redirectUri;\n if (originalRedirectUri !== redirectUri) {\n throw new InvalidRequestError('Invalid redirect_uri.');\n }\n\n if (!redirect.exchangedForInstantCode || !redirect.instantCode) {\n throw new InvalidRequestError(\n 'OAuth flow is in an invalid state. Expected to exchange a code for a token first.',\n );\n }\n\n const code = redirect.instantCode;\n\n const tokenInfo = await exchangeCodeForToken({\n code,\n clientId: this.#oauthConfig.clientId,\n clientSecret: this.#oauthConfig.clientSecret,\n redirectUri: `${this.#oauthConfig.serverOrigin}/oauth/external-redirect`,\n });\n\n const instantTokenExpiresAt = tokenInfo.expiresAt;\n const mcpTokenExpiresAt = new Date(\n instantTokenExpiresAt.getTime() - 1000 * 60 * 60,\n );\n\n const mcpToken = `at_${crypto.randomUUID()}`;\n const mcpRefreshToken = `rt_${crypto.randomUUID()}`;\n const mcpTokenId = id();\n const mcpRefreshTokenId = id();\n const instantTokenId = id();\n\n await this.#db.transact([\n this.#db.tx.instantTokens[instantTokenId]\n .update({\n accessToken: encrypt({\n key: this.#keyConfig,\n aad: instantTokenId,\n plaintext: tokenInfo.accessToken,\n }),\n expiresAt: instantTokenExpiresAt.getTime(),\n refreshToken: encrypt({\n key: this.#keyConfig,\n aad: instantTokenId,\n plaintext: tokenInfo.refreshToken,\n }),\n })\n .link({ client: lookup('client_id', client.client_id) }),\n this.#db.tx.mcpTokens[mcpTokenId]\n .update({\n tokenHash: hash(mcpToken),\n expiresAt: mcpTokenExpiresAt.getTime(),\n scope: tokenInfo.scopes,\n })\n .link({ instantToken: instantTokenId })\n .link({ mcpRefreshToken: mcpRefreshTokenId })\n .link({ client: lookup('client_id', client.client_id) }),\n this.#db.tx.mcpRefreshTokens[mcpRefreshTokenId]\n .update({\n tokenHash: hash(mcpRefreshToken),\n scope: tokenInfo.scopes,\n })\n .link({ instantToken: instantTokenId })\n .link({ client: lookup('client_id', client.client_id) }),\n ]);\n\n return {\n access_token: mcpToken,\n token_type: 'bearer',\n expires_in: Math.floor((mcpTokenExpiresAt.getTime() - Date.now()) / 1000),\n scope: tokenInfo.scopes,\n refresh_token: mcpRefreshToken,\n };\n }\n\n async exchangeRefreshToken(\n client: OAuthClientInformationFull,\n refreshToken: string,\n _scopes?: string[],\n ): Promise<OAuthTokens> {\n const queryRes = await this.#db.query({\n mcpRefreshTokens: {\n $: {\n where: {\n tokenHash: hash(refreshToken),\n },\n },\n client: {},\n instantToken: {},\n },\n });\n\n const tokenEnt = queryRes.mcpRefreshTokens[0];\n if (!tokenEnt) {\n throw new InvalidTokenError('Token not found.');\n }\n\n if (client.client_id !== tokenEnt.client!.client_id) {\n throw new InvalidTokenError('Refresh token does not belong to client.');\n }\n\n const mcpToken = `at_${crypto.randomUUID()}`;\n const expiresAt = new Date(Date.now() + 1000 * 60 * 60 * 24 * 14).getTime();\n await this.#db.transact(\n this.#db.tx.mcpTokens[id()]\n .update({\n tokenHash: hash(mcpToken),\n expiresAt,\n scope: tokenEnt.scope,\n })\n // instantToken is required, so we should be able to fix the types\n // so we don't need the `!`s\n .link({ instantToken: tokenEnt.instantToken!.id })\n .link({ mcpRefreshToken: tokenEnt.id })\n .link({ client: lookup('client_id', client.client_id) }),\n );\n return {\n access_token: mcpToken,\n token_type: 'bearer',\n expires_in: Math.floor((Date.now() - expiresAt) / 1000),\n refresh_token: refreshToken,\n scope: tokenEnt.scope,\n };\n }\n\n async verifyAccessToken(token: string): Promise<AuthInfo> {\n const { instantToken, mcpToken } = await tokensOfBearerToken(\n this.#db,\n token,\n );\n const api = new PlatformApi({\n auth: makeApiAuth(\n this.#oauthConfig,\n this.#keyConfig,\n this.#db,\n instantToken,\n ),\n });\n\n try {\n await api.tokenInfo();\n } catch (e) {\n throw new InvalidTokenError(\n e instanceof Error ? e.message : 'Invalid token',\n );\n }\n\n return {\n clientId: mcpToken.client!.client_id,\n scopes: mcpToken.scope.split(' '),\n token,\n expiresAt: new Date(mcpToken.expiresAt).getTime(),\n };\n }\n\n async revokeToken(\n _client: OAuthClientInformationFull,\n request: OAuthTokenRevocationRequest,\n ): Promise<void> {\n const tokenHash = hash(request.token);\n\n await this.#db.transact([\n this.#db.tx.mcpTokens[lookup('tokenHash', tokenHash)].delete(),\n this.#db.tx.mcpRefreshTokens[lookup('tokenHash', tokenHash)].delete(),\n ]);\n }\n}\n\ninterface ReqWithRedirect extends Request {\n oauthRedirect?: InstaQLResult<\n AppSchema,\n {\n redirects: {\n client: {};\n };\n }\n >['redirects'][number];\n}\n\nfunction useRedirectFromCookie(\n db: InstantAdminDatabase<AppSchema>,\n): RequestHandler {\n return async (req: ReqWithRedirect, res: Response, next: NextFunction) => {\n const cookie = req.cookies.__session;\n if (!cookie) {\n res.status(400).send('Missing cookie, cannot complete OAuth flow.');\n return;\n }\n const cookieHash = hash(cookie);\n\n const queryRes = await db.query({\n redirects: {\n $: { where: { cookieHash } },\n client: {},\n },\n });\n\n const redirect = queryRes.redirects[0];\n\n if (!redirect) {\n res.status(400).send('Could not find OAuth flow, please try again.');\n return;\n }\n\n if (new Date(redirect.expiresAt) < new Date()) {\n await db.transact(db.tx.redirects[redirect.id].delete());\n res.status(400).send('OAuth flow is expired, please try again.');\n return;\n }\n\n req.oauthRedirect = redirect;\n next();\n };\n}\n\nasync function cleanupRedirect(\n db: InstantAdminDatabase<AppSchema>,\n redirect: NonNullable<ReqWithRedirect['oauthRedirect']>,\n) {\n await db.transact(db.tx.redirects[redirect.id].delete());\n}\n\nfunction oauthStartHtml(\n redirect: NonNullable<ReqWithRedirect['oauthRedirect']>,\n) {\n const clientName = redirect.client?.client_name || 'Unknown client';\n const redirectUri = encodeURI(redirect.authParams.redirectUri);\n\n return /* HTML */ `<!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Authorize ${clientName}</title>\n <style>\n :root {\n --primary-color: #007bff;\n --primary-hover-color: #0056b3;\n --secondary-color: #6c757d;\n --secondary-hover-color: #5a6268;\n --bg-color: #f8f9fa;\n --card-bg-color: #ffffff;\n --text-color: #212529;\n --border-color: #dee2e6;\n --uri-bg-color: #e9ecef;\n --uri-border-color: #ced4da;\n --border-radius: 8px;\n --shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n }\n\n body {\n font-family: sans-serif;\n background-color: var(--bg-color);\n color: var(--text-color);\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n margin: 0;\n padding: 1rem;\n box-sizing: border-box;\n }\n\n .container {\n background-color: var(--card-bg-color);\n padding: 2.5rem;\n border-radius: var(--border-radius);\n box-shadow: var(--shadow);\n max-width: 520px;\n width: 100%;\n /* CHANGED: Text is now left-aligned */\n text-align: left;\n }\n\n h1 {\n font-size: 1.75rem;\n font-weight: 700;\n margin-top: 0;\n margin-bottom: 1rem;\n }\n\n p {\n line-height: 1.6;\n margin-bottom: 1rem; /* Adjusted margin for new layout */\n }\n\n .client-name {\n font-weight: 700;\n color: var(--primary-color);\n }\n\n /* NEW: Styling for the dedicated URL block */\n .uri-display {\n background-color: var(--uri-bg-color);\n padding: 0.75rem 1rem;\n margin-top: 0.5rem;\n margin-bottom: 2rem;\n border: 1px solid var(--uri-border-color);\n border-radius: 6px;\n font-family: 'Source Code Pro', monospace;\n word-break: break-all;\n font-size: 0.9rem;\n color: var(--text-color);\n }\n\n .actions {\n display: flex;\n gap: 1rem;\n justify-content: flex-start; /* Aligns buttons to the left */\n margin-top: 2rem;\n }\n\n .actions form {\n flex: 1 1 0;\n display: flex;\n }\n\n .btn {\n display: inline-block;\n font-family: inherit;\n font-size: 1rem;\n font-weight: 500;\n padding: 0.75rem 1rem;\n border-radius: var(--border-radius);\n border: 1px solid transparent;\n cursor: pointer;\n transition:\n background-color 0.2s ease-in-out,\n color 0.2s ease-in-out,\n border-color 0.2s ease-in-out;\n width: 100%;\n text-decoration: none;\n text-align: center;\n }\n\n .btn-primary {\n background-color: var(--primary-color);\n color: white;\n }\n\n .btn-primary:hover {\n background-color: var(--primary-hover-color);\n }\n\n .btn-secondary {\n background-color: transparent;\n color: var(--secondary-color);\n border-color: var(--border-color);\n }\n\n .btn-secondary:hover {\n background-color: var(--secondary-color);\n color: white;\n border-color: var(--secondary-color);\n }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Authorize Application</h1>\n <p>\n The application\n <strong class=\"client-name\">${clientName}</strong> is requesting\n permission to access your InstantDB account.\n </p>\n\n <p>\n If you approve, you will first be sent to InstantDB to confirm, then\n you will be redirected to the application at the following address:\n </p>\n\n <div class=\"uri-display\">${redirectUri}</div>\n\n <div class=\"actions\">\n <form method=\"POST\" action=\"/oauth/deny\">\n <button type=\"submit\" class=\"btn btn-secondary\">Deny</button>\n </form>\n <form method=\"POST\" action=\"/oauth/redirect-from-start\">\n <input\n type=\"hidden\"\n name=\"clientToken\"\n value=\"${redirect.clientToken}\"\n />\n <button type=\"submit\" class=\"btn btn-primary\">Authorize</button>\n </form>\n </div>\n </div>\n </body>\n </html>`;\n}\n\nasync function oauthStart(\n db: InstantAdminDatabase<AppSchema>,\n req: ReqWithRedirect,\n res: Response,\n) {\n const redirect = req.oauthRedirect!;\n if (redirect.shownConfirmPage) {\n await cleanupRedirect(db, redirect);\n res\n .status(400)\n .send('OAuth request is in an invalid state. Please try again.');\n return;\n }\n await db.transact(\n db.tx.redirects[redirect.id].update({ shownConfirmPage: true }),\n );\n\n res\n .status(200)\n .set('Content-Type', 'text/html; charset=UTF-8')\n .send(oauthStartHtml(redirect));\n}\n\nasync function oauthRedirectFromStart(\n db: InstantAdminDatabase<AppSchema>,\n oauthConfig: OAuthConfig,\n req: ReqWithRedirect,\n res: Response,\n) {\n const redirect = req.oauthRedirect!;\n\n if (!redirect.shownConfirmPage) {\n await cleanupRedirect(db, redirect);\n res\n .status(400)\n .send('OAuth request is in an invalid state. Please try again.');\n return;\n }\n\n if (\n !req.body.clientToken ||\n !crypto.timingSafeEqual(\n Buffer.from(req.body.clientToken, 'utf-8'),\n Buffer.from(redirect.clientToken, 'utf-8'),\n )\n ) {\n await cleanupRedirect(db, redirect);\n res.status(400).send('Invalid OAuth request. Please try again.');\n return;\n }\n const externalAuthUrl = new URL(\n `https://api.interfacedb.com/platform/oauth/start`,\n );\n externalAuthUrl.searchParams.set('client_id', oauthConfig.clientId);\n externalAuthUrl.searchParams.set('response_type', 'code');\n externalAuthUrl.searchParams.set('state', redirect.state);\n externalAuthUrl.searchParams.set(\n 'scope',\n redirect.authParams.scopes?.join(' ') ||\n redirect.client!.scope ||\n 'apps-read apps-write',\n );\n\n externalAuthUrl.searchParams.set(\n 'redirect_uri',\n `${oauthConfig.serverOrigin}/oauth/external-redirect`,\n );\n\n res.redirect(externalAuthUrl.toString());\n}\n\nasync function oauthExternalRedirect(\n db: InstantAdminDatabase<AppSchema>,\n req: ReqWithRedirect,\n res: Response,\n) {\n const redirect = req.oauthRedirect!;\n\n if (redirect.exchangedForInstantCode) {\n await cleanupRedirect(db, redirect);\n res.status(400).send('OAuth flow is expired, please try again.');\n return;\n }\n\n if (req.query.error) {\n await cleanupRedirect(db, redirect);\n const redirectUri = new URL(\n (redirect.authParams as AuthorizationParams).redirectUri,\n );\n redirectUri.searchParams.set('error', req.query.error as string);\n if (req.query.error_description) {\n redirectUri.searchParams.set(\n 'error_description',\n req.query.error_description as string,\n );\n }\n res.redirect(redirectUri.toString());\n return;\n }\n\n const instantCode = req.query.code as string | undefined;\n\n if (!instantCode) {\n await cleanupRedirect(db, redirect);\n res\n .status(400)\n .send(\n 'Could not complete OAuth flow, missing code param. Please try again.',\n );\n return;\n }\n\n const state = req.query.state;\n\n if (!state) {\n await cleanupRedirect(db, redirect);\n res\n .status(400)\n .send(\n 'Could not complete OAuth flow, missing state param. Please try again.',\n );\n return;\n }\n\n if (\n !crypto.timingSafeEqual(\n Buffer.from(state as string),\n Buffer.from(redirect.state),\n )\n ) {\n await cleanupRedirect(db, redirect);\n res\n .status(400)\n .send(\n 'Could not complete OAuth flow, invalid state param. Please try again.',\n );\n return;\n }\n\n const mcpCode = crypto.randomUUID();\n const mcpCodeHash = hash(mcpCode);\n\n await db.transact(\n db.tx.redirects[redirect.id].update({\n instantCode,\n mcpCodeHash,\n exchangedForInstantCode: true,\n }),\n );\n\n const mcpRedirectUri = new URL(redirect.authParams.redirectUri);\n\n mcpRedirectUri.searchParams.set('code', mcpCode);\n if (redirect.authParams.state) {\n mcpRedirectUri.searchParams.set('state', redirect.authParams.state);\n }\n\n res.redirect(mcpRedirectUri.toString());\n}\n\nexport function addOAuthRoutes(\n app: Express,\n db: InstantAdminDatabase<AppSchema>,\n oauthConfig: OAuthConfig,\n) {\n app.get(\n '/oauth/start',\n cookieParser(),\n useRedirectFromCookie(db),\n async (req: Request, res: Response) => {\n return await oauthStart(db, req, res);\n },\n );\n\n app.post(\n '/oauth/redirect-from-start',\n cookieParser(),\n useRedirectFromCookie(db),\n urlencoded({ extended: true }),\n async (req: Request, res: Response) => {\n return await oauthRedirectFromStart(db, oauthConfig, req, res);\n },\n );\n\n app.post(\n '/oauth/deny',\n cookieParser(),\n useRedirectFromCookie(db),\n async (req: ReqWithRedirect, res: Response) => {\n const redirect = req.oauthRedirect!;\n await db.transact(db.tx.redirects[redirect.id].delete());\n const redirectUri = new URL(\n (redirect.authParams as AuthorizationParams).redirectUri,\n );\n redirectUri.searchParams.set('error', 'access_denied');\n res.redirect(redirectUri.toString());\n },\n );\n\n app.get(\n '/oauth/external-redirect',\n cookieParser(),\n useRedirectFromCookie(db),\n async (req: Request, res: Response) => {\n return await oauthExternalRedirect(db, req, res);\n },\n );\n}\n"]}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
type AttributeConfig = {
|
|
2
|
+
type: 'string' | 'number' | 'boolean' | 'date' | 'json';
|
|
3
|
+
required?: boolean;
|
|
4
|
+
unique?: boolean;
|
|
5
|
+
indexed?: boolean;
|
|
6
|
+
};
|
|
7
|
+
type LinkConfig = {
|
|
8
|
+
from: {
|
|
9
|
+
entity: string;
|
|
10
|
+
has: 'one' | 'many';
|
|
11
|
+
label: string;
|
|
12
|
+
required?: boolean;
|
|
13
|
+
onDelete?: 'cascade';
|
|
14
|
+
};
|
|
15
|
+
to: {
|
|
16
|
+
entity: string;
|
|
17
|
+
has: 'one' | 'many';
|
|
18
|
+
label: string;
|
|
19
|
+
required?: boolean;
|
|
20
|
+
onDelete?: 'cascade';
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
type Additions = {
|
|
24
|
+
entities?: Record<string, Record<string, AttributeConfig>>;
|
|
25
|
+
links?: Record<string, LinkConfig>;
|
|
26
|
+
};
|
|
27
|
+
export declare function zodToSchema(additions: Additions): import("@interface-db/core").InstantSchemaDef<import("@interface-db/core").EntitiesWithLinks<Record<string, any>, Record<string, any>>, import("@interface-db/core").LinksDef<any>, {}>;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAKA,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,KAAK,GAAG,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;KACtB,CAAC;IACF,EAAE,EAAE;QACF,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,KAAK,GAAG,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;KACtB,CAAC;CACH,CAAC;AAEF,KAAK,SAAS,GAAG;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACpC,CAAC;AAEF,wBAAgB,WAAW,CAAC,SAAS,EAAE,SAAS,2LAmD/C"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Helper function to convert Zod schema definition for modifying InstantDB
|
|
2
|
+
// schema to a format the InstantDB platform can use
|
|
3
|
+
import { i } from '@interface-db/core';
|
|
4
|
+
export function zodToSchema(additions) {
|
|
5
|
+
const schema = {
|
|
6
|
+
entities: {},
|
|
7
|
+
links: {},
|
|
8
|
+
};
|
|
9
|
+
// Handle entities
|
|
10
|
+
if (additions.entities) {
|
|
11
|
+
for (const [entityName, attributes] of Object.entries(additions.entities)) {
|
|
12
|
+
const entityDef = {};
|
|
13
|
+
for (const [attrName, attrConfig] of Object.entries(attributes)) {
|
|
14
|
+
// (TODO): Fix me?
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
let attr = i[attrConfig.type]();
|
|
17
|
+
// Apply modifiers
|
|
18
|
+
if (attrConfig.unique)
|
|
19
|
+
attr = attr.unique();
|
|
20
|
+
if (attrConfig.indexed)
|
|
21
|
+
attr = attr.indexed();
|
|
22
|
+
if (attrConfig.required === false)
|
|
23
|
+
attr = attr.optional();
|
|
24
|
+
entityDef[attrName] = attr;
|
|
25
|
+
}
|
|
26
|
+
schema.entities[entityName] = i.entity(entityDef);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Handle links
|
|
30
|
+
if (additions.links) {
|
|
31
|
+
for (const [linkName, linkConfig] of Object.entries(additions.links)) {
|
|
32
|
+
schema.links[linkName] = {
|
|
33
|
+
forward: {
|
|
34
|
+
on: linkConfig.from.entity,
|
|
35
|
+
has: linkConfig.from.has,
|
|
36
|
+
label: linkConfig.from.label,
|
|
37
|
+
required: linkConfig.from.required,
|
|
38
|
+
onDelete: linkConfig.from.onDelete,
|
|
39
|
+
},
|
|
40
|
+
reverse: {
|
|
41
|
+
on: linkConfig.to.entity,
|
|
42
|
+
has: linkConfig.to.has,
|
|
43
|
+
label: linkConfig.to.label,
|
|
44
|
+
required: linkConfig.to.required,
|
|
45
|
+
onDelete: linkConfig.to.onDelete,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return i.schema(schema);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,oDAAoD;AAEpD,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAC;AA+BvC,MAAM,UAAU,WAAW,CAAC,SAAoB;IAC9C,MAAM,MAAM,GAAG;QACb,QAAQ,EAAE,EAAyB;QACnC,KAAK,EAAE,EAAyB;KACjC,CAAC;IAEF,kBAAkB;IAClB,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1E,MAAM,SAAS,GAAwB,EAAE,CAAC;YAE1C,KAAK,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBAChE,kBAAkB;gBAClB,aAAa;gBACb,IAAI,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAEhC,kBAAkB;gBAClB,IAAI,UAAU,CAAC,MAAM;oBAAE,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC5C,IAAI,UAAU,CAAC,OAAO;oBAAE,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC9C,IAAI,UAAU,CAAC,QAAQ,KAAK,KAAK;oBAAE,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAE1D,SAAS,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;YAC7B,CAAC;YAED,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,eAAe;IACf,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;QACpB,KAAK,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACrE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG;gBACvB,OAAO,EAAE;oBACP,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM;oBAC1B,GAAG,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG;oBACxB,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK;oBAC5B,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,QAAQ;oBAClC,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,QAAQ;iBACnC;gBACD,OAAO,EAAE;oBACP,EAAE,EAAE,UAAU,CAAC,EAAE,CAAC,MAAM;oBACxB,GAAG,EAAE,UAAU,CAAC,EAAE,CAAC,GAAG;oBACtB,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC,KAAK;oBAC1B,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC,QAAQ;oBAChC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC,QAAQ;iBACjC;aACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC","sourcesContent":["// Helper function to convert Zod schema definition for modifying InstantDB\n// schema to a format the InstantDB platform can use\n\nimport { i } from '@interface-db/core';\n\ntype AttributeConfig = {\n type: 'string' | 'number' | 'boolean' | 'date' | 'json';\n required?: boolean;\n unique?: boolean;\n indexed?: boolean;\n};\n\ntype LinkConfig = {\n from: {\n entity: string;\n has: 'one' | 'many';\n label: string;\n required?: boolean;\n onDelete?: 'cascade';\n };\n to: {\n entity: string;\n has: 'one' | 'many';\n label: string;\n required?: boolean;\n onDelete?: 'cascade';\n };\n};\n\ntype Additions = {\n entities?: Record<string, Record<string, AttributeConfig>>;\n links?: Record<string, LinkConfig>;\n};\n\nexport function zodToSchema(additions: Additions) {\n const schema = {\n entities: {} as Record<string, any>,\n links: {} as Record<string, any>,\n };\n\n // Handle entities\n if (additions.entities) {\n for (const [entityName, attributes] of Object.entries(additions.entities)) {\n const entityDef: Record<string, any> = {};\n\n for (const [attrName, attrConfig] of Object.entries(attributes)) {\n // (TODO): Fix me?\n // @ts-ignore\n let attr = i[attrConfig.type]();\n\n // Apply modifiers\n if (attrConfig.unique) attr = attr.unique();\n if (attrConfig.indexed) attr = attr.indexed();\n if (attrConfig.required === false) attr = attr.optional();\n\n entityDef[attrName] = attr;\n }\n\n schema.entities[entityName] = i.entity(entityDef);\n }\n }\n\n // Handle links\n if (additions.links) {\n for (const [linkName, linkConfig] of Object.entries(additions.links)) {\n schema.links[linkName] = {\n forward: {\n on: linkConfig.from.entity,\n has: linkConfig.from.has,\n label: linkConfig.from.label,\n required: linkConfig.from.required,\n onDelete: linkConfig.from.onDelete,\n },\n reverse: {\n on: linkConfig.to.entity,\n has: linkConfig.to.has,\n label: linkConfig.to.label,\n required: linkConfig.to.required,\n onDelete: linkConfig.to.onDelete,\n },\n };\n }\n }\n\n return i.schema(schema);\n}\n"]}
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { PlatformApi } from '@interface-db/platform';
|
|
2
|
+
type ToolResult = {
|
|
3
|
+
isError?: boolean;
|
|
4
|
+
content: {
|
|
5
|
+
type: 'text';
|
|
6
|
+
text: string;
|
|
7
|
+
}[];
|
|
8
|
+
};
|
|
9
|
+
export declare function handleQuery(api: PlatformApi, appId: string, query: Record<string, any>): Promise<ToolResult>;
|
|
10
|
+
export declare function handleTransact(api: PlatformApi, appId: string, steps: any[][]): Promise<ToolResult>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAIrD,KAAK,UAAU,GAAG;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3C,CAAC;AA8CF,wBAAsB,WAAW,CAC/B,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACzB,OAAO,CAAC,UAAU,CAAC,CAiBrB;AAED,wBAAsB,cAAc,CAClC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,GAAG,EAAE,EAAE,GACb,OAAO,CAAC,UAAU,CAAC,CAiBrB"}
|
package/dist/tools.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const API_URL = process.env.INSTANT_API_URL || 'https://api.interfacedb.com';
|
|
2
|
+
async function adminQuery(apiURI, token, appId, query) {
|
|
3
|
+
const res = await fetch(`${apiURI}/admin/query`, {
|
|
4
|
+
method: 'POST',
|
|
5
|
+
headers: {
|
|
6
|
+
'Content-Type': 'application/json',
|
|
7
|
+
Authorization: `Bearer ${token}`,
|
|
8
|
+
'App-Id': appId,
|
|
9
|
+
},
|
|
10
|
+
body: JSON.stringify({ query }),
|
|
11
|
+
});
|
|
12
|
+
const data = await res.json();
|
|
13
|
+
if (!res.ok) {
|
|
14
|
+
throw new Error(JSON.stringify(data));
|
|
15
|
+
}
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
18
|
+
async function adminTransact(apiURI, token, appId, steps) {
|
|
19
|
+
const res = await fetch(`${apiURI}/admin/transact`, {
|
|
20
|
+
method: 'POST',
|
|
21
|
+
headers: {
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
Authorization: `Bearer ${token}`,
|
|
24
|
+
'App-Id': appId,
|
|
25
|
+
},
|
|
26
|
+
body: JSON.stringify({ steps }),
|
|
27
|
+
});
|
|
28
|
+
const data = await res.json();
|
|
29
|
+
if (!res.ok) {
|
|
30
|
+
throw new Error(JSON.stringify(data));
|
|
31
|
+
}
|
|
32
|
+
return data;
|
|
33
|
+
}
|
|
34
|
+
export async function handleQuery(api, appId, query) {
|
|
35
|
+
try {
|
|
36
|
+
const data = await api.withRetry(adminQuery, [
|
|
37
|
+
API_URL,
|
|
38
|
+
api.token(),
|
|
39
|
+
appId,
|
|
40
|
+
query,
|
|
41
|
+
]);
|
|
42
|
+
return {
|
|
43
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
return {
|
|
48
|
+
isError: true,
|
|
49
|
+
content: [{ type: 'text', text: `Error querying app: ${e.message}` }],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export async function handleTransact(api, appId, steps) {
|
|
54
|
+
try {
|
|
55
|
+
const data = await api.withRetry(adminTransact, [
|
|
56
|
+
API_URL,
|
|
57
|
+
api.token(),
|
|
58
|
+
appId,
|
|
59
|
+
steps,
|
|
60
|
+
]);
|
|
61
|
+
return {
|
|
62
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
return {
|
|
67
|
+
isError: true,
|
|
68
|
+
content: [{ type: 'text', text: `Error transacting: ${e.message}` }],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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","sourcesContent":["import { PlatformApi } from '@interface-db/platform';\n\nconst API_URL = process.env.INSTANT_API_URL || 'https://api.interfacedb.com';\n\ntype ToolResult = {\n isError?: boolean;\n content: { type: 'text'; text: string }[];\n};\n\nasync function adminQuery(\n apiURI: string,\n token: string,\n appId: string,\n query: Record<string, any>,\n) {\n const res = await fetch(`${apiURI}/admin/query`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n 'App-Id': appId,\n },\n body: JSON.stringify({ query }),\n });\n const data = await res.json();\n if (!res.ok) {\n throw new Error(JSON.stringify(data));\n }\n return data;\n}\n\nasync function adminTransact(\n apiURI: string,\n token: string,\n appId: string,\n steps: any[][],\n) {\n const res = await fetch(`${apiURI}/admin/transact`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n 'App-Id': appId,\n },\n body: JSON.stringify({ steps }),\n });\n const data = await res.json();\n if (!res.ok) {\n throw new Error(JSON.stringify(data));\n }\n return data;\n}\n\nexport async function handleQuery(\n api: PlatformApi,\n appId: string,\n query: Record<string, any>,\n): Promise<ToolResult> {\n try {\n const data = await api.withRetry(adminQuery, [\n API_URL,\n api.token(),\n appId,\n query,\n ]);\n return {\n content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],\n };\n } catch (e: any) {\n return {\n isError: true,\n content: [{ type: 'text', text: `Error querying app: ${e.message}` }],\n };\n }\n}\n\nexport async function handleTransact(\n api: PlatformApi,\n appId: string,\n steps: any[][],\n): Promise<ToolResult> {\n try {\n const data = await api.withRetry(adminTransact, [\n API_URL,\n api.token(),\n appId,\n steps,\n ]);\n return {\n content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],\n };\n } catch (e: any) {\n return {\n isError: true,\n content: [{ type: 'text', text: `Error transacting: ${e.message}` }],\n };\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,eAAe,OAAO,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,eAAe,OAAO,CAAC","sourcesContent":["import { version } from '@interface-db/version';\n\nexport default version;\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@interface-db/mcp",
|
|
3
|
+
"version": "1.0.67",
|
|
4
|
+
"description": "Model Context Protocol (MCP) server for managing InterfaceDB apps, schemas, and permissions!",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://github.com/InterfaceLDN/InterfaceDB/tree/main/client/packages/mcp",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/InterfaceLDN/InterfaceDB.git",
|
|
10
|
+
"directory": "client/packages/mcp"
|
|
11
|
+
},
|
|
12
|
+
"type": "module",
|
|
13
|
+
"bin": {
|
|
14
|
+
"interfacedb-mcp": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"LICENSE.md",
|
|
19
|
+
"NOTICE"
|
|
20
|
+
],
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/cookie-parser": "^1.4.9",
|
|
23
|
+
"@types/express": "^4.17.21",
|
|
24
|
+
"@types/node": "^18.11.18",
|
|
25
|
+
"pino-pretty": "^13.0.0",
|
|
26
|
+
"tsx": "^4.7.0",
|
|
27
|
+
"typescript": "^5.9.3",
|
|
28
|
+
"vitest": "^3.2.4",
|
|
29
|
+
"@interface-db/cli": "1.0.67"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@honeycombio/opentelemetry-node": "^0.7.2",
|
|
33
|
+
"@modelcontextprotocol/sdk": "^1.17.2",
|
|
34
|
+
"@opentelemetry/api": "^1.9.0",
|
|
35
|
+
"cookie-parser": "^1.4.7",
|
|
36
|
+
"dotenv": "^16.3.1",
|
|
37
|
+
"esbuild": "^0.25.5",
|
|
38
|
+
"express": "^4.18.2",
|
|
39
|
+
"pino": "^9.7.0",
|
|
40
|
+
"pino-http": "^10.5.0",
|
|
41
|
+
"zod": "^3.25.39",
|
|
42
|
+
"@interface-db/admin": "1.0.67",
|
|
43
|
+
"@interface-db/core": "1.0.67",
|
|
44
|
+
"@interface-db/platform": "1.0.67",
|
|
45
|
+
"@interface-db/version": "1.0.67"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public",
|
|
52
|
+
"registry": "https://registry.npmjs.org/"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"test": "vitest --project unit",
|
|
56
|
+
"test:e2e": "vitest --project e2e",
|
|
57
|
+
"test:ci": "vitest run",
|
|
58
|
+
"dev": "tsc --watch --preserveWatchOutput -p tsconfig.dev.json",
|
|
59
|
+
"clean": "rm -rf dist",
|
|
60
|
+
"build": "rm -rf dist && tsc",
|
|
61
|
+
"pull:dev": "INSTANT_SCHEMA_FILE_PATH=./src/db/instant.schema.ts INSTANT_PERMS_FILE_PATH=./src/db/instant.perms.ts instant-cli pull --app 2366e905-5ce1-4cfa-8de1-ed3450a4ed2b",
|
|
62
|
+
"push:dev": "INSTANT_SCHEMA_FILE_PATH=./src/db/instant.schema.ts INSTANT_PERMS_FILE_PATH=./src/db/instant.perms.ts instant-cli push --app 2366e905-5ce1-4cfa-8de1-ed3450a4ed2b",
|
|
63
|
+
"instant-cli-init:dev": "INSTANT_SCHEMA_FILE_PATH=./src/db/instant.schema.ts INSTANT_PERMS_FILE_PATH=./src/db/instant.perms.ts instant-cli init --app 22d72c26-0514-4d75-b410-564416ddf0ba",
|
|
64
|
+
"pull": "INSTANT_SCHEMA_FILE_PATH=./src/db/instant.schema.ts INSTANT_PERMS_FILE_PATH=./src/db/instant.perms.ts instant-cli pull --app 22d72c26-0514-4d75-b410-564416ddf0ba",
|
|
65
|
+
"push": "INSTANT_SCHEMA_FILE_PATH=./src/db/instant.schema.ts INSTANT_PERMS_FILE_PATH=./src/db/instant.perms.ts instant-cli push --app 22d72c26-0514-4d75-b410-564416ddf0ba",
|
|
66
|
+
"instant-cli-init": "INSTANT_SCHEMA_FILE_PATH=./src/db/instant.schema.ts INSTANT_PERMS_FILE_PATH=./src/db/instant.perms.ts instant-cli init --app 22d72c26-0514-4d75-b410-564416ddf0ba"
|
|
67
|
+
}
|
|
68
|
+
}
|