diff --git a/CHANGELOG.md b/CHANGELOG.md index 614e3094aa..22f74653b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Extended the account detail dialog to include the change and the performance +- Deprecated the `api/v1/auth-device` endpoint in favor of the `api/v1/auth-devices` endpoint +- Deprecated the `api/v1/exchange-rate` endpoint in favor of the `api/v1/exchange-rates` endpoint +- Upgraded `@modelcontextprotocol/core` and `@modelcontextprotocol/server` from version `2.0.0` to `2.3.1` +- Upgraded `@modelcontextprotocol/node` from version `2.0.0` to `2.1.1` +- Upgraded `@rekog/mcp-nest` from version `2.0.7` to `2.0.8` ## 3.89.0 - 2026-10-20 diff --git a/apps/api/src/app/__snapshots__/app.module.spec.ts.snap b/apps/api/src/app/__snapshots__/app.module.spec.ts.snap index 68defd9062..f5e8b793d4 100644 --- a/apps/api/src/app/__snapshots__/app.module.spec.ts.snap +++ b/apps/api/src/app/__snapshots__/app.module.spec.ts.snap @@ -116,6 +116,15 @@ exports[`AppModule should keep the security of each route 1`] = ` "interceptors": [], "permission": "deleteAuthDevice", }, + "DELETE /auth-devices/:id": { + "allowDuringImpersonation": true, + "guards": [ + "AuthGuard('jwt')", + "HasPermissionGuard", + ], + "interceptors": [], + "permission": "deleteAuthDevice", + }, "DELETE /benchmarks/:dataSource/:symbol": { "allowDuringImpersonation": true, "guards": [ @@ -489,6 +498,13 @@ exports[`AppModule should keep the security of each route 1`] = ` ], "interceptors": [], }, + "GET /exchange-rates/:symbol/:dateString": { + "guards": [ + "AuthGuard('jwt')", + "HasPermissionGuard", + ], + "interceptors": [], + }, "GET /export": { "guards": [ "AuthGuard('jwt')", diff --git a/apps/api/src/app/app.module.ts b/apps/api/src/app/app.module.ts index 4286bf7870..7cfba8455c 100644 --- a/apps/api/src/app/app.module.ts +++ b/apps/api/src/app/app.module.ts @@ -41,15 +41,16 @@ import { ActivitiesModule } from './activities/activities.module'; import { AdminModule } from './admin/admin.module'; import { AppController } from './app.controller'; import { AssetModule } from './asset/asset.module'; -import { AuthDeviceModule } from './auth-device/auth-device.module'; import { AuthModule } from './auth/auth.module'; import { CacheModule } from './cache/cache.module'; import { AiModule } from './endpoints/ai/ai.module'; import { ApiKeysModule } from './endpoints/api-keys/api-keys.module'; import { AssetProfilesModule } from './endpoints/asset-profiles/asset-profiles.module'; import { AssetsModule } from './endpoints/assets/assets.module'; +import { AuthDevicesModule } from './endpoints/auth-devices/auth-devices.module'; import { BenchmarksModule } from './endpoints/benchmarks/benchmarks.module'; import { GhostfolioModule } from './endpoints/data-providers/ghostfolio/ghostfolio.module'; +import { ExchangeRatesModule } from './endpoints/exchange-rates/exchange-rates.module'; import { MarketDataModule } from './endpoints/market-data/market-data.module'; import { McpModule } from './endpoints/mcp/mcp.module'; import { PlatformsModule } from './endpoints/platforms/platforms.module'; @@ -57,7 +58,6 @@ import { PublicModule } from './endpoints/public/public.module'; import { SitemapModule } from './endpoints/sitemap/sitemap.module'; import { TagsModule } from './endpoints/tags/tags.module'; import { WatchlistModule } from './endpoints/watchlist/watchlist.module'; -import { ExchangeRateModule } from './exchange-rate/exchange-rate.module'; import { ExportModule } from './export/export.module'; import { HealthModule } from './health/health.module'; import { ImportModule } from './import/import.module'; @@ -80,7 +80,7 @@ import { UserModule } from './user/user.module'; AssetProfilesModule, AssetModule, AssetsModule, - AuthDeviceModule, + AuthDevicesModule, AuthModule, BenchmarksModule, BullBoardModule.forRoot({ @@ -119,8 +119,8 @@ import { UserModule } from './user/user.module'; DataProviderModule, EventEmitterModule.forRoot(), EventsModule, - ExchangeRateModule, ExchangeRateDataModule, + ExchangeRatesModule, ExportModule, GhostfolioModule, HealthModule, diff --git a/apps/api/src/app/auth-device/auth-device.module.ts b/apps/api/src/app/auth-device/auth-device.module.ts deleted file mode 100644 index 515efa155c..0000000000 --- a/apps/api/src/app/auth-device/auth-device.module.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { AuthDeviceController } from '@ghostfolio/api/app/auth-device/auth-device.controller'; -import { AuthDeviceService } from '@ghostfolio/api/app/auth-device/auth-device.service'; -import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module'; - -import { Module } from '@nestjs/common'; -import { JwtModule } from '@nestjs/jwt'; - -@Module({ - controllers: [AuthDeviceController], - imports: [ - JwtModule.register({ - secret: process.env.JWT_SECRET_KEY, - signOptions: { expiresIn: '180 days' } - }), - PrismaModule - ], - providers: [AuthDeviceService] -}) -export class AuthDeviceModule {} diff --git a/apps/api/src/app/auth/auth.module.ts b/apps/api/src/app/auth/auth.module.ts index 1eafdb6091..afeebe98d0 100644 --- a/apps/api/src/app/auth/auth.module.ts +++ b/apps/api/src/app/auth/auth.module.ts @@ -1,9 +1,9 @@ -import { AuthDeviceService } from '@ghostfolio/api/app/auth-device/auth-device.service'; import { WebAuthService } from '@ghostfolio/api/app/auth/web-auth.service'; import { SubscriptionModule } from '@ghostfolio/api/app/subscription/subscription.module'; import { UserModule } from '@ghostfolio/api/app/user/user.module'; import { ApiKeyService } from '@ghostfolio/api/services/api-key/api-key.service'; import { ApiModule } from '@ghostfolio/api/services/api/api.module'; +import { AuthDeviceModule } from '@ghostfolio/api/services/auth-device/auth-device.module'; import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { FetchModule } from '@ghostfolio/api/services/fetch/fetch.module'; @@ -29,6 +29,7 @@ import { OidcStrategy } from './oidc.strategy'; controllers: [AuthController], imports: [ ApiModule, + AuthDeviceModule, ConfigurationModule, FetchModule, JwtModule.register({ @@ -45,7 +46,6 @@ import { OidcStrategy } from './oidc.strategy'; providers: [ ApiKeyService, ApiKeyStrategy, - AuthDeviceService, AuthService, GoogleStrategy, JwtStrategy, diff --git a/apps/api/src/app/auth/web-auth.service.ts b/apps/api/src/app/auth/web-auth.service.ts index fe9a9467b2..3bae3de88f 100644 --- a/apps/api/src/app/auth/web-auth.service.ts +++ b/apps/api/src/app/auth/web-auth.service.ts @@ -1,7 +1,7 @@ -import { AuthDeviceService } from '@ghostfolio/api/app/auth-device/auth-device.service'; import { PortfolioSnapshotValue } from '@ghostfolio/api/app/portfolio/interfaces/snapshot-value.interface'; import { UserService } from '@ghostfolio/api/app/user/user.service'; import { ApiService } from '@ghostfolio/api/services/api/api.service'; +import { AuthDeviceService } from '@ghostfolio/api/services/auth-device/auth-device.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { RedisCacheService } from '@ghostfolio/api/services/redis-cache/redis-cache.service'; diff --git a/apps/api/src/app/auth-device/auth-device.controller.ts b/apps/api/src/app/endpoints/auth-devices/auth-devices.controller.ts similarity index 87% rename from apps/api/src/app/auth-device/auth-device.controller.ts rename to apps/api/src/app/endpoints/auth-devices/auth-devices.controller.ts index 509746ca97..7577c16901 100644 --- a/apps/api/src/app/auth-device/auth-device.controller.ts +++ b/apps/api/src/app/endpoints/auth-devices/auth-devices.controller.ts @@ -1,7 +1,7 @@ -import { AuthDeviceService } from '@ghostfolio/api/app/auth-device/auth-device.service'; import { AllowDuringImpersonation } from '@ghostfolio/api/decorators/allow-during-impersonation.decorator'; import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; +import { AuthDeviceService } from '@ghostfolio/api/services/auth-device/auth-device.service'; import { permissions } from '@ghostfolio/common/permissions'; import type { RequestWithUser } from '@ghostfolio/common/types'; @@ -18,8 +18,12 @@ import { AuthGuard } from '@nestjs/passport'; import { getReasonPhrase, StatusCodes } from 'http-status-codes'; @AllowDuringImpersonation() -@Controller('auth-device') -export class AuthDeviceController { +@Controller([ + 'auth-devices', + /** @deprecated */ + 'auth-device' +]) +export class AuthDevicesController { public constructor( private readonly authDeviceService: AuthDeviceService, @Inject(REQUEST) private readonly request: RequestWithUser diff --git a/apps/api/src/app/endpoints/auth-devices/auth-devices.module.ts b/apps/api/src/app/endpoints/auth-devices/auth-devices.module.ts new file mode 100644 index 0000000000..ce5042d264 --- /dev/null +++ b/apps/api/src/app/endpoints/auth-devices/auth-devices.module.ts @@ -0,0 +1,11 @@ +import { AuthDeviceModule } from '@ghostfolio/api/services/auth-device/auth-device.module'; + +import { Module } from '@nestjs/common'; + +import { AuthDevicesController } from './auth-devices.controller'; + +@Module({ + controllers: [AuthDevicesController], + imports: [AuthDeviceModule] +}) +export class AuthDevicesModule {} diff --git a/apps/api/src/app/exchange-rate/exchange-rate.controller.ts b/apps/api/src/app/endpoints/exchange-rates/exchange-rates.controller.ts similarity index 65% rename from apps/api/src/app/exchange-rate/exchange-rate.controller.ts rename to apps/api/src/app/endpoints/exchange-rates/exchange-rates.controller.ts index 239b4b27a1..7a873b11db 100644 --- a/apps/api/src/app/exchange-rate/exchange-rate.controller.ts +++ b/apps/api/src/app/endpoints/exchange-rates/exchange-rates.controller.ts @@ -1,5 +1,5 @@ import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; -import { DataProviderHistoricalResponse } from '@ghostfolio/common/interfaces'; +import { ExchangeRateResponse } from '@ghostfolio/common/interfaces'; import { Controller, @@ -12,12 +12,16 @@ import { AuthGuard } from '@nestjs/passport'; import { parseISO } from 'date-fns'; import { StatusCodes, getReasonPhrase } from 'http-status-codes'; -import { ExchangeRateService } from './exchange-rate.service'; +import { ExchangeRatesService } from './exchange-rates.service'; -@Controller('exchange-rate') -export class ExchangeRateController { +@Controller([ + 'exchange-rates', + /** @deprecated */ + 'exchange-rate' +]) +export class ExchangeRatesController { public constructor( - private readonly exchangeRateService: ExchangeRateService + private readonly exchangeRatesService: ExchangeRatesService ) {} @Get(':symbol/:dateString') @@ -25,10 +29,10 @@ export class ExchangeRateController { public async getExchangeRate( @Param('dateString') dateString: string, @Param('symbol') symbol: string - ): Promise { + ): Promise { const date = parseISO(dateString); - const exchangeRate = await this.exchangeRateService.getExchangeRate({ + const exchangeRate = await this.exchangeRatesService.getExchangeRate({ date, symbol }); diff --git a/apps/api/src/app/endpoints/exchange-rates/exchange-rates.module.ts b/apps/api/src/app/endpoints/exchange-rates/exchange-rates.module.ts new file mode 100644 index 0000000000..c143ddc336 --- /dev/null +++ b/apps/api/src/app/endpoints/exchange-rates/exchange-rates.module.ts @@ -0,0 +1,13 @@ +import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.module'; + +import { Module } from '@nestjs/common'; + +import { ExchangeRatesController } from './exchange-rates.controller'; +import { ExchangeRatesService } from './exchange-rates.service'; + +@Module({ + controllers: [ExchangeRatesController], + imports: [ExchangeRateDataModule], + providers: [ExchangeRatesService] +}) +export class ExchangeRatesModule {} diff --git a/apps/api/src/app/exchange-rate/exchange-rate.service.ts b/apps/api/src/app/endpoints/exchange-rates/exchange-rates.service.ts similarity index 94% rename from apps/api/src/app/exchange-rate/exchange-rate.service.ts rename to apps/api/src/app/endpoints/exchange-rates/exchange-rates.service.ts index d70fd534c0..e66cc591ae 100644 --- a/apps/api/src/app/exchange-rate/exchange-rate.service.ts +++ b/apps/api/src/app/endpoints/exchange-rates/exchange-rates.service.ts @@ -3,7 +3,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate- import { Injectable } from '@nestjs/common'; @Injectable() -export class ExchangeRateService { +export class ExchangeRatesService { public constructor( private readonly exchangeRateDataService: ExchangeRateDataService ) {} diff --git a/apps/api/src/app/exchange-rate/exchange-rate.module.ts b/apps/api/src/app/exchange-rate/exchange-rate.module.ts deleted file mode 100644 index e1d9d18917..0000000000 --- a/apps/api/src/app/exchange-rate/exchange-rate.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.module'; - -import { Module } from '@nestjs/common'; - -import { ExchangeRateController } from './exchange-rate.controller'; -import { ExchangeRateService } from './exchange-rate.service'; - -@Module({ - controllers: [ExchangeRateController], - exports: [ExchangeRateService], - imports: [ExchangeRateDataModule], - providers: [ExchangeRateService] -}) -export class ExchangeRateModule {} diff --git a/apps/api/src/services/auth-device/auth-device.module.ts b/apps/api/src/services/auth-device/auth-device.module.ts new file mode 100644 index 0000000000..0594fccb7d --- /dev/null +++ b/apps/api/src/services/auth-device/auth-device.module.ts @@ -0,0 +1,12 @@ +import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module'; + +import { Module } from '@nestjs/common'; + +import { AuthDeviceService } from './auth-device.service'; + +@Module({ + exports: [AuthDeviceService], + imports: [PrismaModule], + providers: [AuthDeviceService] +}) +export class AuthDeviceModule {} diff --git a/apps/api/src/app/auth-device/auth-device.service.ts b/apps/api/src/services/auth-device/auth-device.service.ts similarity index 100% rename from apps/api/src/app/auth-device/auth-device.service.ts rename to apps/api/src/services/auth-device/auth-device.service.ts diff --git a/apps/client/src/app/services/web-authn.service.ts b/apps/client/src/app/services/web-authn.service.ts index b769e8506c..37ba6ebf61 100644 --- a/apps/client/src/app/services/web-authn.service.ts +++ b/apps/client/src/app/services/web-authn.service.ts @@ -66,7 +66,7 @@ export class WebAuthnService { const deviceId = this.getDeviceId(); return this.http - .delete(`/api/v1/auth-device/${deviceId}`) + .delete(`/api/v1/auth-devices/${deviceId}`) .pipe( catchError((error) => { console.warn(`Could not deregister device ${deviceId}`, error); diff --git a/libs/common/src/lib/interfaces/index.ts b/libs/common/src/lib/interfaces/index.ts index c39fd74c55..d17f2377b7 100644 --- a/libs/common/src/lib/interfaces/index.ts +++ b/libs/common/src/lib/interfaces/index.ts @@ -67,6 +67,7 @@ import type { } from './responses/data-provider-response.interface'; import type { DividendsResponse } from './responses/dividends-response.interface'; import type { ResponseError } from './responses/errors.interface'; +import type { ExchangeRateResponse } from './responses/exchange-rate-response.interface'; import type { ExportResponse } from './responses/export-response.interface'; import type { HistoricalResponse } from './responses/historical-response.interface'; import type { ImportResponse } from './responses/import-response.interface'; @@ -150,6 +151,7 @@ export { DataProviderResponse, DividendsResponse, EnhancedAssetProfile, + ExchangeRateResponse, ExportResponse, Filter, FilterGroup, diff --git a/libs/common/src/lib/interfaces/responses/exchange-rate-response.interface.ts b/libs/common/src/lib/interfaces/responses/exchange-rate-response.interface.ts new file mode 100644 index 0000000000..6991fed809 --- /dev/null +++ b/libs/common/src/lib/interfaces/responses/exchange-rate-response.interface.ts @@ -0,0 +1,3 @@ +export interface ExchangeRateResponse { + marketPrice: number; +} diff --git a/libs/ui/src/lib/services/data.service.ts b/libs/ui/src/lib/services/data.service.ts index ca10f91b52..6292f8770a 100644 --- a/libs/ui/src/lib/services/data.service.ts +++ b/libs/ui/src/lib/services/data.service.ts @@ -40,7 +40,6 @@ import { CreateActivityResponse, CreateStripeCheckoutSessionResponse, DataProviderHealthResponse, - DataProviderHistoricalResponse, ExportResponse, Filter, ImportResponse, @@ -309,18 +308,6 @@ export class DataService { ); } - public fetchExchangeRateForDate({ - date, - symbol - }: { - date: Date; - symbol: string; - }) { - return this.http.get( - `/api/v1/exchange-rate/${encodeURIComponent(symbol)}/${format(date, DATE_FORMAT, { in: utc })}` - ); - } - public deleteAccess(aId: string) { return this.http.delete(`/api/v1/access/${aId}`); } diff --git a/package-lock.json b/package-lock.json index 4aa91be806..faf228c31a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,9 +29,9 @@ "@internationalized/number": "3.6.8", "@ionic/angular": "8.8.12", "@keyv/redis": "5.1.6", - "@modelcontextprotocol/core": "2.0.0", - "@modelcontextprotocol/node": "2.0.0", - "@modelcontextprotocol/server": "2.0.0", + "@modelcontextprotocol/core": "2.3.1", + "@modelcontextprotocol/node": "2.1.1", + "@modelcontextprotocol/server": "2.3.1", "@nest-lab/throttler-storage-redis": "1.2.0", "@nestjs/bull": "11.0.5", "@nestjs/cache-manager": "3.1.3", @@ -49,7 +49,7 @@ "@openrouter/ai-sdk-provider": "3.1.0", "@prisma/adapter-pg": "7.10.0", "@prisma/client": "7.10.0", - "@rekog/mcp-nest": "2.0.7", + "@rekog/mcp-nest": "2.0.8", "@simplewebauthn/browser": "14.0.0", "@simplewebauthn/server": "14.0.3", "ai": "7.0.127", @@ -9043,10 +9043,10 @@ } }, "node_modules/@modelcontextprotocol/core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/core/-/core-2.0.0.tgz", - "integrity": "sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==", - "license": "MIT", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/core/-/core-2.3.1.tgz", + "integrity": "sha512-laVmIhPGpWi7rG9q+0UigblRN0Hws/Yjlb6qLFtVqryXVLkc4h+yN8z731POD2LnAGQlFe7/tXhUm7Bi0YB91g==", + "license": "Apache-2.0", "dependencies": { "zod": "^4.2.0" }, @@ -9055,24 +9055,19 @@ } }, "node_modules/@modelcontextprotocol/node": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/node/-/node-2.0.0.tgz", - "integrity": "sha512-Y4hAC2XdGDUdDOCbLDOCA4+aL3NUldjsOWlDL/YwpAxrPhRm1xHd7lZ+mLacvZ9t3PaH28wgNoaLQGrIk1P2pg==", - "license": "MIT", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/node/-/node-2.1.1.tgz", + "integrity": "sha512-EY92OAXN2xYL7tNS/MVsWJW1v8VHAPwl9B4Ca3pCrjmvqyC+S1C/6UHsMxF2GoFPraS5Yyg56vFz9brVpFojMA==", + "license": "Apache-2.0", "dependencies": { - "@hono/node-server": "^1.19.9" + "@hono/node-server": "^1.19.9", + "hono": "^4.11.4" }, "engines": { "node": ">=20" }, "peerDependencies": { - "@modelcontextprotocol/server": "^2.0.0", - "hono": "^4.11.4" - }, - "peerDependenciesMeta": { - "hono": { - "optional": true - } + "@modelcontextprotocol/server": "^2.3.0" } }, "node_modules/@modelcontextprotocol/sdk": { @@ -9116,12 +9111,12 @@ } }, "node_modules/@modelcontextprotocol/server": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/server/-/server-2.0.0.tgz", - "integrity": "sha512-YhHWdHfpFMQfd0prsEnxKeS3Qz3ytIGmsS0sth4KDjnacIT7hxk6hXHkJ9KysxlkvTM+WZAtQbbcUhdoP4Hvtw==", - "license": "MIT", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/server/-/server-2.3.1.tgz", + "integrity": "sha512-e59MfWuSssj6DoQ96JCTqdW1AXT5/XtnTl0WWd6MU1Ka434fFUGGosCLJbGNySDhHGvxQWoRWK137FXYFkYNWw==", + "license": "Apache-2.0", "dependencies": { - "@modelcontextprotocol/core": "2.0.0", + "@modelcontextprotocol/core": "2.3.1", "zod": "^4.2.0" }, "engines": { @@ -12758,9 +12753,9 @@ } }, "node_modules/@rekog/mcp-nest": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@rekog/mcp-nest/-/mcp-nest-2.0.7.tgz", - "integrity": "sha512-8DWrSapEA9Z/YJL9dFmj7sSbemmeQmf0VkGkW6Sn1itwKFf0n9hzTiwWt8XBtZvV5JVDNCtvRZKYYKgNjDcYPg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@rekog/mcp-nest/-/mcp-nest-2.0.8.tgz", + "integrity": "sha512-CDqzT1RBdvCNsRkDthcNPG3nxoy0GbRCrdrK+TjL+90ElL+j65lquBhUQcR37csGyeLa8uLnj/2unLqlKZRzoA==", "license": "MIT", "dependencies": { "multer": "^2.3.0", diff --git a/package.json b/package.json index 305d8fb12a..4348407e87 100644 --- a/package.json +++ b/package.json @@ -73,9 +73,9 @@ "@internationalized/number": "3.6.8", "@ionic/angular": "8.8.12", "@keyv/redis": "5.1.6", - "@modelcontextprotocol/core": "2.0.0", - "@modelcontextprotocol/node": "2.0.0", - "@modelcontextprotocol/server": "2.0.0", + "@modelcontextprotocol/core": "2.3.1", + "@modelcontextprotocol/node": "2.1.1", + "@modelcontextprotocol/server": "2.3.1", "@nest-lab/throttler-storage-redis": "1.2.0", "@nestjs/bull": "11.0.5", "@nestjs/cache-manager": "3.1.3", @@ -93,7 +93,7 @@ "@openrouter/ai-sdk-provider": "3.1.0", "@prisma/adapter-pg": "7.10.0", "@prisma/client": "7.10.0", - "@rekog/mcp-nest": "2.0.7", + "@rekog/mcp-nest": "2.0.8", "@simplewebauthn/browser": "14.0.0", "@simplewebauthn/server": "14.0.3", "ai": "7.0.127",