@tunnelhub/mcp 1.0.0

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 (112) hide show
  1. package/CONTRIBUTING.md +70 -0
  2. package/LICENSE +21 -0
  3. package/README.md +322 -0
  4. package/dist/auth/browser-auth.d.ts +16 -0
  5. package/dist/auth/browser-auth.d.ts.map +1 -0
  6. package/dist/auth/browser-auth.js +144 -0
  7. package/dist/auth/browser-auth.js.map +1 -0
  8. package/dist/auth/cognito-client.d.ts +14 -0
  9. package/dist/auth/cognito-client.d.ts.map +1 -0
  10. package/dist/auth/cognito-client.js +69 -0
  11. package/dist/auth/cognito-client.js.map +1 -0
  12. package/dist/auth/session-manager.d.ts +17 -0
  13. package/dist/auth/session-manager.d.ts.map +1 -0
  14. package/dist/auth/session-manager.js +152 -0
  15. package/dist/auth/session-manager.js.map +1 -0
  16. package/dist/auth/token-manager.d.ts +50 -0
  17. package/dist/auth/token-manager.d.ts.map +1 -0
  18. package/dist/auth/token-manager.js +107 -0
  19. package/dist/auth/token-manager.js.map +1 -0
  20. package/dist/index.d.ts +3 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +6 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/prompts/index.d.ts +3 -0
  25. package/dist/prompts/index.d.ts.map +1 -0
  26. package/dist/prompts/index.js +7 -0
  27. package/dist/prompts/index.js.map +1 -0
  28. package/dist/resources/index.d.ts +3 -0
  29. package/dist/resources/index.d.ts.map +1 -0
  30. package/dist/resources/index.js +7 -0
  31. package/dist/resources/index.js.map +1 -0
  32. package/dist/server.d.ts +12 -0
  33. package/dist/server.d.ts.map +1 -0
  34. package/dist/server.js +46 -0
  35. package/dist/server.js.map +1 -0
  36. package/dist/tools/api-gateway/index.d.ts +3 -0
  37. package/dist/tools/api-gateway/index.d.ts.map +1 -0
  38. package/dist/tools/api-gateway/index.js +9 -0
  39. package/dist/tools/api-gateway/index.js.map +1 -0
  40. package/dist/tools/automations/index.d.ts +3 -0
  41. package/dist/tools/automations/index.d.ts.map +1 -0
  42. package/dist/tools/automations/index.js +201 -0
  43. package/dist/tools/automations/index.js.map +1 -0
  44. package/dist/tools/integrations/index.d.ts +3 -0
  45. package/dist/tools/integrations/index.d.ts.map +1 -0
  46. package/dist/tools/integrations/index.js +10 -0
  47. package/dist/tools/integrations/index.js.map +1 -0
  48. package/dist/tools/monitoring/index.d.ts +3 -0
  49. package/dist/tools/monitoring/index.d.ts.map +1 -0
  50. package/dist/tools/monitoring/index.js +331 -0
  51. package/dist/tools/monitoring/index.js.map +1 -0
  52. package/dist/tools/packages/index.d.ts +3 -0
  53. package/dist/tools/packages/index.d.ts.map +1 -0
  54. package/dist/tools/packages/index.js +7 -0
  55. package/dist/tools/packages/index.js.map +1 -0
  56. package/dist/tools/session/current-session.d.ts +35 -0
  57. package/dist/tools/session/current-session.d.ts.map +1 -0
  58. package/dist/tools/session/current-session.js +32 -0
  59. package/dist/tools/session/current-session.js.map +1 -0
  60. package/dist/tools/session/index.d.ts +3 -0
  61. package/dist/tools/session/index.d.ts.map +1 -0
  62. package/dist/tools/session/index.js +16 -0
  63. package/dist/tools/session/index.js.map +1 -0
  64. package/dist/tools/session/list-environments.d.ts +35 -0
  65. package/dist/tools/session/list-environments.d.ts.map +1 -0
  66. package/dist/tools/session/list-environments.js +36 -0
  67. package/dist/tools/session/list-environments.js.map +1 -0
  68. package/dist/tools/session/list-sessions.d.ts +35 -0
  69. package/dist/tools/session/list-sessions.d.ts.map +1 -0
  70. package/dist/tools/session/list-sessions.js +37 -0
  71. package/dist/tools/session/list-sessions.js.map +1 -0
  72. package/dist/tools/session/login.d.ts +34 -0
  73. package/dist/tools/session/login.d.ts.map +1 -0
  74. package/dist/tools/session/login.js +27 -0
  75. package/dist/tools/session/login.js.map +1 -0
  76. package/dist/tools/session/logout.d.ts +42 -0
  77. package/dist/tools/session/logout.d.ts.map +1 -0
  78. package/dist/tools/session/logout.js +32 -0
  79. package/dist/tools/session/logout.js.map +1 -0
  80. package/dist/tools/session/switch-session.d.ts +42 -0
  81. package/dist/tools/session/switch-session.d.ts.map +1 -0
  82. package/dist/tools/session/switch-session.js +27 -0
  83. package/dist/tools/session/switch-session.js.map +1 -0
  84. package/dist/tools/tenants/index.d.ts +3 -0
  85. package/dist/tools/tenants/index.d.ts.map +1 -0
  86. package/dist/tools/tenants/index.js +61 -0
  87. package/dist/tools/tenants/index.js.map +1 -0
  88. package/dist/tools/users/index.d.ts +3 -0
  89. package/dist/tools/users/index.d.ts.map +1 -0
  90. package/dist/tools/users/index.js +7 -0
  91. package/dist/tools/users/index.js.map +1 -0
  92. package/dist/types/api.d.ts +108 -0
  93. package/dist/types/api.d.ts.map +1 -0
  94. package/dist/types/api.js +2 -0
  95. package/dist/types/api.js.map +1 -0
  96. package/dist/types/dynamodb.d.ts +54 -0
  97. package/dist/types/dynamodb.d.ts.map +1 -0
  98. package/dist/types/dynamodb.js +55 -0
  99. package/dist/types/dynamodb.js.map +1 -0
  100. package/dist/types/mcp.d.ts +271 -0
  101. package/dist/types/mcp.d.ts.map +1 -0
  102. package/dist/types/mcp.js +62 -0
  103. package/dist/types/mcp.js.map +1 -0
  104. package/dist/utils/api-client.d.ts +44 -0
  105. package/dist/utils/api-client.d.ts.map +1 -0
  106. package/dist/utils/api-client.js +201 -0
  107. package/dist/utils/api-client.js.map +1 -0
  108. package/dist/utils/error-handler.d.ts +28 -0
  109. package/dist/utils/error-handler.d.ts.map +1 -0
  110. package/dist/utils/error-handler.js +58 -0
  111. package/dist/utils/error-handler.js.map +1 -0
  112. package/package.json +90 -0
