@softure-ai/mcp-access 0.0.0-stage → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +177 -2
  3. package/dist/client-setup.d.ts +32 -0
  4. package/dist/client-setup.d.ts.map +1 -0
  5. package/dist/client-setup.js +57 -0
  6. package/dist/client-setup.js.map +1 -0
  7. package/dist/contract.d.ts +80 -0
  8. package/dist/contract.d.ts.map +1 -0
  9. package/dist/contract.js +2 -0
  10. package/dist/contract.js.map +1 -0
  11. package/dist/index.d.ts +119 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +50 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/messages/en.d.ts +77 -0
  16. package/dist/messages/en.d.ts.map +1 -0
  17. package/dist/messages/en.js +77 -0
  18. package/dist/messages/en.js.map +1 -0
  19. package/dist/messages/index.d.ts +161 -0
  20. package/dist/messages/index.d.ts.map +1 -0
  21. package/dist/messages/index.js +14 -0
  22. package/dist/messages/index.js.map +1 -0
  23. package/dist/messages/pl.d.ts +3 -0
  24. package/dist/messages/pl.d.ts.map +1 -0
  25. package/dist/messages/pl.js +77 -0
  26. package/dist/messages/pl.js.map +1 -0
  27. package/dist/next/actions.d.ts +6 -0
  28. package/dist/next/actions.d.ts.map +1 -0
  29. package/dist/next/actions.js +88 -0
  30. package/dist/next/actions.js.map +1 -0
  31. package/dist/next/context.d.ts +4 -0
  32. package/dist/next/context.d.ts.map +1 -0
  33. package/dist/next/context.js +13 -0
  34. package/dist/next/context.js.map +1 -0
  35. package/dist/next/format.d.ts +4 -0
  36. package/dist/next/format.d.ts.map +1 -0
  37. package/dist/next/format.js +7 -0
  38. package/dist/next/format.js.map +1 -0
  39. package/dist/next/index.d.ts +4 -0
  40. package/dist/next/index.d.ts.map +1 -0
  41. package/dist/next/index.js +6 -0
  42. package/dist/next/index.js.map +1 -0
  43. package/dist/next/pages.d.ts +2 -0
  44. package/dist/next/pages.d.ts.map +1 -0
  45. package/dist/next/pages.js +61 -0
  46. package/dist/next/pages.js.map +1 -0
  47. package/dist/next/route.d.ts +3 -0
  48. package/dist/next/route.d.ts.map +1 -0
  49. package/dist/next/route.js +24 -0
  50. package/dist/next/route.js.map +1 -0
  51. package/dist/options.d.ts +43 -0
  52. package/dist/options.d.ts.map +1 -0
  53. package/dist/options.js +47 -0
  54. package/dist/options.js.map +1 -0
  55. package/dist/schema.d.ts +145 -0
  56. package/dist/schema.d.ts.map +1 -0
  57. package/dist/schema.js +18 -0
  58. package/dist/schema.js.map +1 -0
  59. package/dist/server/endpoint.d.ts +26 -0
  60. package/dist/server/endpoint.d.ts.map +1 -0
  61. package/dist/server/endpoint.js +107 -0
  62. package/dist/server/endpoint.js.map +1 -0
  63. package/dist/server/health.d.ts +3 -0
  64. package/dist/server/health.d.ts.map +1 -0
  65. package/dist/server/health.js +11 -0
  66. package/dist/server/health.js.map +1 -0
  67. package/dist/server/index.d.ts +6 -0
  68. package/dist/server/index.d.ts.map +1 -0
  69. package/dist/server/index.js +8 -0
  70. package/dist/server/index.js.map +1 -0
  71. package/dist/server/options.d.ts +20 -0
  72. package/dist/server/options.d.ts.map +1 -0
  73. package/dist/server/options.js +40 -0
  74. package/dist/server/options.js.map +1 -0
  75. package/dist/server/privacy.d.ts +15 -0
  76. package/dist/server/privacy.d.ts.map +1 -0
  77. package/dist/server/privacy.js +36 -0
  78. package/dist/server/privacy.js.map +1 -0
  79. package/dist/server/tokens.d.ts +66 -0
  80. package/dist/server/tokens.d.ts.map +1 -0
  81. package/dist/server/tokens.js +138 -0
  82. package/dist/server/tokens.js.map +1 -0
  83. package/dist/token-status.d.ts +9 -0
  84. package/dist/token-status.d.ts.map +1 -0
  85. package/dist/token-status.js +14 -0
  86. package/dist/token-status.js.map +1 -0
  87. package/dist/ui/index.d.ts +2 -0
  88. package/dist/ui/index.d.ts.map +1 -0
  89. package/dist/ui/index.js +4 -0
  90. package/dist/ui/index.js.map +1 -0
  91. package/dist/ui/token-manager.d.ts +43 -0
  92. package/dist/ui/token-manager.d.ts.map +1 -0
  93. package/dist/ui/token-manager.js +50 -0
  94. package/dist/ui/token-manager.js.map +1 -0
  95. package/migrations/0001_create_access_tokens.sql +24 -0
  96. package/module.json +15 -0
  97. package/package.json +65 -4
  98. package/src/client-setup.ts +71 -0
  99. package/src/contract.ts +80 -0
  100. package/src/index.ts +81 -0
  101. package/src/messages/en.ts +76 -0
  102. package/src/messages/index.ts +18 -0
  103. package/src/messages/pl.ts +78 -0
  104. package/src/next/actions.ts +91 -0
  105. package/src/next/context.ts +14 -0
  106. package/src/next/format.ts +10 -0
  107. package/src/next/index.ts +5 -0
  108. package/src/next/next-modules.d.ts +16 -0
  109. package/src/next/pages.tsx +80 -0
  110. package/src/next/route.ts +24 -0
  111. package/src/options.ts +58 -0
  112. package/src/schema.ts +19 -0
  113. package/src/server/endpoint.ts +141 -0
  114. package/src/server/health.ts +12 -0
  115. package/src/server/index.ts +36 -0
  116. package/src/server/options.ts +54 -0
  117. package/src/server/privacy.ts +49 -0
  118. package/src/server/tokens.ts +188 -0
  119. package/src/token-status.ts +27 -0
  120. package/src/ui/index.ts +11 -0
  121. package/src/ui/token-manager.tsx +254 -0
