fix: align MCP server schema with memento-note + per-request user isolation
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 12s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 12s
- Remove `embedding` column from MCP Note model (dropped by migration 20260425120000) - Add missing columns: trashedAt, dismissedFromRecent, contentUpdatedAt, cardSizeMode - Add NoteEmbedding model and Label.notebook relation - Use AsyncLocalStorage to pass authenticated userId from API key to tool handlers - Enable SSE mode and auth in docker-compose for N8N integration Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,7 @@ import {
|
||||
ListToolsRequestSchema,
|
||||
McpError,
|
||||
} from '@modelcontextprotocol/sdk/types.js';
|
||||
import { requestContext } from './request-context.js';
|
||||
|
||||
// ─── Configuration ─────────────────────────────────────────────────────────
|
||||
|
||||
@@ -603,22 +604,30 @@ const toolDefinitions = [
|
||||
* @param {string} [options.appBaseUrl] - Optional base URL of the Next.js app for AI API calls
|
||||
*/
|
||||
export function registerTools(server, prisma, options = {}) {
|
||||
const { userId = null, appBaseUrl = null } = options;
|
||||
const { appBaseUrl = null } = options;
|
||||
|
||||
// Resolve userId per-request from AsyncLocalStorage (set by auth middleware)
|
||||
const getResolvedUserId = () => {
|
||||
const store = requestContext.getStore();
|
||||
return store?.userId || null;
|
||||
};
|
||||
|
||||
// Fallback: auto-detect first user when no auth context
|
||||
let fallbackUserId = null;
|
||||
let fallbackPromise = null;
|
||||
|
||||
// Resolve userId: if not provided, auto-detect the first user
|
||||
let resolvedUserId = userId;
|
||||
let userIdPromise = null;
|
||||
|
||||
const ensureUserId = async () => {
|
||||
if (resolvedUserId) return resolvedUserId;
|
||||
if (userIdPromise) return userIdPromise;
|
||||
|
||||
userIdPromise = prisma.user.findFirst({ select: { id: true } }).then(u => {
|
||||
if (u) resolvedUserId = u.id;
|
||||
return resolvedUserId;
|
||||
const fromContext = getResolvedUserId();
|
||||
if (fromContext) return fromContext;
|
||||
if (fallbackUserId) return fallbackUserId;
|
||||
if (fallbackPromise) return fallbackPromise;
|
||||
|
||||
fallbackPromise = prisma.user.findFirst({ select: { id: true } }).then(u => {
|
||||
if (u) fallbackUserId = u.id;
|
||||
return fallbackUserId;
|
||||
});
|
||||
|
||||
return userIdPromise;
|
||||
|
||||
return fallbackPromise;
|
||||
};
|
||||
|
||||
// ── List Tools ────────────────────────────────────────────────────────────
|
||||
@@ -629,6 +638,7 @@ export function registerTools(server, prisma, options = {}) {
|
||||
// ── Call Tools ────────────────────────────────────────────────────────────
|
||||
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||
const { name, arguments: args } = request.params;
|
||||
const resolvedUserId = getResolvedUserId();
|
||||
|
||||
try {
|
||||
switch (name) {
|
||||
|
||||
Reference in New Issue
Block a user