diff --git a/CHANGELOG.md b/CHANGELOG.md
index a1aec1796..a23d3e6b5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
+- Restricted the _Restricted view and manage_ permission of the access to share the portfolio to the Model Context Protocol (MCP) (experimental)
- Upgraded `nestjs` from version `11.1.28` to `11.2.1`
### Fixed
diff --git a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts
index b0be5c0c5..8c2bb0353 100644
--- a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts
+++ b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts
@@ -6,6 +6,7 @@ import { Filter, PortfolioPosition } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import {
Scope,
+ canGrantRestrictedWriteAccess,
getAccessLevel,
getScopesOfAccess,
getScopesOfAccessLevel,
@@ -125,6 +126,10 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit {
return this.hasExperimentalFeatures && this.hasPermissionToEnableMcp;
}
+ public get canGrantRestrictedWriteAccess() {
+ return canGrantRestrictedWriteAccess({ type: this.accessType });
+ }
+
public get canGrantWriteAccess() {
return this.hasExperimentalFeatures;
}
diff --git a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html
index 89893e570..21c0cd3a8 100644
--- a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html
+++ b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html
@@ -82,7 +82,7 @@
- @if (!isPublicAccess) {
+ @if (canGrantRestrictedWriteAccess) {
= {
MCP: [...SCOPES_OF_READ_RESTRICTED_ACCESS, scopes.activityCreate],
@@ -72,6 +74,14 @@ const SCOPES_OF_TYPE: Record = {
PUBLIC: SCOPES_OF_PUBLIC_ACCESS
};
+/**
+ * Access types which combine a write scope with the restricted read access,
+ * because their tools change data without exposing the monetary values
+ */
+export function canGrantRestrictedWriteAccess({ type }: { type: AccessType }) {
+ return type === 'MCP';
+}
+
/**
* Access level which the scopes of an access grant
*/
@@ -96,9 +106,16 @@ export function getScopesOfAccess({
}): string[] {
const scopesToEvaluate = scopesOfAccess ?? [];
+ const permitsWriteAccess =
+ canGrantRestrictedWriteAccess({ type }) ||
+ hasScope(scopesToEvaluate, scopes.portfolioReadValues);
+
// An unknown scope is dropped
return SCOPES_OF_TYPE[type].filter((scope) => {
- return scopesToEvaluate.includes(scope);
+ return (
+ scopesToEvaluate.includes(scope) &&
+ (permitsWriteAccess || !SCOPES_OF_WRITE_ACCESS.includes(scope))
+ );
});
}