@@ -0,0 +1,70 @@
1
+ # Contributing
2
+
3
+ Thanks for contributing to `@tunnelhub/mcp`.
4
+
5
+ ## Development setup
6
+
7
+ ```bash
8
+ pnpm install
9
+ pnpm typecheck
10
+ pnpm build
11
+ ```
12
+
13
+ For local development:
14
+
15
+ ```bash
16
+ pnpm dev
17
+ ```
18
+
19
+ ## Before opening a PR
20
+
21
+ Please run:
22
+
23
+ ```bash
24
+ pnpm lint
25
+ pnpm typecheck
26
+ pnpm test
27
+ pnpm build
28
+ ```
29
+
30
+ Or run everything with:
31
+
32
+ ```bash
33
+ pnpm check
34
+ ```
35
+
36
+ ## Contribution guidelines
37
+
38
+ - Keep changes focused.
39
+ - Follow existing project patterns.
40
+ - Prefer improving MCP usability over exposing raw backend behavior.
41
+ - Preserve REST-only integration. Do not add direct DynamoDB access.
42
+ - Keep README user-facing and technical details in `docs/technical-overview.md`.
43
+
44
+ ## Reporting issues
45
+
46
+ When reporting a bug, include:
47
+
48
+ - MCP client used
49
+ - operating system
50
+ - Node.js version
51
+ - steps to reproduce
52
+ - expected behavior
53
+ - actual behavior
54
+ - relevant logs or tool outputs
55
+
56
+ ## Suggested PR format
57
+
58
+ - short title
59
+ - problem being solved
60
+ - summary of changes
61
+ - how it was tested
62
+
63
+ ## Release notes
64
+
65
+ Package publication is validated with:
66
+
67
+ ```bash
68
+ pnpm pack:check
69
+ pnpm publish:dry-run
70
+ ```
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 TunnelHub
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,322 @@
1
+ # TunnelHub MCP
2
+
3
+ Conecte clientes MCP ao TunnelHub para investigar automações, execuções, logs e traces usando o mesmo fluxo de autenticação do frontend.
4
+
5
+ Este MCP é especialmente útil para:
6
+
7
+ - Acompanhar automações do TunnelHub
8
+ - Localizar e resumir execuções
9
+ - Imprimir logs e traces
10
+ - Analisar falhas parciais e dependências externas
11
+ - Trabalhar com ambientes da empresa atual
12
+
13
+ ## ✨ O que você pode fazer
14
+
15
+ - Autenticar no TunnelHub pelo navegador
16
+ - Listar ambientes disponíveis
17
+ - Listar e inspecionar automações
18
+ - Localizar execuções por intervalo de tempo
19
+ - Resumir uma execução completa
20
+ - Consultar logs e traces de uma execução
21
+ - Ler informações básicas da empresa atual
22
+
23
+ ## 🚀 Comece em 2 minutos
24
+
25
+ A forma principal de uso é via `npx`:
26
+
27
+ ```bash
28
+ npx @tunnelhub/mcp
29
+ ```
30
+
31
+ Se você estiver desenvolvendo localmente:
32
+
33
+ ```bash
34
+ pnpm install
35
+ pnpm build
36
+ node dist/index.js
37
+ ```
38
+
39
+ ## ✅ Pré-requisitos
40
+
41
+ Você vai precisar de:
42
+
43
+ - Node.js 22+
44
+ - Acesso a uma empresa do TunnelHub
45
+ - Um cliente compatível com MCP via `stdio`
46
+
47
+ Clientes recomendados:
48
+
49
+ - OpenCode
50
+ - Claude Desktop
51
+ - Cursor
52
+ - Outros clientes MCP compatíveis com `stdio`
53
+
54
+ ## ⚙️ Variáveis de ambiente
55
+
56
+ Variáveis suportadas:
57
+
58
+ - `OAUTH_CALLBACK_PORT` padrão `3333`
59
+ - `TUNNELHUB_FRONTEND_URL` opcional
60
+ - `TUNNELHUB_API_HOST` opcional; padrão `https://api.tunnelhub.io`
61
+
62
+ Observações:
63
+
64
+ - O login usa o fluxo do frontend do TunnelHub
65
+ - Quando possível, o MCP reutiliza o domínio personalizado da empresa
66
+ - A porta do callback OAuth prefere `3333` e procura outra livre se necessário
67
+
68
+ ## 🔌 Configuração oficial por cliente
69
+
70
+ ### OpenCode via CLI
71
+
72
+ Depois da publicação, a forma recomendada será:
73
+
74
+ ```bash
75
+ opencode mcp add tunnelhub -- npx @tunnelhub/mcp
76
+ ```
77
+
78
+ Para desenvolvimento local:
79
+
80
+ ```bash
81
+ opencode mcp add tunnelhub -- node /caminho/para/mcp/dist/index.js
82
+ ```
83
+
84
+ Depois confirme:
85
+
86
+ ```bash
87
+ opencode mcp list
88
+ ```
89
+
90
+ ### OpenCode via `opencode.json`
91
+
92
+ Exemplo completo:
93
+
94
+ ```json
95
+ {
96
+ "mcp": {
97
+ "tunnelhub": {
98
+ "type": "local",
99
+ "command": [
100
+ "npx",
101
+ "@tunnelhub/mcp"
102
+ ],
103
+ "enabled": true,
104
+ "environment": {
105
+ "OAUTH_CALLBACK_PORT": "3333"
106
+ }
107
+ }
108
+ }
109
+ }
110
+ ```
111
+
112
+ Exemplo usando build local:
113
+
114
+ ```json
115
+ {
116
+ "mcp": {
117
+ "tunnelhub": {
118
+ "type": "local",
119
+ "command": [
120
+ "node",
121
+ "/caminho/para/mcp/dist/index.js"
122
+ ],
123
+ "enabled": true,
124
+ "environment": {
125
+ "OAUTH_CALLBACK_PORT": "3333"
126
+ }
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ ### Claude Desktop
133
+
134
+ Exemplo de configuração no `claude_desktop_config.json`:
135
+
136
+ ```json
137
+ {
138
+ "mcpServers": {
139
+ "tunnelhub": {
140
+ "command": "npx",
141
+ "args": ["@tunnelhub/mcp"],
142
+ "env": {
143
+ "OAUTH_CALLBACK_PORT": "3333"
144
+ }
145
+ }
146
+ }
147
+ }
148
+ ```
149
+
150
+ Exemplo usando build local:
151
+
152
+ ```json
153
+ {
154
+ "mcpServers": {
155
+ "tunnelhub": {
156
+ "command": "node",
157
+ "args": ["/caminho/para/mcp/dist/index.js"],
158
+ "env": {
159
+ "OAUTH_CALLBACK_PORT": "3333"
160
+ }
161
+ }
162
+ }
163
+ }
164
+ ```
165
+
166
+ ### Cursor
167
+
168
+ Use o mesmo comando `stdio` do cliente MCP:
169
+
170
+ ```json
171
+ {
172
+ "mcpServers": {
173
+ "tunnelhub": {
174
+ "command": "npx",
175
+ "args": ["@tunnelhub/mcp"],
176
+ "env": {
177
+ "OAUTH_CALLBACK_PORT": "3333"
178
+ }
179
+ }
180
+ }
181
+ }
182
+ ```
183
+
184
+ Exemplo usando build local:
185
+
186
+ ```json
187
+ {
188
+ "mcpServers": {
189
+ "tunnelhub": {
190
+ "command": "node",
191
+ "args": ["/caminho/para/mcp/dist/index.js"],
192
+ "env": {
193
+ "OAUTH_CALLBACK_PORT": "3333"
194
+ }
195
+ }
196
+ }
197
+ }
198
+ ```
199
+
200
+ ### Outros clientes MCP compatíveis com `stdio`
201
+
202
+ Se o cliente aceitar um comando local, use:
203
+
204
+ ```bash
205
+ npx @tunnelhub/mcp
206
+ ```
207
+
208
+ Ou, em desenvolvimento:
209
+
210
+ ```bash
211
+ node /caminho/para/mcp/dist/index.js
212
+ ```
213
+
214
+ ## 🔐 Como funciona o login
215
+
216
+ No primeiro uso, chame a ferramenta de login do MCP.
217
+
218
+ Fluxo esperado:
219
+
220
+ 1. O cliente chama `login_tunnelhub`
221
+ 2. O MCP abre o navegador local
222
+ 3. Você faz login no TunnelHub
223
+ 4. A sessão fica salva localmente
224
+ 5. As próximas ferramentas passam a usar a empresa e o ambiente ativos
225
+
226
+ Ferramentas básicas de sessão:
227
+
228
+ - `login_tunnelhub`
229
+ - `current_session_tunnelhub`
230
+ - `list_sessions_tunnelhub`
231
+ - `list_environments_tunnelhub`
232
+ - `switch_environment_tunnelhub`
233
+ - `logout_tunnelhub`
234
+
235
+ ## 💬 Exemplos de perguntas
236
+
237
+ Você pode pedir coisas como:
238
+
239
+ - `Qual sessão está ativa?`
240
+ - `Liste os ambientes disponíveis`
241
+ - `Liste as automações ativas`
242
+ - `Ache a execução 9b696080439f no dia 2026-03-13`
243
+ - `Resuma a execução 019ce7f3-2707-740c-8692-9b696080439f`
244
+ - `Me mostre os traces com ERROR dessa execução`
245
+ - `Me mostre os logs dessa execução`
246
+ - `Essa execução teve sucesso degradado?`
247
+ - `Quais dependências externas falharam nessa execução?`
248
+ - `Só usando o MCP, me diga o que precisa ser corrigido nessa automação`
249
+
250
+ ## 🧰 Principais ferramentas disponíveis
251
+
252
+ ### Sessão
253
+
254
+ - `login_tunnelhub`
255
+ - `current_session_tunnelhub`
256
+ - `list_sessions_tunnelhub`
257
+ - `list_environments_tunnelhub`
258
+ - `switch_environment_tunnelhub`
259
+ - `logout_tunnelhub`
260
+
261
+ ### Empresas
262
+
263
+ - `list_tenants_tunnelhub`
264
+ - `get_tenant_tunnelhub`
265
+
266
+ ### Automações
267
+
268
+ - `list_automations_tunnelhub`
269
+ - `get_automation_tunnelhub`
270
+ - `list_automation_deploys_tunnelhub`
271
+ - `get_automation_action_logs_tunnelhub`
272
+ - `execute_automation_tunnelhub`
273
+
274
+ ### Monitoramento
275
+
276
+ - `list_automation_executions_tunnelhub`
277
+ - `find_execution_tunnelhub`
278
+ - `get_execution_tunnelhub`
279
+ - `summarize_execution_tunnelhub`
280
+ - `get_execution_traces_tunnelhub`
281
+ - `get_execution_logs_tunnelhub`
282
+
283
+ ## 🧭 Dicas de uso
284
+
285
+ - Ao procurar uma execução, informe sempre a data ou um intervalo de tempo
286
+ - Quando já souber `automationId`, `executionId` e `executionPeriod`, use direto as ferramentas de detalhe
287
+ - Para diagnóstico rápido, prefira `summarize_execution_tunnelhub`
288
+ - Para investigação detalhada, consulte traces e logs em seguida
289
+
290
+ ## ⚠️ Limitações atuais
291
+
292
+ - O foco atual está em automações e monitoramento
293
+ - Algumas APIs do backend têm comportamentos específicos de filtro e paginação
294
+ - A listagem de execuções depende de intervalo de tempo obrigatório
295
+
296
+ ## 🛠️ Desenvolvimento local
297
+
298
+ Comandos úteis:
299
+
300
+ ```bash
301
+ pnpm install
302
+ pnpm typecheck
303
+ pnpm build
304
+ pnpm dev
305
+ ```
306
+
307
+ ## 🤝 Contribuições
308
+
309
+ Feedback, sugestões e contribuições são bem-vindos.
310
+
311
+ Se você estiver evoluindo o MCP internamente, vale sempre validar:
312
+
313
+ - Experiência de uso no cliente MCP
314
+ - Clareza das respostas textuais
315
+ - Consistência dos filtros
316
+ - Qualidade dos exemplos do README
317
+
318
+ ## 📚 Documentação técnica
319
+
320
+ Detalhes técnicos, arquitetura e comportamento interno estão documentados em inglês:
321
+
322
+ - `docs/technical-overview.md`
@@ -0,0 +1,16 @@
1
+ export interface BrowserAuthTokens {
2
+ idToken: string;
3
+ accessToken: string;
4
+ refreshToken: string;
5
+ expiresIn: number;
6
+ }
7
+ export declare class BrowserAuthFlow {
8
+ private port;
9
+ private readonly server;
10
+ private readonly sessionId;
11
+ constructor(port?: number);
12
+ authenticate(frontendUrl: string, tenantId?: string): Promise<BrowserAuthTokens>;
13
+ private resolveCallbackPort;
14
+ private isPortFree;
15
+ }
16
+ //# sourceMappingURL=browser-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-auth.d.ts","sourceRoot":"","sources":["../../src/auth/browser-auth.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,IAAI,CAAS;IAErB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IAEzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,IAAI,SAAkD;IAqB5D,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;YA6GxE,mBAAmB;YAenB,UAAU;CAezB"}
@@ -0,0 +1,144 @@
1
+ import express from 'express';
2
+ import { v4 as uuidv4 } from 'uuid';
3
+ import open from 'open';
4
+ import net from 'node:net';
5
+ export class BrowserAuthFlow {
6
+ port;
7
+ server;
8
+ sessionId;
9
+ constructor(port = Number(process.env.OAUTH_CALLBACK_PORT || 3333)) {
10
+ this.port = port;
11
+ this.sessionId = uuidv4();
12
+ this.server = express();
13
+ this.server.use((req, res, next) => {
14
+ res.header('Access-Control-Allow-Origin', '*');
15
+ res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
16
+ res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
17
+ if (req.method === 'OPTIONS') {
18
+ res.sendStatus(200);
19
+ return;
20
+ }
21
+ next();
22
+ });
23
+ this.server.use(express.json());
24
+ }
25
+ async authenticate(frontendUrl, tenantId) {
26
+ this.port = await this.resolveCallbackPort(this.port);
27
+ return new Promise((resolve, reject) => {
28
+ const cleanup = () => {
29
+ if (timeoutHandle) {
30
+ clearTimeout(timeoutHandle);
31
+ }
32
+ if (httpServer) {
33
+ httpServer.close();
34
+ }
35
+ };
36
+ this.server.post('/auth/callback', (req, res) => {
37
+ const { idToken, accessToken, refreshToken, expiresIn } = req.body;
38
+ if (!idToken || !accessToken || !refreshToken || !expiresIn) {
39
+ res.status(400).json({ success: false, message: 'Tokens not received' });
40
+ cleanup();
41
+ reject(new Error('Tokens not received from frontend auth flow.'));
42
+ return;
43
+ }
44
+ res.json({ success: true });
45
+ setTimeout(() => {
46
+ cleanup();
47
+ resolve({
48
+ idToken,
49
+ accessToken,
50
+ refreshToken,
51
+ expiresIn: Number(expiresIn),
52
+ });
53
+ }, 500);
54
+ });
55
+ this.server.get('/', (_req, res) => {
56
+ const redirectUri = `http://localhost:${this.port}/auth/callback`;
57
+ const authCliUrl = new URL(`${frontendUrl.replace(/\/$/, '')}/#/auth-cli`);
58
+ const searchParams = new URLSearchParams({
59
+ sessionId: this.sessionId,
60
+ redirect_uri: redirectUri,
61
+ });
62
+ if (tenantId) {
63
+ searchParams.set('tenantId', tenantId);
64
+ }
65
+ res.send(`<!DOCTYPE html>
66
+ <html>
67
+ <head>
68
+ <title>TunnelHub MCP Authentication</title>
69
+ <style>
70
+ body { font-family: Arial, sans-serif; text-align: center; padding: 40px; }
71
+ .container { max-width: 600px; margin: 0 auto; }
72
+ .spinner { border: 4px solid rgba(0, 0, 0, 0.1); width: 36px; height: 36px; border-radius: 50%; border-left-color: #09f; animation: spin 1s linear infinite; margin: 20px auto; }
73
+ @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
74
+ </style>
75
+ </head>
76
+ <body>
77
+ <div class="container">
78
+ <h1>TunnelHub MCP Authentication</h1>
79
+ <p>You will be redirected to the TunnelHub login page.</p>
80
+ <div class="spinner"></div>
81
+ <p>Redirecting...</p>
82
+ </div>
83
+ <script>
84
+ setTimeout(() => {
85
+ window.location.href = ${JSON.stringify(`${authCliUrl.toString()}?${searchParams.toString()}`)};
86
+ }, 1200);
87
+ </script>
88
+ </body>
89
+ </html>`);
90
+ });
91
+ this.server.get('/status', (_req, res) => {
92
+ res.json({ status: 'running', sessionId: this.sessionId });
93
+ });
94
+ const timeoutHandle = setTimeout(() => {
95
+ cleanup();
96
+ reject(new Error('Authentication timed out after 5 minutes.'));
97
+ }, 5 * 60 * 1000);
98
+ const httpServer = this.server.listen(this.port, async () => {
99
+ const localUrl = `http://localhost:${this.port}`;
100
+ console.log('\nStarting TunnelHub MCP authentication...');
101
+ console.log(`If browser does not open, visit:\n${localUrl}\n`);
102
+ try {
103
+ await open(localUrl);
104
+ }
105
+ catch (error) {
106
+ console.error('Failed to open browser automatically:', error);
107
+ }
108
+ });
109
+ httpServer.on('error', (error) => {
110
+ cleanup();
111
+ if (error.code === 'EADDRINUSE') {
112
+ reject(new Error(`OAuth callback port ${this.port} already in use.`));
113
+ return;
114
+ }
115
+ reject(error);
116
+ });
117
+ });
118
+ }
119
+ async resolveCallbackPort(preferredPort) {
120
+ if (await this.isPortFree(preferredPort)) {
121
+ return preferredPort;
122
+ }
123
+ for (let port = preferredPort + 1; port <= preferredPort + 20; port += 1) {
124
+ if (await this.isPortFree(port)) {
125
+ console.log(`OAuth callback port ${preferredPort} busy. Using ${port}.`);
126
+ return port;
127
+ }
128
+ }
129
+ throw new Error(`No free OAuth callback port found from ${preferredPort} to ${preferredPort + 20}.`);
130
+ }
131
+ async isPortFree(port) {
132
+ return new Promise((resolve) => {
133
+ const tester = net.createServer();
134
+ tester.once('error', () => {
135
+ resolve(false);
136
+ });
137
+ tester.once('listening', () => {
138
+ tester.close(() => resolve(true));
139
+ });
140
+ tester.listen(port, '127.0.0.1');
141
+ });
142
+ }
143
+ }
144
+ //# sourceMappingURL=browser-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-auth.js","sourceRoot":"","sources":["../../src/auth/browser-auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { BrowserAuthTokens } from './browser-auth.js';
2
+ export declare class CognitoClient {
3
+ private client;
4
+ constructor();
5
+ /**
6
+ * Refresh tokens using refresh token
7
+ */
8
+ refreshTokens(clientId: string, refreshToken: string): Promise<BrowserAuthTokens>;
9
+ /**
10
+ * Initiate password auth (for future use if needed)
11
+ */
12
+ authenticateWithPassword(clientId: string, username: string, password: string): Promise<BrowserAuthTokens>;
13
+ }
14
+ //# sourceMappingURL=cognito-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cognito-client.d.ts","sourceRoot":"","sources":["../../src/auth/cognito-client.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAgC;;IAQ9C;;OAEG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA6BvF;;OAEG;IACG,wBAAwB,CAC5B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,CAAC;CA6B9B"}
@@ -0,0 +1,69 @@
1
+ import { CognitoIdentityProviderClient, InitiateAuthCommand, } from '@aws-sdk/client-cognito-identity-provider';
2
+ export class CognitoClient {
3
+ client;
4
+ constructor() {
5
+ this.client = new CognitoIdentityProviderClient({
6
+ region: 'us-east-1'
7
+ });
8
+ }
9
+ /**
10
+ * Refresh tokens using refresh token
11
+ */
12
+ async refreshTokens(clientId, refreshToken) {
13
+ const input = {
14
+ AuthFlow: 'REFRESH_TOKEN_AUTH',
15
+ ClientId: clientId,
16
+ AuthParameters: {
17
+ REFRESH_TOKEN: refreshToken,
18
+ },
19
+ };
20
+ try {
21
+ const command = new InitiateAuthCommand(input);
22
+ const response = await this.client.send(command);
23
+ if (!response.AuthenticationResult) {
24
+ throw new Error('No authentication result received');
25
+ }
26
+ return {
27
+ idToken: response.AuthenticationResult.IdToken,
28
+ accessToken: response.AuthenticationResult.AccessToken,
29
+ refreshToken: refreshToken, // Refresh token doesn't change
30
+ expiresIn: response.AuthenticationResult.ExpiresIn,
31
+ };
32
+ }
33
+ catch (error) {
34
+ console.error('Failed to refresh tokens:', error);
35
+ throw error;
36
+ }
37
+ }
38
+ /**
39
+ * Initiate password auth (for future use if needed)
40
+ */
41
+ async authenticateWithPassword(clientId, username, password) {
42
+ const input = {
43
+ AuthFlow: 'USER_PASSWORD_AUTH',
44
+ ClientId: clientId,
45
+ AuthParameters: {
46
+ USERNAME: username,
47
+ PASSWORD: password,
48
+ },
49
+ };
50
+ try {
51
+ const command = new InitiateAuthCommand(input);
52
+ const response = await this.client.send(command);
53
+ if (!response.AuthenticationResult) {
54
+ throw new Error('No authentication result received');
55
+ }
56
+ return {
57
+ idToken: response.AuthenticationResult.IdToken,
58
+ accessToken: response.AuthenticationResult.AccessToken,
59
+ refreshToken: response.AuthenticationResult.RefreshToken,
60
+ expiresIn: response.AuthenticationResult.ExpiresIn,
61
+ };
62
+ }
63
+ catch (error) {
64
+ console.error('Failed to authenticate:', error);
65
+ throw error;
66
+ }
67
+ }
68
+ }
69
+ //# sourceMappingURL=cognito-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cognito-client.js","sourceRoot":"","sources":["../../src/auth/cognito-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,mBAAmB,GAEpB,MAAM,2CAA2C,CAAC;AAGnD,MAAM,OAAO,aAAa;IAChB,MAAM,CAAgC;IAE9C;QACE,IAAI,CAAC,MAAM,GAAG,IAAI,6BAA6B,CAAC;YAC9C,MAAM,EAAE,WAAW;SACpB,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,QAAgB,EAAE,YAAoB;QACxD,MAAM,KAAK,GAA6B;YACtC,QAAQ,EAAE,oBAAoB;YAC9B,QAAQ,EAAE,QAAQ;YAClB,cAAc,EAAE;gBACd,aAAa,EAAE,YAAY;aAC5B;SACF,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAC/C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAEjD,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;YACvD,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,QAAQ,CAAC,oBAAoB,CAAC,OAAQ;gBAC/C,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,WAAY;gBACvD,YAAY,EAAE,YAAY,EAAE,+BAA+B;gBAC3D,SAAS,EAAE,QAAQ,CAAC,oBAAoB,CAAC,SAAU;aACpD,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;YAClD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,wBAAwB,CAC5B,QAAgB,EAChB,QAAgB,EAChB,QAAgB;QAEhB,MAAM,KAAK,GAA6B;YACtC,QAAQ,EAAE,oBAAoB;YAC9B,QAAQ,EAAE,QAAQ;YAClB,cAAc,EAAE;gBACd,QAAQ,EAAE,QAAQ;gBAClB,QAAQ,EAAE,QAAQ;aACnB;SACF,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAC/C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAEjD,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;YACvD,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,QAAQ,CAAC,oBAAoB,CAAC,OAAQ;gBAC/C,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,WAAY;gBACvD,YAAY,EAAE,QAAQ,CAAC,oBAAoB,CAAC,YAAa;gBACzD,SAAS,EAAE,QAAQ,CAAC,oBAAoB,CAAC,SAAU;aACpD,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;YAChD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF"}