From 0fc152cc5a49834a725b660c82258d4b0658d9d1 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 26 Sep 2026 10:13:29 +0200 Subject: [PATCH 1/3] Task/filter MCP tools by scopes of access (#7935) * Update @rekog/mcp-nest to version 2.0.7 * Filter MCP tools by scopes of access * Update changelog --- CHANGELOG.md | 2 + .../app/endpoints/mcp/mcp.controller.spec.ts | 105 +++++++++++++++++- .../src/app/endpoints/mcp/mcp.controller.ts | 8 +- apps/api/src/app/endpoints/mcp/mcp.module.ts | 4 +- .../requires-scope-of-access.decorator.ts | 11 +- apps/api/src/guards/access.guard.ts | 8 +- .../src/helper/bearer-token.helper.spec.ts | 31 ++++++ apps/api/src/helper/bearer-token.helper.ts | 29 +++++ package-lock.json | 80 ++++++++++--- package.json | 2 +- 10 files changed, 252 insertions(+), 28 deletions(-) create mode 100644 apps/api/src/helper/bearer-token.helper.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index d69d280038..f4efde2ebb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Improved the server of the Model Context Protocol (MCP) to list only the tools covered by the scopes of the access (experimental) - Refreshed the cryptocurrencies list - Improved the language localization for Catalan (`ca`) +- Upgraded `@rekog/mcp-nest` from version `2.0.2` to `2.0.7` - Upgraded `bull-board` from version `9.9.0` to `9.10.1` - Upgraded `zod` from version `4.5.4` to `4.6.5` diff --git a/apps/api/src/app/endpoints/mcp/mcp.controller.spec.ts b/apps/api/src/app/endpoints/mcp/mcp.controller.spec.ts index f6e1d04383..4fcb92a9be 100644 --- a/apps/api/src/app/endpoints/mcp/mcp.controller.spec.ts +++ b/apps/api/src/app/endpoints/mcp/mcp.controller.spec.ts @@ -1,13 +1,26 @@ import { REQUIRES_SCOPE_KEY } from '@ghostfolio/api/decorators/requires-scope.decorator'; import { McpToolExceptionFilter } from '@ghostfolio/api/filters/mcp-tool-exception.filter'; import { AccessGuard } from '@ghostfolio/api/guards/access.guard'; -import { Scope, scopes } from '@ghostfolio/common/scopes'; +import { getMcpUserOfBearerToken } from '@ghostfolio/api/helper/bearer-token.helper'; +import { + getScopesOfAccess, + getScopesOfAccessLevel, + Scope, + scopes +} from '@ghostfolio/common/scopes'; import { EXCEPTION_FILTERS_METADATA, GUARDS_METADATA } from '@nestjs/common/constants'; -import { MCP_TOOL_METADATA_KEY, ToolMetadata } from '@rekog/mcp-nest'; +import { + AccessMatchMode, + MCP_SCOPES_MATCH_METADATA_KEY, + MCP_SCOPES_METADATA_KEY, + MCP_TOOL_METADATA_KEY, + ToolAuthorizationService, + ToolMetadata +} from '@rekog/mcp-nest'; import { GhostfolioMcpController } from './mcp.controller'; @@ -35,6 +48,41 @@ function getToolMethodNames() { ); } +/** + * Gives the names of the tools which the transport lists for the request. The + * metadata of each tool is read as the transport reads it. + */ +function getNamesOfListedTools(request: unknown) { + const toolAuthorizationService = new ToolAuthorizationService(); + const user = getMcpUserOfBearerToken(request); + + return getToolMethodNames() + .map((methodName) => { + return { + metadata: { + ...getMetadataOfMethod( + MCP_TOOL_METADATA_KEY, + methodName + ), + requiredScopes: getMetadataOfMethod( + MCP_SCOPES_METADATA_KEY, + methodName + ), + requiredScopesMatch: getMetadataOfMethod( + MCP_SCOPES_MATCH_METADATA_KEY, + methodName + ) + } + }; + }) + .filter((tool) => { + return toolAuthorizationService.canAccessTool(user, tool); + }) + .map(({ metadata: { name } }) => { + return name; + }); +} + describe('GhostfolioMcpController', () => { // A tool without the decorator of the scope would be open to every access, // hence a new tool has to declare its scope @@ -71,6 +119,59 @@ describe('GhostfolioMcpController', () => { expect(toolMethodNamesWithoutGuardOfAccess).toEqual([]); }); + it('Lists only the tools to read for an access with the permission "Restricted view"', () => { + expect( + getNamesOfListedTools({ + impersonationOfBearerToken: { + isActive: true, + scopes: getScopesOfAccess({ + scopes: getScopesOfAccessLevel('READ_RESTRICTED'), + type: 'MCP' + }) + } + }) + ).toEqual([ + 'get-accounts', + 'get-activities', + 'get-portfolio', + 'get-watchlist' + ]); + }); + + it('Lists every tool for an access with the permission "Restricted view and manage"', () => { + expect( + getNamesOfListedTools({ + impersonationOfBearerToken: { + isActive: true, + scopes: getScopesOfAccess({ + scopes: getScopesOfAccessLevel( + 'CREATE_READ_RESTRICTED_UPDATE_DELETE' + ), + type: 'MCP' + }) + } + }) + ).toEqual([ + 'get-accounts', + 'get-activities', + 'get-portfolio', + 'get-watchlist', + 'import-activities', + 'search-asset-profiles' + ]); + }); + + it('Lists no tool for an inactive access', () => { + expect( + getNamesOfListedTools({ + impersonationOfBearerToken: { + isActive: false, + scopes: getScopesOfAccessLevel('CREATE_READ_RESTRICTED_UPDATE_DELETE') + } + }) + ).toEqual([]); + }); + it('Requires the scope to create an activity for the tool to import activities', () => { expect( getMetadataOfMethod(REQUIRES_SCOPE_KEY, 'importActivities') diff --git a/apps/api/src/app/endpoints/mcp/mcp.controller.ts b/apps/api/src/app/endpoints/mcp/mcp.controller.ts index dee145015f..802567ad35 100644 --- a/apps/api/src/app/endpoints/mcp/mcp.controller.ts +++ b/apps/api/src/app/endpoints/mcp/mcp.controller.ts @@ -101,12 +101,6 @@ export class GhostfolioMcpController { return this.mcpService.getWatchlist({ userId }); } - /** - * The transport gives the tool to every client, because it filters the list - * of the tools by the scopes of request.user, which a request of an access - * never has. The guard refuses the call itself, hence the description names - * the permission which the access needs. - */ @RequiresScopeOfAccess(scopes.activityCreate) @Tool({ annotations: { @@ -115,7 +109,7 @@ export class GhostfolioMcpController { readOnlyHint: false, title: 'Import activities' }, - description: `Imports activities into the portfolio and gives the number of the imported activities and the number of the skipped activities. Use search-asset-profiles first unless the exact symbol and data source are already known. An activity is skipped if an equal activity is in the portfolio already, hence send each activity one time only: two equal activities of the same call are both imported. The access needs the permission "Restricted view and manage". At most ${MCP_MAX_ACTIVITIES} activities are imported per call, while the instance can have a lower limit, which an error names. An error does not remove the activities of the same call which are imported already, hence get the activities after an error before you import them again.`, + description: `Imports activities into the portfolio and gives the number of the imported activities and the number of the skipped activities. Use search-asset-profiles first unless the exact symbol and data source are already known. An activity is skipped if an equal activity is in the portfolio already, hence send each activity one time only: two equal activities of the same call are both imported. At most ${MCP_MAX_ACTIVITIES} activities are imported per call, while the instance can have a lower limit, which an error names. An error does not remove the activities of the same call which are imported already, hence get the activities after an error before you import them again.`, name: 'import-activities', parameters: IMPORT_ACTIVITIES_PARAMETERS }) diff --git a/apps/api/src/app/endpoints/mcp/mcp.module.ts b/apps/api/src/app/endpoints/mcp/mcp.module.ts index be81137f54..1da7a06823 100644 --- a/apps/api/src/app/endpoints/mcp/mcp.module.ts +++ b/apps/api/src/app/endpoints/mcp/mcp.module.ts @@ -2,6 +2,7 @@ import { ImportModule } from '@ghostfolio/api/app/import/import.module'; import { SymbolModule } from '@ghostfolio/api/app/symbol/symbol.module'; import { UserModule } from '@ghostfolio/api/app/user/user.module'; import { environment } from '@ghostfolio/api/environments/environment'; +import { getMcpUserOfBearerToken } from '@ghostfolio/api/helper/bearer-token.helper'; import { ApiModule } from '@ghostfolio/api/services/api/api.module'; import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; @@ -38,8 +39,9 @@ import { McpService } from './mcp.service'; return new McpStrategy({ instructions: - 'Ghostfolio is a wealth management application. The tools read the portfolio and the watchlist of the user who granted the access and import activities into the portfolio. They give no quantity and no monetary value (except the unit price of an activity).', + 'Ghostfolio is a wealth management application. The tools read the portfolio and the watchlist of the user who granted the access and import activities into the portfolio. They give no quantity and no monetary value (except the unit price of an activity). Only the tools which the permission of the access covers are listed. To import activities, the access needs the permission "Restricted view and manage".', name: 'ghostfolio', + resolveUser: getMcpUserOfBearerToken, title: 'Ghostfolio', transports: [ new StreamableHttpTransport({ diff --git a/apps/api/src/decorators/requires-scope-of-access.decorator.ts b/apps/api/src/decorators/requires-scope-of-access.decorator.ts index b76f1441c1..f0d35effcb 100644 --- a/apps/api/src/decorators/requires-scope-of-access.decorator.ts +++ b/apps/api/src/decorators/requires-scope-of-access.decorator.ts @@ -4,15 +4,24 @@ import { ScopeGuard } from '@ghostfolio/api/guards/scope.guard'; import { Scope } from '@ghostfolio/common/scopes'; import { applyDecorators, SetMetadata, UseGuards } from '@nestjs/common'; +import { ToolScopes } from '@rekog/mcp-nest'; /** * Marks a handler which requires the given scopes of an access, but no * authenticated user. The access itself is the credential, hence a client of * the model context protocol can use it. + * + * The same scopes are declared to the transport of the model context + * protocol, which lists a tool only for an access whose scopes cover it. The + * transport refuses the call of a tool which it does not list with a protocol + * error before the guards and the filter of the exceptions run. */ -export function RequiresScopeOfAccess(...requiredScopes: Scope[]) { +export function RequiresScopeOfAccess(scope: Scope, ...otherScopes: Scope[]) { + const requiredScopes = [scope, ...otherScopes]; + return applyDecorators( SetMetadata(REQUIRES_SCOPE_KEY, requiredScopes), + ToolScopes(requiredScopes), UseGuards(AccessGuard, ScopeGuard) ); } diff --git a/apps/api/src/guards/access.guard.ts b/apps/api/src/guards/access.guard.ts index 87a1f24692..f57c5a5b85 100644 --- a/apps/api/src/guards/access.guard.ts +++ b/apps/api/src/guards/access.guard.ts @@ -1,3 +1,4 @@ +import { getActiveImpersonationOfBearerToken } from '@ghostfolio/api/helper/bearer-token.helper'; import { getRequest } from '@ghostfolio/api/helper/execution-context.helper'; import type { RequestWithUser } from '@ghostfolio/common/types'; @@ -28,14 +29,17 @@ export class AccessGuard implements CanActivate { public canActivate(context: ExecutionContext) { const request = getRequest(context); - if (!request?.impersonationOfBearerToken?.isActive) { + const impersonationOfBearerToken = + getActiveImpersonationOfBearerToken(request); + + if (!impersonationOfBearerToken) { throw new HttpException( getReasonPhrase(StatusCodes.FORBIDDEN), StatusCodes.FORBIDDEN ); } - request.impersonation = request.impersonationOfBearerToken; + request.impersonation = impersonationOfBearerToken; return true; } diff --git a/apps/api/src/helper/bearer-token.helper.spec.ts b/apps/api/src/helper/bearer-token.helper.spec.ts new file mode 100644 index 0000000000..e2f48ff5bb --- /dev/null +++ b/apps/api/src/helper/bearer-token.helper.spec.ts @@ -0,0 +1,31 @@ +import { scopes } from '@ghostfolio/common/scopes'; + +import { getMcpUserOfBearerToken } from './bearer-token.helper'; + +describe('getMcpUserOfBearerToken', () => { + it('should give the scopes of an active access', () => { + expect( + getMcpUserOfBearerToken({ + impersonationOfBearerToken: { + isActive: true, + scopes: [scopes.portfolioRead] + } + }) + ).toEqual({ scopes: [scopes.portfolioRead] }); + }); + + it('should give no user for an inactive access', () => { + expect( + getMcpUserOfBearerToken({ + impersonationOfBearerToken: { + isActive: false, + scopes: [scopes.portfolioRead] + } + }) + ).toBeUndefined(); + }); + + it('should give no user without an access', () => { + expect(getMcpUserOfBearerToken({})).toBeUndefined(); + }); +}); diff --git a/apps/api/src/helper/bearer-token.helper.ts b/apps/api/src/helper/bearer-token.helper.ts index 5641016f5b..47be1e69b6 100644 --- a/apps/api/src/helper/bearer-token.helper.ts +++ b/apps/api/src/helper/bearer-token.helper.ts @@ -1,3 +1,5 @@ +import type { RequestWithUser } from '@ghostfolio/common/types'; + const PREFIX_OF_BEARER_TOKEN = 'bearer '; /** @@ -16,3 +18,30 @@ export function getAccessIdOfBearerToken(authorization?: string) { ? value.slice(PREFIX_OF_BEARER_TOKEN.length).trim() || undefined : undefined; } + +/** + * Gives the context of the access which the authorization middleware of the + * model context protocol resolved from the bearer token, but only while the + * access is active + */ +export function getActiveImpersonationOfBearerToken( + request?: Pick +) { + return request?.impersonationOfBearerToken?.isActive + ? request.impersonationOfBearerToken + : undefined; +} + +/** + * Gives the user which the transport of the model context protocol evaluates + * to list and to call the tools. It carries the scopes of the active access, + * hence the transport lists only the tools which the access covers. + */ +export function getMcpUserOfBearerToken(request: unknown) { + const impersonationOfBearerToken = + getActiveImpersonationOfBearerToken(request); + + return impersonationOfBearerToken + ? { scopes: impersonationOfBearerToken.scopes } + : undefined; +} diff --git a/package-lock.json b/package-lock.json index 9ed3b35966..9469e56421 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,7 +49,7 @@ "@openrouter/ai-sdk-provider": "3.0.0", "@prisma/adapter-pg": "7.10.0", "@prisma/client": "7.10.0", - "@rekog/mcp-nest": "2.0.2", + "@rekog/mcp-nest": "2.0.7", "@simplewebauthn/browser": "13.3.0", "@simplewebauthn/server": "13.3.1", "ai": "7.0.37", @@ -13614,14 +13614,13 @@ } }, "node_modules/@rekog/mcp-nest": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@rekog/mcp-nest/-/mcp-nest-2.0.2.tgz", - "integrity": "sha512-kuye6wmRk5Gw4KZSCSXd83cWznRw4eFbvNUXsd8+1dYcS4uWKVVbRvxQIKNCyxc2UcljpsmLpnksr1NCRn3YAQ==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@rekog/mcp-nest/-/mcp-nest-2.0.7.tgz", + "integrity": "sha512-8DWrSapEA9Z/YJL9dFmj7sSbemmeQmf0VkGkW6Sn1itwKFf0n9hzTiwWt8XBtZvV5JVDNCtvRZKYYKgNjDcYPg==", "license": "MIT", "dependencies": { - "multer": "^2.2.0", - "path-to-regexp": "^8.4.2", - "rxjs": "^7.8.2" + "multer": "^2.3.0", + "path-to-regexp": "^8.4.2" }, "peerDependencies": { "@modelcontextprotocol/core": "^2.0.0-beta.5", @@ -13630,9 +13629,10 @@ "@nestjs/common": ">=9.0.0", "@nestjs/core": ">=9.0.0", "@nestjs/microservices": ">=9.0.0", - "@nestjs/platform-fastify": "^11.1.5", + "@nestjs/platform-fastify": "^11.1.5 || ^12.0.0", "express": ">=4.0.0", "reflect-metadata": "^0.2.2", + "rxjs": "^7.1.0", "zod": "^4.3.5" }, "peerDependenciesMeta": { @@ -13641,13 +13641,65 @@ } } }, - "node_modules/@rekog/mcp-nest/node_modules/rxjs": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", - "license": "Apache-2.0", + "node_modules/@rekog/mcp-nest/node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@rekog/mcp-nest/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@rekog/mcp-nest/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { - "tslib": "^2.1.0" + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@rekog/mcp-nest/node_modules/multer": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/multer/-/multer-2.4.0.tgz", + "integrity": "sha512-7dqa0ZcFfzbefdTuIkzOSMvZWC0J7FLqBOjJUZvDCXShIURWKxAyTT1wHhnE5q19c7jOJf43IYYKjBmZVZmvhg==", + "license": "MIT", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.6.0", + "type-is": "^1.6.18" + }, + "engines": { + "node": ">= 10.16.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/@rekog/mcp-nest/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" } }, "node_modules/@rolldown/binding-android-arm64": { diff --git a/package.json b/package.json index 83aff10108..638fd1ed10 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "@openrouter/ai-sdk-provider": "3.0.0", "@prisma/adapter-pg": "7.10.0", "@prisma/client": "7.10.0", - "@rekog/mcp-nest": "2.0.2", + "@rekog/mcp-nest": "2.0.7", "@simplewebauthn/browser": "13.3.0", "@simplewebauthn/server": "13.3.1", "ai": "7.0.37", From 3cd7c1d093689d22026f1d33fa4fdf2e9ca27ab2 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 26 Sep 2026 10:14:36 +0200 Subject: [PATCH 2/3] Task/extend personal finance tools with last update date (#7942) Extend with last update date --- libs/common/src/lib/personal-finance-tools.ts | 274 +++++++++++++++++- 1 file changed, 258 insertions(+), 16 deletions(-) diff --git a/libs/common/src/lib/personal-finance-tools.ts b/libs/common/src/lib/personal-finance-tools.ts index fcc4901de1..f713871dc8 100644 --- a/libs/common/src/lib/personal-finance-tools.ts +++ b/libs/common/src/lib/personal-finance-tools.ts @@ -32,6 +32,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['MACOS', 'WINDOWS'], pricingPerYear: '$44.95', slogan: 'Lifetime Personal Finance Control, One Single Payment.', + updatedAt: '2026-07-05', url: 'https://www.mechcad.net' }, { @@ -39,6 +40,7 @@ export const personalFinanceTools: Product[] = ( key: 'addepar', name: 'Addepar', slogan: 'Transform your business with Addepar', + updatedAt: '2026-08-28', url: 'https://addepar.com' }, { @@ -72,6 +74,7 @@ export const personalFinanceTools: Product[] = ( key: 'akkuro', name: 'Akkuro', slogan: 'Composable Banking', + updatedAt: '2026-07-09', url: 'https://akkuro.com' }, { @@ -83,6 +86,7 @@ export const personalFinanceTools: Product[] = ( name: 'AllInvestView', platforms: ['WEB'], slogan: 'All your Investments in One View', + updatedAt: '2026-07-05', url: 'https://www.allinvestview.com' }, { @@ -94,6 +98,7 @@ export const personalFinanceTools: Product[] = ( name: 'Allvue Systems', origin: 'US', slogan: 'Investment Software Suite', + updatedAt: '2026-07-05', url: 'https://www.allvuesystems.com' }, { @@ -115,6 +120,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: 'CHF 99', slogan: 'Manage your entire Swiss wealth in one place', + updatedAt: '2026-08-27', url: 'https://alpgain.ch' }, { @@ -140,6 +146,7 @@ export const personalFinanceTools: Product[] = ( name: 'AlphaTrackr', platforms: ['WEB'], slogan: 'Investment Portfolio Tracking Tool', + updatedAt: '2026-07-05', url: 'https://www.alphatrackr.com' }, { @@ -151,6 +158,7 @@ export const personalFinanceTools: Product[] = ( origin: 'CH', platforms: ['WEB'], slogan: 'Simplicity for Complex Wealth', + updatedAt: '2026-07-05', url: 'https://altoo.io' }, { @@ -163,6 +171,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', platforms: ['WEB'], slogan: 'The wealth platform built for independent advisors', + updatedAt: '2026-07-05', url: 'https://altruist.com' }, { @@ -175,6 +184,7 @@ export const personalFinanceTools: Product[] = ( origin: 'SG', pricingPerYear: '$228', slogan: 'Portfolio Visualizer', + updatedAt: '2026-07-05', url: 'https://amsflow.com' }, { @@ -187,6 +197,7 @@ export const personalFinanceTools: Product[] = ( origin: 'FR', platforms: ['WEB'], slogan: 'The investment copilot with no conflict of interest', + updatedAt: '2026-08-16', url: 'https://anantys.com' }, { @@ -201,6 +212,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$120', slogan: 'Analyze and track your portfolio.', + updatedAt: '2026-07-05', url: 'https://anlage.app' }, { @@ -238,6 +250,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', platforms: ['WEB'], slogan: 'The Intelligent Family Office Suite', + updatedAt: '2026-07-05', url: 'https://www.asseta.ai' }, { @@ -247,6 +260,7 @@ export const personalFinanceTools: Product[] = ( name: 'Atominvest', origin: 'GB', slogan: 'Portfolio Management', + updatedAt: '2026-07-05', url: 'https://www.atominvest.co' }, { @@ -260,6 +274,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$47.99', slogan: 'The Smarter Way to Track Your Finances', + updatedAt: '2026-07-05', url: 'https://www.balancepro.app' }, { @@ -273,6 +288,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '€39.99', slogan: 'L’app tout-en-1 pour mieux gérer son argent', + updatedAt: '2026-08-17', url: 'https://www.bankin.com' }, { @@ -285,6 +301,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['IOS', 'MACOS'], pricingPerYear: '$59.99', slogan: 'Proactive money management app for macOS & iOS', + updatedAt: '2026-07-05', url: 'https://www.banktivity.com' }, { @@ -292,6 +309,7 @@ export const personalFinanceTools: Product[] = ( key: 'basil-wealth', name: 'Basil', platforms: ['WEB'], + updatedAt: '2026-07-05', url: 'https://basilwealth.com' }, { @@ -303,6 +321,7 @@ export const personalFinanceTools: Product[] = ( name: 'Basil Finance', slogan: 'The ultimate solution for tracking and managing your investments', + updatedAt: '2026-07-05', url: 'https://basil.fi' }, { @@ -316,6 +335,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS'], pricingPerYear: '$49.99', slogan: 'Stop guessing your net worth', + updatedAt: '2026-08-27', url: 'https://www.get-beam.app' }, { @@ -329,6 +349,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$100', slogan: 'Stock Portfolio Tracker for Smart Investors', + updatedAt: '2026-07-05', url: 'https://beanvest.com' }, { @@ -368,6 +389,7 @@ export const personalFinanceTools: Product[] = ( origin: 'CA', platforms: ['ANDROID', 'IOS'], slogan: 'Be Money Mindful', + updatedAt: '2026-08-17', url: 'https://billi.webflow.io' }, { @@ -380,6 +402,7 @@ export const personalFinanceTools: Product[] = ( origin: 'CA', platforms: ['ANDROID', 'IOS'], slogan: 'Real Portfolios, Trades & Market Insights', + updatedAt: '2026-08-16', url: 'https://blossomsocial.com' }, { @@ -392,6 +415,7 @@ export const personalFinanceTools: Product[] = ( origin: 'CH', platforms: ['ANDROID', 'IOS'], slogan: 'Schweizer Budget App für einfache & smarte Budgetplanung', + updatedAt: '2026-07-05', url: 'https://www.bluebudget.ch' }, { @@ -406,6 +430,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$144', slogan: 'Take control with retirement planning tools that begin with you', + updatedAt: '2026-07-05', url: 'https://www.boldin.com' }, { @@ -453,6 +478,7 @@ export const personalFinanceTools: Product[] = ( origin: 'CZ', platforms: ['ANDROID', 'IOS', 'WEB'], slogan: 'Your Finances in One Place', + updatedAt: '2026-08-18', url: 'https://budgetbakers.com' }, { @@ -462,6 +488,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', platforms: ['WEB'], slogan: 'Giving life to your finance!', + updatedAt: '2026-07-05', url: 'https://www.budgetpulse.com' }, { @@ -476,6 +503,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '$96', regions: ['Global'], slogan: 'Take control of your financial future', + updatedAt: '2026-07-09', url: 'https://www.buxfer.com' }, { @@ -488,6 +516,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€80', slogan: 'Optimize your investments performance', + updatedAt: '2026-07-05', url: 'https://www.mycapitally.com' }, { @@ -499,13 +528,15 @@ export const personalFinanceTools: Product[] = ( note: 'CapMon.org was discontinued in 2023', origin: 'DE', platforms: ['WEB'], - slogan: 'Next Generation Assets Tracking' + slogan: 'Next Generation Assets Tracking', + updatedAt: '2026-07-05' }, { categories: ['INVESTMENT_RESEARCH'], key: 'cbonds', name: 'Cbonds', slogan: 'Financial Market Data Hub', + updatedAt: '2026-08-28', url: 'https://cbonds.com' }, { @@ -513,6 +544,7 @@ export const personalFinanceTools: Product[] = ( key: 'chaikin-analytics', name: 'Chaikin Analytics', slogan: 'Investing tools and research from Marc Chaikin & Team', + updatedAt: '2026-08-28', url: 'https://chaikinanalytics.com' }, { @@ -522,7 +554,8 @@ export const personalFinanceTools: Product[] = ( key: 'cleverbilling', languages: ['Español'], name: 'CleverBilling', - slogan: 'Toma el control total de tus finanzas.' + slogan: 'Toma el control total de tus finanzas.', + updatedAt: '2025-07-27' }, { categories: ['WEALTH_MANAGEMENT'], @@ -532,6 +565,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', platforms: ['WEB'], slogan: 'Next-Level Portfolio Monitoring', + updatedAt: '2026-07-05', url: 'https://www.cobalt.pe' }, { @@ -545,6 +579,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$168', slogan: 'Manage All Your Wallets & Exchanges From One Place', + updatedAt: '2026-07-05', url: 'https://coinstats.app' }, { @@ -559,6 +594,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$120', slogan: 'The leading Crypto Portfolio Tracker & Tax Calculator', + updatedAt: '2026-07-05', url: 'https://cointracking.info' }, { @@ -579,6 +615,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', platforms: ['IOS', 'WEB'], slogan: 'Modern Wealth & Investment Management', + updatedAt: '2026-07-05', url: 'https://compoundplanning.com' }, { @@ -592,6 +629,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['IOS', 'MACOS', 'WEB'], pricingPerYear: '$95', slogan: 'Do money better with Copilot', + updatedAt: '2026-07-05', url: 'https://www.copilot.money' }, { @@ -604,6 +642,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$9.99', slogan: 'Customizable and Secure Personal Finance App', + updatedAt: '2026-07-05', url: 'https://countabout.com' }, { @@ -656,6 +695,7 @@ export const personalFinanceTools: Product[] = ( name: 'Danelfin', pricingPerYear: '$264', slogan: 'AI-Powered Stock Picking', + updatedAt: '2026-08-28', url: 'https://danelfin.com' }, { @@ -666,6 +706,7 @@ export const personalFinanceTools: Product[] = ( name: 'Danti', origin: 'GB', slogan: 'Digitising Generational Wealth', + updatedAt: '2026-07-05', url: 'https://danti.io' }, { @@ -675,6 +716,7 @@ export const personalFinanceTools: Product[] = ( languages: ['English'], name: 'De.Fi', slogan: 'DeFi Portfolio Tracker', + updatedAt: '2026-07-05', url: 'https://de.fi' }, { @@ -687,6 +729,7 @@ export const personalFinanceTools: Product[] = ( name: 'DeepVest', slogan: 'The AI-Powered Research Platform for Financial Advisors and Investment Managers', + updatedAt: '2026-08-28', url: 'https://www.deepvest.ai' }, { @@ -701,6 +744,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$99', slogan: 'DeFi Portfolio Tracker for All Chains', + updatedAt: '2026-07-05', url: 'https://zerion.io/defi-portfolio-tracker' }, { @@ -715,6 +759,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€24', slogan: 'Democratizing Data Analytics', + updatedAt: '2026-07-05', url: 'https://capitalyse.app/app/degiro' }, { @@ -729,6 +774,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'MACOS', 'WEB', 'WINDOWS'], pricingPerYear: '$150', slogan: 'The app to track all your investments. Make smart moves only.', + updatedAt: '2026-07-05', url: 'https://delta.app' }, { @@ -741,6 +787,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$49.90', slogan: 'Dividend Portfolio Tracker', + updatedAt: '2026-07-05', url: 'https://www.digrin.com' }, { @@ -765,6 +812,7 @@ export const personalFinanceTools: Product[] = ( name: 'Dividend Watch', pricingPerYear: '$72', slogan: 'The Essential Dividend and Portfolio Tracker', + updatedAt: '2026-08-28', url: 'https://dividend.watch' }, { @@ -773,6 +821,7 @@ export const personalFinanceTools: Product[] = ( name: 'Dividend Wealth', pricingPerYear: '$99.99', slogan: 'Track Your Dividends Like a Pro', + updatedAt: '2026-08-28', url: 'https://dividend-wealth.com' }, { @@ -801,6 +850,7 @@ export const personalFinanceTools: Product[] = ( name: 'DivTracker', pricingPerYear: '$29.99', slogan: 'Your Ultimate Dividend Tracker', + updatedAt: '2026-08-28', url: 'https://divtracker.app' }, { @@ -815,6 +865,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '€65', slogan: 'Your personal Dividend Calendar', + updatedAt: '2026-07-05', url: 'https://divvydiary.com' }, { @@ -828,6 +879,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'WEB'], pricingPerYear: '€57.48', slogan: 'The Portfolio Tracker that replaces your spreadsheets', + updatedAt: '2026-08-16', url: 'https://www.donkycapital.com' }, { @@ -851,6 +903,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', platforms: ['WEB'], slogan: 'Get answers to your money questions', + updatedAt: '2026-07-05', url: 'https://www.empower.com' }, { @@ -862,6 +915,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', platforms: ['ANDROID', 'IOS', 'WEB'], slogan: 'Portfolio Tracker Designed by Professional Investors', + updatedAt: '2026-07-05', url: 'https://8figures.com' }, { @@ -875,6 +929,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '£41.99', slogan: 'Take control of your money', + updatedAt: '2026-08-17', url: 'https://emma-app.com' }, { @@ -882,6 +937,7 @@ export const personalFinanceTools: Product[] = ( key: 'envestnet', name: 'Envestnet', slogan: 'Everybody Deserves Financial Wellness', + updatedAt: '2026-08-28', url: 'https://www.envestnet.com' }, { @@ -919,6 +975,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', pricingPerYear: '$83.88', slogan: 'Stock Selection Analytics for Investors', + updatedAt: '2026-08-28', url: 'https://epsmomentum.com' }, { @@ -944,6 +1001,7 @@ export const personalFinanceTools: Product[] = ( key: 'etf-action', name: 'ETF Action', slogan: 'Markets through the lens of ETFs', + updatedAt: '2026-08-28', url: 'https://www.etfaction.com' }, { @@ -951,6 +1009,7 @@ export const personalFinanceTools: Product[] = ( key: 'etf-insider', name: 'ETF Insider', slogan: 'Precision asset allocation', + updatedAt: '2026-08-28', url: 'https://etfinsider.co' }, { @@ -959,6 +1018,7 @@ export const personalFinanceTools: Product[] = ( key: 'etf-research-center', name: 'ETF Research Center', slogan: 'A Smarter Approach to Exchange Traded Funds', + updatedAt: '2026-08-28', url: 'https://www.etfrc.com' }, { @@ -981,6 +1041,7 @@ export const personalFinanceTools: Product[] = ( origin: 'CH', platforms: ['WEB'], slogan: 'Your financial superpower', + updatedAt: '2026-07-05', url: 'https://www.etops.com' }, { @@ -993,6 +1054,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', platforms: ['ANDROID', 'IOS', 'WEB'], slogan: 'Plan, track, find more margin', + updatedAt: '2026-07-05', url: 'https://www.ramseysolutions.com/money/everydollar' }, { @@ -1025,6 +1087,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$100', slogan: 'All your wealth, in one place.', + updatedAt: '2026-07-05', url: 'https://www.exirio.com' }, { @@ -1035,6 +1098,7 @@ export const personalFinanceTools: Product[] = ( name: 'Expersoft', origin: 'CH', slogan: 'Investment Management Platforms', + updatedAt: '2026-07-05', url: 'https://www.expersoft.com' }, { @@ -1049,6 +1113,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '€89.99', slogan: 'Die besten ETFs finden, vergleichen und beobachten', + updatedAt: '2026-08-16', url: 'https://extraetf.com' }, { @@ -1056,6 +1121,7 @@ export const personalFinanceTools: Product[] = ( key: 'factorstoday', name: 'FactorsToday', slogan: 'Modern Quantitative Analysis', + updatedAt: '2026-08-28', url: 'https://www.factorstoday.com' }, { @@ -1064,6 +1130,7 @@ export const personalFinanceTools: Product[] = ( name: 'FAST Graphs', pricingPerYear: '$191.40', slogan: 'Invest Intelligently with the Most Powerful Stock Analysis Tool', + updatedAt: '2026-08-28', url: 'https://www.fastgraphs.com' }, { @@ -1078,6 +1145,7 @@ export const personalFinanceTools: Product[] = ( origin: 'CA', pricingPerYear: '$300', slogan: 'Make better investments.', + updatedAt: '2026-07-05', url: 'https://fey.com' }, { @@ -1103,6 +1171,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', pricingPerYear: '$115', slogan: 'Flexible Financial Management', + updatedAt: '2026-06-04', url: 'https://www.fina.money' }, { @@ -1131,6 +1200,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '€69.99', slogan: 'Portfolio Tracker für dein Vermögen', + updatedAt: '2026-07-05', url: 'https://www.finanzfluss.de/copilot' }, { @@ -1144,6 +1214,7 @@ export const personalFinanceTools: Product[] = ( origin: 'DE', platforms: ['ANDROID', 'IOS', 'MACOS'], slogan: 'Finanzen. Magisch. Einfach.', + updatedAt: '2026-07-05', url: 'https://www.finanzguru.de' }, { @@ -1155,6 +1226,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', platforms: ['ANDROID', 'IOS', 'WEB'], slogan: 'Real-Time Portfolio Tracker & Stock Tracker', + updatedAt: '2026-07-05', url: 'https://finary.com' }, { @@ -1169,6 +1241,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS'], slogan: 'The most convenient mobile application for personal finance accounting', + updatedAt: '2026-07-05', url: 'https://finateka.com' }, { @@ -1178,6 +1251,7 @@ export const personalFinanceTools: Product[] = ( name: 'Fincake', origin: 'VG', slogan: 'Easy-to-use Portfolio Tracker', + updatedAt: '2026-07-05', url: 'https://fincake.io' }, { @@ -1189,6 +1263,7 @@ export const personalFinanceTools: Product[] = ( origin: 'DE', platforms: ['WEB'], slogan: 'Wealth Management Software', + updatedAt: '2026-07-05', url: 'https://fincite.de' }, { @@ -1212,6 +1287,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$84.00', slogan: 'Sync your bank to spreadsheets', + updatedAt: '2026-08-17', url: 'https://fintable.io' }, { @@ -1219,6 +1295,7 @@ export const personalFinanceTools: Product[] = ( key: 'fintel', name: 'Fintel', slogan: 'Essential Tools for Investors and Traders', + updatedAt: '2026-08-28', url: 'https://fintel.io' }, { @@ -1247,6 +1324,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', platforms: ['ANDROID', 'IOS', 'WEB'], slogan: 'Grow your wealth in a stress-free way', + updatedAt: '2026-07-05', url: 'https://www.getfinvest.com' }, { @@ -1257,6 +1335,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '$299.50', slogan: 'Stock screener for investors and traders, financial visualizations', + updatedAt: '2026-08-28', url: 'https://finviz.com' }, { @@ -1269,6 +1348,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '€69.99', slogan: 'Personal finances, simplified', + updatedAt: '2026-07-05', url: 'https://finwiseapp.io' }, { @@ -1282,6 +1362,7 @@ export const personalFinanceTools: Product[] = ( origin: 'UA', pricingPerYear: '$40', slogan: 'A simple solution to track your wealth online', + updatedAt: '2026-07-05', url: 'https://firekit.space' }, { @@ -1289,6 +1370,7 @@ export const personalFinanceTools: Product[] = ( key: 'fiscal.ai', name: 'Fiscal.ai', slogan: 'The Modern Financial Data Platform', + updatedAt: '2026-08-28', url: 'https://fiscal.ai' }, { @@ -1302,6 +1384,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS'], pricingPerYear: '€23.88', slogan: 'Your money on autopilot', + updatedAt: '2026-08-17', url: 'https://flowyour.money' }, { @@ -1314,6 +1397,7 @@ export const personalFinanceTools: Product[] = ( origin: 'AT', pricingPerYear: '$65', slogan: 'Take control over your investments', + updatedAt: '2026-07-05', url: 'https://www.folishare.com' }, { @@ -1341,6 +1425,7 @@ export const personalFinanceTools: Product[] = ( origin: 'AU', platforms: ['ANDROID', 'IOS'], slogan: 'Feel good about money', + updatedAt: '2026-08-17', url: 'https://www.frollo.com.au' }, { @@ -1354,6 +1439,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WINDOWS'], pricingPerYear: '$99', slogan: 'Powerful portfolio management software', + updatedAt: '2026-07-05', url: 'https://www.fundmanagersoftware.com' }, { @@ -1375,6 +1461,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '$60', regions: ['Global'], slogan: 'Take control of your finances from WhatsApp', + updatedAt: '2026-07-05', url: 'https://gasti.pro' }, { @@ -1404,6 +1491,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '€48', slogan: 'Portfolio Tracker, Analysis & Community', + updatedAt: '2026-07-05', url: 'https://www.getquin.com' }, { @@ -1415,6 +1503,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', platforms: ['ANDROID', 'IOS', 'WEB'], slogan: 'Budget with a why', + updatedAt: '2026-07-05', url: 'https://goodbudget.com' }, { @@ -1425,13 +1514,15 @@ export const personalFinanceTools: Product[] = ( name: 'goSPATZ', note: 'Renamed to Money Peak', origin: 'DE', - slogan: 'Volle Kontrolle über deine Investitionen' + slogan: 'Volle Kontrolle über deine Investitionen', + updatedAt: '2025-04-17' }, { categories: ['INVESTMENT_RESEARCH'], key: 'gurufocus', name: 'GuruFocus', slogan: 'Stock Market Research, Data and Tools', + updatedAt: '2026-08-28', url: 'https://www.gurufocus.com' }, { @@ -1446,6 +1537,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '€59.99', slogan: 'Prenez enfin le contrôle de votre argent', + updatedAt: '2026-07-05', url: 'https://get-gustav.com' }, { @@ -1453,6 +1545,7 @@ export const personalFinanceTools: Product[] = ( key: 'hedgefollow', name: 'HedgeFollow', slogan: 'Follow Hedge Funds & Insiders using 13F filings', + updatedAt: '2026-08-28', url: 'https://hedgefollow.com' }, { @@ -1484,6 +1577,7 @@ export const personalFinanceTools: Product[] = ( origin: 'CH', platforms: ['IOS', 'WEB'], slogan: 'Dein Vermögen im Überblick', + updatedAt: '2026-08-18', url: 'https://www.helvestor.ch' }, { @@ -1496,6 +1590,7 @@ export const personalFinanceTools: Product[] = ( origin: 'DE', platforms: ['ANDROID', 'IOS', 'WEB'], slogan: 'Die All-in-One Lösung für dein Vermögen.', + updatedAt: '2026-07-05', url: 'https://holistic.capital', useAnonymously: true }, @@ -1508,6 +1603,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', platforms: ['ANDROID', 'IOS'], slogan: 'Finance App for Couples', + updatedAt: '2026-07-05', url: 'https://www.honeydue.com' }, { @@ -1517,7 +1613,8 @@ export const personalFinanceTools: Product[] = ( key: 'ibank', name: 'iBank', note: 'Renamed to Banktivity', - origin: 'US' + origin: 'US', + updatedAt: '2026-06-23' }, { founded: 2022, @@ -1526,13 +1623,15 @@ export const personalFinanceTools: Product[] = ( name: 'Income Reign', note: 'Income Reign was discontinued in 2025', origin: 'US', - pricingPerYear: '$120' + pricingPerYear: '$120', + updatedAt: '2025-08-27' }, { categories: ['INVESTMENT_RESEARCH'], hasFreePlan: true, key: 'insidearbitrage', name: 'InsideArbitrage', + updatedAt: '2026-08-28', url: 'https://www.insidearbitrage.com' }, { @@ -1544,13 +1643,15 @@ export const personalFinanceTools: Product[] = ( note: 'Intuit Mint was discontinued in 2023', origin: 'US', pricingPerYear: '$60', - slogan: 'Managing money, made simple' + slogan: 'Managing money, made simple', + updatedAt: '2024-10-19' }, { categories: ['INVESTMENT_RESEARCH'], key: 'invesst', name: 'Invesst', slogan: 'Power Your Portfolio with AI', + updatedAt: '2026-08-28', url: 'https://invesst.ai' }, { @@ -1562,6 +1663,7 @@ export const personalFinanceTools: Product[] = ( origin: 'PK', platforms: ['ANDROID', 'IOS'], slogan: 'Advanced portfolio tracking and stock market information', + updatedAt: '2026-07-05', url: 'https://www.investify.pk' }, { @@ -1626,6 +1728,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['MACOS'], pricingPerYear: '$156', slogan: 'Track all your assets, investments and portfolios in one place', + updatedAt: '2026-07-05', url: 'https://invmon.com', useAnonymously: true }, @@ -1639,6 +1742,7 @@ export const personalFinanceTools: Product[] = ( origin: 'PL', platforms: ['ANDROID', 'IOS', 'WEB'], slogan: 'Inwestujesz? Śledź swój majątek w jednym miejscu', + updatedAt: '2026-08-16', url: 'https://inwestuje.app' }, { @@ -1667,6 +1771,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '€119', slogan: 'ETF portfolios made simple', + updatedAt: '2026-07-05', url: 'https://www.justetf.com' }, { @@ -1678,6 +1783,7 @@ export const personalFinanceTools: Product[] = ( name: 'Koinly', origin: 'SG', slogan: 'Track all your crypto wallets in one place', + updatedAt: '2026-07-05', url: 'https://koinly.io' }, { @@ -1691,6 +1797,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$468', slogan: 'Comprehensive financial data analysis', + updatedAt: '2026-07-05', url: 'https://www.koyfin.com' }, { @@ -1704,6 +1811,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$249', slogan: 'The Time Machine for your Net Worth', + updatedAt: '2026-07-05', url: 'https://www.kubera.com' }, { @@ -1739,6 +1847,7 @@ export const personalFinanceTools: Product[] = ( languages: ['English'], name: 'Kyro', platforms: ['WEB'], + updatedAt: '2026-08-27', url: 'https://my.kyro.app' }, { @@ -1750,6 +1859,7 @@ export const personalFinanceTools: Product[] = ( name: 'Leafs', origin: 'CH', slogan: 'Sustainability insights for wealth managers', + updatedAt: '2026-07-05', url: 'https://leafs.ch' }, { @@ -1763,6 +1873,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS'], pricingPerYear: '£26.99', slogan: 'Couples finances, made easy', + updatedAt: '2026-08-17', url: 'https://www.lumio-app.com' }, { @@ -1774,6 +1885,7 @@ export const personalFinanceTools: Product[] = ( name: 'Lunch Money', origin: 'CA', slogan: 'Delightfully simple personal finance and budgeting', + updatedAt: '2026-07-05', url: 'https://lunchmoney.app' }, { @@ -1787,6 +1899,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$132', slogan: 'AI Investing Assistant', + updatedAt: '2026-07-05', url: 'https://magnifi.com' }, { @@ -1809,6 +1922,7 @@ export const personalFinanceTools: Product[] = ( key: 'marketinout', name: 'MarketInOut', slogan: 'Stock Screener with Backtesting & Advanced Filters', + updatedAt: '2026-08-28', url: 'https://www.marketinout.com' }, { @@ -1816,6 +1930,7 @@ export const personalFinanceTools: Product[] = ( key: 'marketlog', name: 'Marketlog', slogan: 'Stock Portfolio and Investments Tracker', + updatedAt: '2026-08-28', url: 'https://www.marketlog.com' }, { @@ -1831,6 +1946,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '€168', regions: ['Global'], slogan: 'Financial Intelligence Platform', + updatedAt: '2026-07-05', url: 'https://markets.sh' }, { @@ -1838,6 +1954,7 @@ export const personalFinanceTools: Product[] = ( key: 'marketscreener', name: 'MarketScreener', slogan: 'Financial News & Stock Market Quotes', + updatedAt: '2026-08-28', url: 'https://www.marketscreener.com' }, { @@ -1846,6 +1963,7 @@ export const personalFinanceTools: Product[] = ( name: 'MarketXLS', pricingPerYear: '$850', slogan: 'Real-Time Stock Data & Analysis in Excel', + updatedAt: '2026-08-28', url: 'https://marketxls.com' }, { @@ -1855,6 +1973,7 @@ export const personalFinanceTools: Product[] = ( name: 'Masttro', origin: 'US', slogan: 'Your platform for wealth in full view', + updatedAt: '2026-07-05', url: 'https://masttro.com' }, { @@ -1871,6 +1990,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '$145', regions: ['US'], slogan: 'Your financial future, in your control', + updatedAt: '2026-06-04', url: 'https://github.com/maybe-finance/maybe' }, { @@ -1885,6 +2005,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '$204', regions: ['CA', 'US'], slogan: 'The smartest way to track your crypto', + updatedAt: '2026-07-05', url: 'https://www.merlincrypto.com' }, { @@ -1897,6 +2018,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['IOS', 'WEB'], pricingPerYear: '$48', slogan: 'Self-manage your wealth. Get fiduciary advice.', + updatedAt: '2026-07-05', url: 'https://www.mezzi.com' }, { @@ -1906,13 +2028,15 @@ export const personalFinanceTools: Product[] = ( key: 'microsoft-money', name: 'Microsoft Money', note: 'Microsoft Money was discontinued in 2010', - origin: 'US' + origin: 'US', + updatedAt: '2024-10-19' }, { categories: ['INVESTMENT_RESEARCH'], key: 'moatmap', name: 'MoatMap', slogan: 'AI Stock Screening & Equity Research', + updatedAt: '2026-08-28', url: 'https://moatmap.ai' }, { @@ -1926,6 +2050,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$99.99', slogan: 'The modern way to manage your money', + updatedAt: '2026-07-05', url: 'https://www.monarch.com' }, { @@ -1939,6 +2064,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'LINUX', 'MACOS', 'WINDOWS'], pricingPerYear: '$100', slogan: 'Personal Finance Manager for Mac, Windows, and Linux', + updatedAt: '2026-07-05', url: 'https://moneydance.com' }, { @@ -1951,6 +2077,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', pricingPerYear: '$29.99', slogan: 'Personal Accounting Made Easy, Accurate, Comprehensive', + updatedAt: '2026-07-05', url: 'https://www.moneypatrol.com' }, { @@ -1963,6 +2090,7 @@ export const personalFinanceTools: Product[] = ( origin: 'DE', platforms: ['ANDROID', 'IOS', 'WEB'], slogan: 'Dein smarter Finance Assistant', + updatedAt: '2026-07-05', url: 'https://moneypeak.ai' }, { @@ -1975,6 +2103,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['LINUX', 'MACOS', 'WINDOWS'], pricingPerYear: '$59.99', slogan: 'Have total control of your financial life', + updatedAt: '2026-07-05', url: 'https://www.moneyspire.com' }, { @@ -1986,6 +2115,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', platforms: ['IOS', 'MACOS'], slogan: 'Personal Budgeting Software for Mac and iOS', + updatedAt: '2026-07-05', url: 'https://moneywell.app' }, { @@ -2010,6 +2140,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['IOS', 'MACOS'], pricingPerYear: '$29.99', slogan: 'Get money management superpowers', + updatedAt: '2026-07-05', url: 'https://www.wiz.money' }, { @@ -2022,6 +2153,7 @@ export const personalFinanceTools: Product[] = ( note: 'Renamed to Nexafin', pricingPerYear: '$60', slogan: 'Gain financial control and keep your data private.', + updatedAt: '2026-07-05', url: 'https://monse.app' }, { @@ -2036,6 +2168,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$20', slogan: 'Smart, simple, stress-free money tracking.', + updatedAt: '2026-07-05', url: 'https://www.monsy.app' }, { @@ -2064,6 +2197,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], slogan: 'Track your equity, fund, investment trust, ETF and pension investments in one place.', + updatedAt: '2026-07-05', url: 'https://www.morningstar.com/mm' }, { @@ -2083,6 +2217,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '$49.99', slogan: 'Keep track of and visualize your investments throughout your day', + updatedAt: '2026-08-16', url: 'https://peeksoft.co' }, { @@ -2095,6 +2230,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$36', slogan: 'Your Personal Finance Command Center', + updatedAt: '2026-07-05', url: 'https://myfinancetools.io' }, { @@ -2108,6 +2244,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: 'PLN 36.10', slogan: 'Manage all your assets and accounts in one place', + updatedAt: '2026-08-16', url: 'https://myfund.pl' }, { @@ -2121,6 +2258,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$1188', slogan: 'Your Complete Crypto Portfolio, Reimagined', + updatedAt: '2026-07-05', url: 'https://www.nansen.ai/crypto-portfolio-tracker' }, { @@ -2134,6 +2272,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$90', slogan: 'The Intelligent Portfolio Tracker', + updatedAt: '2026-07-05', url: 'https://www.navexa.com' }, { @@ -2155,6 +2294,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '$75', slogan: 'Everything you own. Everything you owe. Everything in one place.', + updatedAt: '2026-09-02', url: 'https://neontra.com' }, { @@ -2166,6 +2306,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€49.99', slogan: 'Your Personal Financial Analyst, powered by AI.', + updatedAt: '2026-07-05', url: 'https://networthy.pro' }, { @@ -2174,6 +2315,7 @@ export const personalFinanceTools: Product[] = ( name: 'Nexafin', platforms: ['WEB'], slogan: 'Your Finances. Finally Clear.', + updatedAt: '2026-07-05', url: 'https://nexafin.com' }, { @@ -2200,6 +2342,7 @@ export const personalFinanceTools: Product[] = ( key: 'okama', name: 'okama', slogan: 'Efficient Frontier for the investment portfolios', + updatedAt: '2026-08-28', url: 'https://okama.io' }, { @@ -2212,6 +2355,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS'], pricingPerYear: '€49.99', slogan: 'Dividend Day Should Feel Like Payday', + updatedAt: '2026-08-28', url: 'https://onlydividends.app' }, { @@ -2295,6 +2439,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '€99.99', regions: ['AT', 'CH', 'DE'], slogan: 'Dein Vermögen immer im Blick', + updatedAt: '2026-07-05', url: 'https://www.parqet.com' }, { @@ -2309,6 +2454,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$99', slogan: 'Autopilot for your Portfolio', + updatedAt: '2026-08-16', url: 'https://passiv.com' }, { @@ -2328,6 +2474,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€49', slogan: 'Votre patrimoine, enfin clair', + updatedAt: '2026-07-05', url: 'https://mypatrice.com' }, { @@ -2338,6 +2485,7 @@ export const personalFinanceTools: Product[] = ( origin: 'SG', platforms: ['IOS'], slogan: 'Feel in control of your money without spreadsheets or shame', + updatedAt: '2026-07-05', url: 'https://peek.money' }, { @@ -2348,6 +2496,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['IOS'], pricingPerYear: '$39.99', slogan: 'Your money. Made simple.', + updatedAt: '2026-07-05', url: 'https://www.getpennies.com' }, { @@ -2374,6 +2523,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€50', slogan: 'Invest smarter, not harder', + updatedAt: '2026-07-05', url: 'https://pinklion.xyz' }, { @@ -2387,6 +2537,7 @@ export const personalFinanceTools: Product[] = ( origin: 'PL', pricingPerYear: '$74', slogan: 'Free dividend tracker for your portfolio', + updatedAt: '2026-07-05', url: 'https://plainzer.com' }, { @@ -2398,6 +2549,7 @@ export const personalFinanceTools: Product[] = ( origin: 'IT', platforms: ['WEB'], slogan: 'Your Personal Finance Hub', + updatedAt: '2026-07-05', url: 'https://www.plannix.co' }, { @@ -2411,6 +2563,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$74.99', slogan: 'Budgeting App & Finance Planner', + updatedAt: '2026-07-05', url: 'https://pocketguard.com' }, { @@ -2426,6 +2579,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '$120', regions: ['Global'], slogan: 'Know where your money is going', + updatedAt: '2026-07-05', url: 'https://www.pocketsmith.com' }, { @@ -2452,6 +2606,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: 'PLN 168', slogan: 'Wszystkie Twoje inwestycje w jednym miejscu', + updatedAt: '2026-08-16', url: 'https://www.portfeo.pl' }, { @@ -2465,6 +2620,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '£120', slogan: 'Know your wealth. Ask it anything.', + updatedAt: '2026-08-13', url: 'https://portfoliocoach.co.uk' }, { @@ -2478,6 +2634,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€60', slogan: 'Manage all your portfolios', + updatedAt: '2026-07-05', url: 'https://portfoliodividendtracker.com' }, { @@ -2491,6 +2648,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['IOS'], slogan: 'Professional stock portfolio tracking for iPhone, iPad and Apple Watch', + updatedAt: '2026-08-16', url: 'https://www.iportfoliotrader.com' }, { @@ -2502,6 +2660,7 @@ export const personalFinanceTools: Product[] = ( name: 'Portfolio Visualizer', pricingPerYear: '$360', slogan: 'Tools for Better Investors', + updatedAt: '2026-07-05', url: 'https://www.portfoliovisualizer.com' }, { @@ -2509,6 +2668,7 @@ export const personalFinanceTools: Product[] = ( key: 'portfolio123', name: 'Portfolio123', slogan: 'Power Your Portfolio with Backtested Stock Strategies', + updatedAt: '2026-08-28', url: 'https://www.portfolio123.com' }, { @@ -2521,6 +2681,7 @@ export const personalFinanceTools: Product[] = ( origin: 'PL', platforms: ['WEB'], slogan: 'One look. Clear picture of your portfolio.', + updatedAt: '2026-08-13', url: 'https://www.portfolioglance.com' }, { @@ -2565,6 +2726,7 @@ export const personalFinanceTools: Product[] = ( key: 'portfolioslab', name: 'PortfoliosLab', slogan: 'Financial tools for smart investors', + updatedAt: '2026-08-28', url: 'https://portfolioslab.com' }, { @@ -2596,7 +2758,8 @@ export const personalFinanceTools: Product[] = ( name: 'Portfoloo', note: 'Portfoloo was discontinued', slogan: - 'Free Stock Portfolio Tracker with unlimited portfolio and stocks for DIY investors' + 'Free Stock Portfolio Tracker with unlimited portfolio and stocks for DIY investors', + updatedAt: '2026-07-05' }, { categories: ['DIVIDEND_TRACKING', 'STOCK_TRACKING'], @@ -2609,6 +2772,7 @@ export const personalFinanceTools: Product[] = ( origin: 'TH', pricingPerYear: '$96', slogan: 'Portfolio Performance and Dividend Tracker', + updatedAt: '2026-07-05', url: 'https://www.portseido.com' }, { @@ -2622,6 +2786,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$108', slogan: 'Build Financial Plans You Love.', + updatedAt: '2026-07-05', url: 'https://projectionlab.com' }, { @@ -2635,6 +2800,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$60', slogan: 'The stock portfolio tracker built for long-term investors', + updatedAt: '2026-07-05', url: 'https://prostocktracker.com' }, { @@ -2656,6 +2822,7 @@ export const personalFinanceTools: Product[] = ( name: 'Quantive', platforms: ['WEB'], slogan: 'See your financial life clearly', + updatedAt: '2026-07-05', url: 'https://usequantive.app' }, { @@ -2688,6 +2855,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '$99.99', slogan: 'Your entire financial life in one app, monitored continuously by agents', + updatedAt: '2026-07-05', url: 'https://rallies.ai' }, { @@ -2696,6 +2864,7 @@ export const personalFinanceTools: Product[] = ( name: 'Reflexivity', note: 'Originally named as Toggle AI', slogan: 'Faster Insights. Better Analysis. Greater Confidence.', + updatedAt: '2026-09-23', url: 'https://reflexivity.com' }, { @@ -2709,6 +2878,7 @@ export const personalFinanceTools: Product[] = ( origin: 'DE', platforms: ['WEB'], slogan: 'Das kostenfreie Tool für Ihren Finanzerfolg', + updatedAt: '2026-08-16', url: 'https://www.rentablo.de' }, { @@ -2739,6 +2909,7 @@ export const personalFinanceTools: Product[] = ( origin: 'US', platforms: ['ANDROID', 'IOS', 'WEB'], slogan: 'Track your net worth', + updatedAt: '2026-07-05', url: 'https://www.rocketmoney.com' }, { @@ -2764,7 +2935,8 @@ export const personalFinanceTools: Product[] = ( name: 'Sarmaaya.pk Portfolio Tracking', note: 'Sarmaaya.pk Portfolio Tracking was discontinued in 2024', origin: 'PK', - slogan: 'Unified platform for financial research and portfolio tracking' + slogan: 'Unified platform for financial research and portfolio tracking', + updatedAt: '2026-07-05' }, { categories: ['INVESTMENT_RESEARCH'], @@ -2777,6 +2949,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$239', slogan: 'Stock Market Analysis & Tools for Investors', + updatedAt: '2026-07-05', url: 'https://seekingalpha.com' }, { @@ -2787,6 +2960,7 @@ export const personalFinanceTools: Product[] = ( origin: 'RO', platforms: ['WEB'], slogan: 'Track your net worth. Project every possible future.', + updatedAt: '2026-07-05', url: 'https://www.segmio.com' }, { @@ -2796,6 +2970,7 @@ export const personalFinanceTools: Product[] = ( origin: 'GB', slogan: 'Award-winning investment, trading and portfolio management tools', + updatedAt: '2026-08-28', url: 'https://www.sharescope.co.uk' }, { @@ -2810,6 +2985,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '$135', regions: ['Global'], slogan: 'Stock Portfolio Tracker', + updatedAt: '2026-07-05', url: 'https://www.sharesight.com' }, { @@ -2819,7 +2995,8 @@ export const personalFinanceTools: Product[] = ( key: 'sharesmaster', name: 'SharesMaster', note: 'SharesMaster was discontinued', - slogan: 'Free Stock Portfolio Tracker' + slogan: 'Free Stock Portfolio Tracker', + updatedAt: '2026-07-05' }, { categories: ['STOCK_TRACKING'], @@ -2831,6 +3008,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€80', slogan: 'Stock Portfolio Tracker', + updatedAt: '2026-07-05', url: 'https://simpleportfolio.app' }, { @@ -2842,6 +3020,7 @@ export const personalFinanceTools: Product[] = ( name: 'Simplifi by Quicken', origin: 'US', platforms: ['ANDROID', 'IOS', 'WEB'], + updatedAt: '2026-07-05', url: 'https://www.quicken.com/products/simplifi' }, { @@ -2850,6 +3029,7 @@ export const personalFinanceTools: Product[] = ( name: 'Simply Safe Dividends', pricingPerYear: '$468', slogan: 'Proven dividend research and tracking tools', + updatedAt: '2026-08-28', url: 'https://www.simplysafedividends.com' }, { @@ -2863,6 +3043,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$120', slogan: 'Smart portfolio tracker for informed investors', + updatedAt: '2026-07-05', url: 'https://simplywall.st' }, { @@ -2897,6 +3078,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS'], pricingPerYear: '£47.99', slogan: 'Cut the cost of living and build your savings', + updatedAt: '2026-08-17', url: 'https://snoop.app' }, { @@ -2910,6 +3092,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$80', slogan: 'Simple and powerful portfolio tracker', + updatedAt: '2026-07-05', url: 'https://snowball-analytics.com' }, { @@ -2923,19 +3106,22 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$14.99', slogan: 'The only app that gets your money into shape', + updatedAt: '2026-08-17', url: 'https://www.spendee.com' }, { key: 'splashmoney', name: 'SplashMoney', origin: 'US', - slogan: 'Manage your money anytime, anywhere.' + slogan: 'Manage your money anytime, anywhere.', + updatedAt: '2025-09-14' }, { categories: ['FINANCIAL_ADVISOR', 'WEALTH_MANAGEMENT'], key: 'ssc-black-diamond', name: 'SS&C Black Diamond Wealth Solutions', slogan: 'The Cornerstone of a Successful Business', + updatedAt: '2026-08-28', url: 'https://www.sscblackdiamond.com' }, { @@ -2943,6 +3129,7 @@ export const personalFinanceTools: Product[] = ( key: 'statfolio', name: 'Statfolio', slogan: 'Take control of your investments', + updatedAt: '2026-08-28', url: 'https://statfolio.net' }, { @@ -2968,6 +3155,7 @@ export const personalFinanceTools: Product[] = ( name: 'Stock Analysis', pricingPerYear: '$79', slogan: 'Free Online Stock Information for Investors', + updatedAt: '2026-08-28', url: 'https://stockanalysis.com' }, { @@ -2979,6 +3167,7 @@ export const personalFinanceTools: Product[] = ( origin: 'DE', platforms: ['ANDROID', 'IOS', 'WEB'], slogan: 'Track all your Investments', + updatedAt: '2026-07-05', url: 'https://stockevents.app' }, { @@ -3016,6 +3205,7 @@ export const personalFinanceTools: Product[] = ( name: 'StockCharts', pricingPerYear: '$239.40', slogan: 'Advanced Charting, Screening & Financial Analysis Tools', + updatedAt: '2026-08-28', url: 'https://stockcharts.com' }, { @@ -3025,6 +3215,7 @@ export const personalFinanceTools: Product[] = ( origin: 'FI', platforms: ['WEB'], slogan: 'Supercharge your investments tracking experience', + updatedAt: '2026-07-05', url: 'https://stockle.app' }, { @@ -3054,7 +3245,8 @@ export const personalFinanceTools: Product[] = ( name: 'StockMarketEye', origin: 'FR', note: 'StockMarketEye was discontinued in 2023', - slogan: 'A Powerful Portfolio & Investment Tracking App' + slogan: 'A Powerful Portfolio & Investment Tracking App', + updatedAt: '2026-07-05' }, { categories: ['DIVIDEND_TRACKING', 'STOCK_TRACKING', 'TAX_REPORTING'], @@ -3076,6 +3268,7 @@ export const personalFinanceTools: Product[] = ( name: 'Stockopedia', pricingPerYear: '€550', slogan: 'Data-Driven Stock Research for Active Investors', + updatedAt: '2026-08-28', url: 'https://www.stockopedia.com' }, { @@ -3089,6 +3282,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$79.99', slogan: 'Investment Research and Portfolio Management', + updatedAt: '2026-07-05', url: 'https://www.stockrover.com' }, { @@ -3097,6 +3291,7 @@ export const personalFinanceTools: Product[] = ( name: 'Stock Unlock', pricingPerYear: '$90', slogan: 'Unique Stock Insights & Portfolio Tracking', + updatedAt: '2026-08-28', url: 'https://stockunlock.com' }, { @@ -3124,6 +3319,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€49.90', slogan: 'Visualize all of your portfolios', + updatedAt: '2026-07-05', url: 'https://stonksfolio.com' }, { @@ -3148,6 +3344,7 @@ export const personalFinanceTools: Product[] = ( name: 'StreamXLS', pricingPerYear: '$590', slogan: 'Excel bridge to IBKR TWS', + updatedAt: '2026-08-28', url: 'https://streamxls.com' }, { @@ -3160,6 +3357,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS'], pricingPerYear: '$20', slogan: 'AI-Powered Portfolio & Net Worth Tracker', + updatedAt: '2026-07-05', url: 'https://www.sumio.app' }, { @@ -3167,6 +3365,7 @@ export const personalFinanceTools: Product[] = ( key: 'tc2000', name: 'TC2000', slogan: 'Helping traders think for themselves for over 30 years', + updatedAt: '2026-08-28', url: 'https://www.tc2000.com' }, { @@ -3174,6 +3373,7 @@ export const personalFinanceTools: Product[] = ( key: 'tickeron', name: 'Tickeron', slogan: 'AI Trading Agents, Tools and News', + updatedAt: '2026-08-28', url: 'https://tickeron.com' }, { @@ -3182,6 +3382,7 @@ export const personalFinanceTools: Product[] = ( name: 'Tickertape', pricingPerYear: '₹2999', slogan: 'Financial freedom begins here', + updatedAt: '2026-08-28', url: 'https://www.tickertape.in' }, { @@ -3190,6 +3391,7 @@ export const personalFinanceTools: Product[] = ( key: 'tikr', name: 'TIKR', slogan: 'Invest like Wall Street with TIKR Terminal', + updatedAt: '2026-08-28', url: 'https://www.tikr.com' }, { @@ -3203,6 +3405,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '$79', slogan: 'Your financial life in a spreadsheet, automatically updated each day', + updatedAt: '2026-07-05', url: 'https://tiller.com' }, { @@ -3216,6 +3419,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€35', slogan: 'Your key to empowered wealth management', + updatedAt: '2026-08-13', url: 'https://www.tinywallet.de' }, { @@ -3223,6 +3427,7 @@ export const personalFinanceTools: Product[] = ( key: 'tipranks', name: 'TipRanks', slogan: 'Make Smarter, Data-Driven Investment Decisions', + updatedAt: '2026-08-28', url: 'https://www.tipranks.com' }, { @@ -3236,6 +3441,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['IOS'], pricingPerYear: '$24.99', slogan: 'Make your money go further with daily budgets', + updatedAt: '2026-08-18', url: 'https://www.todays-budget.com' }, { @@ -3263,6 +3469,7 @@ export const personalFinanceTools: Product[] = ( key: 'trackinsight', name: 'Trackinsight', slogan: 'Empowering ETF Investors', + updatedAt: '2026-08-28', url: 'https://www.trackinsight.com' }, { @@ -3275,6 +3482,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€40', slogan: 'See your real investment performance — across every broker', + updatedAt: '2026-08-16', url: 'https://trackinv.com' }, { @@ -3289,6 +3497,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '$99.99', slogan: 'Follow the Performance, Payments, and Diversification of Your Dividend Portfolio', + updatedAt: '2026-08-16', url: 'https://www.trackyourdividends.com' }, { @@ -3312,6 +3521,7 @@ export const personalFinanceTools: Product[] = ( name: 'TradeBB', slogan: 'Trading journal for tracking, reviewing, and improving your trades', + updatedAt: '2026-08-28', url: 'https://www.tradebb.ai' }, { @@ -3321,6 +3531,7 @@ export const personalFinanceTools: Product[] = ( pricingPerYear: '$219', regions: ['US'], slogan: 'Take Control Of Trader Taxes', + updatedAt: '2026-08-28', url: 'https://tradelog.com' }, { @@ -3361,6 +3572,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$360', slogan: 'The Trading Journal to Improve Your Trading Performance', + updatedAt: '2026-07-05', url: 'https://www.tradervue.com' }, { @@ -3368,6 +3580,7 @@ export const personalFinanceTools: Product[] = ( name: 'TradeZella', pricingPerYear: '$315', slogan: 'Meet Your AI Trading Partner', + updatedAt: '2026-08-28', url: 'https://www.tradezella.com' }, { @@ -3376,6 +3589,7 @@ export const personalFinanceTools: Product[] = ( key: 'tradingview', name: 'TradingView', slogan: 'Track All Markets', + updatedAt: '2026-08-28', url: 'https://www.tradingview.com' }, { @@ -3389,6 +3603,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€80.04', slogan: 'Investing that never bores you', + updatedAt: '2026-08-16', url: 'https://www.treestep.fr' }, { @@ -3410,6 +3625,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€60', slogan: 'The Extra Leaf for Your Portfolio', + updatedAt: '2026-07-05', url: 'https://trefolio.com' }, { @@ -3418,6 +3634,7 @@ export const personalFinanceTools: Product[] = ( name: 'Trendlyne', pricingPerYear: '₹2190', slogan: 'The Stock Market Platform to Stay Ahead', + updatedAt: '2026-08-28', url: 'https://trendlyne.com' }, { @@ -3445,7 +3662,8 @@ export const personalFinanceTools: Product[] = ( note: 'Renamed to Parqet', origin: 'DE', regions: ['AT', 'CH', 'DE'], - slogan: 'Dein Vermögen immer im Blick' + slogan: 'Dein Vermögen immer im Blick', + updatedAt: '2026-07-05' }, { categories: ['NET_WORTH_TRACKING', 'STOCK_TRACKING'], @@ -3458,6 +3676,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€35.90', slogan: 'Your complete portfolio and expense tracker. Actually private.', + updatedAt: '2026-09-09', url: 'https://www.turbobulls.com' }, { @@ -3465,6 +3684,7 @@ export const personalFinanceTools: Product[] = ( key: 'tweenvest', name: 'Tweenvest', slogan: 'Analyzing stocks has never been easier', + updatedAt: '2026-08-28', url: 'https://www.tweenvest.com' }, { @@ -3504,6 +3724,7 @@ export const personalFinanceTools: Product[] = ( name: 'Uncle Stock', pricingPerYear: '$130', slogan: 'Fundamental Stock Screener', + updatedAt: '2026-08-28', url: 'https://www.unclestock.com' }, { @@ -3530,6 +3751,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$300', slogan: 'Your Portfolio. Revealed.', + updatedAt: '2026-07-05', url: 'https://www.utluna.com', useAnonymously: true }, @@ -3539,6 +3761,7 @@ export const personalFinanceTools: Product[] = ( name: 'Validea', slogan: 'Factor-Based Portfolios and Investment Research Utilizing Proven Long-Term Strategies', + updatedAt: '2026-08-28', url: 'https://www.validea.com' }, { @@ -3550,6 +3773,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€78', slogan: 'Track your real portfolio. Not a watchlist.', + updatedAt: '2026-07-05', url: 'https://valuedge.app' }, { @@ -3591,6 +3815,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$348', slogan: 'Virtual Family Office for Smart Wealth Management', + updatedAt: '2026-07-05', url: 'https://vyzer.co' }, { @@ -3604,6 +3829,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '€90', slogan: 'Personal finance reimagined with AI', + updatedAt: '2026-07-05', url: 'https://walletguide.com' }, { @@ -3615,7 +3841,8 @@ export const personalFinanceTools: Product[] = ( note: 'wallmine was discontinued in 2024', origin: 'CZ', pricingPerYear: '$600', - slogan: 'Make Smarter Investments' + slogan: 'Make Smarter Investments', + updatedAt: '2025-12-13' }, { categories: ['INVESTMENT_RESEARCH'], @@ -3628,6 +3855,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$234', slogan: 'Stock market analysis for the serious part-time investor', + updatedAt: '2026-07-05', url: 'https://www.wallstreetzen.com' }, { @@ -3654,6 +3882,7 @@ export const personalFinanceTools: Product[] = ( origin: 'CH', platforms: ['WEB'], slogan: 'Manage wealth data more efficiently', + updatedAt: '2026-07-05', url: 'https://www.wealtharc.com' }, { @@ -3666,6 +3895,7 @@ export const personalFinanceTools: Product[] = ( origin: 'AE', platforms: ['WEB'], slogan: 'Portfolio Management System', + updatedAt: '2026-07-05', url: 'https://wealthbrain.com' }, { @@ -3680,6 +3910,7 @@ export const personalFinanceTools: Product[] = ( origin: 'CA', platforms: ['IOS', 'LINUX', 'MACOS', 'WEB', 'WINDOWS'], slogan: 'Open-Source, Offline & Private Portfolio Tracker', + updatedAt: '2026-07-05', url: 'https://wealthfolio.app' }, { @@ -3694,6 +3925,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$50', slogan: 'See all your investments in one place', + updatedAt: '2026-07-05', url: 'https://wealthica.com' }, { @@ -3705,6 +3937,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$60', slogan: 'Personal Finance & Budgeting App', + updatedAt: '2026-07-05', url: 'https://www.wealthposition.com' }, { @@ -3717,6 +3950,7 @@ export const personalFinanceTools: Product[] = ( origin: 'IN', platforms: ['WEB'], slogan: 'One app to manage all your investments', + updatedAt: '2026-07-05', url: 'https://www.wealthy.in/tracker' }, { @@ -3724,7 +3958,8 @@ export const personalFinanceTools: Product[] = ( key: 'whal', name: 'Whal', origin: 'US', - slogan: 'Manage your investments in one place' + slogan: 'Manage your investments in one place', + updatedAt: '2026-07-05' }, { categories: ['INVESTMENT_RESEARCH'], @@ -3732,6 +3967,7 @@ export const personalFinanceTools: Product[] = ( name: 'Wisesheets', pricingPerYear: '$60', slogan: 'The Ultimate Spreadsheet Add-On for Stock Investors', + updatedAt: '2026-08-28', url: 'https://www.wisesheets.io' }, { @@ -3743,6 +3979,7 @@ export const personalFinanceTools: Product[] = ( key: 'ycharts', name: 'YCharts', slogan: 'Financial Research and Proposal Platform', + updatedAt: '2026-08-28', url: 'https://ycharts.com' }, { @@ -3757,7 +3994,8 @@ export const personalFinanceTools: Product[] = ( note: 'yeekatee was discontinued in 2024', origin: 'CH', regions: ['Global'], - slogan: 'Connect. Share. Invest.' + slogan: 'Connect. Share. Invest.', + updatedAt: '2026-07-05' }, { categories: ['BUDGETING'], @@ -3770,6 +4008,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['ANDROID', 'IOS', 'WEB'], pricingPerYear: '$109', slogan: 'Change Your Relationship With Money', + updatedAt: '2026-07-05', url: 'https://www.ynab.com' }, { @@ -3778,6 +4017,7 @@ export const personalFinanceTools: Product[] = ( key: 'zacks', name: 'Zacks', slogan: 'Stock Research, Analysis, & Recommendations', + updatedAt: '2026-08-28', url: 'https://www.zacks.com' }, { @@ -3785,6 +4025,7 @@ export const personalFinanceTools: Product[] = ( key: 'zenvesto', name: 'Zenvesto', slogan: 'Smart Investment Portfolio Tracker', + updatedAt: '2026-08-28', url: 'https://zenvesto.com' }, { @@ -3798,6 +4039,7 @@ export const personalFinanceTools: Product[] = ( platforms: ['WEB'], pricingPerYear: '$84', slogan: 'Your solution for investing success', + updatedAt: '2026-07-05', url: 'https://ziggma.com' } ] satisfies Product[] From 6282e39b6bbe9849ba83a0403d2dbf1f5e97b17b Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 26 Sep 2026 10:17:14 +0200 Subject: [PATCH 3/3] Release 3.73.0 (#7949) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4efde2ebb..fe31b7a9b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 3.73.0 - 2026-09-26 ### Changed diff --git a/package-lock.json b/package-lock.json index 9469e56421..b3eae247c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "3.72.0", + "version": "3.73.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "3.72.0", + "version": "3.73.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 638fd1ed10..5648ac6693 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "3.72.0", + "version": "3.73.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio",