From ab3751761c6e8f07afb0f189fe5f4698b9a025b0 Mon Sep 17 00:00:00 2001 From: Maurice Date: Fri, 28 Aug 2026 13:09:15 +0200 Subject: [PATCH] feat(mcp): files and settings scope groups Two domains an assistant cannot reach at all today need somewhere to hang, so this is the credential half on its own, ahead of the tools. files:content is a third mode rather than a second group. Listing the documents on a trip and reading the bytes inside a booking PDF are different privileges, and the plugin host already draws that line between db:read:files and db:read:files:content. It is not implied by files:write, the same way journey:share is not implied by journey:write; the policy's fallback branch covers both. settings:write is scoped to display preferences. Settings also holds the webhook URL, the ntfy token and the Mapbox, Carto and LLM keys, so the tools that ride this scope work off an allow-list rather than off the settings row. 34 scopes across 16 groups, translated into all 23 languages. --- client/src/api/oauthScopes.ts | 5 +++++ server/src/mcp/scopes.ts | 24 ++++++++++++++++++++++++ server/tests/unit/mcp/scopes.test.ts | 4 +++- shared/src/i18n/ar/oauth.ts | 12 ++++++++++++ shared/src/i18n/br/oauth.ts | 12 ++++++++++++ shared/src/i18n/ca/oauth.ts | 12 ++++++++++++ shared/src/i18n/cs/oauth.ts | 12 ++++++++++++ shared/src/i18n/de/oauth.ts | 12 ++++++++++++ shared/src/i18n/en/oauth.ts | 12 ++++++++++++ shared/src/i18n/es/oauth.ts | 12 ++++++++++++ shared/src/i18n/fr/oauth.ts | 12 ++++++++++++ shared/src/i18n/gr/oauth.ts | 12 ++++++++++++ shared/src/i18n/hu/oauth.ts | 12 ++++++++++++ shared/src/i18n/id/oauth.ts | 12 ++++++++++++ shared/src/i18n/it/oauth.ts | 12 ++++++++++++ shared/src/i18n/ja/oauth.ts | 12 ++++++++++++ shared/src/i18n/ko/oauth.ts | 12 ++++++++++++ shared/src/i18n/nl/oauth.ts | 12 ++++++++++++ shared/src/i18n/pl/oauth.ts | 12 ++++++++++++ shared/src/i18n/ru/oauth.ts | 12 ++++++++++++ shared/src/i18n/sv/oauth.ts | 12 ++++++++++++ shared/src/i18n/tr/oauth.ts | 12 ++++++++++++ shared/src/i18n/uk/oauth.ts | 12 ++++++++++++ shared/src/i18n/vi/oauth.ts | 12 ++++++++++++ shared/src/i18n/zh-TW/oauth.ts | 12 ++++++++++++ shared/src/i18n/zh/oauth.ts | 12 ++++++++++++ wiki/MCP-Scopes.md | 11 +++++++++-- 27 files changed, 317 insertions(+), 3 deletions(-) diff --git a/client/src/api/oauthScopes.ts b/client/src/api/oauthScopes.ts index d11bf853e..3f266e519 100644 --- a/client/src/api/oauthScopes.ts +++ b/client/src/api/oauthScopes.ts @@ -43,6 +43,11 @@ export const SCOPE_GROUPS: Record = { 'journey:read': { labelKey: 'oauth.scope.journey:read.label', descriptionKey: 'oauth.scope.journey:read.description', groupKey: 'oauth.scope.group.journey' }, 'journey:write': { labelKey: 'oauth.scope.journey:write.label', descriptionKey: 'oauth.scope.journey:write.description', groupKey: 'oauth.scope.group.journey' }, 'journey:share': { labelKey: 'oauth.scope.journey:share.label', descriptionKey: 'oauth.scope.journey:share.description', groupKey: 'oauth.scope.group.journey' }, + 'files:read': { labelKey: 'oauth.scope.files:read.label', descriptionKey: 'oauth.scope.files:read.description', groupKey: 'oauth.scope.group.files' }, + 'files:write': { labelKey: 'oauth.scope.files:write.label', descriptionKey: 'oauth.scope.files:write.description', groupKey: 'oauth.scope.group.files' }, + 'files:content': { labelKey: 'oauth.scope.files:content.label', descriptionKey: 'oauth.scope.files:content.description', groupKey: 'oauth.scope.group.files' }, + 'settings:read': { labelKey: 'oauth.scope.settings:read.label', descriptionKey: 'oauth.scope.settings:read.description', groupKey: 'oauth.scope.group.settings' }, + 'settings:write': { labelKey: 'oauth.scope.settings:write.label', descriptionKey: 'oauth.scope.settings:write.description', groupKey: 'oauth.scope.group.settings' }, } export const ALL_SCOPES = Object.keys(SCOPE_GROUPS) diff --git a/server/src/mcp/scopes.ts b/server/src/mcp/scopes.ts index 2ef5062a7..760021e28 100644 --- a/server/src/mcp/scopes.ts +++ b/server/src/mcp/scopes.ts @@ -32,6 +32,16 @@ export const SCOPES = { JOURNEY_READ: 'journey:read', JOURNEY_WRITE: 'journey:write', JOURNEY_SHARE: 'journey:share', + FILES_READ: 'files:read', + FILES_WRITE: 'files:write', + // A third mode rather than a second group: listing what a trip carries and + // reading the bytes of a booking PDF are different privileges, and the plugin + // host already draws that line (db:read:files vs db:read:files:content). Not + // implied by files:write, the way journey:share is not implied by + // journey:write. The policy's fallback branch covers both. + FILES_CONTENT: 'files:content', + SETTINGS_READ: 'settings:read', + SETTINGS_WRITE: 'settings:write', } as const; export type Scope = typeof SCOPES[keyof typeof SCOPES]; @@ -77,6 +87,11 @@ export const SCOPE_INFO: Record = { 'journey:read': { label: 'View journeys', description: 'Read journeys, entries, and contributor list', group: 'Journey' }, 'journey:write': { label: 'Manage journeys', description: 'Create, update, and delete journeys and their entries', group: 'Journey' }, 'journey:share': { label: 'Manage journey links', description: 'Create, update, and revoke public share links for journeys', group: 'Journey' }, + 'files:read': { label: 'View trip files', description: 'List the documents on a trip: names, sizes, who uploaded them, what they link to', group: 'Files' }, + 'files:write': { label: 'Organise trip files', description: 'Rename and describe files, link them to bookings and places, star and trash them', group: 'Files' }, + 'files:content': { label: 'Read file contents', description: 'Read what is inside an uploaded document, such as a booking PDF or a ticket', group: 'Files' }, + 'settings:read': { label: 'View your preferences', description: 'Read units, time format, language, default currency, and start page', group: 'Settings' }, + 'settings:write': { label: 'Change your preferences', description: 'Change units, time format, language, default currency, and start page. Never stored API keys', group: 'Settings' }, }; // --------------------------------------------------------------------------- @@ -114,6 +129,15 @@ export function canShareTrips(scopes: string[] | null): boolean { return scopes.includes('trips:share'); } +/** + * files:content is a separate scope from files:read: a token may list a trip's + * documents without being allowed to read what is inside them. + */ +export function canReadFileContent(scopes: string[] | null): boolean { + if (!scopes) return true; + return scopes.includes('files:content'); +} + /** journey:share is a separate scope for managing public share links for journeys */ export function canShareJourneys(scopes: string[] | null): boolean { if (!scopes) return true; diff --git a/server/tests/unit/mcp/scopes.test.ts b/server/tests/unit/mcp/scopes.test.ts index 15a310eb1..f922f641d 100644 --- a/server/tests/unit/mcp/scopes.test.ts +++ b/server/tests/unit/mcp/scopes.test.ts @@ -46,7 +46,7 @@ describe('ALL_SCOPES', () => { expect(ALL_SCOPES.length).toBeGreaterThan(0); }); - it('derives exactly the 14 known scope groups (ScopeGroup lockstep)', () => { + it('derives exactly the 16 known scope groups (ScopeGroup lockstep)', () => { // The runtime half of the ScopeGroup lockstep — the type half is // MCP_ACCESS_GROUPS_MATCH_SCOPE_GROUPS in src/mcp/nest-mcp-policy.ts, // covered by `npm run typecheck`. If this list changes, the MCP @@ -57,12 +57,14 @@ describe('ALL_SCOPES', () => { 'budget', 'collab', 'collections', + 'files', 'geo', 'journey', 'notifications', 'packing', 'places', 'reservations', + 'settings', 'todos', 'trips', 'vacay', diff --git a/shared/src/i18n/ar/oauth.ts b/shared/src/i18n/ar/oauth.ts index d097cc7f8..54036bfdc 100644 --- a/shared/src/i18n/ar/oauth.ts +++ b/shared/src/i18n/ar/oauth.ts @@ -93,5 +93,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'الملفات', + 'oauth.scope.group.settings': 'الإعدادات', + 'oauth.scope.files:read.label': 'عرض ملفات الرحلة', + 'oauth.scope.files:read.description': 'سرد مستندات الرحلة: الأسماء والأحجام ومن رفعها وبماذا ترتبط', + 'oauth.scope.files:write.label': 'إدارة ملفات الرحلة', + 'oauth.scope.files:write.description': 'إعادة تسمية الملفات ووصفها وربطها بالحجوزات والأماكن وتمييزها ونقلها إلى سلة المهملات', + 'oauth.scope.files:content.label': 'قراءة محتوى الملفات', + 'oauth.scope.files:content.description': 'قراءة محتوى مستند مرفوع، مثل ملف PDF لحجز أو تذكرة', + 'oauth.scope.settings:read.label': 'عرض تفضيلاتك', + 'oauth.scope.settings:read.description': 'قراءة الوحدات وتنسيق الوقت واللغة والعملة الافتراضية وصفحة البداية', + 'oauth.scope.settings:write.label': 'تغيير تفضيلاتك', + 'oauth.scope.settings:write.description': 'تغيير الوحدات وتنسيق الوقت واللغة والعملة الافتراضية وصفحة البداية. لا مفاتيح API المخزنة أبدًا', }; export default oauth; diff --git a/shared/src/i18n/br/oauth.ts b/shared/src/i18n/br/oauth.ts index 7a8456907..f67f140b5 100644 --- a/shared/src/i18n/br/oauth.ts +++ b/shared/src/i18n/br/oauth.ts @@ -95,5 +95,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'Arquivos', + 'oauth.scope.group.settings': 'Configurações', + 'oauth.scope.files:read.label': 'Ver arquivos da viagem', + 'oauth.scope.files:read.description': 'Listar os documentos de uma viagem: nomes, tamanhos, quem enviou e a que estão vinculados', + 'oauth.scope.files:write.label': 'Gerenciar arquivos da viagem', + 'oauth.scope.files:write.description': 'Renomear e descrever arquivos, vinculá-los a reservas e lugares, favoritá-los e movê-los para a lixeira', + 'oauth.scope.files:content.label': 'Ler o conteúdo dos arquivos', + 'oauth.scope.files:content.description': 'Ler o conteúdo de um documento enviado, como um PDF de reserva ou um bilhete', + 'oauth.scope.settings:read.label': 'Ver suas preferências', + 'oauth.scope.settings:read.description': 'Ler unidades, formato de hora, idioma, moeda padrão e página inicial', + 'oauth.scope.settings:write.label': 'Alterar suas preferências', + 'oauth.scope.settings:write.description': 'Alterar unidades, formato de hora, idioma, moeda padrão e página inicial. Nunca as chaves de API salvas', }; export default oauth; diff --git a/shared/src/i18n/ca/oauth.ts b/shared/src/i18n/ca/oauth.ts index a434960e4..49228d9a4 100644 --- a/shared/src/i18n/ca/oauth.ts +++ b/shared/src/i18n/ca/oauth.ts @@ -97,5 +97,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysTool.listTrips': 'Llista els teus viatges perquè la IA pugui descobrir els IDs dels viatges', 'oauth.authorize.alwaysTool.getTripSummary': 'Llegeix una visió general del viatge necessària per utilitzar qualsevol altra eina', + 'oauth.scope.group.files': 'Fitxers', + 'oauth.scope.group.settings': 'Configuració', + 'oauth.scope.files:read.label': 'Veure els fitxers del viatge', + 'oauth.scope.files:read.description': 'Llistar els documents d’un viatge: noms, mides, qui els ha pujat i a què estan vinculats', + 'oauth.scope.files:write.label': 'Gestionar els fitxers del viatge', + 'oauth.scope.files:write.description': 'Reanomenar i descriure fitxers, vincular-los a reserves i llocs, destacar-los i enviar-los a la paperera', + 'oauth.scope.files:content.label': 'Llegir el contingut dels fitxers', + 'oauth.scope.files:content.description': 'Llegir el contingut d’un document pujat, com un PDF de reserva o un bitllet', + 'oauth.scope.settings:read.label': 'Veure les teves preferències', + 'oauth.scope.settings:read.description': 'Llegir unitats, format d’hora, idioma, moneda per defecte i pàgina d’inici', + 'oauth.scope.settings:write.label': 'Canviar les teves preferències', + 'oauth.scope.settings:write.description': 'Canviar unitats, format d’hora, idioma, moneda per defecte i pàgina d’inici. Mai les claus API desades', }; export default oauth; diff --git a/shared/src/i18n/cs/oauth.ts b/shared/src/i18n/cs/oauth.ts index 5d456cb45..29914ad9d 100644 --- a/shared/src/i18n/cs/oauth.ts +++ b/shared/src/i18n/cs/oauth.ts @@ -93,5 +93,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'Soubory', + 'oauth.scope.group.settings': 'Nastavení', + 'oauth.scope.files:read.label': 'Zobrazit soubory cesty', + 'oauth.scope.files:read.description': 'Vypsat dokumenty cesty: názvy, velikosti, kdo je nahrál a k čemu jsou připojené', + 'oauth.scope.files:write.label': 'Spravovat soubory cesty', + 'oauth.scope.files:write.description': 'Přejmenovat a popsat soubory, připojit je k rezervacím a místům, označit hvězdičkou a přesunout do koše', + 'oauth.scope.files:content.label': 'Číst obsah souborů', + 'oauth.scope.files:content.description': 'Přečíst obsah nahraného dokumentu, například PDF rezervace nebo jízdenku', + 'oauth.scope.settings:read.label': 'Zobrazit vaše předvolby', + 'oauth.scope.settings:read.description': 'Číst jednotky, formát času, jazyk, výchozí měnu a úvodní stránku', + 'oauth.scope.settings:write.label': 'Změnit vaše předvolby', + 'oauth.scope.settings:write.description': 'Změnit jednotky, formát času, jazyk, výchozí měnu a úvodní stránku. Nikdy uložené API klíče', }; export default oauth; diff --git a/shared/src/i18n/de/oauth.ts b/shared/src/i18n/de/oauth.ts index aa875e99d..99beea982 100644 --- a/shared/src/i18n/de/oauth.ts +++ b/shared/src/i18n/de/oauth.ts @@ -97,5 +97,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'Dateien', + 'oauth.scope.group.settings': 'Einstellungen', + 'oauth.scope.files:read.label': 'Reisedateien ansehen', + 'oauth.scope.files:read.description': 'Dokumente einer Reise auflisten: Namen, Größen, wer sie hochgeladen hat und woran sie hängen', + 'oauth.scope.files:write.label': 'Reisedateien verwalten', + 'oauth.scope.files:write.description': 'Dateien umbenennen und beschreiben, mit Buchungen und Orten verknüpfen, markieren und in den Papierkorb legen', + 'oauth.scope.files:content.label': 'Dateiinhalte lesen', + 'oauth.scope.files:content.description': 'Den Inhalt eines hochgeladenen Dokuments lesen, etwa ein Buchungs-PDF oder ein Ticket', + 'oauth.scope.settings:read.label': 'Einstellungen ansehen', + 'oauth.scope.settings:read.description': 'Einheiten, Zeitformat, Sprache, Standardwährung und Startseite lesen', + 'oauth.scope.settings:write.label': 'Einstellungen ändern', + 'oauth.scope.settings:write.description': 'Einheiten, Zeitformat, Sprache, Standardwährung und Startseite ändern. Niemals gespeicherte API-Schlüssel', }; export default oauth; diff --git a/shared/src/i18n/en/oauth.ts b/shared/src/i18n/en/oauth.ts index 8271153cb..350598c8f 100644 --- a/shared/src/i18n/en/oauth.ts +++ b/shared/src/i18n/en/oauth.ts @@ -94,5 +94,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', + 'oauth.scope.group.files': 'Files', + 'oauth.scope.group.settings': 'Settings', + 'oauth.scope.files:read.label': 'View trip files', + 'oauth.scope.files:read.description': 'List the documents on a trip: names, sizes, who uploaded them, what they link to', + 'oauth.scope.files:write.label': 'Organise trip files', + 'oauth.scope.files:write.description': 'Rename and describe files, link them to bookings and places, star and trash them', + 'oauth.scope.files:content.label': 'Read file contents', + 'oauth.scope.files:content.description': 'Read what is inside an uploaded document, such as a booking PDF or a ticket', + 'oauth.scope.settings:read.label': 'View your preferences', + 'oauth.scope.settings:read.description': 'Read units, time format, language, default currency, and start page', + 'oauth.scope.settings:write.label': 'Change your preferences', + 'oauth.scope.settings:write.description': 'Change units, time format, language, default currency, and start page. Never stored API keys', }; export default oauth; diff --git a/shared/src/i18n/es/oauth.ts b/shared/src/i18n/es/oauth.ts index 8794a2b2e..8746c3d5b 100644 --- a/shared/src/i18n/es/oauth.ts +++ b/shared/src/i18n/es/oauth.ts @@ -94,5 +94,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'Archivos', + 'oauth.scope.group.settings': 'Configuración', + 'oauth.scope.files:read.label': 'Ver archivos del viaje', + 'oauth.scope.files:read.description': 'Listar los documentos de un viaje: nombres, tamaños, quién los subió y a qué están vinculados', + 'oauth.scope.files:write.label': 'Gestionar archivos del viaje', + 'oauth.scope.files:write.description': 'Renombrar y describir archivos, vincularlos a reservas y lugares, destacarlos y enviarlos a la papelera', + 'oauth.scope.files:content.label': 'Leer el contenido de archivos', + 'oauth.scope.files:content.description': 'Leer el contenido de un documento subido, como un PDF de reserva o un billete', + 'oauth.scope.settings:read.label': 'Ver tus preferencias', + 'oauth.scope.settings:read.description': 'Leer unidades, formato de hora, idioma, moneda predeterminada y página de inicio', + 'oauth.scope.settings:write.label': 'Cambiar tus preferencias', + 'oauth.scope.settings:write.description': 'Cambiar unidades, formato de hora, idioma, moneda predeterminada y página de inicio. Nunca las claves API guardadas', }; export default oauth; diff --git a/shared/src/i18n/fr/oauth.ts b/shared/src/i18n/fr/oauth.ts index 645b6f537..5dd222a52 100644 --- a/shared/src/i18n/fr/oauth.ts +++ b/shared/src/i18n/fr/oauth.ts @@ -97,5 +97,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'Fichiers', + 'oauth.scope.group.settings': 'Paramètres', + 'oauth.scope.files:read.label': 'Voir les fichiers du voyage', + 'oauth.scope.files:read.description': 'Lister les documents d’un voyage : noms, tailles, qui les a envoyés et ce à quoi ils sont liés', + 'oauth.scope.files:write.label': 'Gérer les fichiers du voyage', + 'oauth.scope.files:write.description': 'Renommer et décrire les fichiers, les lier aux réservations et aux lieux, les épingler et les mettre à la corbeille', + 'oauth.scope.files:content.label': 'Lire le contenu des fichiers', + 'oauth.scope.files:content.description': 'Lire le contenu d’un document envoyé, par exemple un PDF de réservation ou un billet', + 'oauth.scope.settings:read.label': 'Voir vos préférences', + 'oauth.scope.settings:read.description': 'Lire les unités, le format horaire, la langue, la devise par défaut et la page d’accueil', + 'oauth.scope.settings:write.label': 'Modifier vos préférences', + 'oauth.scope.settings:write.description': 'Modifier les unités, le format horaire, la langue, la devise par défaut et la page d’accueil. Jamais les clés API enregistrées', }; export default oauth; diff --git a/shared/src/i18n/gr/oauth.ts b/shared/src/i18n/gr/oauth.ts index 54dbcea48..133ab0b81 100644 --- a/shared/src/i18n/gr/oauth.ts +++ b/shared/src/i18n/gr/oauth.ts @@ -99,5 +99,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'Αρχεία', + 'oauth.scope.group.settings': 'Ρυθμίσεις', + 'oauth.scope.files:read.label': 'Προβολή αρχείων ταξιδιού', + 'oauth.scope.files:read.description': 'Λίστα των εγγράφων ενός ταξιδιού: ονόματα, μεγέθη, ποιος τα ανέβασε και με τι συνδέονται', + 'oauth.scope.files:write.label': 'Διαχείριση αρχείων ταξιδιού', + 'oauth.scope.files:write.description': 'Μετονομασία και περιγραφή αρχείων, σύνδεσή τους με κρατήσεις και τοποθεσίες, επισήμανση και διαγραφή', + 'oauth.scope.files:content.label': 'Ανάγνωση περιεχομένου αρχείων', + 'oauth.scope.files:content.description': 'Ανάγνωση του περιεχομένου ενός ανεβασμένου εγγράφου, όπως ένα PDF κράτησης ή ένα εισιτήριο', + 'oauth.scope.settings:read.label': 'Προβολή προτιμήσεων', + 'oauth.scope.settings:read.description': 'Ανάγνωση μονάδων, μορφής ώρας, γλώσσας, προεπιλεγμένου νομίσματος και αρχικής σελίδας', + 'oauth.scope.settings:write.label': 'Αλλαγή προτιμήσεων', + 'oauth.scope.settings:write.description': 'Αλλαγή μονάδων, μορφής ώρας, γλώσσας, προεπιλεγμένου νομίσματος και αρχικής σελίδας. Ποτέ αποθηκευμένων κλειδιών API', }; export default oauth; diff --git a/shared/src/i18n/hu/oauth.ts b/shared/src/i18n/hu/oauth.ts index 1ae2caa30..f16fd6034 100644 --- a/shared/src/i18n/hu/oauth.ts +++ b/shared/src/i18n/hu/oauth.ts @@ -97,5 +97,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'Fájlok', + 'oauth.scope.group.settings': 'Beállítások', + 'oauth.scope.files:read.label': 'Az utazás fájljainak megtekintése', + 'oauth.scope.files:read.description': 'Az utazás dokumentumainak listázása: nevek, méretek, ki töltötte fel és mihez kapcsolódnak', + 'oauth.scope.files:write.label': 'Az utazás fájljainak kezelése', + 'oauth.scope.files:write.description': 'Fájlok átnevezése és leírása, foglalásokhoz és helyekhez kapcsolása, megjelölése és kukába helyezése', + 'oauth.scope.files:content.label': 'Fájltartalom olvasása', + 'oauth.scope.files:content.description': 'Feltöltött dokumentum tartalmának olvasása, például egy foglalási PDF vagy jegy', + 'oauth.scope.settings:read.label': 'Beállítások megtekintése', + 'oauth.scope.settings:read.description': 'Mértékegységek, időformátum, nyelv, alapértelmezett pénznem és kezdőoldal olvasása', + 'oauth.scope.settings:write.label': 'Beállítások módosítása', + 'oauth.scope.settings:write.description': 'Mértékegységek, időformátum, nyelv, alapértelmezett pénznem és kezdőoldal módosítása. Soha nem a tárolt API-kulcsok', }; export default oauth; diff --git a/shared/src/i18n/id/oauth.ts b/shared/src/i18n/id/oauth.ts index 0e2918e1b..4b1b2bff4 100644 --- a/shared/src/i18n/id/oauth.ts +++ b/shared/src/i18n/id/oauth.ts @@ -94,5 +94,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'Berkas', + 'oauth.scope.group.settings': 'Pengaturan', + 'oauth.scope.files:read.label': 'Lihat berkas perjalanan', + 'oauth.scope.files:read.description': 'Menampilkan dokumen perjalanan: nama, ukuran, siapa yang mengunggah, dan tautannya', + 'oauth.scope.files:write.label': 'Kelola berkas perjalanan', + 'oauth.scope.files:write.description': 'Ganti nama dan deskripsi berkas, tautkan ke pemesanan dan tempat, beri bintang dan buang ke sampah', + 'oauth.scope.files:content.label': 'Baca isi berkas', + 'oauth.scope.files:content.description': 'Membaca isi dokumen yang diunggah, misalnya PDF pemesanan atau tiket', + 'oauth.scope.settings:read.label': 'Lihat preferensi Anda', + 'oauth.scope.settings:read.description': 'Membaca satuan, format waktu, bahasa, mata uang bawaan, dan halaman awal', + 'oauth.scope.settings:write.label': 'Ubah preferensi Anda', + 'oauth.scope.settings:write.description': 'Mengubah satuan, format waktu, bahasa, mata uang bawaan, dan halaman awal. Tidak pernah kunci API tersimpan', }; export default oauth; diff --git a/shared/src/i18n/it/oauth.ts b/shared/src/i18n/it/oauth.ts index 3f730e874..fc743448e 100644 --- a/shared/src/i18n/it/oauth.ts +++ b/shared/src/i18n/it/oauth.ts @@ -95,5 +95,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'File', + 'oauth.scope.group.settings': 'Impostazioni', + 'oauth.scope.files:read.label': 'Vedere i file del viaggio', + 'oauth.scope.files:read.description': 'Elencare i documenti di un viaggio: nomi, dimensioni, chi li ha caricati e a cosa sono collegati', + 'oauth.scope.files:write.label': 'Gestire i file del viaggio', + 'oauth.scope.files:write.description': 'Rinominare e descrivere i file, collegarli a prenotazioni e luoghi, contrassegnarli e cestinarli', + 'oauth.scope.files:content.label': 'Leggere il contenuto dei file', + 'oauth.scope.files:content.description': 'Leggere il contenuto di un documento caricato, come un PDF di prenotazione o un biglietto', + 'oauth.scope.settings:read.label': 'Vedere le tue preferenze', + 'oauth.scope.settings:read.description': 'Leggere unità, formato orario, lingua, valuta predefinita e pagina iniziale', + 'oauth.scope.settings:write.label': 'Modificare le tue preferenze', + 'oauth.scope.settings:write.description': 'Modificare unità, formato orario, lingua, valuta predefinita e pagina iniziale. Mai le chiavi API salvate', }; export default oauth; diff --git a/shared/src/i18n/ja/oauth.ts b/shared/src/i18n/ja/oauth.ts index cf4d8dfca..6fe50bedf 100644 --- a/shared/src/i18n/ja/oauth.ts +++ b/shared/src/i18n/ja/oauth.ts @@ -94,5 +94,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'ファイル', + 'oauth.scope.group.settings': '設定', + 'oauth.scope.files:read.label': '旅行のファイルを表示', + 'oauth.scope.files:read.description': '旅行の書類を一覧表示します。名前、サイズ、アップロードした人、リンク先', + 'oauth.scope.files:write.label': '旅行のファイルを管理', + 'oauth.scope.files:write.description': 'ファイルの名前と説明の変更、予約や場所への紐付け、スターとゴミ箱への移動', + 'oauth.scope.files:content.label': 'ファイルの中身を読む', + 'oauth.scope.files:content.description': 'アップロードされた書類の中身を読みます。予約PDFやチケットなど', + 'oauth.scope.settings:read.label': '環境設定を表示', + 'oauth.scope.settings:read.description': '単位、時刻表示、言語、既定通貨、開始ページの読み取り', + 'oauth.scope.settings:write.label': '環境設定を変更', + 'oauth.scope.settings:write.description': '単位、時刻表示、言語、既定通貨、開始ページの変更。保存されたAPIキーは対象外', }; export default oauth; diff --git a/shared/src/i18n/ko/oauth.ts b/shared/src/i18n/ko/oauth.ts index 356810d38..5fcf3be70 100644 --- a/shared/src/i18n/ko/oauth.ts +++ b/shared/src/i18n/ko/oauth.ts @@ -92,5 +92,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': '파일', + 'oauth.scope.group.settings': '설정', + 'oauth.scope.files:read.label': '여행 파일 보기', + 'oauth.scope.files:read.description': '여행의 문서를 나열합니다. 이름, 크기, 업로드한 사람, 연결된 항목', + 'oauth.scope.files:write.label': '여행 파일 관리', + 'oauth.scope.files:write.description': '파일 이름과 설명 변경, 예약 및 장소에 연결, 즐겨찾기 및 휴지통 이동', + 'oauth.scope.files:content.label': '파일 내용 읽기', + 'oauth.scope.files:content.description': '업로드된 문서의 내용을 읽습니다. 예약 PDF나 티켓 등', + 'oauth.scope.settings:read.label': '환경설정 보기', + 'oauth.scope.settings:read.description': '단위, 시간 형식, 언어, 기본 통화, 시작 페이지 읽기', + 'oauth.scope.settings:write.label': '환경설정 변경', + 'oauth.scope.settings:write.description': '단위, 시간 형식, 언어, 기본 통화, 시작 페이지 변경. 저장된 API 키는 제외', }; export default oauth; diff --git a/shared/src/i18n/nl/oauth.ts b/shared/src/i18n/nl/oauth.ts index 976ef0006..940379624 100644 --- a/shared/src/i18n/nl/oauth.ts +++ b/shared/src/i18n/nl/oauth.ts @@ -96,5 +96,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'Bestanden', + 'oauth.scope.group.settings': 'Instellingen', + 'oauth.scope.files:read.label': 'Reisbestanden bekijken', + 'oauth.scope.files:read.description': 'De documenten van een reis tonen: namen, groottes, wie ze heeft geüpload en waaraan ze gekoppeld zijn', + 'oauth.scope.files:write.label': 'Reisbestanden beheren', + 'oauth.scope.files:write.description': 'Bestanden hernoemen en beschrijven, koppelen aan boekingen en plaatsen, markeren en naar de prullenbak verplaatsen', + 'oauth.scope.files:content.label': 'Bestandsinhoud lezen', + 'oauth.scope.files:content.description': 'De inhoud van een geüpload document lezen, zoals een boekings-PDF of een ticket', + 'oauth.scope.settings:read.label': 'Je voorkeuren bekijken', + 'oauth.scope.settings:read.description': 'Eenheden, tijdnotatie, taal, standaardvaluta en startpagina lezen', + 'oauth.scope.settings:write.label': 'Je voorkeuren wijzigen', + 'oauth.scope.settings:write.description': 'Eenheden, tijdnotatie, taal, standaardvaluta en startpagina wijzigen. Nooit opgeslagen API-sleutels', }; export default oauth; diff --git a/shared/src/i18n/pl/oauth.ts b/shared/src/i18n/pl/oauth.ts index 5481512e5..19e20eba3 100644 --- a/shared/src/i18n/pl/oauth.ts +++ b/shared/src/i18n/pl/oauth.ts @@ -95,5 +95,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'Pliki', + 'oauth.scope.group.settings': 'Ustawienia', + 'oauth.scope.files:read.label': 'Przeglądanie plików podróży', + 'oauth.scope.files:read.description': 'Wyświetlanie dokumentów podróży: nazw, rozmiarów, kto je przesłał i z czym są powiązane', + 'oauth.scope.files:write.label': 'Zarządzanie plikami podróży', + 'oauth.scope.files:write.description': 'Zmiana nazw i opisów plików, wiązanie ich z rezerwacjami i miejscami, oznaczanie i przenoszenie do kosza', + 'oauth.scope.files:content.label': 'Odczyt zawartości plików', + 'oauth.scope.files:content.description': 'Odczyt zawartości przesłanego dokumentu, na przykład PDF-u rezerwacji lub biletu', + 'oauth.scope.settings:read.label': 'Przeglądanie preferencji', + 'oauth.scope.settings:read.description': 'Odczyt jednostek, formatu czasu, języka, waluty domyślnej i strony startowej', + 'oauth.scope.settings:write.label': 'Zmiana preferencji', + 'oauth.scope.settings:write.description': 'Zmiana jednostek, formatu czasu, języka, waluty domyślnej i strony startowej. Nigdy zapisanych kluczy API', }; export default oauth; diff --git a/shared/src/i18n/ru/oauth.ts b/shared/src/i18n/ru/oauth.ts index 9e71181ce..ece34f24b 100644 --- a/shared/src/i18n/ru/oauth.ts +++ b/shared/src/i18n/ru/oauth.ts @@ -95,5 +95,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'Файлы', + 'oauth.scope.group.settings': 'Настройки', + 'oauth.scope.files:read.label': 'Просмотр файлов поездки', + 'oauth.scope.files:read.description': 'Список документов поездки: названия, размеры, кто их загрузил и с чем они связаны', + 'oauth.scope.files:write.label': 'Управление файлами поездки', + 'oauth.scope.files:write.description': 'Переименование и описание файлов, привязка к бронированиям и местам, отметка и удаление в корзину', + 'oauth.scope.files:content.label': 'Чтение содержимого файлов', + 'oauth.scope.files:content.description': 'Чтение содержимого загруженного документа, например PDF бронирования или билета', + 'oauth.scope.settings:read.label': 'Просмотр ваших настроек', + 'oauth.scope.settings:read.description': 'Чтение единиц измерения, формата времени, языка, валюты по умолчанию и стартовой страницы', + 'oauth.scope.settings:write.label': 'Изменение ваших настроек', + 'oauth.scope.settings:write.description': 'Изменение единиц измерения, формата времени, языка, валюты по умолчанию и стартовой страницы. Никогда сохранённых ключей API', }; export default oauth; diff --git a/shared/src/i18n/sv/oauth.ts b/shared/src/i18n/sv/oauth.ts index 614093af6..b9dcf97ed 100644 --- a/shared/src/i18n/sv/oauth.ts +++ b/shared/src/i18n/sv/oauth.ts @@ -100,5 +100,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysTool.listTrips': 'Lista dina resor så att AI:n kan identifiera resenummer', 'oauth.authorize.alwaysTool.getTripSummary': 'Läs en översikt över resan som krävs för att kunna använda något annat verktyg', + 'oauth.scope.group.files': 'Filer', + 'oauth.scope.group.settings': 'Inställningar', + 'oauth.scope.files:read.label': 'Visa resans filer', + 'oauth.scope.files:read.description': 'Lista dokumenten på en resa: namn, storlek, vem som laddade upp dem och vad de är kopplade till', + 'oauth.scope.files:write.label': 'Hantera resans filer', + 'oauth.scope.files:write.description': 'Byt namn på och beskriv filer, koppla dem till bokningar och platser, stjärnmärk och släng dem', + 'oauth.scope.files:content.label': 'Läsa filinnehåll', + 'oauth.scope.files:content.description': 'Läsa innehållet i ett uppladdat dokument, till exempel en boknings-PDF eller en biljett', + 'oauth.scope.settings:read.label': 'Visa dina inställningar', + 'oauth.scope.settings:read.description': 'Läsa enheter, tidsformat, språk, standardvaluta och startsida', + 'oauth.scope.settings:write.label': 'Ändra dina inställningar', + 'oauth.scope.settings:write.description': 'Ändra enheter, tidsformat, språk, standardvaluta och startsida. Aldrig sparade API-nycklar', }; export default oauth; diff --git a/shared/src/i18n/tr/oauth.ts b/shared/src/i18n/tr/oauth.ts index 29216f452..231f7fb1e 100644 --- a/shared/src/i18n/tr/oauth.ts +++ b/shared/src/i18n/tr/oauth.ts @@ -98,5 +98,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'Dosyalar', + 'oauth.scope.group.settings': 'Ayarlar', + 'oauth.scope.files:read.label': 'Gezi dosyalarını görüntüle', + 'oauth.scope.files:read.description': 'Bir gezinin belgelerini listele: adlar, boyutlar, kimin yüklediği ve neye bağlı oldukları', + 'oauth.scope.files:write.label': 'Gezi dosyalarını yönet', + 'oauth.scope.files:write.description': 'Dosyaları yeniden adlandır ve açıkla, rezervasyonlara ve yerlere bağla, yıldızla ve çöpe taşı', + 'oauth.scope.files:content.label': 'Dosya içeriğini oku', + 'oauth.scope.files:content.description': 'Yüklenmiş bir belgenin içeriğini oku, örneğin bir rezervasyon PDF’i veya bir bilet', + 'oauth.scope.settings:read.label': 'Tercihlerini görüntüle', + 'oauth.scope.settings:read.description': 'Birimleri, saat biçimini, dili, varsayılan para birimini ve başlangıç sayfasını oku', + 'oauth.scope.settings:write.label': 'Tercihlerini değiştir', + 'oauth.scope.settings:write.description': 'Birimleri, saat biçimini, dili, varsayılan para birimini ve başlangıç sayfasını değiştir. Kayıtlı API anahtarlarını asla', }; export default oauth; diff --git a/shared/src/i18n/uk/oauth.ts b/shared/src/i18n/uk/oauth.ts index ed4109f1b..d9e3f4786 100644 --- a/shared/src/i18n/uk/oauth.ts +++ b/shared/src/i18n/uk/oauth.ts @@ -94,5 +94,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': 'Файли', + 'oauth.scope.group.settings': 'Налаштування', + 'oauth.scope.files:read.label': 'Перегляд файлів подорожі', + 'oauth.scope.files:read.description': 'Список документів подорожі: назви, розміри, хто їх завантажив і з чим вони пов’язані', + 'oauth.scope.files:write.label': 'Керування файлами подорожі', + 'oauth.scope.files:write.description': 'Перейменування та опис файлів, прив’язка до бронювань і місць, позначення та переміщення в кошик', + 'oauth.scope.files:content.label': 'Читання вмісту файлів', + 'oauth.scope.files:content.description': 'Читання вмісту завантаженого документа, наприклад PDF бронювання або квитка', + 'oauth.scope.settings:read.label': 'Перегляд ваших налаштувань', + 'oauth.scope.settings:read.description': 'Читання одиниць вимірювання, формату часу, мови, валюти за умовчанням і стартової сторінки', + 'oauth.scope.settings:write.label': 'Зміна ваших налаштувань', + 'oauth.scope.settings:write.description': 'Зміна одиниць вимірювання, формату часу, мови, валюти за умовчанням і стартової сторінки. Ніколи збережених ключів API', }; export default oauth; diff --git a/shared/src/i18n/vi/oauth.ts b/shared/src/i18n/vi/oauth.ts index 410e5e28e..84723220b 100644 --- a/shared/src/i18n/vi/oauth.ts +++ b/shared/src/i18n/vi/oauth.ts @@ -97,5 +97,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysTool.listTrips': 'Liệt kê các chuyến đi của bạn để AI có thể khám phá ID chuyến đi', 'oauth.authorize.alwaysTool.getTripSummary': 'Đọc tổng quan về chuyến đi cần thiết để sử dụng bất kỳ công cụ nào khác', + 'oauth.scope.group.files': 'Tệp', + 'oauth.scope.group.settings': 'Cài đặt', + 'oauth.scope.files:read.label': 'Xem tệp của chuyến đi', + 'oauth.scope.files:read.description': 'Liệt kê tài liệu của chuyến đi: tên, kích thước, ai đã tải lên và chúng liên kết với gì', + 'oauth.scope.files:write.label': 'Quản lý tệp của chuyến đi', + 'oauth.scope.files:write.description': 'Đổi tên và mô tả tệp, liên kết với đặt chỗ và địa điểm, gắn sao và chuyển vào thùng rác', + 'oauth.scope.files:content.label': 'Đọc nội dung tệp', + 'oauth.scope.files:content.description': 'Đọc nội dung của tài liệu đã tải lên, chẳng hạn PDF đặt chỗ hoặc vé', + 'oauth.scope.settings:read.label': 'Xem tuỳ chọn của bạn', + 'oauth.scope.settings:read.description': 'Đọc đơn vị, định dạng giờ, ngôn ngữ, tiền tệ mặc định và trang khởi đầu', + 'oauth.scope.settings:write.label': 'Thay đổi tuỳ chọn của bạn', + 'oauth.scope.settings:write.description': 'Thay đổi đơn vị, định dạng giờ, ngôn ngữ, tiền tệ mặc định và trang khởi đầu. Không bao giờ khoá API đã lưu', }; export default oauth; diff --git a/shared/src/i18n/zh-TW/oauth.ts b/shared/src/i18n/zh-TW/oauth.ts index 81b2eebd1..9aa758ce2 100644 --- a/shared/src/i18n/zh-TW/oauth.ts +++ b/shared/src/i18n/zh-TW/oauth.ts @@ -92,5 +92,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': 'Always included', // en-fallback 'oauth.authorize.alwaysTool.listTrips': 'List your trips so the AI can discover trip IDs', // en-fallback 'oauth.authorize.alwaysTool.getTripSummary': 'Read a trip overview needed to use any other tool', // en-fallback + 'oauth.scope.group.files': '檔案', + 'oauth.scope.group.settings': '設定', + 'oauth.scope.files:read.label': '檢視行程檔案', + 'oauth.scope.files:read.description': '列出行程的文件:名稱、大小、上傳者以及關聯的對象', + 'oauth.scope.files:write.label': '管理行程檔案', + 'oauth.scope.files:write.description': '重新命名與描述檔案,關聯至訂位和地點,加上星號並移至垃圾桶', + 'oauth.scope.files:content.label': '讀取檔案內容', + 'oauth.scope.files:content.description': '讀取已上傳文件的內容,例如訂位 PDF 或票券', + 'oauth.scope.settings:read.label': '檢視你的偏好設定', + 'oauth.scope.settings:read.description': '讀取單位、時間格式、語言、預設貨幣和起始頁', + 'oauth.scope.settings:write.label': '更改你的偏好設定', + 'oauth.scope.settings:write.description': '更改單位、時間格式、語言、預設貨幣和起始頁。絕不涉及已儲存的 API 金鑰', }; export default oauth; diff --git a/shared/src/i18n/zh/oauth.ts b/shared/src/i18n/zh/oauth.ts index e1338aeec..1410c6933 100644 --- a/shared/src/i18n/zh/oauth.ts +++ b/shared/src/i18n/zh/oauth.ts @@ -92,5 +92,17 @@ const oauth: TranslationStrings = { 'oauth.authorize.alwaysIncluded': '始终包含', 'oauth.authorize.alwaysTool.listTrips': '列出你的行程,以使 AI 找到行程 ID', 'oauth.authorize.alwaysTool.getTripSummary': '读取行程概览,这是使用其他工具所需的信息', + 'oauth.scope.group.files': '文件', + 'oauth.scope.group.settings': '设置', + 'oauth.scope.files:read.label': '查看行程文件', + 'oauth.scope.files:read.description': '列出行程的文档:名称、大小、上传者以及关联的对象', + 'oauth.scope.files:write.label': '管理行程文件', + 'oauth.scope.files:write.description': '重命名和描述文件,关联到预订和地点,标记星标并移入回收站', + 'oauth.scope.files:content.label': '读取文件内容', + 'oauth.scope.files:content.description': '读取已上传文档的内容,例如预订 PDF 或票据', + 'oauth.scope.settings:read.label': '查看你的偏好设置', + 'oauth.scope.settings:read.description': '读取单位、时间格式、语言、默认货币和起始页', + 'oauth.scope.settings:write.label': '更改你的偏好设置', + 'oauth.scope.settings:write.description': '更改单位、时间格式、语言、默认货币和起始页。绝不涉及已保存的 API 密钥', }; export default oauth; diff --git a/wiki/MCP-Scopes.md b/wiki/MCP-Scopes.md index ec4037c2e..d24610bbb 100644 --- a/wiki/MCP-Scopes.md +++ b/wiki/MCP-Scopes.md @@ -6,7 +6,7 @@ OAuth scopes control exactly which data your AI client can read or write in TREK ## All scopes -TREK defines 29 scopes across 14 groups. +TREK defines 34 scopes across 16 groups. | Group | Scope | Permission | |---|---|---| @@ -39,12 +39,19 @@ TREK defines 29 scopes across 14 groups. | **Journey** | `journey:read` | Read journeys, entries, and contributor list | | | `journey:write` | Create, update, and delete journeys and their entries | | | `journey:share` | Create, update, and revoke public share links for journeys | +| **Files** | `files:read` | List the documents on a trip: names, sizes, who uploaded them, what they link to | +| | `files:write` | Rename and describe files, link them to bookings and places, star and trash them | +| | `files:content` | Read what is inside an uploaded document, such as a booking PDF or a ticket | +| **Settings** | `settings:read` | Read units, time format, language, default currency, and start page | +| | `settings:write` | Change units, time format, language, default currency, and start page | ## Scope rules - A `:write` scope implies `:read` access for the same group (e.g. `budget:write` also grants read access to budget data). - Any `trips:*` scope (`trips:read`, `trips:write`, `trips:delete`, or `trips:share`) grants trip read access. -- `journey:read` or `journey:write` grants journey read access. `journey:share` alone does **not** grant read access — it only enables managing public share links. +- `journey:read` or `journey:write` grants journey read access. `journey:share` alone does **not** grant read access, it only enables managing public share links. +- `files:content` is a **separate** scope from `files:read` and is not implied by `files:write`. A token can list a trip's documents without being allowed to read what is inside them. Content reads are capped at 10 MB per file. +- `settings:write` never reaches a stored credential. The API keys, tokens and webhook URLs kept in settings are refused by the same allow-list the REST route uses, so an assistant can switch you to Fahrenheit but cannot read or replace your Mapbox key. - `list_trips` and `get_trip_summary` are always available regardless of scope — they are navigation tools. - Static tokens and web session JWTs have full access equivalent to all scopes. - Addon-gated tools (Packing, To-dos, Budget, Collections, Atlas, Collab, Vacay, Journey) require both the relevant scope **and** the corresponding addon to be enabled by an admin. The to-do tools ride the **Packing** addon, not an addon of their own.