@@ -0,0 +1,77 @@
1
+ export const en = {
2
+ page: {
3
+ title: "AI assistant access",
4
+ lead: "Connect an AI assistant such as Claude to your account over MCP. Each assistant gets its own token, which you can revoke at any time.",
5
+ },
6
+ tools: {
7
+ title: "What an assistant can do",
8
+ empty: "The app lists no tools yet.",
9
+ read: "Reads",
10
+ write: "Changes data",
11
+ writeUnavailable: "Changes data (turned off in this app)",
12
+ },
13
+ issue: {
14
+ title: "New token",
15
+ name: "Name",
16
+ nameHint: "Where you will use it, e.g. Laptop or Claude Desktop.",
17
+ canWrite: "Allow changes",
18
+ canWriteHint: "Without it, the assistant can only read.",
19
+ submit: "Create token",
20
+ pending: "Creating…",
21
+ limit: "You can hold up to {max} active tokens.",
22
+ },
23
+ issued: {
24
+ title: "Token created: {name}",
25
+ once: "Copy it now. It is shown only once; after you leave this page, only its name remains.",
26
+ expires: "Works until {date}.",
27
+ readOnly: "This token can only read.",
28
+ readWrite: "This token can read and change data.",
29
+ promptTitle: "Easiest: let Claude Code set it up",
30
+ promptHint: "Paste this into a conversation with Claude Code. It runs the command and checks the connection.",
31
+ openClaudeCode: "Open in Claude Code",
32
+ commandTitle: "Terminal command (Claude Code)",
33
+ jsonTitle: "Configuration file (Cursor, VS Code, Windsurf)",
34
+ desktopTitle: "Claude Desktop (claude_desktop_config.json)",
35
+ headerTitle: "Other clients: server address and Authorization header",
36
+ copy: "Copy",
37
+ copied: "Copied",
38
+ done: "Done, hide the token",
39
+ },
40
+ setup: {
41
+ assistantPrompt: "Connect to my {serverName} account over MCP.\nRun: {command}\nThen check /mcp and tell me whether the server \"{serverName}\" is connected.",
42
+ },
43
+ list: {
44
+ title: "Your tokens",
45
+ empty: "You have no tokens yet.",
46
+ readOnly: "Read only",
47
+ readWrite: "Read and change",
48
+ active: "Active",
49
+ expired: "Expired",
50
+ expiresToday: "Expires today",
51
+ expiresTomorrow: "Expires tomorrow",
52
+ expiresInDays: "Expires in {days} days",
53
+ expiresOn: "Valid until {date}",
54
+ expiredOn: "Expired on {date}",
55
+ createdOn: "Created {date}",
56
+ lastUsed: "Last used {date}",
57
+ neverUsed: "Not used yet",
58
+ revoke: "Revoke",
59
+ revoking: "Revoking…",
60
+ },
61
+ errors: {
62
+ "mcp-access": {
63
+ name_required: "Give the token a name, so you can tell it from the others.",
64
+ name_too_long: "The name is too long.",
65
+ token_limit_reached: "You already hold the most active tokens allowed. Revoke one before creating another.",
66
+ token_not_found: "This token no longer exists. It may have been revoked already.",
67
+ },
68
+ auth: {
69
+ unauthenticated: "Your session has ended. Log in again.",
70
+ },
71
+ core: {
72
+ database_failed: "Something went wrong on our side. Try again in a moment.",
73
+ unexpected: "Something went wrong on our side. Try again in a moment.",
74
+ },
75
+ },
76
+ };
77
+ //# sourceMappingURL=en.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en.js","sourceRoot":"","sources":["../../src/messages/en.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,IAAI,EAAE;QACJ,KAAK,EAAE,qBAAqB;QAC5B,IAAI,EAAE,uIAAuI;KAC9I;IACD,KAAK,EAAE;QACL,KAAK,EAAE,0BAA0B;QACjC,KAAK,EAAE,6BAA6B;QACpC,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,cAAc;QACrB,gBAAgB,EAAE,uCAAuC;KAC1D;IACD,KAAK,EAAE;QACL,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,uDAAuD;QACjE,QAAQ,EAAE,eAAe;QACzB,YAAY,EAAE,0CAA0C;QACxD,MAAM,EAAE,cAAc;QACtB,OAAO,EAAE,WAAW;QACpB,KAAK,EAAE,yCAAyC;KACjD;IACD,MAAM,EAAE;QACN,KAAK,EAAE,uBAAuB;QAC9B,IAAI,EAAE,uFAAuF;QAC7F,OAAO,EAAE,qBAAqB;QAC9B,QAAQ,EAAE,2BAA2B;QACrC,SAAS,EAAE,sCAAsC;QACjD,WAAW,EAAE,oCAAoC;QACjD,UAAU,EAAE,iGAAiG;QAC7G,cAAc,EAAE,qBAAqB;QACrC,YAAY,EAAE,gCAAgC;QAC9C,SAAS,EAAE,gDAAgD;QAC3D,YAAY,EAAE,6CAA6C;QAC3D,WAAW,EAAE,wDAAwD;QACrE,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,sBAAsB;KAC7B;IACD,KAAK,EAAE;QACL,eAAe,EAAE,6IAA6I;KAC/J;IACD,IAAI,EAAE;QACJ,KAAK,EAAE,aAAa;QACpB,KAAK,EAAE,yBAAyB;QAChC,QAAQ,EAAE,WAAW;QACrB,SAAS,EAAE,iBAAiB;QAC5B,MAAM,EAAE,QAAQ;QAChB,OAAO,EAAE,SAAS;QAClB,YAAY,EAAE,eAAe;QAC7B,eAAe,EAAE,kBAAkB;QACnC,aAAa,EAAE,wBAAwB;QACvC,SAAS,EAAE,oBAAoB;QAC/B,SAAS,EAAE,mBAAmB;QAC9B,SAAS,EAAE,gBAAgB;QAC3B,QAAQ,EAAE,kBAAkB;QAC5B,SAAS,EAAE,cAAc;QACzB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,WAAW;KACtB;IACD,MAAM,EAAE;QACN,YAAY,EAAE;YACZ,aAAa,EAAE,4DAA4D;YAC3E,aAAa,EAAE,uBAAuB;YACtC,mBAAmB,EAAE,sFAAsF;YAC3G,eAAe,EAAE,gEAAgE;SAClF;QACD,IAAI,EAAE;YACJ,eAAe,EAAE,uCAAuC;SACzD;QACD,IAAI,EAAE;YACJ,eAAe,EAAE,0DAA0D;YAC3E,UAAU,EAAE,0DAA0D;SACvE;KACF;CACF,CAAC"}
@@ -0,0 +1,161 @@
1
+ import type { TokenFormErrorCode } from "../contract.js";
2
+ import { en } from "./en.js";
3
+ /** Complete default dictionaries; apps pass partial overrides per locale. */
4
+ export declare const mcpAccessMessages: {
5
+ en: {
6
+ page: {
7
+ title: string;
8
+ lead: string;
9
+ };
10
+ tools: {
11
+ title: string;
12
+ empty: string;
13
+ read: string;
14
+ write: string;
15
+ writeUnavailable: string;
16
+ };
17
+ issue: {
18
+ title: string;
19
+ name: string;
20
+ nameHint: string;
21
+ canWrite: string;
22
+ canWriteHint: string;
23
+ submit: string;
24
+ pending: string;
25
+ limit: string;
26
+ };
27
+ issued: {
28
+ title: string;
29
+ once: string;
30
+ expires: string;
31
+ readOnly: string;
32
+ readWrite: string;
33
+ promptTitle: string;
34
+ promptHint: string;
35
+ openClaudeCode: string;
36
+ commandTitle: string;
37
+ jsonTitle: string;
38
+ desktopTitle: string;
39
+ headerTitle: string;
40
+ copy: string;
41
+ copied: string;
42
+ done: string;
43
+ };
44
+ setup: {
45
+ assistantPrompt: string;
46
+ };
47
+ list: {
48
+ title: string;
49
+ empty: string;
50
+ readOnly: string;
51
+ readWrite: string;
52
+ active: string;
53
+ expired: string;
54
+ expiresToday: string;
55
+ expiresTomorrow: string;
56
+ expiresInDays: string;
57
+ expiresOn: string;
58
+ expiredOn: string;
59
+ createdOn: string;
60
+ lastUsed: string;
61
+ neverUsed: string;
62
+ revoke: string;
63
+ revoking: string;
64
+ };
65
+ errors: {
66
+ "mcp-access": {
67
+ name_required: string;
68
+ name_too_long: string;
69
+ token_limit_reached: string;
70
+ token_not_found: string;
71
+ };
72
+ auth: {
73
+ unauthenticated: string;
74
+ };
75
+ core: {
76
+ database_failed: string;
77
+ unexpected: string;
78
+ };
79
+ };
80
+ };
81
+ pl: {
82
+ page: {
83
+ title: string;
84
+ lead: string;
85
+ };
86
+ tools: {
87
+ title: string;
88
+ empty: string;
89
+ read: string;
90
+ write: string;
91
+ writeUnavailable: string;
92
+ };
93
+ issue: {
94
+ title: string;
95
+ name: string;
96
+ nameHint: string;
97
+ canWrite: string;
98
+ canWriteHint: string;
99
+ submit: string;
100
+ pending: string;
101
+ limit: string;
102
+ };
103
+ issued: {
104
+ title: string;
105
+ once: string;
106
+ expires: string;
107
+ readOnly: string;
108
+ readWrite: string;
109
+ promptTitle: string;
110
+ promptHint: string;
111
+ openClaudeCode: string;
112
+ commandTitle: string;
113
+ jsonTitle: string;
114
+ desktopTitle: string;
115
+ headerTitle: string;
116
+ copy: string;
117
+ copied: string;
118
+ done: string;
119
+ };
120
+ setup: {
121
+ assistantPrompt: string;
122
+ };
123
+ list: {
124
+ title: string;
125
+ empty: string;
126
+ readOnly: string;
127
+ readWrite: string;
128
+ active: string;
129
+ expired: string;
130
+ expiresToday: string;
131
+ expiresTomorrow: string;
132
+ expiresInDays: string;
133
+ expiresOn: string;
134
+ expiredOn: string;
135
+ createdOn: string;
136
+ lastUsed: string;
137
+ neverUsed: string;
138
+ revoke: string;
139
+ revoking: string;
140
+ };
141
+ errors: {
142
+ "mcp-access": {
143
+ name_required: string;
144
+ name_too_long: string;
145
+ token_limit_reached: string;
146
+ token_not_found: string;
147
+ };
148
+ auth: {
149
+ unauthenticated: string;
150
+ };
151
+ core: {
152
+ database_failed: string;
153
+ unexpected: string;
154
+ };
155
+ };
156
+ };
157
+ };
158
+ export type McpAccessMessages = typeof en;
159
+ /** The copy for an error code; an unknown code gets the generic failure. */
160
+ export declare function getTokenErrorMessage(messages: McpAccessMessages, code: TokenFormErrorCode): string;
161
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/messages/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAG7B,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAa,CAAC;AAE5C,MAAM,MAAM,iBAAiB,GAAG,OAAO,EAAE,CAAC;AAE1C,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAOlG"}
@@ -0,0 +1,14 @@
1
+ import { en } from "./en.js";
2
+ import { pl } from "./pl.js";
3
+ /** Complete default dictionaries; apps pass partial overrides per locale. */
4
+ export const mcpAccessMessages = { en, pl };
5
+ /** The copy for an error code; an unknown code gets the generic failure. */
6
+ export function getTokenErrorMessage(messages, code) {
7
+ const separator = code.lastIndexOf(".");
8
+ const namespace = code.slice(0, separator);
9
+ const name = code.slice(separator + 1);
10
+ const groups = messages.errors;
11
+ const group = Object.hasOwn(groups, namespace) ? groups[namespace] : undefined;
12
+ return (group !== undefined && Object.hasOwn(group, name) ? group[name] : undefined) ?? messages.errors.core.unexpected;
13
+ }
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/messages/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B,6EAA6E;AAC7E,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;AAI5C,4EAA4E;AAC5E,MAAM,UAAU,oBAAoB,CAAC,QAA2B,EAAE,IAAwB;IACxF,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAoE,CAAC;IAC7F,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;AAC1H,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { en } from "./en.js";
2
+ export declare const pl: typeof en;
3
+ //# sourceMappingURL=pl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pl.d.ts","sourceRoot":"","sources":["../../src/messages/pl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAElC,eAAO,MAAM,EAAE,EAAE,OAAO,EA2EvB,CAAC"}
@@ -0,0 +1,77 @@
1
+ export const pl = {
2
+ page: {
3
+ title: "Dostęp dla asystenta AI",
4
+ lead: "Połącz asystenta AI, na przykład Claude, ze swoim kontem przez MCP. Każdy asystent dostaje własny token, który możesz w każdej chwili unieważnić.",
5
+ },
6
+ tools: {
7
+ title: "Co może asystent",
8
+ empty: "Aplikacja nie udostępnia jeszcze żadnych narzędzi.",
9
+ read: "Odczyt",
10
+ write: "Zmienia dane",
11
+ writeUnavailable: "Zmienia dane (wyłączone w tej aplikacji)",
12
+ },
13
+ issue: {
14
+ title: "Nowy token",
15
+ name: "Nazwa",
16
+ nameHint: "Gdzie go użyjesz, na przykład Laptop albo Claude Desktop.",
17
+ canWrite: "Pozwól na zmiany",
18
+ canWriteHint: "Bez tego asystent może tylko czytać.",
19
+ submit: "Utwórz token",
20
+ pending: "Tworzenie…",
21
+ limit: "Możesz mieć najwyżej {max} aktywnych tokenów.",
22
+ },
23
+ issued: {
24
+ title: "Utworzono token: {name}",
25
+ once: "Skopiuj go teraz. Pokazujemy go tylko raz; gdy opuścisz tę stronę, zostanie tylko jego nazwa.",
26
+ expires: "Działa do {date}.",
27
+ readOnly: "Ten token może tylko czytać.",
28
+ readWrite: "Ten token może czytać i zmieniać dane.",
29
+ promptTitle: "Najprościej: niech Claude Code sam to skonfiguruje",
30
+ promptHint: "Wklej to do rozmowy z Claude Code. Wykona polecenie i sprawdzi połączenie.",
31
+ openClaudeCode: "Otwórz w Claude Code",
32
+ commandTitle: "Polecenie w terminalu (Claude Code)",
33
+ jsonTitle: "Plik konfiguracyjny (Cursor, VS Code, Windsurf)",
34
+ desktopTitle: "Claude Desktop (claude_desktop_config.json)",
35
+ headerTitle: "Inne klienty: adres serwera i nagłówek Authorization",
36
+ copy: "Kopiuj",
37
+ copied: "Skopiowano",
38
+ done: "Gotowe, ukryj token",
39
+ },
40
+ setup: {
41
+ assistantPrompt: "Połącz się z moim kontem {serverName} przez MCP.\nWykonaj: {command}\nPotem sprawdź /mcp i powiedz mi, czy serwer „{serverName}” jest połączony.",
42
+ },
43
+ list: {
44
+ title: "Twoje tokeny",
45
+ empty: "Nie masz jeszcze żadnych tokenów.",
46
+ readOnly: "Tylko odczyt",
47
+ readWrite: "Odczyt i zmiany",
48
+ active: "Aktywny",
49
+ expired: "Wygasł",
50
+ expiresToday: "Wygasa dziś",
51
+ expiresTomorrow: "Wygasa jutro",
52
+ expiresInDays: "Wygasa za {days} dni",
53
+ expiresOn: "Ważny do {date}",
54
+ expiredOn: "Wygasł {date}",
55
+ createdOn: "Utworzony {date}",
56
+ lastUsed: "Ostatnio użyty {date}",
57
+ neverUsed: "Jeszcze nieużywany",
58
+ revoke: "Unieważnij",
59
+ revoking: "Unieważnianie…",
60
+ },
61
+ errors: {
62
+ "mcp-access": {
63
+ name_required: "Nadaj tokenowi nazwę, żeby odróżnić go od pozostałych.",
64
+ name_too_long: "Nazwa jest za długa.",
65
+ token_limit_reached: "Masz już najwięcej aktywnych tokenów, ile można. Unieważnij któryś, zanim utworzysz nowy.",
66
+ token_not_found: "Ten token już nie istnieje. Mógł zostać unieważniony.",
67
+ },
68
+ auth: {
69
+ unauthenticated: "Twoja sesja wygasła. Zaloguj się ponownie.",
70
+ },
71
+ core: {
72
+ database_failed: "Coś poszło nie tak po naszej stronie. Spróbuj ponownie za chwilę.",
73
+ unexpected: "Coś poszło nie tak po naszej stronie. Spróbuj ponownie za chwilę.",
74
+ },
75
+ },
76
+ };
77
+ //# sourceMappingURL=pl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pl.js","sourceRoot":"","sources":["../../src/messages/pl.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,EAAE,GAAc;IAC3B,IAAI,EAAE;QACJ,KAAK,EAAE,yBAAyB;QAChC,IAAI,EAAE,mJAAmJ;KAC1J;IACD,KAAK,EAAE;QACL,KAAK,EAAE,kBAAkB;QACzB,KAAK,EAAE,oDAAoD;QAC3D,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,cAAc;QACrB,gBAAgB,EAAE,0CAA0C;KAC7D;IACD,KAAK,EAAE;QACL,KAAK,EAAE,YAAY;QACnB,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,2DAA2D;QACrE,QAAQ,EAAE,kBAAkB;QAC5B,YAAY,EAAE,sCAAsC;QACpD,MAAM,EAAE,cAAc;QACtB,OAAO,EAAE,YAAY;QACrB,KAAK,EAAE,+CAA+C;KACvD;IACD,MAAM,EAAE;QACN,KAAK,EAAE,yBAAyB;QAChC,IAAI,EAAE,+FAA+F;QACrG,OAAO,EAAE,mBAAmB;QAC5B,QAAQ,EAAE,8BAA8B;QACxC,SAAS,EAAE,wCAAwC;QACnD,WAAW,EAAE,oDAAoD;QACjE,UAAU,EAAE,4EAA4E;QACxF,cAAc,EAAE,sBAAsB;QACtC,YAAY,EAAE,qCAAqC;QACnD,SAAS,EAAE,iDAAiD;QAC5D,YAAY,EAAE,6CAA6C;QAC3D,WAAW,EAAE,sDAAsD;QACnE,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,YAAY;QACpB,IAAI,EAAE,qBAAqB;KAC5B;IACD,KAAK,EAAE;QACL,eAAe,EAAE,kJAAkJ;KACpK;IACD,IAAI,EAAE;QACJ,KAAK,EAAE,cAAc;QACrB,KAAK,EAAE,mCAAmC;QAC1C,QAAQ,EAAE,cAAc;QACxB,SAAS,EAAE,iBAAiB;QAC5B,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,QAAQ;QACjB,YAAY,EAAE,aAAa;QAC3B,eAAe,EAAE,cAAc;QAC/B,aAAa,EAAE,sBAAsB;QACrC,SAAS,EAAE,iBAAiB;QAC5B,SAAS,EAAE,eAAe;QAC1B,SAAS,EAAE,kBAAkB;QAC7B,QAAQ,EAAE,uBAAuB;QACjC,SAAS,EAAE,oBAAoB;QAC/B,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,gBAAgB;KAC3B;IACD,MAAM,EAAE;QACN,YAAY,EAAE;YACZ,aAAa,EAAE,wDAAwD;YACvE,aAAa,EAAE,sBAAsB;YACrC,mBAAmB,EAAE,2FAA2F;YAChH,eAAe,EAAE,uDAAuD;SACzE;QACD,IAAI,EAAE;YACJ,eAAe,EAAE,4CAA4C;SAC9D;QACD,IAAI,EAAE;YACJ,eAAe,EAAE,mEAAmE;YACpF,UAAU,EAAE,mEAAmE;SAChF;KACF;CACF,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { IssueTokenFormState, RevokeTokenFormState } from "../contract.js";
2
+ /** Issues a token for the signed-in user and returns its plaintext with the setup snippets, once. */
3
+ export declare function issueTokenAction(_previous: IssueTokenFormState, formData: FormData): Promise<IssueTokenFormState>;
4
+ /** Revokes one of the signed-in user's tokens; another account's id matches nothing. */
5
+ export declare function revokeTokenAction(_previous: RevokeTokenFormState, formData: FormData): Promise<RevokeTokenFormState>;
6
+ //# sourceMappingURL=actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/next/actions.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AA8BhF,qGAAqG;AACrG,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA+BvH;AAED,wFAAwF;AACxF,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,oBAAoB,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAc1H"}
@@ -0,0 +1,88 @@
1
+ "use server";
2
+ // The token page's server actions. The owner comes from the session (never from a bound argument,
3
+ // which the client controls, docs/02 §8) before the form is read, and every query is scoped to
4
+ // that owner. Unexpected failures become `safeError` codes; the token never reaches a log.
5
+ import { getCurrentUser } from "@softure-ai/auth/next";
6
+ import { errorLogLabel, formatMessage, safeError } from "@softure-ai/core";
7
+ import { getSoftureConfig } from "@softure-ai/core/next";
8
+ import { revalidatePath } from "next/cache";
9
+ import { z } from "zod";
10
+ import { getMcpClientSetup } from "../client-setup.js";
11
+ import { MAX_TOKEN_NAME_LENGTH } from "../options.js";
12
+ import { getMcpAccessMessages, getMcpAccessOptions, getMcpAccessRoutes, getMcpEndpointUrl } from "../server/options.js";
13
+ import { issueAccessToken, revokeAccessToken } from "../server/tokens.js";
14
+ import { getMcpAccessContext } from "./context.js";
15
+ import { formatDate } from "./format.js";
16
+ /** Longer values are cut: the server functions refuse them anyway, and nothing huge is echoed back. */
17
+ const MAX_FIELD_LENGTH = MAX_TOKEN_NAME_LENGTH * 4;
18
+ const text = z
19
+ .string()
20
+ .catch("")
21
+ .transform((value) => value.slice(0, MAX_FIELD_LENGTH));
22
+ const issueInput = z.object({
23
+ name: text,
24
+ // A checked HTML checkbox sends "on"; an unchecked one sends nothing, which means read only.
25
+ canWrite: z.string().nullable().catch(null),
26
+ });
27
+ const revokeInput = z.object({ id: text });
28
+ function reportFailure(operation, error) {
29
+ console.error(`@softure-ai/mcp-access: ${operation} failed: ${errorLogLabel(error)}`);
30
+ return safeError(error).error;
31
+ }
32
+ function refreshPage(config) {
33
+ revalidatePath(getMcpAccessRoutes(config).page);
34
+ }
35
+ /** Issues a token for the signed-in user and returns its plaintext with the setup snippets, once. */
36
+ export async function issueTokenAction(_previous, formData) {
37
+ const config = getSoftureConfig();
38
+ const user = await getCurrentUser();
39
+ if (user === null)
40
+ return { status: "error", error: "auth.unauthenticated" };
41
+ // Every field has a `catch`, so parsing cannot fail.
42
+ const input = issueInput.parse({ name: formData.get("name"), canWrite: formData.get("canWrite") });
43
+ try {
44
+ const result = await issueAccessToken(await getMcpAccessContext(config), { userId: user.id, name: input.name, canWrite: input.canWrite !== null });
45
+ if (!result.ok)
46
+ return { status: "error", error: result.error };
47
+ refreshPage(config);
48
+ const issued = result.value;
49
+ const messages = getMcpAccessMessages(config);
50
+ return {
51
+ status: "ok",
52
+ issued: {
53
+ id: issued.id,
54
+ name: issued.name,
55
+ canWrite: issued.canWrite,
56
+ expiresText: formatMessage(messages.issued.expires, { date: formatDate(config, issued.expiresAt) }),
57
+ setup: getMcpClientSetup({
58
+ serverName: getMcpAccessOptions(config).serverName,
59
+ endpointUrl: getMcpEndpointUrl(config),
60
+ token: issued.token,
61
+ promptTemplate: messages.setup.assistantPrompt,
62
+ }),
63
+ },
64
+ };
65
+ }
66
+ catch (error) {
67
+ return { status: "error", error: reportFailure("issuing a token", error) };
68
+ }
69
+ }
70
+ /** Revokes one of the signed-in user's tokens; another account's id matches nothing. */
71
+ export async function revokeTokenAction(_previous, formData) {
72
+ const config = getSoftureConfig();
73
+ const user = await getCurrentUser();
74
+ if (user === null)
75
+ return { status: "error", error: "auth.unauthenticated" };
76
+ const input = revokeInput.parse({ id: formData.get("id") });
77
+ try {
78
+ const result = await revokeAccessToken(await getMcpAccessContext(config), { userId: user.id, tokenId: input.id });
79
+ if (!result.ok)
80
+ return { status: "error", error: result.error };
81
+ refreshPage(config);
82
+ return { status: "ok" };
83
+ }
84
+ catch (error) {
85
+ return { status: "error", error: reportFailure("revoking a token", error) };
86
+ }
87
+ }
88
+ //# sourceMappingURL=actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/next/actions.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,kGAAkG;AAClG,+FAA+F;AAC/F,2FAA2F;AAC3F,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAsB,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACxH,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,uGAAuG;AACvG,MAAM,gBAAgB,GAAG,qBAAqB,GAAG,CAAC,CAAC;AACnD,MAAM,IAAI,GAAG,CAAC;KACX,MAAM,EAAE;KACR,KAAK,CAAC,EAAE,CAAC;KACT,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAE1D,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,IAAI,EAAE,IAAI;IACV,6FAA6F;IAC7F,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;CAC5C,CAAC,CAAC;AACH,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AAE3C,SAAS,aAAa,CAAC,SAAiB,EAAE,KAAc;IACtD,OAAO,CAAC,KAAK,CAAC,2BAA2B,SAAS,YAAY,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACtF,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC;AAChC,CAAC;AAED,SAAS,WAAW,CAAC,MAAqB;IACxC,cAAc,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AAClD,CAAC;AAED,qGAAqG;AACrG,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,SAA8B,EAAE,QAAkB;IACvF,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;IACpC,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAE7E,qDAAqD;IACrD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACnG,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,MAAM,mBAAmB,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC,CAAC;QACnJ,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QAChE,WAAW,CAAC,MAAM,CAAC,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;QAC5B,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC9C,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE;gBACN,EAAE,EAAE,MAAM,CAAC,EAAE;gBACb,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,WAAW,EAAE,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gBACnG,KAAK,EAAE,iBAAiB,CAAC;oBACvB,UAAU,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,UAAU;oBAClD,WAAW,EAAE,iBAAiB,CAAC,MAAM,CAAC;oBACtC,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC,eAAe;iBAC/C,CAAC;aACH;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC;IAC7E,CAAC;AACH,CAAC;AAED,wFAAwF;AACxF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,SAA+B,EAAE,QAAkB;IACzF,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;IACpC,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAE7E,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,MAAM,mBAAmB,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QAClH,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QAChE,WAAW,CAAC,MAAM,CAAC,CAAC;QACpB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC;IAC9E,CAAC;AACH,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type SoftureConfig } from "@softure-ai/core";
2
+ import type { McpAccessContext } from "../server/tokens.js";
3
+ export declare function getMcpAccessContext(config?: SoftureConfig): Promise<McpAccessContext>;
4
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/next/context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,wBAAsB,mBAAmB,CAAC,MAAM,GAAE,aAAkC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAM/G"}
@@ -0,0 +1,13 @@
1
+ // What the adapter hands the server functions: the registered config, the process-wide database
2
+ // handle and the wall clock.
3
+ import { systemClock } from "@softure-ai/core";
4
+ import { getSoftureConfig } from "@softure-ai/core/next";
5
+ import { getSharedDatabase } from "@softure-ai/db";
6
+ export async function getMcpAccessContext(config = getSoftureConfig()) {
7
+ if (config.database === null) {
8
+ throw new Error("@softure-ai/mcp-access: softure.config.ts has no database; mcp-access needs one");
9
+ }
10
+ const { db } = await getSharedDatabase(config.database.url);
11
+ return { db, clock: systemClock, config };
12
+ }
13
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/next/context.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,6BAA6B;AAC7B,OAAO,EAAE,WAAW,EAAsB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGnD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,SAAwB,gBAAgB,EAAE;IAClF,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACrG,CAAC;IACD,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC5D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { SoftureConfig } from "@softure-ai/core";
2
+ export declare function formatDate(config: SoftureConfig, date: Date): string;
3
+ export declare function formatDateTime(config: SoftureConfig, date: Date): string;
4
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/next/format.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,wBAAgB,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CAEpE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CAExE"}
@@ -0,0 +1,7 @@
1
+ export function formatDate(config, date) {
2
+ return new Intl.DateTimeFormat(config.locale, { dateStyle: "long", timeZone: config.timezone }).format(date);
3
+ }
4
+ export function formatDateTime(config, date) {
5
+ return new Intl.DateTimeFormat(config.locale, { dateStyle: "medium", timeStyle: "short", timeZone: config.timezone }).format(date);
6
+ }
7
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/next/format.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,UAAU,CAAC,MAAqB,EAAE,IAAU;IAC1D,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC/G,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAqB,EAAE,IAAU;IAC9D,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACrI,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { issueTokenAction, revokeTokenAction } from "./actions.js";
2
+ export { McpAccessPage } from "./pages.js";
3
+ export { createMcpRoute } from "./route.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,6 @@
1
+ // The Next.js adapter of @softure-ai/mcp-access: the MCP route factory, the token page and its
2
+ // server actions (docs/02-module-standard.md §8).
3
+ export { issueTokenAction, revokeTokenAction } from "./actions.js";
4
+ export { McpAccessPage } from "./pages.js";
5
+ export { createMcpRoute } from "./route.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,kDAAkD;AAClD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function McpAccessPage(): Promise<import("react").JSX.Element>;
2
+ //# sourceMappingURL=pages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pages.d.ts","sourceRoot":"","sources":["../../src/next/pages.tsx"],"names":[],"mappings":"AAuDA,wBAAsB,aAAa,yCAwBlC"}
@@ -0,0 +1,61 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // The token page, ready to mount with one line:
3
+ // `export { McpAccessPage as default } from "@softure-ai/mcp-access/next"`.
4
+ // A server component for the signed-in user; without a session it redirects to the login page and
5
+ // back. Everything the client part shows is prepared here, so dates are formatted once, in the
6
+ // app's locale and time zone, and never differ between the server render and hydration.
7
+ import { requireUser } from "@softure-ai/auth/next";
8
+ import { formatMessage } from "@softure-ai/core";
9
+ import { getSoftureConfig } from "@softure-ai/core/next";
10
+ import { Card } from "@softure-ai/ui";
11
+ import { getLocalizedText, getMcpAccessMessages, getMcpAccessOptions, getMcpAccessRoutes } from "../server/options.js";
12
+ import { listAccessTokens } from "../server/tokens.js";
13
+ import { getAccessTokenStatus } from "../token-status.js";
14
+ import { TokenManager } from "../ui/token-manager.js";
15
+ import { issueTokenAction, revokeTokenAction } from "./actions.js";
16
+ import { getMcpAccessContext } from "./context.js";
17
+ import { formatDate, formatDateTime } from "./format.js";
18
+ const LAYOUT_CLASS = "sft:mx-auto sft:box-border sft:w-full sft:sm:max-w-3xl sft:px-4 sft:py-4";
19
+ function describeStatus(status, messages) {
20
+ switch (status.kind) {
21
+ case "active":
22
+ return messages.list.active;
23
+ case "expired":
24
+ return messages.list.expired;
25
+ case "expiring":
26
+ if (status.daysLeft === 0)
27
+ return messages.list.expiresToday;
28
+ if (status.daysLeft === 1)
29
+ return messages.list.expiresTomorrow;
30
+ return formatMessage(messages.list.expiresInDays, { days: status.daysLeft });
31
+ }
32
+ }
33
+ function toRow(token, now, config, options, messages) {
34
+ const status = getAccessTokenStatus(token.expiresAt, now, { timezone: config.timezone, warningDays: options.expiryWarningDays });
35
+ const isExpired = status.kind === "expired";
36
+ const expiry = formatMessage(isExpired ? messages.list.expiredOn : messages.list.expiresOn, { date: formatDate(config, token.expiresAt) });
37
+ const lastUse = token.lastUsedAt === null ? messages.list.neverUsed : formatMessage(messages.list.lastUsed, { date: formatDateTime(config, token.lastUsedAt) });
38
+ return {
39
+ id: token.id,
40
+ name: token.name,
41
+ scopeText: token.canWrite && options.allowWrites ? messages.list.readWrite : messages.list.readOnly,
42
+ statusText: describeStatus(status, messages),
43
+ isExpired,
44
+ details: [formatMessage(messages.list.createdOn, { date: formatDate(config, token.createdAt) }), expiry, lastUse],
45
+ };
46
+ }
47
+ function toTool(tool, config, options, messages) {
48
+ const accessText = tool.access === "read" ? messages.tools.read : options.allowWrites ? messages.tools.write : messages.tools.writeUnavailable;
49
+ return { name: tool.name, description: getLocalizedText(tool.description, config.locale), accessText };
50
+ }
51
+ export async function McpAccessPage() {
52
+ const config = getSoftureConfig();
53
+ const user = await requireUser({ next: getMcpAccessRoutes(config).page });
54
+ const options = getMcpAccessOptions(config);
55
+ const messages = getMcpAccessMessages(config);
56
+ const ctx = await getMcpAccessContext(config);
57
+ const now = ctx.clock.now();
58
+ const tokens = await listAccessTokens(ctx, user.id);
59
+ return (_jsx("main", { className: LAYOUT_CLASS, children: _jsx(Card, { title: messages.page.title, subtitle: messages.page.lead, children: _jsx(TokenManager, { tools: options.tools.map((tool) => toTool(tool, config, options, messages)), tokens: tokens.map((token) => toRow(token, now, config, options, messages)), allowWrites: options.allowWrites, maxTokens: options.maxTokensPerUser, issueAction: issueTokenAction, revokeAction: revokeTokenAction, messages: messages, locale: config.locale }) }) }));
60
+ }
61
+ //# sourceMappingURL=pages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pages.js","sourceRoot":"","sources":["../../src/next/pages.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type McpEndpointOptions } from "../server/endpoint.js";
2
+ export declare function createMcpRoute(options: McpEndpointOptions): (request: Request) => Promise<Response>;
3
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/next/route.ts"],"names":[],"mappings":"AAMA,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAKnF,wBAAgB,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAYnG"}