Localize mcp.php + add mcp-tool.php detail pages for all 19 MCP tools
- Replace all hardcoded English strings in mcp.php with dbnToolsT() calls - Add 44 MCP UI chrome translation keys to includes/i18n.php (en/no/uk/pl) - Generate includes/mcp-tool-translations.php with tool names, descriptions, and parameter docs translated into Norwegian, Ukrainian, and Polish via Azure OpenAI - Create mcp-tool.php: parameterized detail page (?tool=dbn.slug) with parameter table, example request/response JSON, and privacy section, all localized - Add "View details →" links on tool cards in mcp.php (shown on expand) - Add translations/mcp-chrome.php and scripts/generate-mcp-translations.php Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -458,6 +458,56 @@ function dbnToolsTranslations(): array
|
||||
'lt_engine_hint' => 'Engine: Azure GPT-4o · Legal documents are processed in memory and never stored.',
|
||||
'lt_same_lang_error' => 'Source and target languages must be different.',
|
||||
'lt_disclaimer' => 'This is an AI-assisted translation. Always verify with a qualified legal interpreter for official use.',
|
||||
|
||||
// MCP setup page + tool detail pages
|
||||
'mcp_page_title' => 'MCP — Do Better Norge',
|
||||
'mcp_meta_desc' => 'Connect Claude, Cursor, and other AI tools to all 19 DBN legal preparation tools via MCP.',
|
||||
'mcp_hero_badge' => '✦ Plus & Pro',
|
||||
'mcp_hero_h1' => 'Use DBN tools from Claude, Cursor & Copilot',
|
||||
'mcp_hero_sub' => 'Connect any MCP client to all 19 Do Better Norge tools — transcription, legal analysis, timelines, redaction, and more.',
|
||||
'mcp_token_section_title' => 'Your MCP token',
|
||||
'mcp_gate_guest_p' => 'Sign in to create your personal MCP token. Available to Plus and Pro members.',
|
||||
'mcp_gate_guest_btn' => 'Sign in',
|
||||
'mcp_gate_free_p' => 'MCP access is available on Plus and Pro plans. Upgrade to connect your AI tools.',
|
||||
'mcp_gate_free_btn' => 'Upgrade plan',
|
||||
'mcp_token_hint' => 'Tokens are shown once at creation. Create one per client (Claude, Cursor, VS Code…).',
|
||||
'mcp_token_create_btn' => 'Create token',
|
||||
'mcp_token_reveal_label' => 'Copy this token now — it will not be shown again:',
|
||||
'mcp_token_copy_btn' => 'Copy token',
|
||||
'mcp_token_no_tokens' => 'No MCP tokens yet.',
|
||||
'mcp_token_active' => 'Active',
|
||||
'mcp_token_revoked' => 'Revoked',
|
||||
'mcp_token_never_used' => 'Never used',
|
||||
'mcp_token_last_used' => 'Last used',
|
||||
'mcp_token_revoke_btn' => 'Revoke',
|
||||
'mcp_config_title' => 'Client configuration',
|
||||
'mcp_config_hint' => 'Paste your token into the config below after creating it above.',
|
||||
'mcp_config_token_filled' => 'Token auto-filled.',
|
||||
'mcp_config_run_terminal' => 'Run in your terminal:',
|
||||
'mcp_test_btn' => 'Test connection',
|
||||
'mcp_test_no_token' => 'Create a token first.',
|
||||
'mcp_test_testing' => 'Testing…',
|
||||
'mcp_tools_title' => 'Available tools',
|
||||
'mcp_tools_sub' => 'All tools run on your Plus or Pro plan credits. Click a card for full technical details.',
|
||||
'mcp_tools_param_req_hint' => 'Purple = required',
|
||||
'mcp_tools_view_details' => 'View details →',
|
||||
'mcp_privacy_title' => 'Privacy',
|
||||
'mcp_privacy_text' => 'Process-and-forget by default. All tool calls process your text in memory and return results to your AI client. Nothing is saved to My Case unless you explicitly call dbn.save_to_case.',
|
||||
'mcp_privacy_legal' => 'Tools provide legal preparation support, not final legal advice. Results are for informational purposes and should be reviewed by a qualified legal professional.',
|
||||
'mcp_tool_back' => '← Back to MCP setup',
|
||||
'mcp_tool_params_title' => 'Parameters',
|
||||
'mcp_tool_no_params' => 'This tool takes no input parameters.',
|
||||
'mcp_tool_col_param' => 'Parameter',
|
||||
'mcp_tool_col_type' => 'Type',
|
||||
'mcp_tool_col_required' => 'Required',
|
||||
'mcp_tool_col_desc' => 'Description',
|
||||
'mcp_tool_example_req' => 'Example request',
|
||||
'mcp_tool_example_resp' => 'Example response',
|
||||
'mcp_tool_connect_title' => 'Connect',
|
||||
'mcp_tool_connect_text' => 'Create your MCP token on the setup page and use it with any supported client.',
|
||||
'mcp_tool_setup_link' => 'Set up MCP →',
|
||||
'mcp_tool_yes' => 'Yes',
|
||||
'mcp_tool_no' => 'No',
|
||||
],
|
||||
'no' => [
|
||||
'meta_title' => 'Do Better Norge - juridiske AI-verktøy',
|
||||
@@ -848,6 +898,56 @@ function dbnToolsTranslations(): array
|
||||
'lt_engine_hint' => 'Motor: Azure GPT-4o · Juridiske dokumenter behandles i minnet og lagres aldri.',
|
||||
'lt_same_lang_error' => 'Kilde- og målspråk må være forskjellige.',
|
||||
'lt_disclaimer' => 'Dette er en AI-assistert oversettelse. Verifiser alltid med en kvalifisert juridisk tolk til offisielt bruk.',
|
||||
|
||||
// MCP setup page + tool detail pages
|
||||
'mcp_page_title' => 'MCP — Do Better Norge',
|
||||
'mcp_meta_desc' => 'Koble Claude, Cursor og andre AI-verktøy til alle 19 DBN juridiske forberedelsesverktøy via MCP.',
|
||||
'mcp_hero_badge' => '✦ Plus & Pro',
|
||||
'mcp_hero_h1' => 'Bruk DBN-verktøy fra Claude, Cursor & Copilot',
|
||||
'mcp_hero_sub' => 'Koble enhver MCP-klient til alle 19 Do Better Norge-verktøy — transkripsjon, juridisk analyse, tidslinjer, redigering og mer.',
|
||||
'mcp_token_section_title' => 'Din MCP-token',
|
||||
'mcp_gate_guest_p' => 'Logg inn for å opprette din personlige MCP-token. Tilgjengelig for Plus- og Pro-medlemmer.',
|
||||
'mcp_gate_guest_btn' => 'Logg inn',
|
||||
'mcp_gate_free_p' => 'MCP-tilgang er tilgjengelig på Plus- og Pro-planer. Oppgrader for å koble dine AI-verktøy.',
|
||||
'mcp_gate_free_btn' => 'Oppgrader plan',
|
||||
'mcp_token_hint' => 'Tokens vises én gang ved opprettelse. Opprett én per klient (Claude, Cursor, VS Code…).',
|
||||
'mcp_token_create_btn' => 'Opprett token',
|
||||
'mcp_token_reveal_label' => 'Kopier denne token nå — den vil ikke bli vist igjen:',
|
||||
'mcp_token_copy_btn' => 'Kopier token',
|
||||
'mcp_token_no_tokens' => 'Ingen MCP-tokens ennå.',
|
||||
'mcp_token_active' => 'Aktiv',
|
||||
'mcp_token_revoked' => 'Tilbaketrukket',
|
||||
'mcp_token_never_used' => 'Aldri brukt',
|
||||
'mcp_token_last_used' => 'Sist brukt',
|
||||
'mcp_token_revoke_btn' => 'Tilbakekall',
|
||||
'mcp_config_title' => 'Klientkonfigurasjon',
|
||||
'mcp_config_hint' => 'Lim inn tokenet ditt i konfigurasjonen nedenfor etter å ha opprettet det ovenfor.',
|
||||
'mcp_config_token_filled' => 'Token automatisk fylt ut.',
|
||||
'mcp_config_run_terminal' => 'Kjør i terminalen din:',
|
||||
'mcp_test_btn' => 'Test tilkobling',
|
||||
'mcp_test_no_token' => 'Opprett et token først.',
|
||||
'mcp_test_testing' => 'Tester…',
|
||||
'mcp_tools_title' => 'Tilgjengelige verktøy',
|
||||
'mcp_tools_sub' => 'Alle verktøy kjører på kreditter fra din Plus- eller Pro-plan. Klikk på et kort for full teknisk informasjon.',
|
||||
'mcp_tools_param_req_hint' => 'Lilla = påkrevd',
|
||||
'mcp_tools_view_details' => 'Se detaljer →',
|
||||
'mcp_privacy_title' => 'Personvern',
|
||||
'mcp_privacy_text' => 'Prosesser og glem som standard. Alle verktøyanrop prosesserer teksten din i minnet og returnerer resultater til din AI-klient. Ingenting lagres i Min sak med mindre du eksplisitt kaller dbn.save_to_case.',
|
||||
'mcp_privacy_legal' => 'Verktøyene gir støtte til juridisk forberedelse, ikke endelig juridisk rådgivning. Resultatene er kun til informasjonsformål og bør vurderes av en kvalifisert juridisk profesjonell.',
|
||||
'mcp_tool_back' => '← Tilbake til MCP-oppsett',
|
||||
'mcp_tool_params_title' => 'Parametere',
|
||||
'mcp_tool_no_params' => 'Dette verktøyet tar ingen inndata-parametere.',
|
||||
'mcp_tool_col_param' => 'Parameter',
|
||||
'mcp_tool_col_type' => 'Type',
|
||||
'mcp_tool_col_required' => 'Påkrevd',
|
||||
'mcp_tool_col_desc' => 'Beskrivelse',
|
||||
'mcp_tool_example_req' => 'Eksempel på forespørsel',
|
||||
'mcp_tool_example_resp' => 'Eksempel på svar',
|
||||
'mcp_tool_connect_title' => 'Koble til',
|
||||
'mcp_tool_connect_text' => 'Opprett din MCP-token på oppsettssiden og bruk den med enhver støttet klient.',
|
||||
'mcp_tool_setup_link' => 'Sett opp MCP →',
|
||||
'mcp_tool_yes' => 'Ja',
|
||||
'mcp_tool_no' => 'Nei',
|
||||
],
|
||||
'uk' => [
|
||||
'meta_title' => 'Do Better Norge - юридичні AI інструменти',
|
||||
@@ -1238,6 +1338,56 @@ function dbnToolsTranslations(): array
|
||||
'lt_engine_hint' => 'Механізм: Azure GPT-4o · Юридичні документи обробляються в пам\'яті та не зберігаються.',
|
||||
'lt_same_lang_error' => 'Мова оригіналу та мова перекладу повинні бути різними.',
|
||||
'lt_disclaimer' => 'Це переклад за допомогою штучного інтелекту. Завжди перевіряйте з кваліфікованим юридичним перекладачем для офіційного використання.',
|
||||
|
||||
// MCP setup page + tool detail pages
|
||||
'mcp_page_title' => 'MCP — Do Better Norge',
|
||||
'mcp_meta_desc' => 'Підключіть Claude, Cursor та інші інструменти ШІ до всіх 19 юридичних підготовчих інструментів DBN через MCP.',
|
||||
'mcp_hero_badge' => '✦ Плюс та Профі',
|
||||
'mcp_hero_h1' => 'Використовуйте інструменти DBN від Claude, Cursor та Copilot',
|
||||
'mcp_hero_sub' => 'Підключіть будь-якого клієнта MCP до всіх 19 інструментів Do Better Norge — транскрипція, юридичний аналіз, часові лінії, редагування та інше.',
|
||||
'mcp_token_section_title' => 'Ваш токен MCP',
|
||||
'mcp_gate_guest_p' => 'Увійдіть, щоб створити свій особистий токен MCP. Доступно для учасників Плюс та Профі.',
|
||||
'mcp_gate_guest_btn' => 'Увійти',
|
||||
'mcp_gate_free_p' => 'Доступ до MCP доступний у планах Плюс та Профі. Оновіть, щоб підключити свої інструменти ШІ.',
|
||||
'mcp_gate_free_btn' => 'Оновити план',
|
||||
'mcp_token_hint' => 'Токени показуються один раз під час створення. Створіть один для кожного клієнта (Claude, Cursor, VS Code…).',
|
||||
'mcp_token_create_btn' => 'Створити токен',
|
||||
'mcp_token_reveal_label' => 'Скопіюйте цей токен зараз — він більше не буде показаний:',
|
||||
'mcp_token_copy_btn' => 'Скопіювати токен',
|
||||
'mcp_token_no_tokens' => 'Ще немає токенів MCP.',
|
||||
'mcp_token_active' => 'Активний',
|
||||
'mcp_token_revoked' => 'Скасовано',
|
||||
'mcp_token_never_used' => 'Ніколи не використовувався',
|
||||
'mcp_token_last_used' => 'Останній раз використовувався',
|
||||
'mcp_token_revoke_btn' => 'Скасувати',
|
||||
'mcp_config_title' => 'Конфігурація клієнта',
|
||||
'mcp_config_hint' => 'Вставте свій токен у конфігурацію нижче після його створення вище.',
|
||||
'mcp_config_token_filled' => 'Токен автоматично заповнений.',
|
||||
'mcp_config_run_terminal' => 'Запустіть у вашому терміналі:',
|
||||
'mcp_test_btn' => 'Перевірити з\'єднання',
|
||||
'mcp_test_no_token' => 'Спочатку створіть токен.',
|
||||
'mcp_test_testing' => 'Тестування…',
|
||||
'mcp_tools_title' => 'Доступні інструменти',
|
||||
'mcp_tools_sub' => 'Усі інструменти працюють на кредитах вашого плану Plus або Pro. Натисніть на картку для отримання повних технічних деталей.',
|
||||
'mcp_tools_param_req_hint' => 'Фіолетовий = обов\'язковий',
|
||||
'mcp_tools_view_details' => 'Переглянути деталі →',
|
||||
'mcp_privacy_title' => 'Конфіденційність',
|
||||
'mcp_privacy_text' => 'Обробка та забуття за замовчуванням. Усі виклики інструментів обробляють ваш текст у пам\'яті та повертають результати вашому AI-клієнту. Нічого не зберігається у My Case, якщо ви явно не викликаєте dbn.save_to_case.',
|
||||
'mcp_privacy_legal' => 'Інструменти надають підтримку в підготовці юридичних документів, а не остаточні юридичні поради. Результати призначені лише для інформаційних цілей і повинні бути переглянуті кваліфікованим юридичним фахівцем.',
|
||||
'mcp_tool_back' => '← Повернутися до налаштування MCP',
|
||||
'mcp_tool_params_title' => 'Параметри',
|
||||
'mcp_tool_no_params' => 'Цей інструмент не приймає вхідних параметрів.',
|
||||
'mcp_tool_col_param' => 'Параметр',
|
||||
'mcp_tool_col_type' => 'Тип',
|
||||
'mcp_tool_col_required' => 'Обов\'язковий',
|
||||
'mcp_tool_col_desc' => 'Опис',
|
||||
'mcp_tool_example_req' => 'Приклад запиту',
|
||||
'mcp_tool_example_resp' => 'Приклад відповіді',
|
||||
'mcp_tool_connect_title' => 'Підключити',
|
||||
'mcp_tool_connect_text' => 'Створіть свій токен MCP на сторінці налаштувань і використовуйте його з будь-яким підтримуваним клієнтом.',
|
||||
'mcp_tool_setup_link' => 'Налаштувати MCP →',
|
||||
'mcp_tool_yes' => 'Так',
|
||||
'mcp_tool_no' => 'Ні',
|
||||
],
|
||||
'pl' => [
|
||||
'meta_title' => 'Do Better Norge - prawne narzędzia AI',
|
||||
@@ -1628,6 +1778,56 @@ function dbnToolsTranslations(): array
|
||||
'lt_engine_hint' => 'Silnik: Azure GPT-4o · Dokumenty prawne są przetwarzane w pamięci i nigdy nie zapisywane.',
|
||||
'lt_same_lang_error' => 'Języki źródłowy i docelowy muszą być różne.',
|
||||
'lt_disclaimer' => 'To jest tłumaczenie wspomagane AI. Zawsze weryfikuj z wykwalifikowanym tłumaczem prawnym do oficjalnego użytku.',
|
||||
|
||||
// MCP setup page + tool detail pages
|
||||
'mcp_page_title' => 'MCP — Do Better Norge',
|
||||
'mcp_meta_desc' => 'Połącz Claude, Cursor i inne narzędzia AI z wszystkimi 19 narzędziami przygotowania prawnego DBN za pośrednictwem MCP.',
|
||||
'mcp_hero_badge' => '✦ Plus & Pro',
|
||||
'mcp_hero_h1' => 'Użyj narzędzi DBN z Claude, Cursor i Copilot',
|
||||
'mcp_hero_sub' => 'Połącz dowolnego klienta MCP ze wszystkimi 19 narzędziami Do Better Norge — transkrypcja, analiza prawna, harmonogramy, redakcja i inne.',
|
||||
'mcp_token_section_title' => 'Twój token MCP',
|
||||
'mcp_gate_guest_p' => 'Zaloguj się, aby utworzyć swój osobisty token MCP. Dostępny dla członków Plus i Pro.',
|
||||
'mcp_gate_guest_btn' => 'Zaloguj się',
|
||||
'mcp_gate_free_p' => 'Dostęp do MCP jest dostępny w planach Plus i Pro. Uaktualnij, aby połączyć swoje narzędzia AI.',
|
||||
'mcp_gate_free_btn' => 'Uaktualnij plan',
|
||||
'mcp_token_hint' => 'Tokeny są wyświetlane tylko raz przy tworzeniu. Utwórz jeden na klienta (Claude, Cursor, VS Code…).',
|
||||
'mcp_token_create_btn' => 'Utwórz token',
|
||||
'mcp_token_reveal_label' => 'Skopiuj ten token teraz — nie będzie już wyświetlany:',
|
||||
'mcp_token_copy_btn' => 'Skopiuj token',
|
||||
'mcp_token_no_tokens' => 'Brak tokenów MCP.',
|
||||
'mcp_token_active' => 'Aktywny',
|
||||
'mcp_token_revoked' => 'Cofnięty',
|
||||
'mcp_token_never_used' => 'Nigdy nie używany',
|
||||
'mcp_token_last_used' => 'Ostatnio używany',
|
||||
'mcp_token_revoke_btn' => 'Cofnij',
|
||||
'mcp_config_title' => 'Konfiguracja klienta',
|
||||
'mcp_config_hint' => 'Wklej swój token do konfiguracji poniżej po jego utworzeniu powyżej.',
|
||||
'mcp_config_token_filled' => 'Token automatycznie wypełniony.',
|
||||
'mcp_config_run_terminal' => 'Uruchom w swoim terminalu:',
|
||||
'mcp_test_btn' => 'Testuj połączenie',
|
||||
'mcp_test_no_token' => 'Najpierw utwórz token.',
|
||||
'mcp_test_testing' => 'Testowanie…',
|
||||
'mcp_tools_title' => 'Dostępne narzędzia',
|
||||
'mcp_tools_sub' => 'Wszystkie narzędzia działają na kredytach Twojego planu Plus lub Pro. Kliknij kartę, aby uzyskać pełne szczegóły techniczne.',
|
||||
'mcp_tools_param_req_hint' => 'Fioletowy = wymagany',
|
||||
'mcp_tools_view_details' => 'Zobacz szczegóły →',
|
||||
'mcp_privacy_title' => 'Prywatność',
|
||||
'mcp_privacy_text' => 'Domyślnie przetwarzaj i zapomnij. Wszystkie wywołania narzędzi przetwarzają Twój tekst w pamięci i zwracają wyniki do Twojego klienta AI. Nic nie jest zapisywane w Mojej Sprawie, chyba że wyraźnie wywołasz dbn.save_to_case.',
|
||||
'mcp_privacy_legal' => 'Narzędzia zapewniają wsparcie w zakresie przygotowania prawnego, a nie ostatecznej porady prawnej. Wyniki mają charakter informacyjny i powinny być przeglądane przez wykwalifikowanego profesjonalistę prawnego.',
|
||||
'mcp_tool_back' => '← Powrót do konfiguracji MCP',
|
||||
'mcp_tool_params_title' => 'Parametry',
|
||||
'mcp_tool_no_params' => 'To narzędzie nie przyjmuje parametrów wejściowych.',
|
||||
'mcp_tool_col_param' => 'Parametr',
|
||||
'mcp_tool_col_type' => 'Typ',
|
||||
'mcp_tool_col_required' => 'Wymagany',
|
||||
'mcp_tool_col_desc' => 'Opis',
|
||||
'mcp_tool_example_req' => 'Przykładowe żądanie',
|
||||
'mcp_tool_example_resp' => 'Przykładowa odpowiedź',
|
||||
'mcp_tool_connect_title' => 'Połącz',
|
||||
'mcp_tool_connect_text' => 'Utwórz swój token MCP na stronie konfiguracji i użyj go z dowolnym obsługiwanym klientem.',
|
||||
'mcp_tool_setup_link' => 'Skonfiguruj MCP →',
|
||||
'mcp_tool_yes' => 'Tak',
|
||||
'mcp_tool_no' => 'Nie',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,970 @@
|
||||
<?php
|
||||
// MCP tool translations — display_name, description, param descriptions
|
||||
// DO NOT EDIT MANUALLY — regenerate with scripts/generate-mcp-translations.php
|
||||
return array (
|
||||
'dbn.search_legal' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Search DBN legal corpus',
|
||||
'description' => 'Search the DBN Norwegian family-law corpus.',
|
||||
'params' =>
|
||||
array (
|
||||
'query' => 'The search query (minimum 3 characters). Enter a legal topic, keyword, or question.',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto (detect from input).',
|
||||
'limit' => 'Maximum number of results to return (1–10).',
|
||||
'corpus_scope' => 'Which corpus to search: shared (public legal corpus), private (your uploaded documents), or both.',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Søk i DBN juridisk korpus',
|
||||
'description' => 'Søk i DBN norsk familierett korpus.',
|
||||
'params' =>
|
||||
array (
|
||||
'query' => 'Søketeksten (minimum 3 tegn). Skriv inn et juridisk emne, nøkkelord eller spørsmål.',
|
||||
'language' => 'Svarspråk: en, no, uk, pl, eller auto (oppdages fra input).',
|
||||
'limit' => 'Maksimalt antall resultater som skal returneres (1–10).',
|
||||
'corpus_scope' => 'Hvilket korpus skal søkes i: delt (offentlig juridisk korpus), privat (dine opplastede dokumenter), eller begge.',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Пошук юридичного корпусу DBN',
|
||||
'description' => 'Пошук норвезького корпусу сімейного права DBN.',
|
||||
'params' =>
|
||||
array (
|
||||
'query' => 'Пошуковий запит (мінімум 3 символи). Введіть юридичну тему, ключове слово або запитання.',
|
||||
'language' => 'Мова відповіді: en, no, uk, pl або auto (виявити з введення).',
|
||||
'limit' => 'Максимальна кількість результатів для повернення (1–10).',
|
||||
'corpus_scope' => 'Який корпус шукати: спільний (публічний юридичний корпус), приватний (ваші завантажені документи) або обидва.',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Szukaj w korpusie prawnym DBN',
|
||||
'description' => 'Szukaj w norweskim korpusie prawa rodzinnego DBN.',
|
||||
'params' =>
|
||||
array (
|
||||
'query' => 'Zapytanie wyszukiwania (minimum 3 znaki). Wprowadź temat prawny, słowo kluczowe lub pytanie.',
|
||||
'language' => 'Język odpowiedzi: en, no, uk, pl lub auto (wykrywanie na podstawie wejścia).',
|
||||
'limit' => 'Maksymalna liczba wyników do zwrócenia (1–10).',
|
||||
'corpus_scope' => 'Który korpus przeszukać: wspólny (publiczny korpus prawny), prywatny (twoje przesłane dokumenty) lub oba.',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.ask' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Ask a legal question',
|
||||
'description' => 'Answer a legal preparation question with source-grounded DBN context.',
|
||||
'params' =>
|
||||
array (
|
||||
'question' => 'The legal question to answer (minimum 5 characters).',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'use_case_context' => 'Include context from your Case Workbench session (true/false).',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Still et juridisk spørsmål',
|
||||
'description' => 'Svar på et juridisk forberedelsesspørsmål med kildebasert DBN kontekst.',
|
||||
'params' =>
|
||||
array (
|
||||
'question' => 'Det juridiske spørsmålet som skal besvares (minimum 5 tegn).',
|
||||
'language' => 'Svarspråk: en, no, uk, pl, eller auto.',
|
||||
'use_case_context' => 'Inkluder kontekst fra din Case Workbench økt (true/false).',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Задати юридичне питання',
|
||||
'description' => 'Відповісти на питання підготовки до суду з контекстом, основаним на DBN.',
|
||||
'params' =>
|
||||
array (
|
||||
'question' => 'Юридичне питання для відповіді (мінімум 5 символів).',
|
||||
'language' => 'Мова відповіді: en, no, uk, pl або auto.',
|
||||
'use_case_context' => 'Включити контекст з вашої сесії Case Workbench (true/false).',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Zadaj pytanie prawne',
|
||||
'description' => 'Odpowiedz na pytanie dotyczące przygotowania prawnego z kontekstem opartym na źródłach DBN.',
|
||||
'params' =>
|
||||
array (
|
||||
'question' => 'Pytanie prawne do odpowiedzi (minimum 5 znaków).',
|
||||
'language' => 'Język odpowiedzi: en, no, uk, pl lub auto.',
|
||||
'use_case_context' => 'Uwzględnij kontekst z sesji Case Workbench (prawda/fałsz).',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.summarize' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Summarize document',
|
||||
'description' => 'Summarize pasted case text with optional legal-corpus enrichment.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'The text to summarize.',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'use_legal_corpus' => 'Enrich the summary with relevant legal corpus passages (true/false).',
|
||||
'use_case_context' => 'Include context from your Case Workbench session (true/false).',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Oppsummer dokument',
|
||||
'description' => 'Oppsummer innlimt sakstekst med valgfri berikelse fra juridisk korpus.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Teksten som skal oppsummeres.',
|
||||
'language' => 'Svarspråk: en, no, uk, pl, eller auto.',
|
||||
'use_legal_corpus' => 'Berik oppsummeringen med relevante passasjer fra juridisk korpus (true/false).',
|
||||
'use_case_context' => 'Inkluder kontekst fra din Case Workbench økt (true/false).',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Підсумувати документ',
|
||||
'description' => 'Підсумувати вставлений текст справи з можливим збагаченням юридичним корпусом.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Текст для підсумування.',
|
||||
'language' => 'Мова відповіді: en, no, uk, pl або auto.',
|
||||
'use_legal_corpus' => 'Збагачувати підсумок відповідними уривками з юридичного корпусу (true/false).',
|
||||
'use_case_context' => 'Включити контекст з вашої сесії Case Workbench (true/false).',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Podsumuj dokument',
|
||||
'description' => 'Podsumuj wklejony tekst sprawy z opcjonalnym wzbogaceniem korpusu prawnego.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Tekst do podsumowania.',
|
||||
'language' => 'Język odpowiedzi: en, no, uk, pl lub auto.',
|
||||
'use_legal_corpus' => 'Wzbogac podsumowanie o odpowiednie fragmenty korpusu prawnego (prawda/fałsz).',
|
||||
'use_case_context' => 'Uwzględnij kontekst z sesji Case Workbench (prawda/fałsz).',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.timeline' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Extract timeline',
|
||||
'description' => 'Extract dates, hearings, milestones, and deadlines from case text.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'The case text to extract dates from.',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'focus' => 'What to extract: all (every date), deadlines (appeal windows and filing deadlines), hearings (tribunal and court dates), cps (Barnevernet milestones).',
|
||||
'use_case_context' => 'Include context from your Case Workbench session (true/false).',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Ekstraher tidslinje',
|
||||
'description' => 'Ekstraher datoer, høringer, milepæler og frister fra sakstekst.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Saksteksten for å ekstrahere datoer fra.',
|
||||
'language' => 'Svarspråk: en, no, uk, pl, eller auto.',
|
||||
'focus' => 'Hva som skal hentes ut: alle (hver dato), frister (klagefrister og innleveringsfrister), høringer (tribunal- og rettsdatoer), cps (Barnevernet milepæler).',
|
||||
'use_case_context' => 'Inkluder kontekst fra din Case Workbench-økt (sann/usann).',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Витягти хронологію',
|
||||
'description' => 'Витягти дати, слухання, етапи та терміни з тексту справи.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Текст справи для витягування дат.',
|
||||
'language' => 'Мова відповіді: en, no, uk, pl або auto.',
|
||||
'focus' => 'Що витягнути: всі (кожну дату), терміни (вікна апеляції та терміни подання), слухання (дати трибуналу та суду), cps (етапи Barnevernet).',
|
||||
'use_case_context' => 'Включити контекст з вашої сесії Case Workbench (так/ні).',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Wyodrębnij oś czasu',
|
||||
'description' => 'Wyodrębnij daty, przesłuchania, kamienie milowe i terminy z tekstu sprawy.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Tekst sprawy, z którego należy wyodrębnić daty.',
|
||||
'language' => 'Język odpowiedzi: en, no, uk, pl lub auto.',
|
||||
'focus' => 'Co wyodrębnić: wszystkie (wszystkie daty), terminy (okna odwoławcze i terminy składania), rozprawy (daty trybunałów i sądów), cps (kamienie milowe Barnevernet).',
|
||||
'use_case_context' => 'Uwzględnij kontekst z sesji Case Workbench (prawda/fałsz).',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.redact' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Redact private data',
|
||||
'description' => 'Remove or pseudonymize names, IDs, phone numbers, addresses, and places.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'The text to redact.',
|
||||
'language' => 'Language of the input text: en, no, uk, pl, or auto.',
|
||||
'mode' => 'Redaction scope: standard (names, IDs, phones) or strict (also addresses, locations, institutions).',
|
||||
'output_format' => 'Replacement style: contextual ([PERSON A]), generic (█████), or pseudonym (consistent invented names).',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Rediger private data',
|
||||
'description' => 'Fjern eller pseudonymiser navn, ID-er, telefonnumre, adresser og steder.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Teksten som skal redigeres.',
|
||||
'language' => 'Språk for innholdsteksten: en, no, uk, pl, eller auto.',
|
||||
'mode' => 'Redigeringsomfang: standard (navn, ID-er, telefoner) eller strengt (også adresser, steder, institusjoner).',
|
||||
'output_format' => 'Erstatningsstil: kontekstuell ([PERSON A]), generell (█████), eller pseudonym (konsistente oppdiktede navn).',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Редагувати приватні дані',
|
||||
'description' => 'Видалити або псевдонімізувати імена, ідентифікаційні номери, номери телефонів, адреси та місця.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Текст для редагування.',
|
||||
'language' => 'Мова вхідного тексту: en, no, uk, pl або auto.',
|
||||
'mode' => 'Обсяг редагування: стандартний (імена, ідентифікаційні номери, телефони) або строгий (також адреси, місця, установи).',
|
||||
'output_format' => 'Стиль заміни: контекстуальний ([PERSON A]), загальний (█████) або псевдонім (послідовно вигадані імена).',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Redaguj dane prywatne',
|
||||
'description' => 'Usuń lub zanonimizuj imiona, identyfikatory, numery telefonów, adresy i miejsca.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Tekst do redakcji.',
|
||||
'language' => 'Język tekstu wejściowego: en, no, uk, pl lub auto.',
|
||||
'mode' => 'Zakres redakcji: standardowy (imiona, identyfikatory, telefony) lub ścisły (także adresy, lokalizacje, instytucje).',
|
||||
'output_format' => 'Styl zastąpienia: kontekstowy ([OSOBA A]), ogólny (█████) lub pseudonim (spójne wymyślone imiona).',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.translate' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Translate legal document',
|
||||
'description' => 'Translate Norwegian family-law text with legal terminology annotations.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'The text to translate.',
|
||||
'source_lang' => 'Language of the input text. Use auto to detect automatically.',
|
||||
'target_lang' => 'Language to translate into (required): en, no, uk, or pl.',
|
||||
'doc_type' => 'Document type hint for legal terminology: auto, barnevernet, adopsjon, emergency, samvaer, fylkesnemnd, or other.',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Oversett juridisk dokument',
|
||||
'description' => 'Oversett norsk familierettstekst med juridiske terminologianotasjoner.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Teksten som skal oversettes.',
|
||||
'source_lang' => 'Språk for innholdsteksten. Bruk auto for automatisk deteksjon.',
|
||||
'target_lang' => 'Språk å oversette til (påkrevd): en, no, uk, eller pl.',
|
||||
'doc_type' => 'Dokumenttypehint for juridisk terminologi: auto, barnevernet, adopsjon, akutt, samvær, fylkesnemnd, eller annet.',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Перекласти юридичний документ',
|
||||
'description' => 'Перекласти текст норвезького сімейного права з анотаціями юридичної термінології.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Текст для перекладу.',
|
||||
'source_lang' => 'Мова вхідного тексту. Використовуйте auto для автоматичного визначення.',
|
||||
'target_lang' => 'Мова для перекладу (обов\'язково): en, no, uk або pl.',
|
||||
'doc_type' => 'Підказка щодо типу документа для юридичної термінології: auto, barnevernet, adopsjon, emergency, samvaer, fylkesnemnd або інше.',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Przetłumacz dokument prawny',
|
||||
'description' => 'Przetłumacz tekst dotyczący prawa rodzinnego w Norwegii z adnotacjami terminologii prawnej.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Tekst do przetłumaczenia.',
|
||||
'source_lang' => 'Język tekstu wejściowego. Użyj auto, aby wykryć automatycznie.',
|
||||
'target_lang' => 'Język, na który należy przetłumaczyć (wymagane): en, no, uk lub pl.',
|
||||
'doc_type' => 'Wskazówka dotycząca typu dokumentu dla terminologii prawnej: auto, barnevernet, adopsjon, emergency, samvaer, fylkesnemnd lub inne.',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.legal_analysis' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Legal analysis',
|
||||
'description' => 'Extract legal issues from a document and answer each with DBN legal context.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'The document text to analyze.',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'doc_type' => 'Document type hint: auto, barnevernet, adopsjon, emergency, samvaer, fylkesnemnd, or other.',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Juridisk analyse',
|
||||
'description' => 'Hent ut juridiske spørsmål fra et dokument og svar på hver med DBN juridisk kontekst.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Dokumentteksten som skal analyseres.',
|
||||
'language' => 'Svarspråk: en, no, uk, pl, eller auto.',
|
||||
'doc_type' => 'Dokumenttypehint: auto, barnevernet, adopsjon, akutt, samvær, fylkesnemnd, eller annet.',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Юридичний аналіз',
|
||||
'description' => 'Витягти юридичні питання з документа та відповісти на кожне з контекстом DBN.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Текст документа для аналізу.',
|
||||
'language' => 'Мова відповіді: en, no, uk, pl або auto.',
|
||||
'doc_type' => 'Підказка щодо типу документа: auto, barnevernet, adopsjon, emergency, samvaer, fylkesnemnd або інше.',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Analiza prawna',
|
||||
'description' => 'Wyodrębnij kwestie prawne z dokumentu i odpowiedz na każdą z kontekstem prawnym DBN.',
|
||||
'params' =>
|
||||
array (
|
||||
'text' => 'Tekst dokumentu do analizy.',
|
||||
'language' => 'Język odpowiedzi: en, no, uk, pl lub auto.',
|
||||
'doc_type' => 'Wskazówka dotycząca typu dokumentu: auto, barnevernet, adopsjon, emergency, samvaer, fylkesnemnd lub inne.',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.korrespond' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Draft authority correspondence',
|
||||
'description' => 'Draft a reply or new letter to Norwegian authorities.',
|
||||
'params' =>
|
||||
array (
|
||||
'narrative' => 'Description of your situation — what happened and what you need.',
|
||||
'received_text' => 'Text of the letter or decision you received (for reply mode).',
|
||||
'recipient_body' => 'The authority you are writing to (e.g. Barnevernet, NAV, Skole, Kommune).',
|
||||
'goal' => 'Your legal goal — what you want the letter to achieve.',
|
||||
'mode' => 'reply (responding to a received letter) or initiate (starting new correspondence).',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'use_case_context' => 'Include context from your Case Workbench session (true/false).',
|
||||
'force_draft' => 'Skip the clarify gate and draft immediately (true/false).',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Utkast til myndighetskorrespondanse',
|
||||
'description' => 'Utkast et svar eller nytt brev til norske myndigheter.',
|
||||
'params' =>
|
||||
array (
|
||||
'narrative' => 'Beskrivelse av din situasjon — hva som skjedde og hva du trenger.',
|
||||
'received_text' => 'Tekst av brevet eller vedtaket du mottok (for svarmodus).',
|
||||
'recipient_body' => 'Myndigheten du skriver til (f.eks. Barnevernet, NAV, Skole, Kommune).',
|
||||
'goal' => 'Ditt juridiske mål — hva du ønsker at brevet skal oppnå.',
|
||||
'mode' => 'svar (respondere på et mottatt brev) eller initiere (starte ny korrespondanse).',
|
||||
'language' => 'Svarspråk: en, no, uk, pl, eller auto.',
|
||||
'use_case_context' => 'Inkluder kontekst fra din Sak Arbeidsbenk økt (true/false).',
|
||||
'force_draft' => 'Hopp over avklaringsporten og utkast umiddelbart (true/false).',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Проект кореспонденції з органами влади',
|
||||
'description' => 'Складіть відповідь або новий лист до норвезьких органів влади.',
|
||||
'params' =>
|
||||
array (
|
||||
'narrative' => 'Опис вашої ситуації — що сталося і що вам потрібно.',
|
||||
'received_text' => 'Текст листа або рішення, яке ви отримали (для режиму відповіді).',
|
||||
'recipient_body' => 'Орган влади, до якого ви пишете (наприклад, Barnevernet, NAV, Skole, Kommune).',
|
||||
'goal' => 'Ваша юридична мета — що ви хочете досягти листом.',
|
||||
'mode' => 'відповідь (реагування на отриманий лист) або ініціювати (початок нової кореспонденції).',
|
||||
'language' => 'Мова відповіді: en, no, uk, pl або auto.',
|
||||
'use_case_context' => 'Включити контекст з вашої сесії Case Workbench (так/ні).',
|
||||
'force_draft' => 'Пропустити етап уточнення та одразу скласти проект (так/ні).',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Szkic korespondencji z organami',
|
||||
'description' => 'Szkic odpowiedzi lub nowego listu do norweskich organów.',
|
||||
'params' =>
|
||||
array (
|
||||
'narrative' => 'Opis twojej sytuacji — co się wydarzyło i czego potrzebujesz.',
|
||||
'received_text' => 'Treść listu lub decyzji, którą otrzymałeś (w trybie odpowiedzi).',
|
||||
'recipient_body' => 'Organ, do którego piszesz (np. Barnevernet, NAV, Skole, Kommune).',
|
||||
'goal' => 'Twój cel prawny — co chcesz osiągnąć dzięki temu listowi.',
|
||||
'mode' => 'odpowiedź (odpowiadając na otrzymany list) lub inicjacja (rozpoczynając nową korespondencję).',
|
||||
'language' => 'Język odpowiedzi: en, no, uk, pl lub auto.',
|
||||
'use_case_context' => 'Uwzględnij kontekst z sesji Case Workbench (prawda/fałsz).',
|
||||
'force_draft' => 'Pomiń bramkę wyjaśniającą i natychmiast stwórz szkic (prawda/fałsz).',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.barnevernet_analyze' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Analyze Barnevernet document',
|
||||
'description' => 'Analyze child-welfare documents for red flags and legal issues.',
|
||||
'params' =>
|
||||
array (
|
||||
'document_text' => 'Full text of the child welfare document to analyze (required).',
|
||||
'filename' => 'Original filename for context (helps identify document type).',
|
||||
'advocate_role' => 'Your role in the case: parent, lawyer, guardian ad litem, etc.',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'use_case_context' => 'Include context from your Case Workbench session (true/false).',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Analyser Barnevernet-dokument',
|
||||
'description' => 'Analyser barnevern-dokumenter for røde flagg og juridiske problemer.',
|
||||
'params' =>
|
||||
array (
|
||||
'document_text' => 'Full tekst av barnevern-dokumentet som skal analyseres (påkrevd).',
|
||||
'filename' => 'Original filnavn for kontekst (hjelper med å identifisere dokumenttype).',
|
||||
'advocate_role' => 'Din rolle i saken: forelder, advokat, vergemål, osv.',
|
||||
'language' => 'Svarspråk: en, no, uk, pl, eller auto.',
|
||||
'use_case_context' => 'Inkluder kontekst fra din Sak Arbeidsbenk økt (true/false).',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Аналіз документа Barnevernet',
|
||||
'description' => 'Аналізуйте документи з питань захисту дітей на наявність червоних прапорців та юридичних проблем.',
|
||||
'params' =>
|
||||
array (
|
||||
'document_text' => 'Повний текст документа з питань захисту дітей для аналізу (обов\'язково).',
|
||||
'filename' => 'Оригінальна назва файлу для контексту (допомагає визначити тип документа).',
|
||||
'advocate_role' => 'Ваша роль у справі: батько, адвокат, опікун, призначений судом тощо.',
|
||||
'language' => 'Мова відповіді: en, no, uk, pl або auto.',
|
||||
'use_case_context' => 'Включити контекст з вашої сесії Case Workbench (так/ні).',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Analiza dokumentu Barnevernet',
|
||||
'description' => 'Analiza dokumentów dotyczących opieki nad dziećmi w poszukiwaniu czerwonych flag i problemów prawnych.',
|
||||
'params' =>
|
||||
array (
|
||||
'document_text' => 'Pełny tekst dokumentu dotyczącego opieki nad dziećmi do analizy (wymagane).',
|
||||
'filename' => 'Oryginalna nazwa pliku dla kontekstu (pomaga zidentyfikować typ dokumentu).',
|
||||
'advocate_role' => 'Twoja rola w sprawie: rodzic, prawnik, kurator ad litem itp.',
|
||||
'language' => 'Język odpowiedzi: en, no, uk, pl lub auto.',
|
||||
'use_case_context' => 'Uwzględnij kontekst z sesji Case Workbench (prawda/fałsz).',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.advocate_brief' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Create advocate brief',
|
||||
'description' => 'Generate a source-grounded brief for a chosen party or role.',
|
||||
'params' =>
|
||||
array (
|
||||
'query' => 'Legal question or topic for the brief.',
|
||||
'paste_text' => 'Document text to use as the basis for the brief.',
|
||||
'advocate_role' => 'The party or role to advocate for (required). E.g. parent, child, Barnevernet.',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'use_case_context' => 'Include context from your Case Workbench session (true/false).',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Opprett advokatnotat',
|
||||
'description' => 'Generer et kildebasert notat for en valgt part eller rolle.',
|
||||
'params' =>
|
||||
array (
|
||||
'query' => 'Juridisk spørsmål eller tema for notatet.',
|
||||
'paste_text' => 'Dokumenttekst som skal brukes som grunnlag for brevet.',
|
||||
'advocate_role' => 'Parten eller rollen som skal ivaretas (obligatorisk). F.eks. forelder, barn, Barnevernet.',
|
||||
'language' => 'Svarspråk: en, no, uk, pl, eller auto.',
|
||||
'use_case_context' => 'Inkluder kontekst fra din Case Workbench-økt (sann/usann).',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Створити бриф адвоката',
|
||||
'description' => 'Сгенеруйте бриф, оснований на джерелах, для обраної сторони або ролі.',
|
||||
'params' =>
|
||||
array (
|
||||
'query' => 'Юридичне питання або тема для брифу.',
|
||||
'paste_text' => 'Текст документа, який буде використано як основу для брифу.',
|
||||
'advocate_role' => 'Сторона або роль, за яку потрібно виступити (обов\'язково). Наприклад, батько, дитина, Barnevernet.',
|
||||
'language' => 'Мова відповіді: en, no, uk, pl або auto.',
|
||||
'use_case_context' => 'Включити контекст з вашої сесії Case Workbench (так/ні).',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Utwórz notatkę adwokacką',
|
||||
'description' => 'Generuj notatkę opartą na źródłach dla wybranej strony lub roli.',
|
||||
'params' =>
|
||||
array (
|
||||
'query' => 'Pytanie prawne lub temat notatki.',
|
||||
'paste_text' => 'Tekst dokumentu do wykorzystania jako podstawa dla briefu.',
|
||||
'advocate_role' => 'Strona lub rola, którą należy reprezentować (wymagana). Np. rodzic, dziecko, Barnevernet.',
|
||||
'language' => 'Język odpowiedzi: en, no, uk, pl lub auto.',
|
||||
'use_case_context' => 'Uwzględnij kontekst z sesji Case Workbench (prawda/fałsz).',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.deep_research' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Deep research',
|
||||
'description' => 'Expand a legal question into research angles and synthesize a cited brief.',
|
||||
'params' =>
|
||||
array (
|
||||
'query' => 'Legal question to research in depth.',
|
||||
'paste_text' => 'Supporting document text to research from.',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'use_case_context' => 'Include context from your Case Workbench session (true/false).',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Dyp forskning',
|
||||
'description' => 'Utvid et juridisk spørsmål til forskningsvinkler og syntetiser et siterbart brev.',
|
||||
'params' =>
|
||||
array (
|
||||
'query' => 'Juridisk spørsmål for dypere forskning.',
|
||||
'paste_text' => 'Støttedokumenttekst for forskning.',
|
||||
'language' => 'Svarspråk: en, no, uk, pl, eller auto.',
|
||||
'use_case_context' => 'Inkluder kontekst fra din Case Workbench-økt (sann/usann).',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Глибоке дослідження',
|
||||
'description' => 'Розширити юридичне питання в дослідницькі кути та синтезувати цитований бриф.',
|
||||
'params' =>
|
||||
array (
|
||||
'query' => 'Юридичне питання для глибокого дослідження.',
|
||||
'paste_text' => 'Текст підтримуючого документа для дослідження.',
|
||||
'language' => 'Мова відповіді: en, no, uk, pl або auto.',
|
||||
'use_case_context' => 'Включити контекст з вашої сесії Case Workbench (так/ні).',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Dogłębne badania',
|
||||
'description' => 'Rozwiń pytanie prawne w kierunkach badawczych i zsyntetyzuj cytowany brief.',
|
||||
'params' =>
|
||||
array (
|
||||
'query' => 'Pytanie prawne do zbadania w szczegółach.',
|
||||
'paste_text' => 'Tekst dokumentu wspierającego do badania.',
|
||||
'language' => 'Język odpowiedzi: en, no, uk, pl lub auto.',
|
||||
'use_case_context' => 'Uwzględnij kontekst z sesji Case Workbench (prawda/fałsz).',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.discrepancy_find' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Find document discrepancies',
|
||||
'description' => 'Compare two document versions for contradictions, deletions, and added claims.',
|
||||
'params' =>
|
||||
array (
|
||||
'document_a_text' => 'Text of the first document (required).',
|
||||
'document_b_text' => 'Text of the second document to compare against the first (required).',
|
||||
'filename_a' => 'Filename of the first document (for reference in the report).',
|
||||
'filename_b' => 'Filename of the second document (for reference in the report).',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Finn dokumentavvik',
|
||||
'description' => 'Sammenlign to dokumentversjoner for motsetninger, slettinger og tillegg.',
|
||||
'params' =>
|
||||
array (
|
||||
'document_a_text' => 'Tekst av det første dokumentet (obligatorisk).',
|
||||
'document_b_text' => 'Tekst av det andre dokumentet som skal sammenlignes med det første (obligatorisk).',
|
||||
'filename_a' => 'Filnavn på det første dokumentet (for referanse i rapporten).',
|
||||
'filename_b' => 'Filnavn på det andre dokumentet (for referanse i rapporten).',
|
||||
'language' => 'Svarspråk: en, no, uk, pl, eller auto.',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Знайти розбіжності в документах',
|
||||
'description' => 'Порівняти дві версії документа на наявність суперечностей, видалень та доданих вимог.',
|
||||
'params' =>
|
||||
array (
|
||||
'document_a_text' => 'Текст першого документа (обов\'язково).',
|
||||
'document_b_text' => 'Текст другого документа для порівняння з першим (обов\'язково).',
|
||||
'filename_a' => 'Ім\'я файлу першого документа (для посилання в звіті).',
|
||||
'filename_b' => 'Ім\'я файлу другого документа (для посилання в звіті).',
|
||||
'language' => 'Мова відповіді: en, no, uk, pl або auto.',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Znajdź niezgodności w dokumentach',
|
||||
'description' => 'Porównaj dwie wersje dokumentu pod kątem sprzeczności, usunięć i dodanych roszczeń.',
|
||||
'params' =>
|
||||
array (
|
||||
'document_a_text' => 'Tekst pierwszego dokumentu (wymagany).',
|
||||
'document_b_text' => 'Tekst drugiego dokumentu do porównania z pierwszym (wymagany).',
|
||||
'filename_a' => 'Nazwa pliku pierwszego dokumentu (do odniesienia w raporcie).',
|
||||
'filename_b' => 'Nazwa pliku drugiego dokumentu (do odniesienia w raporcie).',
|
||||
'language' => 'Język odpowiedzi: en, no, uk, pl lub auto.',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.transcribe_audio' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Transcribe audio',
|
||||
'description' => 'Transcribe an audio file from base64-encoded content or a URL.',
|
||||
'params' =>
|
||||
array (
|
||||
'audio_base64' => 'Base64-encoded audio file content. Use either this or audio_url.',
|
||||
'audio_url' => 'URL to a publicly accessible audio file. Use either this or audio_base64.',
|
||||
'filename' => 'Original filename with extension (e.g. recording.mp3) — helps set the correct audio format.',
|
||||
'language' => 'Language spoken in the audio (e.g. no, en, uk). Leave blank for auto-detection.',
|
||||
'diarize' => 'Enable speaker diarization — label each segment with a speaker identifier (true/false).',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Transkribere lyd',
|
||||
'description' => 'Transkribere en lydfil fra base64-kodet innhold eller en URL.',
|
||||
'params' =>
|
||||
array (
|
||||
'audio_base64' => 'Base64-kodet lydfilinnhold. Bruk enten dette eller audio_url.',
|
||||
'audio_url' => 'URL til en offentlig tilgjengelig lydfil. Bruk enten dette eller audio_base64.',
|
||||
'filename' => 'Original filnavn med filtype (f.eks. opptak.mp3) — hjelper med å sette riktig lydformat.',
|
||||
'language' => 'Språk som snakkes i lyden (f.eks. no, en, uk). La stå tomt for automatisk deteksjon.',
|
||||
'diarize' => 'Aktiver taler diarization — merk hvert segment med en taleridentifikator (sann/usann).',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Транскрибувати аудіо',
|
||||
'description' => 'Транскрибувати аудіофайл з вмісту, закодованого в base64, або з URL.',
|
||||
'params' =>
|
||||
array (
|
||||
'audio_base64' => 'Вміст аудіофайлу, закодованого в base64. Використовуйте або це, або audio_url.',
|
||||
'audio_url' => 'URL до публічно доступного аудіофайлу. Використовуйте або це, або audio_base64.',
|
||||
'filename' => 'Оригінальна назва файлу з розширенням (наприклад, recording.mp3) — допомагає встановити правильний формат аудіо.',
|
||||
'language' => 'Мова, що звучить в аудіо (наприклад, no, en, uk). Залиште порожнім для автоматичного визначення.',
|
||||
'diarize' => 'Увімкнути діаризацію спікерів — позначити кожен сегмент ідентифікатором спікера (true/false).',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Transkrypcja audio',
|
||||
'description' => 'Transkrybuj plik audio z treści zakodowanej w base64 lub z URL.',
|
||||
'params' =>
|
||||
array (
|
||||
'audio_base64' => 'Treść pliku audio zakodowanego w base64. Użyj tego lub audio_url.',
|
||||
'audio_url' => 'URL do publicznie dostępnego pliku audio. Użyj tego lub audio_base64.',
|
||||
'filename' => 'Oryginalna nazwa pliku z rozszerzeniem (np. recording.mp3) — pomaga ustawić poprawny format audio.',
|
||||
'language' => 'Język mówiony w nagraniu (np. no, en, uk). Pozostaw puste dla automatycznego wykrywania.',
|
||||
'diarize' => 'Włącz diarizację mówców — oznacz każdy segment identyfikatorem mówcy (prawda/fałsz).',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.corpus_stats' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Corpus statistics',
|
||||
'description' => 'Return document and chunk counts and active legal sources in the DBN corpus.',
|
||||
'params' =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Korpusstatistikk',
|
||||
'description' => 'Returner dokument- og delmengdeantall samt aktive juridiske kilder i DBN-korpuset.',
|
||||
'params' =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Статистика корпусу',
|
||||
'description' => 'Повернути кількість документів і частин, а також активні юридичні джерела в корпусі DBN.',
|
||||
'params' =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Statystyki korpusu',
|
||||
'description' => 'Zwróć liczbę dokumentów i fragmentów oraz aktywne źródła prawne w korpusie DBN.',
|
||||
'params' =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.list_documents' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'List corpus documents',
|
||||
'description' => 'List DBN legal corpus documents with optional filters.',
|
||||
'params' =>
|
||||
array (
|
||||
'category' => 'Filter by document category (e.g. barnevernet, statsforvalter, echr).',
|
||||
'title' => 'Filter by title — partial match.',
|
||||
'limit' => 'Maximum number of documents to return (1–50, default 20).',
|
||||
'offset' => 'Number of documents to skip (for pagination).',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'List opp korpusdokumenter',
|
||||
'description' => 'List opp DBN juridiske korpusdokumenter med valgfrie filtre.',
|
||||
'params' =>
|
||||
array (
|
||||
'category' => 'Filtrer etter dokumentkategori (f.eks. barnevernet, statsforvalter, echr).',
|
||||
'title' => 'Filtrer etter tittel — delvis samsvar.',
|
||||
'limit' => 'Maksimalt antall dokumenter som skal returneres (1–50, standard 20).',
|
||||
'offset' => 'Antall dokumenter som skal hoppes over (for paginering).',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Список документів корпусу',
|
||||
'description' => 'Список юридичних документів корпусу DBN з необов\'язковими фільтрами.',
|
||||
'params' =>
|
||||
array (
|
||||
'category' => 'Фільтрувати за категорією документа (наприклад, barnevernet, statsforvalter, echr).',
|
||||
'title' => 'Фільтрувати за назвою — часткове співпадіння.',
|
||||
'limit' => 'Максимальна кількість документів для повернення (1–50, за замовчуванням 20).',
|
||||
'offset' => 'Кількість документів, які потрібно пропустити (для пагінації).',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Lista dokumentów korpusu',
|
||||
'description' => 'Lista dokumentów prawnych korpusu DBN z opcjonalnymi filtrami.',
|
||||
'params' =>
|
||||
array (
|
||||
'category' => 'Filtruj według kategorii dokumentu (np. barnevernet, statsforvalter, echr).',
|
||||
'title' => 'Filtruj według tytułu — częściowe dopasowanie.',
|
||||
'limit' => 'Maksymalna liczba dokumentów do zwrócenia (1–50, domyślnie 20).',
|
||||
'offset' => 'Liczba dokumentów do pominięcia (do paginacji).',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.get_document' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Get document chunks',
|
||||
'description' => 'Fetch a document and its text chunks by numeric document ID.',
|
||||
'params' =>
|
||||
array (
|
||||
'document_id' => 'The numeric ID of the document to retrieve (required).',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Hent dokumentdeler',
|
||||
'description' => 'Hent et dokument og dets tekstdeler ved hjelp av numerisk dokument-ID.',
|
||||
'params' =>
|
||||
array (
|
||||
'document_id' => 'Den numeriske ID-en til dokumentet som skal hentes (påkrevd).',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Отримати частини документа',
|
||||
'description' => 'Отримати документ та його текстові частини за числовим ідентифікатором документа.',
|
||||
'params' =>
|
||||
array (
|
||||
'document_id' => 'Числовий ідентифікатор документа для отримання (обов\'язково).',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Pobierz fragmenty dokumentu',
|
||||
'description' => 'Pobierz dokument i jego fragmenty tekstowe według numerycznego ID dokumentu.',
|
||||
'params' =>
|
||||
array (
|
||||
'document_id' => 'Numeryczne ID dokumentu do pobrania (wymagane).',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.citation_graph' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Explore citation graph',
|
||||
'description' => 'Explore cites, cited-by, implementation, or chain relationships.',
|
||||
'params' =>
|
||||
array (
|
||||
'doc_id' => 'The numeric ID of the document to explore (required).',
|
||||
'action' => 'Relationship to traverse: cites, cited_by, implements, or chain (full citation path).',
|
||||
'depth' => 'How many levels of relationships to explore (1–3, default 1).',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Utforsk siteringsgraf',
|
||||
'description' => 'Utforsk siteringer, siterte av, implementering eller kjede relasjoner.',
|
||||
'params' =>
|
||||
array (
|
||||
'doc_id' => 'Den numeriske ID-en til dokumentet som skal utforskes (påkrevd).',
|
||||
'action' => 'Relasjon å traversere: siterer, siteres_av, implementerer, eller kjede (full siteringsbane).',
|
||||
'depth' => 'Hvor mange nivåer av relasjoner som skal utforskes (1–3, standard 1).',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Дослідити граф посилань',
|
||||
'description' => 'Дослідити посилання, посилання на, реалізацію або ланцюгові відносини.',
|
||||
'params' =>
|
||||
array (
|
||||
'doc_id' => 'Числовий ідентифікатор документа для дослідження (обов\'язково).',
|
||||
'action' => 'Відношення для проходження: cites, cited_by, implements, або chain (повний шлях цитування).',
|
||||
'depth' => 'Скільки рівнів відносин досліджувати (1–3, за замовчуванням 1).',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Eksploruj graf cytatów',
|
||||
'description' => 'Eksploruj cytaty, cytowane przez, wdrożenie lub relacje łańcuchowe.',
|
||||
'params' =>
|
||||
array (
|
||||
'doc_id' => 'Numeryczne ID dokumentu do eksploracji (wymagane).',
|
||||
'action' => 'Relacja do przeszukania: cytaty, cytowane_przez, wdraża, lub łańcuch (pełna ścieżka cytatu).',
|
||||
'depth' => 'Ile poziomów relacji do eksploracji (1–3, domyślnie 1).',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.case_workbench_plan' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Plan next case step',
|
||||
'description' => 'Create a stateless legal preparation plan based on your situation.',
|
||||
'params' =>
|
||||
array (
|
||||
'situation' => 'Describe your current legal situation and what you need help with (required).',
|
||||
'goal' => 'Your desired outcome or legal goal.',
|
||||
'deadline' => 'Any relevant deadline (date or description, e.g. "3 weeks").',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Planlegg neste sakstrinn',
|
||||
'description' => 'Lag en statsløs juridisk forberedelsesplan basert på din situasjon.',
|
||||
'params' =>
|
||||
array (
|
||||
'situation' => 'Beskriv din nåværende juridiske situasjon og hva du trenger hjelp med (obligatorisk).',
|
||||
'goal' => 'Ditt ønskede utfall eller juridiske mål.',
|
||||
'deadline' => 'Eventuell relevant frist (dato eller beskrivelse, f.eks. "3 uker").',
|
||||
'language' => 'Svarspråk: en, no, uk, pl, eller auto.',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Плануйте наступний крок у справі',
|
||||
'description' => 'Створіть бездержавний план юридичної підготовки на основі вашої ситуації.',
|
||||
'params' =>
|
||||
array (
|
||||
'situation' => 'Опишіть вашу поточну юридичну ситуацію та те, з чим вам потрібна допомога (обов\'язково).',
|
||||
'goal' => 'Ваш бажаний результат або юридична мета.',
|
||||
'deadline' => 'Будь-який відповідний термін (дата або опис, наприклад, "3 тижні").',
|
||||
'language' => 'Мова відповіді: en, no, uk, pl або auto.',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Zaplanuj następny krok w sprawie',
|
||||
'description' => 'Utwórz bezstanowy plan przygotowania prawnego na podstawie swojej sytuacji.',
|
||||
'params' =>
|
||||
array (
|
||||
'situation' => 'Opisz swoją obecną sytuację prawną i z czym potrzebujesz pomocy (wymagane).',
|
||||
'goal' => 'Twój pożądany wynik lub cel prawny.',
|
||||
'deadline' => 'Jakikolwiek istotny termin (data lub opis, np. "3 tygodnie").',
|
||||
'language' => 'Język odpowiedzi: en, no, uk, pl lub auto.',
|
||||
),
|
||||
),
|
||||
),
|
||||
'dbn.save_to_case' =>
|
||||
array (
|
||||
'en' =>
|
||||
array (
|
||||
'display_name' => 'Save result to My Case',
|
||||
'description' => 'Explicitly save a prior MCP tool result to the user case record.',
|
||||
'params' =>
|
||||
array (
|
||||
'tool' => 'The MCP tool slug whose result you are saving (required).',
|
||||
'title' => 'A descriptive title for this saved result.',
|
||||
'input_payload' => 'The input parameters used to generate the result (required).',
|
||||
'output_payload' => 'The tool result to save (required).',
|
||||
'meta' => 'Optional metadata (e.g. notes, tags, source reference).',
|
||||
),
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'display_name' => 'Lagre resultat til Min Sak',
|
||||
'description' => 'Lagre eksplisitt et tidligere MCP-verktøyresultat til brukerens sakspost.',
|
||||
'params' =>
|
||||
array (
|
||||
'tool' => 'Slug til MCP-verktøyet hvis resultat du lagrer (obligatorisk).',
|
||||
'title' => 'En beskrivende tittel for dette lagrede resultatet.',
|
||||
'input_payload' => 'Inndata-parametrene som ble brukt for å generere resultatet (obligatorisk).',
|
||||
'output_payload' => 'Verktøyresultatet som skal lagres (obligatorisk).',
|
||||
'meta' => 'Valgfri metadata (f.eks. notater, tagger, kildehenvisning).',
|
||||
),
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'display_name' => 'Зберегти результат у Моя справа',
|
||||
'description' => 'Явно зберегти попередній результат інструменту MCP у записі справи користувача.',
|
||||
'params' =>
|
||||
array (
|
||||
'tool' => 'Слаг інструменту MCP, результат якого ви зберігаєте (обов\'язково).',
|
||||
'title' => 'Описовий заголовок для цього збереженого результату.',
|
||||
'input_payload' => 'Вхідні параметри, використані для генерації результату (обов\'язково).',
|
||||
'output_payload' => 'Результат інструменту для збереження (обов\'язково).',
|
||||
'meta' => 'Додаткова метадані (наприклад, нотатки, теги, посилання на джерело).',
|
||||
),
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'display_name' => 'Zapisz wynik do Mojej Sprawy',
|
||||
'description' => 'Wyraźnie zapisz wcześniejszy wynik narzędzia MCP w rejestrze sprawy użytkownika.',
|
||||
'params' =>
|
||||
array (
|
||||
'tool' => 'Slug narzędzia MCP, którego wynik zapisujesz (wymagane).',
|
||||
'title' => 'Opisowy tytuł dla tego zapisanego wyniku.',
|
||||
'input_payload' => 'Parametry wejściowe użyte do wygenerowania wyniku (wymagane).',
|
||||
'output_payload' => 'Wynik narzędzia do zapisania (wymagane).',
|
||||
'meta' => 'Opcjonalne metadane (np. notatki, tagi, odniesienie do źródła).',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
+833
@@ -0,0 +1,833 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/includes/bootstrap.php';
|
||||
require_once __DIR__ . '/includes/DbnMcpRuntime.php';
|
||||
|
||||
$uiLang = dbnToolsCurrentLanguage();
|
||||
|
||||
// ── Load tool from ?tool= param ──────────────────────────────────────────────
|
||||
$requestedSlug = (string)($_GET['tool'] ?? '');
|
||||
$toolCatalog = DbnMcpRuntime::tools();
|
||||
$toolDef = null;
|
||||
foreach ($toolCatalog as $t) {
|
||||
if (($t['slug'] ?? '') === $requestedSlug) {
|
||||
$toolDef = $t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($toolDef === null) {
|
||||
http_response_code(404);
|
||||
echo '<!doctype html><html><head><title>Tool not found</title></head><body><p>MCP tool not found. <a href="/mcp.php">Back to MCP setup</a></p></body></html>';
|
||||
exit;
|
||||
}
|
||||
|
||||
// ── Load translations ─────────────────────────────────────────────────────────
|
||||
$toolTranslations = [];
|
||||
$toolTransFile = __DIR__ . '/includes/mcp-tool-translations.php';
|
||||
if (file_exists($toolTransFile)) {
|
||||
$toolTranslations = (array)include $toolTransFile;
|
||||
}
|
||||
|
||||
function mcpToolT(string $slug, string $field, string $lang, array $trans): string
|
||||
{
|
||||
$fallback = $trans[$slug]['en'][$field] ?? '';
|
||||
return (string)($trans[$slug][$lang][$field] ?? $fallback);
|
||||
}
|
||||
|
||||
function mcpToolParamT(string $slug, string $param, string $lang, array $trans): string
|
||||
{
|
||||
$fallback = $trans[$slug]['en']['params'][$param] ?? '';
|
||||
return (string)($trans[$slug][$lang]['params'][$param] ?? $fallback);
|
||||
}
|
||||
|
||||
// ── Resolved display data ────────────────────────────────────────────────────
|
||||
$slug = (string)($toolDef['slug'] ?? '');
|
||||
$displayName = mcpToolT($slug, 'display_name', $uiLang, $toolTranslations) ?: (string)($toolDef['display_name'] ?? $slug);
|
||||
$description = mcpToolT($slug, 'description', $uiLang, $toolTranslations) ?: (string)($toolDef['description'] ?? '');
|
||||
$props = (array)($toolDef['config']['input_schema']['properties'] ?? []);
|
||||
$required = (array)($toolDef['config']['input_schema']['required'] ?? []);
|
||||
|
||||
$toolIcons = [
|
||||
'dbn.search_legal' => '🔍',
|
||||
'dbn.ask' => '💬',
|
||||
'dbn.summarize' => '📋',
|
||||
'dbn.timeline' => '📅',
|
||||
'dbn.redact' => '🔒',
|
||||
'dbn.translate' => '🌍',
|
||||
'dbn.legal_analysis' => '⚖️',
|
||||
'dbn.korrespond' => '✉️',
|
||||
'dbn.barnevernet_analyze' => '📄',
|
||||
'dbn.advocate_brief' => '🏛️',
|
||||
'dbn.deep_research' => '🔬',
|
||||
'dbn.discrepancy_find' => '🔄',
|
||||
'dbn.transcribe_audio' => '🎤',
|
||||
'dbn.corpus_stats' => '📊',
|
||||
'dbn.list_documents' => '📚',
|
||||
'dbn.get_document' => '📖',
|
||||
'dbn.citation_graph' => '🔗',
|
||||
'dbn.case_workbench_plan' => '🗂️',
|
||||
'dbn.save_to_case' => '💾',
|
||||
];
|
||||
$toolIcon = $toolIcons[$slug] ?? '🔧';
|
||||
|
||||
// ── Example requests (per tool) ───────────────────────────────────────────────
|
||||
$exampleRequests = [
|
||||
'dbn.search_legal' => <<<'JSON'
|
||||
{
|
||||
"query": "emergency care order requirements barnevernet",
|
||||
"language": "en",
|
||||
"limit": 5,
|
||||
"corpus_scope": "shared"
|
||||
}
|
||||
JSON,
|
||||
'dbn.ask' => <<<'JSON'
|
||||
{
|
||||
"question": "Can Barnevernet remove a child without a court hearing?",
|
||||
"language": "en",
|
||||
"use_case_context": false
|
||||
}
|
||||
JSON,
|
||||
'dbn.summarize' => <<<'JSON'
|
||||
{
|
||||
"text": "Paste the case document text here...",
|
||||
"language": "en",
|
||||
"use_legal_corpus": true,
|
||||
"use_case_context": false
|
||||
}
|
||||
JSON,
|
||||
'dbn.timeline' => <<<'JSON'
|
||||
{
|
||||
"text": "Paste case notes or decision letter here...",
|
||||
"language": "en",
|
||||
"focus": "all",
|
||||
"use_case_context": false
|
||||
}
|
||||
JSON,
|
||||
'dbn.redact' => <<<'JSON'
|
||||
{
|
||||
"text": "On 15.03.2024 caseworker Anna Hansen met with...",
|
||||
"language": "no",
|
||||
"mode": "standard",
|
||||
"output_format": "contextual"
|
||||
}
|
||||
JSON,
|
||||
'dbn.translate' => <<<'JSON'
|
||||
{
|
||||
"text": "Barnevernet fattet vedtak om omsorgsovertakelse...",
|
||||
"source_lang": "no",
|
||||
"target_lang": "en",
|
||||
"doc_type": "barnevernet"
|
||||
}
|
||||
JSON,
|
||||
'dbn.legal_analysis' => <<<'JSON'
|
||||
{
|
||||
"text": "Paste the document text to analyze here...",
|
||||
"language": "en",
|
||||
"doc_type": "auto"
|
||||
}
|
||||
JSON,
|
||||
'dbn.korrespond' => <<<'JSON'
|
||||
{
|
||||
"narrative": "Barnevernet issued an emergency placement order without notification.",
|
||||
"recipient_body": "Barnevernet",
|
||||
"goal": "Appeal the decision and request access to case documents.",
|
||||
"mode": "initiate",
|
||||
"language": "en"
|
||||
}
|
||||
JSON,
|
||||
'dbn.barnevernet_analyze' => <<<'JSON'
|
||||
{
|
||||
"document_text": "Paste the Barnevernet document text here...",
|
||||
"filename": "vedtak-omsorgsovertakelse.pdf",
|
||||
"advocate_role": "parent",
|
||||
"language": "en"
|
||||
}
|
||||
JSON,
|
||||
'dbn.advocate_brief' => <<<'JSON'
|
||||
{
|
||||
"query": "Grounds for challenging a care order under BVL §4-12",
|
||||
"advocate_role": "parent",
|
||||
"language": "en",
|
||||
"use_case_context": false
|
||||
}
|
||||
JSON,
|
||||
'dbn.deep_research' => <<<'JSON'
|
||||
{
|
||||
"query": "ECHR Article 8 violations in Norwegian child welfare cases",
|
||||
"language": "en",
|
||||
"use_case_context": false
|
||||
}
|
||||
JSON,
|
||||
'dbn.discrepancy_find' => <<<'JSON'
|
||||
{
|
||||
"document_a_text": "Text of the first document version...",
|
||||
"document_b_text": "Text of the second document version...",
|
||||
"filename_a": "report-2023.pdf",
|
||||
"filename_b": "report-2024.pdf",
|
||||
"language": "en"
|
||||
}
|
||||
JSON,
|
||||
'dbn.transcribe_audio' => <<<'JSON'
|
||||
{
|
||||
"audio_url": "https://example.com/meeting-recording.mp3",
|
||||
"language": "no",
|
||||
"diarize": true
|
||||
}
|
||||
JSON,
|
||||
'dbn.corpus_stats' => '{}',
|
||||
'dbn.list_documents' => <<<'JSON'
|
||||
{
|
||||
"category": "barnevernet",
|
||||
"limit": 20,
|
||||
"offset": 0
|
||||
}
|
||||
JSON,
|
||||
'dbn.get_document' => <<<'JSON'
|
||||
{
|
||||
"document_id": 42
|
||||
}
|
||||
JSON,
|
||||
'dbn.citation_graph' => <<<'JSON'
|
||||
{
|
||||
"doc_id": 42,
|
||||
"action": "cites",
|
||||
"depth": 2
|
||||
}
|
||||
JSON,
|
||||
'dbn.case_workbench_plan' => <<<'JSON'
|
||||
{
|
||||
"situation": "Barnevernet has scheduled a Fylkesnemnda hearing in 3 weeks. I need to prepare a response.",
|
||||
"goal": "Challenge the care order and request return of the child.",
|
||||
"deadline": "2024-06-15",
|
||||
"language": "en"
|
||||
}
|
||||
JSON,
|
||||
'dbn.save_to_case' => <<<'JSON'
|
||||
{
|
||||
"tool": "dbn.legal_analysis",
|
||||
"title": "Legal analysis of care order decision",
|
||||
"input_payload": { "text": "...", "language": "en" },
|
||||
"output_payload": { "issues": [...], "summary": "..." }
|
||||
}
|
||||
JSON,
|
||||
];
|
||||
|
||||
// ── Example responses (per tool) ──────────────────────────────────────────────
|
||||
$exampleResponses = [
|
||||
'dbn.search_legal' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"results": [
|
||||
{
|
||||
"title": "BVL §4-12 — Vedtak om omsorgsovertakelse",
|
||||
"chunk_text": "§ 4-12. Vedtak om å overta omsorgen for et barn kan treffes dersom...",
|
||||
"score": 0.91,
|
||||
"source": "barnevernsloven"
|
||||
},
|
||||
{
|
||||
"title": "NOU 2012:5 — Bedre beskyttelse av barns utvikling",
|
||||
"chunk_text": "Utvalget vurderer at terskelen for akuttvedtak bør klargjøres...",
|
||||
"score": 0.84,
|
||||
"source": "nou"
|
||||
}
|
||||
],
|
||||
"total": 2
|
||||
}
|
||||
JSON,
|
||||
'dbn.ask' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"answer": "Under Norwegian law, Barnevernet may issue an emergency care order (akuttvedtak) under BVL §4-6 without a prior court hearing if there is immediate risk of serious harm. However, the case must be reviewed by Fylkesnemnda within six weeks...",
|
||||
"sources": [
|
||||
{ "title": "BVL §4-6 — Midlertidige vedtak", "url": "/corpus/bvl-4-6" },
|
||||
{ "title": "Strand Lobben m.fl. mot Norge (EMD)", "url": "/corpus/echr-strand-lobben" }
|
||||
],
|
||||
"credits_used": 3
|
||||
}
|
||||
JSON,
|
||||
'dbn.summarize' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"summary": "The document is a Barnevernet investigation report concerning a family with two children. Key findings include...",
|
||||
"key_points": [
|
||||
"Home visit conducted 12.03.2024 — no immediate danger found",
|
||||
"Tiltaksplan proposed with three support measures",
|
||||
"Next review scheduled for 15.06.2024"
|
||||
],
|
||||
"credits_used": 5
|
||||
}
|
||||
JSON,
|
||||
'dbn.timeline' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"events": [
|
||||
{
|
||||
"date": "2024-03-12",
|
||||
"date_type": "ABSOLUTE",
|
||||
"confidence": "HIGH",
|
||||
"actor": "Barnevernet",
|
||||
"description": "Home visit conducted following anonymous report",
|
||||
"source_excerpt": "12.03.2024: hjemmebesøk ble gjennomført..."
|
||||
},
|
||||
{
|
||||
"date": "2024-06-15",
|
||||
"date_type": "ABSOLUTE",
|
||||
"confidence": "HIGH",
|
||||
"actor": "Fylkesnemnda",
|
||||
"description": "Scheduled hearing date",
|
||||
"source_excerpt": "Nemnda berammer møte til 15. juni 2024"
|
||||
}
|
||||
],
|
||||
"next_practical_step": "File your written submission before the 06.06.2024 deadline.",
|
||||
"credits_used": 4
|
||||
}
|
||||
JSON,
|
||||
'dbn.redact' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"redacted_text": "On [DATE A] caseworker [PERSON A] met with [PERSON B] at [ADDRESS A]...",
|
||||
"replacements": [
|
||||
{ "original": "15.03.2024", "replacement": "[DATE A]" },
|
||||
{ "original": "Anna Hansen", "replacement": "[PERSON A]" },
|
||||
{ "original": "Ola Nordmann", "replacement": "[PERSON B]" }
|
||||
],
|
||||
"credits_used": 2
|
||||
}
|
||||
JSON,
|
||||
'dbn.translate' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"source_lang": "no",
|
||||
"target_lang": "en",
|
||||
"translated_text": "Barnevernet issued a care order decision (vedtak om omsorgsovertakelse)...",
|
||||
"annotations": [
|
||||
{
|
||||
"term": "omsorgsovertakelse",
|
||||
"note": "Care order — formal transfer of parental responsibility to the state under BVL §4-12"
|
||||
},
|
||||
{
|
||||
"term": "Fylkesnemnda",
|
||||
"note": "County Social Welfare Board — the quasi-judicial body that reviews Barnevernet decisions"
|
||||
}
|
||||
],
|
||||
"credits_used": 6
|
||||
}
|
||||
JSON,
|
||||
'dbn.legal_analysis' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"issues": [
|
||||
{
|
||||
"issue": "Procedural rights under forvaltningsloven §17",
|
||||
"analysis": "The parent was not given an opportunity to be heard before the decision was made, potentially violating fvl §17...",
|
||||
"legal_basis": ["forvaltningsloven §17", "BVL §6-3"],
|
||||
"sources": [{ "title": "fvl §17 — Plikten til å påse at saken er opplyst" }]
|
||||
}
|
||||
],
|
||||
"overall_assessment": "The document shows potential procedural violations that may form grounds for an appeal.",
|
||||
"credits_used": 8
|
||||
}
|
||||
JSON,
|
||||
'dbn.korrespond' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"letter_no": "Til Barnevernet\nDato: 24.05.2024\n\nAnke på vedtak om omsorgsovertakelse...",
|
||||
"letter_en": "To Barnevernet\nDate: 24.05.2024\n\nAppeal against care order decision...",
|
||||
"cited_sources": ["BVL §4-12", "forvaltningsloven §28", "EMK artikkel 8"],
|
||||
"credits_used": 10
|
||||
}
|
||||
JSON,
|
||||
'dbn.barnevernet_analyze' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"red_flags": [
|
||||
"Decision issued without notification to parent (fvl §16 violation)",
|
||||
"No tiltaksplan offered before escalating to care order (BVL §4-4)"
|
||||
],
|
||||
"legal_issues": [
|
||||
"Potential violation of proportionality principle — less intrusive measures not exhausted",
|
||||
"ECHR Art. 8 family life rights not addressed in reasoning"
|
||||
],
|
||||
"recommendations": [
|
||||
"File an appeal within 3 weeks citing fvl §28",
|
||||
"Request full case file under fvl §18",
|
||||
"Consult Fylkesnemnda procedural timeline"
|
||||
],
|
||||
"credits_used": 7
|
||||
}
|
||||
JSON,
|
||||
'dbn.advocate_brief' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"brief": "On behalf of the parent, the following legal arguments support challenging the care order under BVL §4-12...",
|
||||
"legal_arguments": [
|
||||
"The threshold for care order under §4-12(a) requires 'serious deficiencies' — the report does not meet this standard",
|
||||
"Proportionality requires exhausting support measures (§4-4) before removal"
|
||||
],
|
||||
"sources": [
|
||||
{ "title": "BVL §4-12", "type": "statute" },
|
||||
{ "title": "Rt-2015-110", "type": "case_law" }
|
||||
],
|
||||
"credits_used": 9
|
||||
}
|
||||
JSON,
|
||||
'dbn.deep_research' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"research_angles": [
|
||||
"Procedural safeguards under ECHR Art. 6 in child welfare proceedings",
|
||||
"Substantive requirements for care order threshold (BVL §4-12)",
|
||||
"Norwegian Supreme Court interpretation of best interests standard"
|
||||
],
|
||||
"brief": "Research synthesis: The European Court of Human Rights has found Norway in violation of Art. 8 in 14 cases since 2015, with the core issue being...",
|
||||
"citations": [
|
||||
"Strand Lobben m.fl. mot Norge, EMD-37283/13 (10.09.2019)",
|
||||
"Johansen mot Norge, EMD-17383/90 (07.08.1996)"
|
||||
],
|
||||
"credits_used": 15
|
||||
}
|
||||
JSON,
|
||||
'dbn.discrepancy_find' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"discrepancies": [
|
||||
{
|
||||
"type": "deletion",
|
||||
"location": "Section 3, paragraph 2",
|
||||
"original": "The child expressed a wish to return home.",
|
||||
"modified": "[removed]",
|
||||
"significance": "HIGH — child's stated preference is a legally relevant factor under BVL §6-3"
|
||||
},
|
||||
{
|
||||
"type": "added_claim",
|
||||
"location": "Section 5",
|
||||
"original": "[absent]",
|
||||
"modified": "The parent failed to attend the scheduled meeting.",
|
||||
"significance": "MEDIUM — unverified claim added in the later version"
|
||||
}
|
||||
],
|
||||
"credits_used": 6
|
||||
}
|
||||
JSON,
|
||||
'dbn.transcribe_audio' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"transcript": "Full transcript of the audio recording...",
|
||||
"segments": [
|
||||
{ "speaker": "A", "start": 0.0, "end": 4.2, "text": "God morgen, vi er samlet for å diskutere..." },
|
||||
{ "speaker": "B", "start": 4.5, "end": 9.1, "text": "Takk. Jeg ønsker å starte med å si at..." }
|
||||
],
|
||||
"language_detected": "no",
|
||||
"credits_used": 8
|
||||
}
|
||||
JSON,
|
||||
'dbn.corpus_stats' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"documents": 2847,
|
||||
"chunks": 94231,
|
||||
"sources": {
|
||||
"statutes": 42,
|
||||
"tribunal_decisions": 1204,
|
||||
"echr_cases": 187,
|
||||
"government_reports": 1414
|
||||
},
|
||||
"last_updated": "2024-05-01"
|
||||
}
|
||||
JSON,
|
||||
'dbn.list_documents' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"documents": [
|
||||
{ "id": 42, "title": "BVL §4-12 — Vedtak om omsorgsovertakelse", "category": "statute" },
|
||||
{ "id": 87, "title": "FNV-2023-142 — Fylkesnemnda for barnevern og sosiale saker", "category": "tribunal" },
|
||||
{ "id": 203, "title": "Strand Lobben m.fl. mot Norge (EMD-37283/13)", "category": "echr" }
|
||||
],
|
||||
"total": 847,
|
||||
"offset": 0
|
||||
}
|
||||
JSON,
|
||||
'dbn.get_document' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"document": {
|
||||
"id": 42,
|
||||
"title": "BVL §4-12 — Vedtak om omsorgsovertakelse",
|
||||
"category": "statute",
|
||||
"chunks": [
|
||||
{ "chunk_id": 1, "text": "§ 4-12. Vedtak om å overta omsorgen for et barn kan treffes dersom..." },
|
||||
{ "chunk_id": 2, "text": "(a) det er alvorlige mangler ved den daglige omsorg som barnet får..." }
|
||||
]
|
||||
}
|
||||
}
|
||||
JSON,
|
||||
'dbn.citation_graph' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"action": "cites",
|
||||
"root": { "id": 42, "title": "BVL §4-12" },
|
||||
"nodes": [
|
||||
{ "id": 42, "title": "BVL §4-12", "type": "statute" },
|
||||
{ "id": 15, "title": "BVL §4-4 — Hjelpetiltak", "type": "statute" },
|
||||
{ "id": 203, "title": "Strand Lobben m.fl. mot Norge", "type": "echr" }
|
||||
],
|
||||
"edges": [
|
||||
{ "from": 42, "to": 15, "type": "cites" },
|
||||
{ "from": 42, "to": 203, "type": "cites" }
|
||||
],
|
||||
"depth": 1
|
||||
}
|
||||
JSON,
|
||||
'dbn.case_workbench_plan' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"plan": {
|
||||
"situation_summary": "Fylkesnemnda hearing scheduled in 3 weeks — care order challenge.",
|
||||
"steps": [
|
||||
"1. Request full case file under forvaltningsloven §18 — submit by 01.06.2024",
|
||||
"2. Run Legal Analysis tool on the original care order decision",
|
||||
"3. Create Advocate Brief (parent role) with the grounds for challenge",
|
||||
"4. Draft formal response letter using Korrespond (Fylkesnemnda preset)",
|
||||
"5. Compile timeline of all procedural dates"
|
||||
],
|
||||
"recommended_tools": ["dbn.legal_analysis", "dbn.advocate_brief", "dbn.korrespond", "dbn.timeline"],
|
||||
"deadline": "2024-06-15"
|
||||
},
|
||||
"credits_used": 3
|
||||
}
|
||||
JSON,
|
||||
'dbn.save_to_case' => <<<'JSON'
|
||||
{
|
||||
"ok": true,
|
||||
"saved": true,
|
||||
"case_entry_id": "entry_abc123",
|
||||
"title": "Legal analysis of care order decision",
|
||||
"saved_at": "2024-05-24T09:15:00Z"
|
||||
}
|
||||
JSON,
|
||||
];
|
||||
|
||||
$exReq = trim($exampleRequests[$slug] ?? '{}');
|
||||
$exResp = trim($exampleResponses[$slug] ?? '{"ok":true}');
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="<?= htmlspecialchars($uiLang) ?>">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title><?= htmlspecialchars($displayName) ?> — <?= htmlspecialchars(dbnToolsT('mcp_page_title', $uiLang)) ?></title>
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
|
||||
<link rel="stylesheet" href="assets/css/tools.css">
|
||||
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
|
||||
<style>
|
||||
.mcp-tool-breadcrumb {
|
||||
font-size: 0.85rem;
|
||||
color: var(--muted, #667085);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
.mcp-tool-breadcrumb a {
|
||||
color: var(--dbn-blue, #00205b);
|
||||
text-decoration: none;
|
||||
}
|
||||
.mcp-tool-breadcrumb a:hover { text-decoration: underline; }
|
||||
.mcp-tool-hero {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.mcp-tool-hero__icon {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.mcp-tool-hero__name {
|
||||
font-family: 'Crimson Pro', serif;
|
||||
font-size: clamp(1.5rem, 3vw, 2rem);
|
||||
font-weight: 700;
|
||||
color: var(--dbn-blue, #00205b);
|
||||
margin: 0 0 0.2rem;
|
||||
}
|
||||
.mcp-tool-hero__slug {
|
||||
font-family: 'IBM Plex Mono', 'Courier New', monospace;
|
||||
font-size: 0.82rem;
|
||||
color: var(--muted, #667085);
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.mcp-tool-hero__desc {
|
||||
font-size: 1rem;
|
||||
color: var(--dbn-ink, #16130f);
|
||||
max-width: 640px;
|
||||
margin: 0;
|
||||
}
|
||||
/* Param table */
|
||||
.mcp-param-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.875rem;
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
.mcp-param-table th {
|
||||
text-align: left;
|
||||
padding: 0.5rem 0.75rem;
|
||||
background: var(--dbn-paper, #f6f2ea);
|
||||
font-weight: 600;
|
||||
font-size: 0.78rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .04em;
|
||||
color: var(--muted, #667085);
|
||||
border-bottom: 2px solid var(--dbn-line, #e5e7eb);
|
||||
}
|
||||
.mcp-param-table td {
|
||||
padding: 0.6rem 0.75rem;
|
||||
border-bottom: 1px solid var(--dbn-line, #e5e7eb);
|
||||
vertical-align: top;
|
||||
}
|
||||
.mcp-param-table tr:last-child td { border-bottom: 0; }
|
||||
.mcp-param-name {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
.mcp-param-name--required {
|
||||
background: #ddd6fe;
|
||||
color: #5b21b6;
|
||||
padding: 0.15rem 0.4rem;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.mcp-param-name--optional {
|
||||
background: #f3f4f6;
|
||||
color: #374151;
|
||||
padding: 0.15rem 0.4rem;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.mcp-param-type {
|
||||
color: var(--muted, #667085);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.mcp-param-enum {
|
||||
font-size: 0.75rem;
|
||||
color: var(--muted, #667085);
|
||||
font-family: monospace;
|
||||
}
|
||||
.mcp-req-yes {
|
||||
color: #065f46;
|
||||
font-weight: 600;
|
||||
}
|
||||
.mcp-req-no {
|
||||
color: var(--muted, #667085);
|
||||
}
|
||||
/* Code blocks (reuse mcp.php style) */
|
||||
.mcp-code-wrap {
|
||||
position: relative;
|
||||
}
|
||||
.mcp-code-wrap pre {
|
||||
background: #101828;
|
||||
color: #f9fafb;
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
font-size: 0.8rem;
|
||||
overflow-x: auto;
|
||||
margin: 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.mcp-copy-btn {
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
right: 0.5rem;
|
||||
background: rgba(249,250,251,.12);
|
||||
border: 1px solid rgba(249,250,251,.2);
|
||||
color: #f9fafb;
|
||||
font-size: 0.75rem;
|
||||
padding: 0.3rem 0.6rem;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
transition: background .15s;
|
||||
}
|
||||
.mcp-copy-btn:hover { background: rgba(249,250,251,.22); }
|
||||
.mcp-code-label {
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
color: var(--muted, #667085);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .04em;
|
||||
margin: 0 0 0.4rem;
|
||||
}
|
||||
.mcp-privacy {
|
||||
background: var(--dbn-paper, #f6f2ea);
|
||||
border-radius: 8px;
|
||||
padding: 1rem 1.25rem;
|
||||
font-size: 0.85rem;
|
||||
color: var(--dbn-ink, #16130f);
|
||||
}
|
||||
.mcp-privacy strong { color: var(--dbn-blue, #00205b); }
|
||||
.mcp-connect-link {
|
||||
display: inline-block;
|
||||
margin-top: 0.75rem;
|
||||
color: var(--dbn-blue, #00205b);
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
.mcp-connect-link:hover { text-decoration: underline; }
|
||||
</style>
|
||||
</head>
|
||||
<body data-authenticated="<?= dbnToolsIsAuthenticated() ? 'true' : 'false' ?>" class="lt-app">
|
||||
<script>
|
||||
window.DBN_TOOLS_AUTHENTICATED = <?= dbnToolsIsAuthenticated() ? 'true' : 'false' ?>;
|
||||
window.DBN_TOOLS_LANG = <?= json_encode($uiLang, JSON_UNESCAPED_UNICODE) ?>;
|
||||
</script>
|
||||
|
||||
<?php include __DIR__ . '/includes/nav.php'; ?>
|
||||
|
||||
<div class="account-shell">
|
||||
|
||||
<!-- ── Breadcrumb ────────────────────────────────────────────── -->
|
||||
<div class="mcp-tool-breadcrumb">
|
||||
<a href="/mcp.php"><?= htmlspecialchars(dbnToolsT('mcp_tool_back', $uiLang)) ?></a>
|
||||
</div>
|
||||
|
||||
<!-- ── Hero ──────────────────────────────────────────────────── -->
|
||||
<section class="account-section">
|
||||
<div class="mcp-tool-hero">
|
||||
<div class="mcp-tool-hero__icon"><?= $toolIcon ?></div>
|
||||
<h1 class="mcp-tool-hero__name"><?= htmlspecialchars($displayName) ?></h1>
|
||||
<div class="mcp-tool-hero__slug"><?= htmlspecialchars($slug) ?></div>
|
||||
<p class="mcp-tool-hero__desc"><?= htmlspecialchars($description) ?></p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ── Parameters ────────────────────────────────────────────── -->
|
||||
<section class="account-section">
|
||||
<p class="account-section__title"><?= htmlspecialchars(dbnToolsT('mcp_tool_params_title', $uiLang)) ?></p>
|
||||
|
||||
<?php if (empty($props)): ?>
|
||||
<p style="color:var(--muted,#667085); font-size:0.88rem;">
|
||||
<?= htmlspecialchars(dbnToolsT('mcp_tool_no_params', $uiLang)) ?>
|
||||
</p>
|
||||
<?php else: ?>
|
||||
<div style="overflow-x:auto;">
|
||||
<table class="mcp-param-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= htmlspecialchars(dbnToolsT('mcp_tool_col_param', $uiLang)) ?></th>
|
||||
<th><?= htmlspecialchars(dbnToolsT('mcp_tool_col_type', $uiLang)) ?></th>
|
||||
<th><?= htmlspecialchars(dbnToolsT('mcp_tool_col_required', $uiLang)) ?></th>
|
||||
<th><?= htmlspecialchars(dbnToolsT('mcp_tool_col_desc', $uiLang)) ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($props as $paramName => $paramDef):
|
||||
$isReq = in_array($paramName, $required, true);
|
||||
$paramType = (string)($paramDef['type'] ?? 'string');
|
||||
$enumVals = (array)($paramDef['enum'] ?? []);
|
||||
$paramDesc = mcpToolParamT($slug, $paramName, $uiLang, $toolTranslations);
|
||||
if ($paramDesc === '') {
|
||||
$paramDesc = (string)($paramDef['description'] ?? '');
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="mcp-param-name <?= $isReq ? 'mcp-param-name--required' : 'mcp-param-name--optional' ?>">
|
||||
<?= htmlspecialchars($paramName) ?><?= $isReq ? '*' : '' ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="mcp-param-type"><?= htmlspecialchars($paramType) ?></span>
|
||||
<?php if (!empty($enumVals)): ?>
|
||||
<br><span class="mcp-param-enum"><?= htmlspecialchars(implode(' | ', $enumVals)) ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($isReq): ?>
|
||||
<span class="mcp-req-yes"><?= htmlspecialchars(dbnToolsT('mcp_tool_yes', $uiLang)) ?></span>
|
||||
<?php else: ?>
|
||||
<span class="mcp-req-no">—</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($paramDesc) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p style="font-size:0.75rem; color:var(--muted,#667085); margin-top:0.5rem;">
|
||||
* <?= htmlspecialchars(dbnToolsT('mcp_tools_param_req_hint', $uiLang)) ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<!-- ── Example request ───────────────────────────────────────── -->
|
||||
<section class="account-section">
|
||||
<p class="account-section__title"><?= htmlspecialchars(dbnToolsT('mcp_tool_example_req', $uiLang)) ?></p>
|
||||
<p class="mcp-code-label">POST /api/mcp/user/tools/<?= htmlspecialchars($slug) ?>/invoke</p>
|
||||
<div class="mcp-code-wrap">
|
||||
<button class="mcp-copy-btn" type="button" id="copyReqBtn">Copy</button>
|
||||
<pre><code id="exReqCode"><?= htmlspecialchars($exReq) ?></code></pre>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ── Example response ──────────────────────────────────────── -->
|
||||
<section class="account-section">
|
||||
<p class="account-section__title"><?= htmlspecialchars(dbnToolsT('mcp_tool_example_resp', $uiLang)) ?></p>
|
||||
<div class="mcp-code-wrap">
|
||||
<button class="mcp-copy-btn" type="button" id="copyRespBtn">Copy</button>
|
||||
<pre><code id="exRespCode"><?= htmlspecialchars($exResp) ?></code></pre>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ── Connect ───────────────────────────────────────────────── -->
|
||||
<section class="account-section">
|
||||
<p class="account-section__title"><?= htmlspecialchars(dbnToolsT('mcp_tool_connect_title', $uiLang)) ?></p>
|
||||
<p style="color:var(--muted,#667085); font-size:0.88rem; margin-top:0;">
|
||||
<?= htmlspecialchars(dbnToolsT('mcp_tool_connect_text', $uiLang)) ?>
|
||||
</p>
|
||||
<a href="/mcp.php" class="mcp-connect-link"><?= htmlspecialchars(dbnToolsT('mcp_tool_setup_link', $uiLang)) ?></a>
|
||||
</section>
|
||||
|
||||
<!-- ── Privacy ───────────────────────────────────────────────── -->
|
||||
<section class="account-section">
|
||||
<p class="account-section__title"><?= htmlspecialchars(dbnToolsT('mcp_privacy_title', $uiLang)) ?></p>
|
||||
<div class="mcp-privacy">
|
||||
<strong><?= htmlspecialchars(dbnToolsT('mcp_privacy_text', $uiLang)) ?></strong>
|
||||
</div>
|
||||
<p style="margin-top:0.75rem; font-size:0.82rem; color:var(--muted,#667085);">
|
||||
<?= htmlspecialchars(dbnToolsT('mcp_privacy_legal', $uiLang)) ?>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
</div><!-- /.account-shell -->
|
||||
|
||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
'use strict';
|
||||
function copyText(text, btn) {
|
||||
var orig = btn.textContent;
|
||||
if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(text).then(function () {
|
||||
btn.textContent = 'Copied!';
|
||||
setTimeout(function () { btn.textContent = orig; }, 1500);
|
||||
});
|
||||
} else {
|
||||
var ta = document.createElement('textarea');
|
||||
ta.value = text;
|
||||
ta.style.cssText = 'position:fixed;opacity:0';
|
||||
document.body.appendChild(ta);
|
||||
ta.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(ta);
|
||||
btn.textContent = 'Copied!';
|
||||
setTimeout(function () { btn.textContent = orig; }, 1500);
|
||||
}
|
||||
}
|
||||
var reqBtn = document.getElementById('copyReqBtn');
|
||||
var respBtn = document.getElementById('copyRespBtn');
|
||||
var reqCode = document.getElementById('exReqCode');
|
||||
var respCode = document.getElementById('exRespCode');
|
||||
if (reqBtn && reqCode) reqBtn.addEventListener('click', function () { copyText(reqCode.textContent, reqBtn); });
|
||||
if (respBtn && respCode) respBtn.addEventListener('click', function () { copyText(respCode.textContent, respBtn); });
|
||||
}());
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -50,8 +50,8 @@ $toolIcons = [
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>MCP — Do Better Norge</title>
|
||||
<meta name="description" content="Connect Claude, Cursor, and other AI tools to all 19 Do Better Norge legal preparation tools via MCP.">
|
||||
<title><?= htmlspecialchars(dbnToolsT('mcp_page_title', $uiLang)) ?></title>
|
||||
<meta name="description" content="<?= htmlspecialchars(dbnToolsT('mcp_meta_desc', $uiLang)) ?>">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
@@ -190,7 +190,16 @@ $toolIcons = [
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
.mcp-tool-card[open] .mcp-tool-card__desc { -webkit-line-clamp: unset; overflow: visible; }
|
||||
.mcp-tool-card[data-expanded="1"] .mcp-tool-card__desc { -webkit-line-clamp: unset; overflow: visible; }
|
||||
.mcp-tool-card__details-link {
|
||||
display: inline-block;
|
||||
margin-top: 0.5rem;
|
||||
font-size: 0.78rem;
|
||||
color: var(--dbn-blue, #00205b);
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
}
|
||||
.mcp-tool-card__details-link:hover { text-decoration: underline; }
|
||||
/* ── Gated states ───────────────────────────────────────────── */
|
||||
.mcp-gate {
|
||||
text-align: center;
|
||||
@@ -259,30 +268,34 @@ window.DBN_TOOLS_LANG = <?= json_encode($uiLang, JSON_UNESCAPED_UNICODE) ?>;
|
||||
|
||||
<!-- ── Hero ─────────────────────────────────────────────────── -->
|
||||
<div class="mcp-hero">
|
||||
<div class="mcp-hero__badge">✦ Plus & Pro</div>
|
||||
<h1>Use DBN tools from Claude, Cursor & Copilot</h1>
|
||||
<p>Connect any MCP client to all 19 Do Better Norge tools — transcription, legal analysis, timelines, redaction, and more.</p>
|
||||
<div class="mcp-hero__badge"><?= htmlspecialchars(dbnToolsT('mcp_hero_badge', $uiLang)) ?></div>
|
||||
<h1><?= htmlspecialchars(dbnToolsT('mcp_hero_h1', $uiLang)) ?></h1>
|
||||
<p><?= htmlspecialchars(dbnToolsT('mcp_hero_sub', $uiLang)) ?></p>
|
||||
</div>
|
||||
|
||||
<!-- ── Token management ─────────────────────────────────────── -->
|
||||
<section class="account-section" id="mcpTokenSection">
|
||||
<p class="account-section__title">Your MCP token</p>
|
||||
<p class="account-section__title"><?= htmlspecialchars(dbnToolsT('mcp_token_section_title', $uiLang)) ?></p>
|
||||
|
||||
<?php if (!$isLoggedIn): ?>
|
||||
<div class="mcp-gate">
|
||||
<p>Sign in to create your personal MCP token for Plus or Pro members.</p>
|
||||
<a href="/?return=<?= urlencode('/mcp.php') ?>" class="account-upgrade-btn" style="display:inline-block; text-decoration:none;">Sign in</a>
|
||||
<p><?= htmlspecialchars(dbnToolsT('mcp_gate_guest_p', $uiLang)) ?></p>
|
||||
<a href="/?return=<?= urlencode('/mcp.php') ?>" class="account-upgrade-btn" style="display:inline-block; text-decoration:none;">
|
||||
<?= htmlspecialchars(dbnToolsT('mcp_gate_guest_btn', $uiLang)) ?>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php elseif (!$isPlusPro): ?>
|
||||
<div class="mcp-gate">
|
||||
<p>MCP access is available on Plus and Pro plans. Upgrade to connect your AI tools.</p>
|
||||
<a href="/account.php" class="account-upgrade-btn" style="display:inline-block; text-decoration:none;">Upgrade plan</a>
|
||||
<p><?= htmlspecialchars(dbnToolsT('mcp_gate_free_p', $uiLang)) ?></p>
|
||||
<a href="/account.php" class="account-upgrade-btn" style="display:inline-block; text-decoration:none;">
|
||||
<?= htmlspecialchars(dbnToolsT('mcp_gate_free_btn', $uiLang)) ?>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<p style="color:var(--muted,#667085); font-size:0.88rem; margin-top:0;">
|
||||
Tokens are shown once at creation. Create one per client (Claude, Cursor, VS Code…).
|
||||
<?= htmlspecialchars(dbnToolsT('mcp_token_hint', $uiLang)) ?>
|
||||
</p>
|
||||
|
||||
<div id="mcpTokenList" style="margin:0.85rem 0 0.25rem;"></div>
|
||||
@@ -290,23 +303,27 @@ window.DBN_TOOLS_LANG = <?= json_encode($uiLang, JSON_UNESCAPED_UNICODE) ?>;
|
||||
<form id="mcpTokenForm" style="display:flex; gap:0.5rem; flex-wrap:wrap; align-items:center; margin-top:0.85rem;">
|
||||
<input id="mcpTokenName" type="text" maxlength="100" value="DBN MCP" aria-label="Token name"
|
||||
style="min-width:220px; padding:0.65rem 0.75rem; border:1px solid var(--line,#d0d5dd); border-radius:8px; font-size:0.9rem;">
|
||||
<button type="submit" class="account-upgrade-btn" style="border:0; cursor:pointer;">Create token</button>
|
||||
<button type="submit" class="account-upgrade-btn" style="border:0; cursor:pointer;">
|
||||
<?= htmlspecialchars(dbnToolsT('mcp_token_create_btn', $uiLang)) ?>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div id="mcpTokenReveal" class="mcp-token-reveal">
|
||||
<strong>Copy this token now — it won't be shown again:</strong>
|
||||
<strong><?= htmlspecialchars(dbnToolsT('mcp_token_reveal_label', $uiLang)) ?></strong>
|
||||
<code id="mcpTokenPlain"></code>
|
||||
<button id="mcpTokenCopyBtn" type="button" style="margin-top:0.6rem; border:1px solid #bbf7d0; background:#fff; border-radius:6px; padding:0.35rem 0.7rem; cursor:pointer; font-size:0.82rem;">Copy token</button>
|
||||
<button id="mcpTokenCopyBtn" type="button" style="margin-top:0.6rem; border:1px solid #bbf7d0; background:#fff; border-radius:6px; padding:0.35rem 0.7rem; cursor:pointer; font-size:0.82rem;">
|
||||
<?= htmlspecialchars(dbnToolsT('mcp_token_copy_btn', $uiLang)) ?>
|
||||
</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<!-- ── Client config ─────────────────────────────────────────── -->
|
||||
<section class="account-section">
|
||||
<p class="account-section__title">Client configuration</p>
|
||||
<p class="account-section__title"><?= htmlspecialchars(dbnToolsT('mcp_config_title', $uiLang)) ?></p>
|
||||
<p style="color:var(--muted,#667085); font-size:0.88rem; margin-top:0; margin-bottom:1rem;">
|
||||
Paste your token into the config below after creating it above.
|
||||
<span id="tokenHint" style="display:none;color:#065f46;font-weight:600;"> Token auto-filled.</span>
|
||||
<?= htmlspecialchars(dbnToolsT('mcp_config_hint', $uiLang)) ?>
|
||||
<span id="tokenHint" style="display:none;color:#065f46;font-weight:600;"> <?= htmlspecialchars(dbnToolsT('mcp_config_token_filled', $uiLang)) ?></span>
|
||||
</p>
|
||||
|
||||
<div class="mcp-tabs" role="tablist" aria-label="MCP client">
|
||||
@@ -343,7 +360,7 @@ window.DBN_TOOLS_LANG = <?= json_encode($uiLang, JSON_UNESCAPED_UNICODE) ?>;
|
||||
<!-- Claude Code -->
|
||||
<div class="mcp-tab-panel" id="tab-claude-code" role="tabpanel">
|
||||
<p style="font-size:0.85rem; color:var(--muted,#667085); margin:0 0 0.75rem;">
|
||||
Run in your terminal:
|
||||
<?= htmlspecialchars(dbnToolsT('mcp_config_run_terminal', $uiLang)) ?>
|
||||
</p>
|
||||
<div class="mcp-code-wrap">
|
||||
<button class="mcp-copy-btn" type="button" data-copy="claude-code">Copy</button>
|
||||
@@ -427,7 +444,7 @@ Authorization: Bearer dbn_user_mcp_...</code></pre>
|
||||
<div style="margin-top:1.25rem; display:flex; align-items:center; gap:0.75rem; flex-wrap:wrap;">
|
||||
<button id="mcpTestBtn" type="button"
|
||||
style="border:1px solid var(--dbn-blue,#00205b); color:var(--dbn-blue,#00205b); background:#fff; border-radius:8px; padding:0.55rem 1rem; cursor:pointer; font-size:0.88rem;">
|
||||
Test connection
|
||||
<?= htmlspecialchars(dbnToolsT('mcp_test_btn', $uiLang)) ?>
|
||||
</button>
|
||||
<span id="mcpTestResult" style="font-size:0.88rem;"></span>
|
||||
</div>
|
||||
@@ -436,9 +453,9 @@ Authorization: Bearer dbn_user_mcp_...</code></pre>
|
||||
|
||||
<!-- ── Tool catalog ───────────────────────────────────────────── -->
|
||||
<section class="account-section">
|
||||
<p class="account-section__title">Available tools (<?= count($toolCatalog) ?>)</p>
|
||||
<p class="account-section__title"><?= htmlspecialchars(dbnToolsT('mcp_tools_title', $uiLang)) ?> (<?= count($toolCatalog) ?>)</p>
|
||||
<p style="color:var(--muted,#667085); font-size:0.88rem; margin-top:0;">
|
||||
All tools run on your Plus or Pro plan credits. Click a card for full details.
|
||||
<?= htmlspecialchars(dbnToolsT('mcp_tools_sub', $uiLang)) ?>
|
||||
</p>
|
||||
|
||||
<div class="mcp-tool-grid" id="mcpToolGrid">
|
||||
@@ -450,6 +467,7 @@ Authorization: Bearer dbn_user_mcp_...</code></pre>
|
||||
$props = (array)($tool['config']['input_schema']['properties'] ?? []);
|
||||
$req = (array)($tool['config']['input_schema']['required'] ?? []);
|
||||
$paramNames = array_keys($props);
|
||||
$detailUrl = '/mcp-tool.php?tool=' . urlencode((string)($tool['slug'] ?? '')) . '&lang=' . urlencode($uiLang);
|
||||
?>
|
||||
<div class="mcp-tool-card" data-slug="<?= $slug ?>">
|
||||
<div class="mcp-tool-card__icon"><?= $icon ?></div>
|
||||
@@ -465,10 +483,14 @@ Authorization: Bearer dbn_user_mcp_...</code></pre>
|
||||
font-family: monospace;"><?= htmlspecialchars($param) ?><?= in_array($param, $req, true) ? '*' : '' ?></span>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<p style="margin:0.5rem 0 0; font-size:0.75rem; color:var(--muted,#667085); display:none;" class="mcp-tool-card__hint">
|
||||
<em>Purple = required</em>
|
||||
<p style="margin:0.3rem 0 0; font-size:0.75rem; color:var(--muted,#667085); display:none;" class="mcp-tool-card__hint">
|
||||
<em><?= htmlspecialchars(dbnToolsT('mcp_tools_param_req_hint', $uiLang)) ?></em>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<a href="<?= htmlspecialchars($detailUrl) ?>" class="mcp-tool-card__details-link" style="display:none;"
|
||||
onclick="event.stopPropagation();">
|
||||
<?= htmlspecialchars(dbnToolsT('mcp_tools_view_details', $uiLang)) ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
@@ -476,15 +498,12 @@ Authorization: Bearer dbn_user_mcp_...</code></pre>
|
||||
|
||||
<!-- ── Privacy notice ─────────────────────────────────────────── -->
|
||||
<section class="account-section">
|
||||
<p class="account-section__title">Privacy</p>
|
||||
<p class="account-section__title"><?= htmlspecialchars(dbnToolsT('mcp_privacy_title', $uiLang)) ?></p>
|
||||
<div class="mcp-privacy">
|
||||
<strong>Process-and-forget by default.</strong> All tool calls process your text in memory and return results to your AI client.
|
||||
Nothing is saved to My Case unless you explicitly call <code>dbn.save_to_case</code>.
|
||||
DBN MCP tokens do not retain input text or tool results after the request completes.
|
||||
<strong><?= htmlspecialchars(dbnToolsT('mcp_privacy_text', $uiLang)) ?></strong>
|
||||
</div>
|
||||
<p style="margin-top:1rem; font-size:0.82rem; color:var(--muted,#667085);">
|
||||
Tools provide legal preparation support, not final legal advice.
|
||||
Results are for informational purposes and should be reviewed by a qualified legal professional.
|
||||
<?= htmlspecialchars(dbnToolsT('mcp_privacy_legal', $uiLang)) ?>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -496,6 +515,17 @@ Authorization: Bearer dbn_user_mcp_...</code></pre>
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/* ── i18n from PHP ─────────────────────────────────────────── */
|
||||
var I = {
|
||||
tokenActive: <?= json_encode(dbnToolsT('mcp_token_active', $uiLang)) ?>,
|
||||
tokenRevoked: <?= json_encode(dbnToolsT('mcp_token_revoked', $uiLang)) ?>,
|
||||
tokenNeverUsed: <?= json_encode(dbnToolsT('mcp_token_never_used', $uiLang)) ?>,
|
||||
tokenLastUsed: <?= json_encode(dbnToolsT('mcp_token_last_used', $uiLang)) ?>,
|
||||
tokenRevokeBtn: <?= json_encode(dbnToolsT('mcp_token_revoke_btn', $uiLang)) ?>,
|
||||
testNoToken: <?= json_encode(dbnToolsT('mcp_test_no_token', $uiLang)) ?>,
|
||||
testTesting: <?= json_encode(dbnToolsT('mcp_test_testing', $uiLang)) ?>,
|
||||
};
|
||||
|
||||
/* ── Helpers ──────────────────────────────────────────────────── */
|
||||
function esc(s) {
|
||||
return String(s || '').replace(/[&<>"']/g, function (c) {
|
||||
@@ -569,15 +599,18 @@ Authorization: Bearer dbn_user_mcp_...</code></pre>
|
||||
var params = card.querySelector('.mcp-tool-card__params');
|
||||
var hint = card.querySelector('.mcp-tool-card__hint');
|
||||
var desc = card.querySelector('.mcp-tool-card__desc');
|
||||
var details = card.querySelector('.mcp-tool-card__details-link');
|
||||
if (expanded) {
|
||||
card.setAttribute('data-expanded', '0');
|
||||
if (params) params.style.display = 'none';
|
||||
if (hint) hint.style.display = 'none';
|
||||
if (details) details.style.display = 'none';
|
||||
if (desc) { desc.style.webkitLineClamp = '2'; desc.style.overflow = 'hidden'; }
|
||||
} else {
|
||||
card.setAttribute('data-expanded', '1');
|
||||
if (params) params.style.display = 'flex';
|
||||
if (hint) hint.style.display = 'block';
|
||||
if (details) details.style.display = 'inline-block';
|
||||
if (desc) { desc.style.webkitLineClamp = 'unset'; desc.style.overflow = 'visible'; }
|
||||
}
|
||||
});
|
||||
@@ -590,20 +623,20 @@ Authorization: Bearer dbn_user_mcp_...</code></pre>
|
||||
function renderTokens(tokens) {
|
||||
if (!tokenList) return;
|
||||
if (!tokens.length) {
|
||||
tokenList.innerHTML = '<p style="color:var(--muted,#667085); font-size:0.88rem;">No MCP tokens yet.</p>';
|
||||
tokenList.innerHTML = '<p style="color:var(--muted,#667085); font-size:0.88rem;"><?= addslashes(dbnToolsT('mcp_token_no_tokens', $uiLang)) ?></p>';
|
||||
return;
|
||||
}
|
||||
tokenList.innerHTML = tokens.map(function (t) {
|
||||
var status = t.is_active ? 'Active' : 'Revoked';
|
||||
var last = t.last_used_at ? 'Last used ' + esc(t.last_used_at) : 'Never used';
|
||||
var status = t.is_active ? esc(I.tokenActive) : esc(I.tokenRevoked);
|
||||
var last = t.last_used_at ? esc(I.tokenLastUsed) + ' ' + esc(t.last_used_at) : esc(I.tokenNeverUsed);
|
||||
var revoke = t.is_active
|
||||
? '<button type="button" class="mcp-token-row__revoke" data-revoke="' + t.id + '">Revoke</button>'
|
||||
? '<button type="button" class="mcp-token-row__revoke" data-revoke="' + t.id + '">' + esc(I.tokenRevokeBtn) + '</button>'
|
||||
: '';
|
||||
return '<div class="mcp-token-row">'
|
||||
+ '<div>'
|
||||
+ '<strong>' + esc(t.name) + '</strong><br>'
|
||||
+ '<code style="font-size:0.8rem;">' + esc(t.token_prefix) + '…</code><br>'
|
||||
+ '<span style="color:var(--muted,#667085); font-size:0.78rem;">' + esc(status) + ' · ' + esc(last) + '</span>'
|
||||
+ '<span style="color:var(--muted,#667085); font-size:0.78rem;">' + status + ' · ' + last + '</span>'
|
||||
+ '</div>'
|
||||
+ revoke
|
||||
+ '</div>';
|
||||
@@ -657,7 +690,6 @@ Authorization: Bearer dbn_user_mcp_...</code></pre>
|
||||
if (reveal) reveal.style.display = 'block';
|
||||
fillToken(tok);
|
||||
loadTokens();
|
||||
// Scroll to config
|
||||
var configSection = document.querySelector('.mcp-tabs');
|
||||
if (configSection) configSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
})
|
||||
@@ -678,11 +710,11 @@ Authorization: Bearer dbn_user_mcp_...</code></pre>
|
||||
if (testBtn) {
|
||||
testBtn.addEventListener('click', function () {
|
||||
if (!activeToken) {
|
||||
if (testResult) { testResult.textContent = 'Create a token first.'; testResult.style.color = '#b45309'; }
|
||||
if (testResult) { testResult.textContent = I.testNoToken; testResult.style.color = '#b45309'; }
|
||||
return;
|
||||
}
|
||||
testBtn.disabled = true;
|
||||
if (testResult) { testResult.textContent = 'Testing…'; testResult.style.color = 'var(--muted,#667085)'; }
|
||||
if (testResult) { testResult.textContent = I.testTesting; testResult.style.color = 'var(--muted,#667085)'; }
|
||||
fetch('/api/mcp/user/session', {
|
||||
headers: { 'Authorization': 'Bearer ' + activeToken }
|
||||
})
|
||||
|
||||
@@ -0,0 +1,463 @@
|
||||
<?php
|
||||
/**
|
||||
* generate-mcp-translations.php
|
||||
* One-shot CLI script: php scripts/generate-mcp-translations.php
|
||||
*
|
||||
* Produces two files:
|
||||
* 1. translations/mcp-chrome.php — UI chrome strings for mcp.php + mcp-tool.php
|
||||
* 2. includes/mcp-tool-translations.php — tool names, descriptions, param docs in all 4 languages
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
define('SCRIPT_MODE', true);
|
||||
require_once dirname(__DIR__) . '/includes/bootstrap.php';
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Azure config (same pattern as generate-page-translations.php)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
$azConfig = [
|
||||
'endpoint' => rtrim((string)dbnToolsEnv('DBN_AZURE_OPENAI_ENDPOINT', ''), '/'),
|
||||
'api_key' => (string)dbnToolsEnv('DBN_AZURE_OPENAI_API_KEY', ''),
|
||||
'api_version' => (string)dbnToolsEnv('DBN_AZURE_OPENAI_API_VERSION', '2024-02-01'),
|
||||
'chat_deployment' => (string)dbnToolsEnv('DBN_AZURE_OPENAI_CHAT_DEPLOYMENT', 'gpt-4o-mini'),
|
||||
];
|
||||
|
||||
function azureChat(array $config, array $messages, array $options = []): array
|
||||
{
|
||||
$url = $config['endpoint']
|
||||
. '/openai/deployments/'
|
||||
. rawurlencode($config['chat_deployment'])
|
||||
. '/chat/completions?api-version='
|
||||
. rawurlencode($config['api_version']);
|
||||
|
||||
$payload = json_encode(array_filter([
|
||||
'messages' => $messages,
|
||||
'temperature' => $options['temperature'] ?? 0.1,
|
||||
'max_tokens' => $options['max_tokens'] ?? 4096,
|
||||
'response_format' => isset($options['json']) && $options['json']
|
||||
? ['type' => 'json_object'] : null,
|
||||
], fn($v) => $v !== null), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $payload,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Content-Type: application/json',
|
||||
'api-key: ' . $config['api_key'],
|
||||
],
|
||||
CURLOPT_TIMEOUT => (int)($options['timeout'] ?? 120),
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_SSL_VERIFYHOST => false,
|
||||
]);
|
||||
|
||||
$body = curl_exec($ch);
|
||||
$code = (int)curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
|
||||
$err = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($body === false) throw new RuntimeException("Azure curl failed: $err");
|
||||
$decoded = json_decode($body, true);
|
||||
if (!is_array($decoded)) throw new RuntimeException("Azure returned non-JSON (HTTP $code)");
|
||||
if ($code < 200 || $code >= 300) {
|
||||
throw new RuntimeException('Azure error: ' . ($decoded['error']['message'] ?? "HTTP $code"));
|
||||
}
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
$languages = [
|
||||
'no' => 'Norwegian (Norsk bokmål)',
|
||||
'uk' => 'Ukrainian',
|
||||
'pl' => 'Polish',
|
||||
];
|
||||
|
||||
$systemPrompt = <<<'PROMPT'
|
||||
You are a professional legal translator specializing in Norwegian family law and child welfare.
|
||||
Translate all JSON string values to {LANG}.
|
||||
|
||||
PRESERVE AS-IS:
|
||||
- Norwegian institution names: Barnevernet, Statsforvalteren, Bufdir, Fylkesnemnda, NAV, Tingretten
|
||||
- Norwegian legal act names: forvaltningsloven, barnevernsloven, opplæringslova, EMK, fvl
|
||||
- Norwegian legal terms: klage, vedtak, saksnummer, akutt, omsorgsovertakelse, tiltaksplan
|
||||
- Technical terms: MCP, DBN, dbn.tool_name, JSON, Bearer token, npx, stdio
|
||||
- Brand names: Do Better Norge, Claude, Cursor, VS Code, Windsurf, Copilot
|
||||
- Code snippets, URLs, env var names like DBN_MCP_TOKEN
|
||||
- HTML entities and tags exactly as they appear
|
||||
- The symbol ← and →
|
||||
|
||||
Return a JSON object with EXACTLY the same keys as the input. Translate only the string values.
|
||||
Use formal/professional register appropriate for a legal tools platform.
|
||||
PROMPT;
|
||||
|
||||
function translateBatch(array $azConfig, string $langName, string $systemPrompt, array $batch): array
|
||||
{
|
||||
$prompt = str_replace('{LANG}', $langName, $systemPrompt);
|
||||
$json = json_encode($batch, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
$response = azureChat($azConfig, [
|
||||
['role' => 'system', 'content' => $prompt],
|
||||
['role' => 'user', 'content' => $json],
|
||||
], ['json' => true, 'max_tokens' => 4096, 'timeout' => 120]);
|
||||
|
||||
$content = trim((string)($response['choices'][0]['message']['content'] ?? ''));
|
||||
$decoded = json_decode($content, true);
|
||||
if (!is_array($decoded)) {
|
||||
echo " [WARN] JSON parse failed, trying extraction...\n";
|
||||
if (preg_match('/\{.*\}/s', $content, $m)) {
|
||||
$decoded = json_decode($m[0], true);
|
||||
}
|
||||
}
|
||||
if (!is_array($decoded)) {
|
||||
echo " [ERROR] Could not parse response, using English fallback\n";
|
||||
return $batch;
|
||||
}
|
||||
foreach ($batch as $k => $v) {
|
||||
if (!isset($decoded[$k])) $decoded[$k] = $v;
|
||||
}
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
function writePhpFile(string $path, array $data, string $comment): void
|
||||
{
|
||||
$php = "<?php\n// $comment\n// DO NOT EDIT MANUALLY — regenerate with scripts/generate-mcp-translations.php\nreturn ";
|
||||
$php .= var_export($data, true);
|
||||
$php .= ";\n";
|
||||
file_put_contents($path, $php);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Part 1 — MCP UI chrome strings
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
$chromeEn = [
|
||||
// mcp.php
|
||||
'mcp_page_title' => 'MCP — Do Better Norge',
|
||||
'mcp_meta_desc' => 'Connect Claude, Cursor, and other AI tools to all 19 DBN legal preparation tools via MCP.',
|
||||
'mcp_hero_badge' => '✦ Plus & Pro',
|
||||
'mcp_hero_h1' => 'Use DBN tools from Claude, Cursor & Copilot',
|
||||
'mcp_hero_sub' => 'Connect any MCP client to all 19 Do Better Norge tools — transcription, legal analysis, timelines, redaction, and more.',
|
||||
'mcp_token_section_title' => 'Your MCP token',
|
||||
'mcp_gate_guest_p' => 'Sign in to create your personal MCP token. Available to Plus and Pro members.',
|
||||
'mcp_gate_guest_btn' => 'Sign in',
|
||||
'mcp_gate_free_p' => 'MCP access is available on Plus and Pro plans. Upgrade to connect your AI tools.',
|
||||
'mcp_gate_free_btn' => 'Upgrade plan',
|
||||
'mcp_token_hint' => 'Tokens are shown once at creation. Create one per client (Claude, Cursor, VS Code…).',
|
||||
'mcp_token_create_btn' => 'Create token',
|
||||
'mcp_token_reveal_label' => 'Copy this token now — it will not be shown again:',
|
||||
'mcp_token_copy_btn' => 'Copy token',
|
||||
'mcp_token_no_tokens' => 'No MCP tokens yet.',
|
||||
'mcp_token_active' => 'Active',
|
||||
'mcp_token_revoked' => 'Revoked',
|
||||
'mcp_token_never_used' => 'Never used',
|
||||
'mcp_token_last_used' => 'Last used',
|
||||
'mcp_token_revoke_btn' => 'Revoke',
|
||||
'mcp_config_title' => 'Client configuration',
|
||||
'mcp_config_hint' => 'Paste your token into the config below after creating it above.',
|
||||
'mcp_config_token_filled' => 'Token auto-filled.',
|
||||
'mcp_config_run_terminal' => 'Run in your terminal:',
|
||||
'mcp_test_btn' => 'Test connection',
|
||||
'mcp_test_no_token' => 'Create a token first.',
|
||||
'mcp_test_testing' => 'Testing…',
|
||||
'mcp_tools_title' => 'Available tools',
|
||||
'mcp_tools_sub' => 'All tools run on your Plus or Pro plan credits. Click a card for full technical details.',
|
||||
'mcp_tools_param_req_hint' => 'Purple = required',
|
||||
'mcp_tools_view_details' => 'View details →',
|
||||
// privacy section
|
||||
'mcp_privacy_title' => 'Privacy',
|
||||
'mcp_privacy_text' => 'Process-and-forget by default. All tool calls process your text in memory and return results to your AI client. Nothing is saved to My Case unless you explicitly call dbn.save_to_case.',
|
||||
'mcp_privacy_legal' => 'Tools provide legal preparation support, not final legal advice. Results are for informational purposes and should be reviewed by a qualified legal professional.',
|
||||
// mcp-tool.php
|
||||
'mcp_tool_back' => '← Back to MCP setup',
|
||||
'mcp_tool_params_title' => 'Parameters',
|
||||
'mcp_tool_no_params' => 'This tool takes no input parameters.',
|
||||
'mcp_tool_col_param' => 'Parameter',
|
||||
'mcp_tool_col_type' => 'Type',
|
||||
'mcp_tool_col_required' => 'Required',
|
||||
'mcp_tool_col_desc' => 'Description',
|
||||
'mcp_tool_example_req' => 'Example request',
|
||||
'mcp_tool_example_resp' => 'Example response',
|
||||
'mcp_tool_connect_title' => 'Connect',
|
||||
'mcp_tool_connect_text' => 'Create your MCP token on the setup page and use it with any supported client.',
|
||||
'mcp_tool_setup_link' => 'Set up MCP →',
|
||||
'mcp_tool_yes' => 'Yes',
|
||||
'mcp_tool_no' => 'No',
|
||||
];
|
||||
|
||||
echo "\n=== Part 1: Translating MCP UI chrome strings ===\n";
|
||||
$chromeTranslations = ['en' => $chromeEn];
|
||||
$batchSize = 20;
|
||||
$keys = array_keys($chromeEn);
|
||||
$batches = array_chunk($keys, $batchSize);
|
||||
|
||||
foreach ($languages as $langCode => $langName) {
|
||||
echo " Language: $langName ($langCode)\n";
|
||||
$langResult = [];
|
||||
foreach ($batches as $idx => $batchKeys) {
|
||||
$batchNum = $idx + 1;
|
||||
echo " Batch $batchNum/" . count($batches) . " (" . count($batchKeys) . " strings)...\n";
|
||||
$batchInput = [];
|
||||
foreach ($batchKeys as $k) $batchInput[$k] = $chromeEn[$k];
|
||||
$langResult = array_merge($langResult, translateBatch($azConfig, $langName, $systemPrompt, $batchInput));
|
||||
}
|
||||
$chromeTranslations[$langCode] = $langResult;
|
||||
}
|
||||
|
||||
$chromeOutPath = dirname(__DIR__) . '/translations/mcp-chrome.php';
|
||||
writePhpFile($chromeOutPath, $chromeTranslations, 'MCP UI chrome translations — mcp.php + mcp-tool.php');
|
||||
echo " Written: $chromeOutPath\n";
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Part 2 — MCP tool content (display_name, description, param descriptions)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
// English source for all tool content — param descriptions are authored here
|
||||
// since DbnMcpRuntime.php params mostly lack description fields.
|
||||
$toolsEn = [
|
||||
'dbn.search_legal' => [
|
||||
'display_name' => 'Search DBN legal corpus',
|
||||
'description' => 'Search the DBN Norwegian family-law corpus.',
|
||||
'params' => [
|
||||
'query' => 'The search query (minimum 3 characters). Enter a legal topic, keyword, or question.',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto (detect from input).',
|
||||
'limit' => 'Maximum number of results to return (1–10).',
|
||||
'corpus_scope' => 'Which corpus to search: shared (public legal corpus), private (your uploaded documents), or both.',
|
||||
],
|
||||
],
|
||||
'dbn.ask' => [
|
||||
'display_name' => 'Ask a legal question',
|
||||
'description' => 'Answer a legal preparation question with source-grounded DBN context.',
|
||||
'params' => [
|
||||
'question' => 'The legal question to answer (minimum 5 characters).',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'use_case_context' => 'Include context from your Case Workbench session (true/false).',
|
||||
],
|
||||
],
|
||||
'dbn.summarize' => [
|
||||
'display_name' => 'Summarize document',
|
||||
'description' => 'Summarize pasted case text with optional legal-corpus enrichment.',
|
||||
'params' => [
|
||||
'text' => 'The text to summarize.',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'use_legal_corpus' => 'Enrich the summary with relevant legal corpus passages (true/false).',
|
||||
'use_case_context' => 'Include context from your Case Workbench session (true/false).',
|
||||
],
|
||||
],
|
||||
'dbn.timeline' => [
|
||||
'display_name' => 'Extract timeline',
|
||||
'description' => 'Extract dates, hearings, milestones, and deadlines from case text.',
|
||||
'params' => [
|
||||
'text' => 'The case text to extract dates from.',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'focus' => 'What to extract: all (every date), deadlines (appeal windows and filing deadlines), hearings (tribunal and court dates), cps (Barnevernet milestones).',
|
||||
'use_case_context' => 'Include context from your Case Workbench session (true/false).',
|
||||
],
|
||||
],
|
||||
'dbn.redact' => [
|
||||
'display_name' => 'Redact private data',
|
||||
'description' => 'Remove or pseudonymize names, IDs, phone numbers, addresses, and places.',
|
||||
'params' => [
|
||||
'text' => 'The text to redact.',
|
||||
'language' => 'Language of the input text: en, no, uk, pl, or auto.',
|
||||
'mode' => 'Redaction scope: standard (names, IDs, phones) or strict (also addresses, locations, institutions).',
|
||||
'output_format' => 'Replacement style: contextual ([PERSON A]), generic (█████), or pseudonym (consistent invented names).',
|
||||
],
|
||||
],
|
||||
'dbn.translate' => [
|
||||
'display_name' => 'Translate legal document',
|
||||
'description' => 'Translate Norwegian family-law text with legal terminology annotations.',
|
||||
'params' => [
|
||||
'text' => 'The text to translate.',
|
||||
'source_lang' => 'Language of the input text. Use auto to detect automatically.',
|
||||
'target_lang' => 'Language to translate into (required): en, no, uk, or pl.',
|
||||
'doc_type' => 'Document type hint for legal terminology: auto, barnevernet, adopsjon, emergency, samvaer, fylkesnemnd, or other.',
|
||||
],
|
||||
],
|
||||
'dbn.legal_analysis' => [
|
||||
'display_name' => 'Legal analysis',
|
||||
'description' => 'Extract legal issues from a document and answer each with DBN legal context.',
|
||||
'params' => [
|
||||
'text' => 'The document text to analyze.',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'doc_type' => 'Document type hint: auto, barnevernet, adopsjon, emergency, samvaer, fylkesnemnd, or other.',
|
||||
],
|
||||
],
|
||||
'dbn.korrespond' => [
|
||||
'display_name' => 'Draft authority correspondence',
|
||||
'description' => 'Draft a reply or new letter to Norwegian authorities.',
|
||||
'params' => [
|
||||
'narrative' => 'Description of your situation — what happened and what you need.',
|
||||
'received_text' => 'Text of the letter or decision you received (for reply mode).',
|
||||
'recipient_body' => 'The authority you are writing to (e.g. Barnevernet, NAV, Skole, Kommune).',
|
||||
'goal' => 'Your legal goal — what you want the letter to achieve.',
|
||||
'mode' => 'reply (responding to a received letter) or initiate (starting new correspondence).',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'use_case_context' => 'Include context from your Case Workbench session (true/false).',
|
||||
'force_draft' => 'Skip the clarify gate and draft immediately (true/false).',
|
||||
],
|
||||
],
|
||||
'dbn.barnevernet_analyze' => [
|
||||
'display_name' => 'Analyze Barnevernet document',
|
||||
'description' => 'Analyze child-welfare documents for red flags and legal issues.',
|
||||
'params' => [
|
||||
'document_text' => 'Full text of the child welfare document to analyze (required).',
|
||||
'filename' => 'Original filename for context (helps identify document type).',
|
||||
'advocate_role' => 'Your role in the case: parent, lawyer, guardian ad litem, etc.',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'use_case_context' => 'Include context from your Case Workbench session (true/false).',
|
||||
],
|
||||
],
|
||||
'dbn.advocate_brief' => [
|
||||
'display_name' => 'Create advocate brief',
|
||||
'description' => 'Generate a source-grounded brief for a chosen party or role.',
|
||||
'params' => [
|
||||
'query' => 'Legal question or topic for the brief.',
|
||||
'paste_text' => 'Document text to use as the basis for the brief.',
|
||||
'advocate_role' => 'The party or role to advocate for (required). E.g. parent, child, Barnevernet.',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'use_case_context' => 'Include context from your Case Workbench session (true/false).',
|
||||
],
|
||||
],
|
||||
'dbn.deep_research' => [
|
||||
'display_name' => 'Deep research',
|
||||
'description' => 'Expand a legal question into research angles and synthesize a cited brief.',
|
||||
'params' => [
|
||||
'query' => 'Legal question to research in depth.',
|
||||
'paste_text' => 'Supporting document text to research from.',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
'use_case_context' => 'Include context from your Case Workbench session (true/false).',
|
||||
],
|
||||
],
|
||||
'dbn.discrepancy_find' => [
|
||||
'display_name' => 'Find document discrepancies',
|
||||
'description' => 'Compare two document versions for contradictions, deletions, and added claims.',
|
||||
'params' => [
|
||||
'document_a_text' => 'Text of the first document (required).',
|
||||
'document_b_text' => 'Text of the second document to compare against the first (required).',
|
||||
'filename_a' => 'Filename of the first document (for reference in the report).',
|
||||
'filename_b' => 'Filename of the second document (for reference in the report).',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
],
|
||||
],
|
||||
'dbn.transcribe_audio' => [
|
||||
'display_name' => 'Transcribe audio',
|
||||
'description' => 'Transcribe an audio file from base64-encoded content or a URL.',
|
||||
'params' => [
|
||||
'audio_base64' => 'Base64-encoded audio file content. Use either this or audio_url.',
|
||||
'audio_url' => 'URL to a publicly accessible audio file. Use either this or audio_base64.',
|
||||
'filename' => 'Original filename with extension (e.g. recording.mp3) — helps set the correct audio format.',
|
||||
'language' => 'Language spoken in the audio (e.g. no, en, uk). Leave blank for auto-detection.',
|
||||
'diarize' => 'Enable speaker diarization — label each segment with a speaker identifier (true/false).',
|
||||
],
|
||||
],
|
||||
'dbn.corpus_stats' => [
|
||||
'display_name' => 'Corpus statistics',
|
||||
'description' => 'Return document and chunk counts and active legal sources in the DBN corpus.',
|
||||
'params' => [],
|
||||
],
|
||||
'dbn.list_documents' => [
|
||||
'display_name' => 'List corpus documents',
|
||||
'description' => 'List DBN legal corpus documents with optional filters.',
|
||||
'params' => [
|
||||
'category' => 'Filter by document category (e.g. barnevernet, statsforvalter, echr).',
|
||||
'title' => 'Filter by title — partial match.',
|
||||
'limit' => 'Maximum number of documents to return (1–50, default 20).',
|
||||
'offset' => 'Number of documents to skip (for pagination).',
|
||||
],
|
||||
],
|
||||
'dbn.get_document' => [
|
||||
'display_name' => 'Get document chunks',
|
||||
'description' => 'Fetch a document and its text chunks by numeric document ID.',
|
||||
'params' => [
|
||||
'document_id' => 'The numeric ID of the document to retrieve (required).',
|
||||
],
|
||||
],
|
||||
'dbn.citation_graph' => [
|
||||
'display_name' => 'Explore citation graph',
|
||||
'description' => 'Explore cites, cited-by, implementation, or chain relationships.',
|
||||
'params' => [
|
||||
'doc_id' => 'The numeric ID of the document to explore (required).',
|
||||
'action' => 'Relationship to traverse: cites, cited_by, implements, or chain (full citation path).',
|
||||
'depth' => 'How many levels of relationships to explore (1–3, default 1).',
|
||||
],
|
||||
],
|
||||
'dbn.case_workbench_plan' => [
|
||||
'display_name' => 'Plan next case step',
|
||||
'description' => 'Create a stateless legal preparation plan based on your situation.',
|
||||
'params' => [
|
||||
'situation' => 'Describe your current legal situation and what you need help with (required).',
|
||||
'goal' => 'Your desired outcome or legal goal.',
|
||||
'deadline' => 'Any relevant deadline (date or description, e.g. "3 weeks").',
|
||||
'language' => 'Response language: en, no, uk, pl, or auto.',
|
||||
],
|
||||
],
|
||||
'dbn.save_to_case' => [
|
||||
'display_name' => 'Save result to My Case',
|
||||
'description' => 'Explicitly save a prior MCP tool result to the user case record.',
|
||||
'params' => [
|
||||
'tool' => 'The MCP tool slug whose result you are saving (required).',
|
||||
'title' => 'A descriptive title for this saved result.',
|
||||
'input_payload' => 'The input parameters used to generate the result (required).',
|
||||
'output_payload' => 'The tool result to save (required).',
|
||||
'meta' => 'Optional metadata (e.g. notes, tags, source reference).',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
echo "\n=== Part 2: Translating MCP tool content ===\n";
|
||||
|
||||
// Flatten all tool strings for translation (display_name, description, params)
|
||||
// Key format: {short_slug}__name, {short_slug}__desc, {short_slug}__p__{param}
|
||||
$flatSource = [];
|
||||
$slugMap = []; // short_slug => full_slug
|
||||
|
||||
foreach ($toolsEn as $fullSlug => $toolData) {
|
||||
$shortSlug = str_replace('dbn.', '', $fullSlug);
|
||||
$slugMap[$shortSlug] = $fullSlug;
|
||||
$flatSource[$shortSlug . '__name'] = $toolData['display_name'];
|
||||
$flatSource[$shortSlug . '__desc'] = $toolData['description'];
|
||||
foreach ($toolData['params'] as $param => $desc) {
|
||||
$flatSource[$shortSlug . '__p__' . $param] = $desc;
|
||||
}
|
||||
}
|
||||
|
||||
// Translate in batches of 20
|
||||
$flatKeys = array_keys($flatSource);
|
||||
$batches = array_chunk($flatKeys, 20);
|
||||
$flatTranslations = ['en' => $flatSource];
|
||||
|
||||
foreach ($languages as $langCode => $langName) {
|
||||
echo " Language: $langName ($langCode)\n";
|
||||
$langResult = [];
|
||||
foreach ($batches as $idx => $batchKeys) {
|
||||
$batchNum = $idx + 1;
|
||||
echo " Batch $batchNum/" . count($batches) . " (" . count($batchKeys) . " strings)...\n";
|
||||
$batchInput = [];
|
||||
foreach ($batchKeys as $k) $batchInput[$k] = $flatSource[$k];
|
||||
$langResult = array_merge($langResult, translateBatch($azConfig, $langName, $systemPrompt, $batchInput));
|
||||
}
|
||||
$flatTranslations[$langCode] = $langResult;
|
||||
}
|
||||
|
||||
// Reconstruct nested structure: [full_slug][lang] => ['display_name', 'description', 'params']
|
||||
$toolTranslations = [];
|
||||
foreach ($toolsEn as $fullSlug => $toolData) {
|
||||
$shortSlug = str_replace('dbn.', '', $fullSlug);
|
||||
foreach (['en', 'no', 'uk', 'pl'] as $lc) {
|
||||
$toolTranslations[$fullSlug][$lc] = [
|
||||
'display_name' => $flatTranslations[$lc][$shortSlug . '__name'] ?? $toolData['display_name'],
|
||||
'description' => $flatTranslations[$lc][$shortSlug . '__desc'] ?? $toolData['description'],
|
||||
'params' => [],
|
||||
];
|
||||
foreach (array_keys($toolData['params']) as $param) {
|
||||
$toolTranslations[$fullSlug][$lc]['params'][$param] =
|
||||
$flatTranslations[$lc][$shortSlug . '__p__' . $param] ?? $toolData['params'][$param];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$toolOutPath = dirname(__DIR__) . '/includes/mcp-tool-translations.php';
|
||||
writePhpFile($toolOutPath, $toolTranslations, 'MCP tool translations — display_name, description, param descriptions');
|
||||
echo " Written: $toolOutPath\n";
|
||||
|
||||
echo "\n✓ Done. Next steps:\n";
|
||||
echo " 1. Copy translations from translations/mcp-chrome.php into includes/i18n.php\n";
|
||||
echo " 2. The tool translations are ready in includes/mcp-tool-translations.php\n";
|
||||
@@ -0,0 +1,209 @@
|
||||
<?php
|
||||
// MCP UI chrome translations — mcp.php + mcp-tool.php
|
||||
// DO NOT EDIT MANUALLY — regenerate with scripts/generate-mcp-translations.php
|
||||
return array (
|
||||
'en' =>
|
||||
array (
|
||||
'mcp_page_title' => 'MCP — Do Better Norge',
|
||||
'mcp_meta_desc' => 'Connect Claude, Cursor, and other AI tools to all 19 DBN legal preparation tools via MCP.',
|
||||
'mcp_hero_badge' => '✦ Plus & Pro',
|
||||
'mcp_hero_h1' => 'Use DBN tools from Claude, Cursor & Copilot',
|
||||
'mcp_hero_sub' => 'Connect any MCP client to all 19 Do Better Norge tools — transcription, legal analysis, timelines, redaction, and more.',
|
||||
'mcp_token_section_title' => 'Your MCP token',
|
||||
'mcp_gate_guest_p' => 'Sign in to create your personal MCP token. Available to Plus and Pro members.',
|
||||
'mcp_gate_guest_btn' => 'Sign in',
|
||||
'mcp_gate_free_p' => 'MCP access is available on Plus and Pro plans. Upgrade to connect your AI tools.',
|
||||
'mcp_gate_free_btn' => 'Upgrade plan',
|
||||
'mcp_token_hint' => 'Tokens are shown once at creation. Create one per client (Claude, Cursor, VS Code…).',
|
||||
'mcp_token_create_btn' => 'Create token',
|
||||
'mcp_token_reveal_label' => 'Copy this token now — it will not be shown again:',
|
||||
'mcp_token_copy_btn' => 'Copy token',
|
||||
'mcp_token_no_tokens' => 'No MCP tokens yet.',
|
||||
'mcp_token_active' => 'Active',
|
||||
'mcp_token_revoked' => 'Revoked',
|
||||
'mcp_token_never_used' => 'Never used',
|
||||
'mcp_token_last_used' => 'Last used',
|
||||
'mcp_token_revoke_btn' => 'Revoke',
|
||||
'mcp_config_title' => 'Client configuration',
|
||||
'mcp_config_hint' => 'Paste your token into the config below after creating it above.',
|
||||
'mcp_config_token_filled' => 'Token auto-filled.',
|
||||
'mcp_config_run_terminal' => 'Run in your terminal:',
|
||||
'mcp_test_btn' => 'Test connection',
|
||||
'mcp_test_no_token' => 'Create a token first.',
|
||||
'mcp_test_testing' => 'Testing…',
|
||||
'mcp_tools_title' => 'Available tools',
|
||||
'mcp_tools_sub' => 'All tools run on your Plus or Pro plan credits. Click a card for full technical details.',
|
||||
'mcp_tools_param_req_hint' => 'Purple = required',
|
||||
'mcp_tools_view_details' => 'View details →',
|
||||
'mcp_privacy_title' => 'Privacy',
|
||||
'mcp_privacy_text' => 'Process-and-forget by default. All tool calls process your text in memory and return results to your AI client. Nothing is saved to My Case unless you explicitly call dbn.save_to_case.',
|
||||
'mcp_privacy_legal' => 'Tools provide legal preparation support, not final legal advice. Results are for informational purposes and should be reviewed by a qualified legal professional.',
|
||||
'mcp_tool_back' => '← Back to MCP setup',
|
||||
'mcp_tool_params_title' => 'Parameters',
|
||||
'mcp_tool_no_params' => 'This tool takes no input parameters.',
|
||||
'mcp_tool_col_param' => 'Parameter',
|
||||
'mcp_tool_col_type' => 'Type',
|
||||
'mcp_tool_col_required' => 'Required',
|
||||
'mcp_tool_col_desc' => 'Description',
|
||||
'mcp_tool_example_req' => 'Example request',
|
||||
'mcp_tool_example_resp' => 'Example response',
|
||||
'mcp_tool_connect_title' => 'Connect',
|
||||
'mcp_tool_connect_text' => 'Create your MCP token on the setup page and use it with any supported client.',
|
||||
'mcp_tool_setup_link' => 'Set up MCP →',
|
||||
'mcp_tool_yes' => 'Yes',
|
||||
'mcp_tool_no' => 'No',
|
||||
),
|
||||
'no' =>
|
||||
array (
|
||||
'mcp_page_title' => 'MCP — Do Better Norge',
|
||||
'mcp_meta_desc' => 'Koble Claude, Cursor og andre AI-verktøy til alle 19 DBN juridiske forberedelsesverktøy via MCP.',
|
||||
'mcp_hero_badge' => '✦ Plus & Pro',
|
||||
'mcp_hero_h1' => 'Bruk DBN-verktøy fra Claude, Cursor & Copilot',
|
||||
'mcp_hero_sub' => 'Koble enhver MCP-klient til alle 19 Do Better Norge-verktøy — transkripsjon, juridisk analyse, tidslinjer, redigering og mer.',
|
||||
'mcp_token_section_title' => 'Din MCP-token',
|
||||
'mcp_gate_guest_p' => 'Logg inn for å opprette din personlige MCP-token. Tilgjengelig for Plus- og Pro-medlemmer.',
|
||||
'mcp_gate_guest_btn' => 'Logg inn',
|
||||
'mcp_gate_free_p' => 'MCP-tilgang er tilgjengelig på Plus- og Pro-planer. Oppgrader for å koble dine AI-verktøy.',
|
||||
'mcp_gate_free_btn' => 'Oppgrader plan',
|
||||
'mcp_token_hint' => 'Tokens vises én gang ved opprettelse. Opprett én per klient (Claude, Cursor, VS Code…).',
|
||||
'mcp_token_create_btn' => 'Opprett token',
|
||||
'mcp_token_reveal_label' => 'Kopier denne token nå — den vil ikke bli vist igjen:',
|
||||
'mcp_token_copy_btn' => 'Kopier token',
|
||||
'mcp_token_no_tokens' => 'Ingen MCP-tokens ennå.',
|
||||
'mcp_token_active' => 'Aktiv',
|
||||
'mcp_token_revoked' => 'Tilbaketrukket',
|
||||
'mcp_token_never_used' => 'Aldri brukt',
|
||||
'mcp_token_last_used' => 'Sist brukt',
|
||||
'mcp_token_revoke_btn' => 'Tilbaketrukk',
|
||||
'mcp_config_title' => 'Klientkonfigurasjon',
|
||||
'mcp_config_hint' => 'Lim inn tokenet ditt i konfigurasjonen nedenfor etter å ha opprettet det ovenfor.',
|
||||
'mcp_config_token_filled' => 'Token automatisk fylt ut.',
|
||||
'mcp_config_run_terminal' => 'Kjør i terminalen din:',
|
||||
'mcp_test_btn' => 'Test tilkobling',
|
||||
'mcp_test_no_token' => 'Opprett et token først.',
|
||||
'mcp_test_testing' => 'Tester…',
|
||||
'mcp_tools_title' => 'Tilgjengelige verktøy',
|
||||
'mcp_tools_sub' => 'Alle verktøy kjører på kreditter fra din Plus- eller Pro-plan. Klikk på et kort for full teknisk informasjon.',
|
||||
'mcp_tools_param_req_hint' => 'Lilla = påkrevd',
|
||||
'mcp_tools_view_details' => 'Se detaljer →',
|
||||
'mcp_privacy_title' => 'Personvern',
|
||||
'mcp_privacy_text' => 'Prosesser og glem som standard. Alle verktøyanrop prosesserer teksten din i minnet og returnerer resultater til din AI-klient. Ingenting lagres i Min sak med mindre du eksplisitt kaller dbn.save_to_case.',
|
||||
'mcp_privacy_legal' => 'Verktøyene gir støtte til juridisk forberedelse, ikke endelig juridisk rådgivning. Resultatene er kun til informasjonsformål og bør vurderes av en kvalifisert juridisk profesjonell.',
|
||||
'mcp_tool_back' => '← Tilbake til MCP-oppsett',
|
||||
'mcp_tool_params_title' => 'Parametere',
|
||||
'mcp_tool_no_params' => 'Dette verktøyet tar ingen inndata-parametere.',
|
||||
'mcp_tool_col_param' => 'Parameter',
|
||||
'mcp_tool_col_type' => 'Type',
|
||||
'mcp_tool_col_required' => 'Påkrevd',
|
||||
'mcp_tool_col_desc' => 'Beskrivelse',
|
||||
'mcp_tool_example_req' => 'Eksempel på forespørsel',
|
||||
'mcp_tool_example_resp' => 'Eksempel på svar',
|
||||
'mcp_tool_connect_title' => 'Koble til',
|
||||
'mcp_tool_connect_text' => 'Opprett din MCP-token på oppsettssiden og bruk den med enhver støttet klient.',
|
||||
'mcp_tool_setup_link' => 'Sett opp MCP →',
|
||||
'mcp_tool_yes' => 'Ja',
|
||||
'mcp_tool_no' => 'Nei',
|
||||
),
|
||||
'uk' =>
|
||||
array (
|
||||
'mcp_page_title' => 'MCP — Do Better Norge',
|
||||
'mcp_meta_desc' => 'Підключіть Claude, Cursor та інші інструменти ШІ до всіх 19 юридичних підготовчих інструментів DBN через MCP.',
|
||||
'mcp_hero_badge' => '✦ Плюс та Профі',
|
||||
'mcp_hero_h1' => 'Використовуйте інструменти DBN від Claude, Cursor та Copilot',
|
||||
'mcp_hero_sub' => 'Підключіть будь-якого клієнта MCP до всіх 19 інструментів Do Better Norge — транскрипція, юридичний аналіз, часові лінії, редагування та інше.',
|
||||
'mcp_token_section_title' => 'Ваш токен MCP',
|
||||
'mcp_gate_guest_p' => 'Увійдіть, щоб створити свій особистий токен MCP. Доступно для учасників Плюс та Профі.',
|
||||
'mcp_gate_guest_btn' => 'Увійти',
|
||||
'mcp_gate_free_p' => 'Доступ до MCP доступний у планах Плюс та Профі. Оновіть, щоб підключити свої інструменти ШІ.',
|
||||
'mcp_gate_free_btn' => 'Оновити план',
|
||||
'mcp_token_hint' => 'Токени показуються один раз під час створення. Створіть один для кожного клієнта (Claude, Cursor, VS Code…).',
|
||||
'mcp_token_create_btn' => 'Створити токен',
|
||||
'mcp_token_reveal_label' => 'Скопіюйте цей токен зараз — він більше не буде показаний:',
|
||||
'mcp_token_copy_btn' => 'Скопіювати токен',
|
||||
'mcp_token_no_tokens' => 'Ще немає токенів MCP.',
|
||||
'mcp_token_active' => 'Активний',
|
||||
'mcp_token_revoked' => 'Скасовано',
|
||||
'mcp_token_never_used' => 'Ніколи не використовувався',
|
||||
'mcp_token_last_used' => 'Останній раз використовувався',
|
||||
'mcp_token_revoke_btn' => 'Скасувати',
|
||||
'mcp_config_title' => 'Конфігурація клієнта',
|
||||
'mcp_config_hint' => 'Вставте свій токен у конфігурацію нижче після його створення вище.',
|
||||
'mcp_config_token_filled' => 'Токен автоматично заповнений.',
|
||||
'mcp_config_run_terminal' => 'Запустіть у вашому терміналі:',
|
||||
'mcp_test_btn' => 'Перевірити з\'єднання',
|
||||
'mcp_test_no_token' => 'Спочатку створіть токен.',
|
||||
'mcp_test_testing' => 'Тестування…',
|
||||
'mcp_tools_title' => 'Доступні інструменти',
|
||||
'mcp_tools_sub' => 'Усі інструменти працюють на кредитах вашого плану Plus або Pro. Натисніть на картку для отримання повних технічних деталей.',
|
||||
'mcp_tools_param_req_hint' => 'Фіолетовий = обов\'язковий',
|
||||
'mcp_tools_view_details' => 'Переглянути деталі →',
|
||||
'mcp_privacy_title' => 'Конфіденційність',
|
||||
'mcp_privacy_text' => 'Обробка та забуття за замовчуванням. Усі виклики інструментів обробляють ваш текст у пам\'яті та повертають результати вашому AI-клієнту. Нічого не зберігається у My Case, якщо ви явно не викликаєте dbn.save_to_case.',
|
||||
'mcp_privacy_legal' => 'Інструменти надають підтримку в підготовці юридичних документів, а не остаточні юридичні поради. Результати призначені лише для інформаційних цілей і повинні бути переглянуті кваліфікованим юридичним фахівцем.',
|
||||
'mcp_tool_back' => '← Повернутися до налаштування MCP',
|
||||
'mcp_tool_params_title' => 'Параметри',
|
||||
'mcp_tool_no_params' => 'Цей інструмент не приймає вхідних параметрів.',
|
||||
'mcp_tool_col_param' => 'Параметр',
|
||||
'mcp_tool_col_type' => 'Тип',
|
||||
'mcp_tool_col_required' => 'Обов\'язковий',
|
||||
'mcp_tool_col_desc' => 'Опис',
|
||||
'mcp_tool_example_req' => 'Приклад запиту',
|
||||
'mcp_tool_example_resp' => 'Приклад відповіді',
|
||||
'mcp_tool_connect_title' => 'Підключити',
|
||||
'mcp_tool_connect_text' => 'Створіть свій токен MCP на сторінці налаштувань і використовуйте його з будь-яким підтримуваним клієнтом.',
|
||||
'mcp_tool_setup_link' => 'Налаштувати MCP →',
|
||||
'mcp_tool_yes' => 'Так',
|
||||
'mcp_tool_no' => 'Ні',
|
||||
),
|
||||
'pl' =>
|
||||
array (
|
||||
'mcp_page_title' => 'MCP — Do Better Norge',
|
||||
'mcp_meta_desc' => 'Połącz Claude, Cursor i inne narzędzia AI z wszystkimi 19 narzędziami przygotowania prawnego DBN za pośrednictwem MCP.',
|
||||
'mcp_hero_badge' => '✦ Plus & Pro',
|
||||
'mcp_hero_h1' => 'Użyj narzędzi DBN z Claude, Cursor i Copilot',
|
||||
'mcp_hero_sub' => 'Połącz dowolnego klienta MCP ze wszystkimi 19 narzędziami Do Better Norge — transkrypcja, analiza prawna, harmonogramy, redakcja i inne.',
|
||||
'mcp_token_section_title' => 'Twój token MCP',
|
||||
'mcp_gate_guest_p' => 'Zaloguj się, aby utworzyć swój osobisty token MCP. Dostępny dla członków Plus i Pro.',
|
||||
'mcp_gate_guest_btn' => 'Zaloguj się',
|
||||
'mcp_gate_free_p' => 'Dostęp do MCP jest dostępny w planach Plus i Pro. Uaktualnij, aby połączyć swoje narzędzia AI.',
|
||||
'mcp_gate_free_btn' => 'Uaktualnij plan',
|
||||
'mcp_token_hint' => 'Tokeny są wyświetlane tylko raz przy tworzeniu. Utwórz jeden na klienta (Claude, Cursor, VS Code…).',
|
||||
'mcp_token_create_btn' => 'Utwórz token',
|
||||
'mcp_token_reveal_label' => 'Skopiuj ten token teraz — nie będzie już wyświetlany:',
|
||||
'mcp_token_copy_btn' => 'Skopiuj token',
|
||||
'mcp_token_no_tokens' => 'Brak tokenów MCP jeszcze.',
|
||||
'mcp_token_active' => 'Aktywny',
|
||||
'mcp_token_revoked' => 'Cofnięty',
|
||||
'mcp_token_never_used' => 'Nigdy nie używany',
|
||||
'mcp_token_last_used' => 'Ostatnio używany',
|
||||
'mcp_token_revoke_btn' => 'Cofnij',
|
||||
'mcp_config_title' => 'Konfiguracja klienta',
|
||||
'mcp_config_hint' => 'Wklej swój token do konfiguracji poniżej po jego utworzeniu powyżej.',
|
||||
'mcp_config_token_filled' => 'Token automatycznie wypełniony.',
|
||||
'mcp_config_run_terminal' => 'Uruchom w swoim terminalu:',
|
||||
'mcp_test_btn' => 'Testuj połączenie',
|
||||
'mcp_test_no_token' => 'Najpierw utwórz token.',
|
||||
'mcp_test_testing' => 'Testowanie…',
|
||||
'mcp_tools_title' => 'Dostępne narzędzia',
|
||||
'mcp_tools_sub' => 'Wszystkie narzędzia działają na kredytach Twojego planu Plus lub Pro. Kliknij kartę, aby uzyskać pełne szczegóły techniczne.',
|
||||
'mcp_tools_param_req_hint' => 'Fioletowy = wymagany',
|
||||
'mcp_tools_view_details' => 'Zobacz szczegóły →',
|
||||
'mcp_privacy_title' => 'Prywatność',
|
||||
'mcp_privacy_text' => 'Domyślnie przetwarzaj i zapomnij. Wszystkie wywołania narzędzi przetwarzają Twój tekst w pamięci i zwracają wyniki do Twojego klienta AI. Nic nie jest zapisywane w Mojej Sprawie, chyba że wyraźnie wywołasz dbn.save_to_case.',
|
||||
'mcp_privacy_legal' => 'Narzędzia zapewniają wsparcie w zakresie przygotowania prawnego, a nie ostatecznej porady prawnej. Wyniki mają charakter informacyjny i powinny być przeglądane przez wykwalifikowanego profesjonalistę prawnego.',
|
||||
'mcp_tool_back' => '← Powrót do konfiguracji MCP',
|
||||
'mcp_tool_params_title' => 'Parametry',
|
||||
'mcp_tool_no_params' => 'To narzędzie nie przyjmuje parametrów wejściowych.',
|
||||
'mcp_tool_col_param' => 'Parametr',
|
||||
'mcp_tool_col_type' => 'Typ',
|
||||
'mcp_tool_col_required' => 'Wymagany',
|
||||
'mcp_tool_col_desc' => 'Opis',
|
||||
'mcp_tool_example_req' => 'Przykładowe żądanie',
|
||||
'mcp_tool_example_resp' => 'Przykładowa odpowiedź',
|
||||
'mcp_tool_connect_title' => 'Połącz',
|
||||
'mcp_tool_connect_text' => 'Utwórz swój token MCP na stronie konfiguracji i użyj go z dowolnym obsługiwanym klientem.',
|
||||
'mcp_tool_setup_link' => 'Skonfiguruj MCP →',
|
||||
'mcp_tool_yes' => 'Tak',
|
||||
'mcp_tool_no' => 'Nie',
|
||||
),
|
||||
);
|
||||
Reference in New Issue
Block a user