@egain/egain-mcp-server 1.0.13 → 1.0.16

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.
@@ -0,0 +1,490 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>eGain MCP - Sign In</title>
7
+ <style>
8
+ * { margin: 0; padding: 0; box-sizing: border-box; }
9
+ body {
10
+ font-family: "Open Sans", "Segoe UI", "SegoeUI", "Helvetica Neue", Helvetica, Arial, sans-serif !important;
11
+ background: #fef1fd;
12
+ min-height: 100vh;
13
+ display: flex;
14
+ justify-content: center;
15
+ align-items: center;
16
+ padding: 20px;
17
+ }
18
+ .container {
19
+ background: white;
20
+ border-radius: 16px;
21
+ box-shadow: 0px 0px 30px 0px rgba(0, 0, 0, 0.12);
22
+ max-width: 500px;
23
+ width: 100%;
24
+ padding: 32px;
25
+ }
26
+ h1 { color: #333; margin-bottom: 8px; font-size: 24px; }
27
+ .subtitle { color: #666; margin-bottom: 20px; font-size: 13px; }
28
+ .quick-signin {
29
+ display: none;
30
+ text-align: center;
31
+ position: relative;
32
+ }
33
+ .quick-signin .icon { font-size: 64px; }
34
+ .quick-signin h1 { text-align: center; }
35
+ .saved-config {
36
+ background: #f8f9fa;
37
+ border-radius: 8px;
38
+ padding: 20px;
39
+ margin: 30px 0;
40
+ text-align: left;
41
+ }
42
+ .saved-config-title {
43
+ font-size: 12px;
44
+ font-weight: 600;
45
+ color: #666;
46
+ text-transform: uppercase;
47
+ margin-bottom: 15px;
48
+ text-align: center;
49
+ }
50
+ .config-item {
51
+ display: flex;
52
+ justify-content: space-between;
53
+ padding: 8px 0;
54
+ border-bottom: 1px solid #e1e4e8;
55
+ font-size: 13px;
56
+ }
57
+ .config-item:last-child { border-bottom: none; }
58
+ .config-label { color: #666; font-weight: 500; }
59
+ .config-value {
60
+ color: #333;
61
+ font-family: 'Courier New', monospace;
62
+ max-width: 300px;
63
+ overflow: hidden;
64
+ text-overflow: ellipsis;
65
+ white-space: nowrap;
66
+ }
67
+ .config-value.masked { color: #999; }
68
+ .form-view { display: none; }
69
+ .form-group { margin-bottom: 16px; }
70
+ label {
71
+ display: flex;
72
+ align-items: center;
73
+ gap: 6px;
74
+ margin-bottom: 6px;
75
+ color: #333;
76
+ font-weight: 500;
77
+ font-size: 14px;
78
+ }
79
+ input {
80
+ width: 100%;
81
+ padding: 10px 12px;
82
+ border: 2px solid #e1e4e8;
83
+ border-radius: 8px;
84
+ font-size: 13px;
85
+ font-family: "Helvetica Neue LT Pro", "Open Sans", 'Courier New', monospace !important;
86
+ transition: border-color 0.2s;
87
+ }
88
+ input:focus {
89
+ outline: none;
90
+ border-color: #b91d8f;
91
+ }
92
+ .optional {
93
+ color: #999;
94
+ font-weight: normal;
95
+ font-size: 12px;
96
+ }
97
+ .tooltip {
98
+ position: relative;
99
+ display: inline-flex;
100
+ align-items: center;
101
+ justify-content: center;
102
+ width: 16px;
103
+ height: 16px;
104
+ background: #b91d8f;
105
+ color: white;
106
+ border-radius: 50%;
107
+ font-size: 11px;
108
+ font-weight: bold;
109
+ cursor: pointer;
110
+ flex-shrink: 0;
111
+ user-select: none;
112
+ }
113
+ .tooltip-content {
114
+ display: none !important;
115
+ position: fixed;
116
+ max-width: 380px;
117
+ width: max-content;
118
+ background: white;
119
+ border-radius: 8px;
120
+ box-shadow: 0 4px 20px rgba(0,0,0,0.3);
121
+ z-index: 10000;
122
+ overflow: hidden;
123
+ border: 2px solid #b91d8f;
124
+ pointer-events: auto;
125
+ }
126
+ .tooltip-content.active {
127
+ display: block !important;
128
+ }
129
+ .tooltip-arrow {
130
+ position: absolute;
131
+ width: 0;
132
+ height: 0;
133
+ border: 8px solid transparent;
134
+ z-index: 1;
135
+ }
136
+ .tooltip-arrow.left {
137
+ left: -16px;
138
+ top: 50%;
139
+ transform: translateY(-50%);
140
+ border-right-color: #b91d8f;
141
+ }
142
+ .tooltip-arrow.right {
143
+ right: -16px;
144
+ top: 50%;
145
+ transform: translateY(-50%);
146
+ border-left-color: #b91d8f;
147
+ }
148
+ .tooltip-arrow.top {
149
+ top: -16px;
150
+ left: 50%;
151
+ transform: translateX(-50%);
152
+ border-bottom-color: #b91d8f;
153
+ }
154
+ .tooltip-arrow.bottom {
155
+ bottom: -16px;
156
+ left: 50%;
157
+ transform: translateX(-50%);
158
+ border-top-color: #b91d8f;
159
+ }
160
+ .tooltip-header {
161
+ background: #b91d8f;
162
+ color: white;
163
+ padding: 8px 12px;
164
+ font-weight: 600;
165
+ font-size: 13px;
166
+ }
167
+ .tooltip-body {
168
+ padding: 10px 12px;
169
+ }
170
+ .tooltip-image {
171
+ width: 100%;
172
+ max-height: 200px;
173
+ object-fit: contain;
174
+ border-radius: 4px;
175
+ margin-bottom: 6px;
176
+ border: 1px solid #e1e4e8;
177
+ background: #f8f9fa;
178
+ }
179
+ .tooltip-text {
180
+ color: #555;
181
+ font-size: 12px;
182
+ line-height: 1.4;
183
+ font-style: italic;
184
+ }
185
+ .button-group {
186
+ display: flex;
187
+ gap: 10px;
188
+ margin-top: 20px;
189
+ }
190
+ button {
191
+ flex: 1;
192
+ padding: 12px;
193
+ border: 2px solid transparent;
194
+ border-radius: 8px;
195
+ font-size: 15px;
196
+ font-weight: 600;
197
+ cursor: pointer;
198
+ transition: all 0.2s;
199
+ }
200
+ .btn-primary {
201
+ background: linear-gradient(135deg, #b91d8f 0%, #7a1460 100%);
202
+ color: white;
203
+ }
204
+ .btn-primary:hover {
205
+ transform: translateY(-2px);
206
+ box-shadow: 0 6px 20px rgba(185, 29, 143, 0.4);
207
+ }
208
+ .btn-secondary {
209
+ background: #f6f8fa;
210
+ color: #666;
211
+ }
212
+ .btn-secondary:hover {
213
+ background: #e1e4e8;
214
+ }
215
+ .btn-danger {
216
+ background: white;
217
+ color: #b91d8f;
218
+ border: 2px solid #b91d8f;
219
+ }
220
+ .btn-danger:hover {
221
+ background: #fef1fd;
222
+ transform: translateY(-1px);
223
+ }
224
+ .btn-link {
225
+ background: transparent;
226
+ color: #b91d8f;
227
+ padding: 8px;
228
+ font-size: 14px;
229
+ }
230
+ .btn-link:hover {
231
+ background: #f6f8fa;
232
+ }
233
+ .status {
234
+ margin-top: 20px;
235
+ padding: 12px;
236
+ border-radius: 8px;
237
+ font-size: 14px;
238
+ display: none;
239
+ }
240
+ .status.success {
241
+ background: #d4edda;
242
+ color: #155724;
243
+ border: 1px solid #c3e6cb;
244
+ }
245
+ .status.error {
246
+ background: #f8d7da;
247
+ color: #721c24;
248
+ border: 1px solid #f5c6cb;
249
+ }
250
+ .status.info {
251
+ background: #d1ecf1;
252
+ color: #0c5460;
253
+ border: 1px solid #bee5eb;
254
+ }
255
+ /* Loading overlay and spinner */
256
+ .loading-overlay {
257
+ display: none;
258
+ position: absolute;
259
+ top: -32px;
260
+ left: -32px;
261
+ right: -32px;
262
+ bottom: -32px;
263
+ background: rgba(255, 255, 255, 0.85);
264
+ backdrop-filter: blur(2px);
265
+ border-radius: 16px;
266
+ z-index: 1000;
267
+ justify-content: center;
268
+ align-items: center;
269
+ flex-direction: column;
270
+ gap: 16px;
271
+ }
272
+ .loading-overlay.active {
273
+ display: flex;
274
+ }
275
+ .spinner {
276
+ width: 48px;
277
+ height: 48px;
278
+ border: 4px solid #e1e4e8;
279
+ border-top-color: #b91d8f;
280
+ border-radius: 50%;
281
+ animation: spin 0.8s linear infinite;
282
+ }
283
+ @keyframes spin {
284
+ to { transform: rotate(360deg); }
285
+ }
286
+ .loading-message {
287
+ color: #666;
288
+ font-size: 14px;
289
+ font-weight: 500;
290
+ text-align: center;
291
+ max-width: 300px;
292
+ }
293
+ .form-view {
294
+ position: relative;
295
+ }
296
+ .modal-overlay {
297
+ display: none;
298
+ position: fixed;
299
+ top: 0;
300
+ left: 0;
301
+ right: 0;
302
+ bottom: 0;
303
+ background: rgba(0, 0, 0, 0.5);
304
+ z-index: 10001;
305
+ justify-content: center;
306
+ align-items: center;
307
+ }
308
+ .modal-overlay.active {
309
+ display: flex;
310
+ }
311
+ .modal-content {
312
+ background: white;
313
+ border-radius: 12px;
314
+ padding: 30px;
315
+ max-width: 400px;
316
+ width: 90%;
317
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
318
+ }
319
+ .modal-title {
320
+ font-size: 20px;
321
+ font-weight: 600;
322
+ color: #333;
323
+ margin-bottom: 12px;
324
+ }
325
+ .modal-message {
326
+ font-size: 14px;
327
+ color: #666;
328
+ margin-bottom: 24px;
329
+ line-height: 1.5;
330
+ }
331
+ .modal-buttons {
332
+ display: flex;
333
+ gap: 10px;
334
+ justify-content: flex-end;
335
+ }
336
+ .modal-buttons button {
337
+ padding: 10px 20px;
338
+ font-size: 14px;
339
+ flex: none;
340
+ }
341
+ </style>
342
+ </head>
343
+ <body>
344
+ <div class="container">
345
+ <div id="quickSigninView" class="quick-signin">
346
+ <div id="loadingOverlayQuickSignin" class="loading-overlay">
347
+ <div class="spinner"></div>
348
+ <div id="loadingMessageQuickSignin" class="loading-message">Redirecting to login...</div>
349
+ </div>
350
+ <div class="icon">🔐</div>
351
+ <h1>Welcome Back!</h1>
352
+ <p class="subtitle">Ready to sign in with your saved configuration</p>
353
+ <div class="saved-config">
354
+ <div class="saved-config-title">Saved Configuration</div>
355
+ <div id="savedConfigList"></div>
356
+ </div>
357
+ <div class="button-group">
358
+ <button type="button" class="btn-danger" onclick="clearConfigAndShowForm()">Clear All</button>
359
+ <button type="button" class="btn-primary" onclick="signInWithSavedConfig()">Sign In</button>
360
+ </div>
361
+ <button type="button" class="btn-link" onclick="showForm()" style="width: 100%; margin-top: 10px;">Edit Configuration</button>
362
+ </div>
363
+ <div id="formView" class="form-view">
364
+ <div id="loadingOverlay" class="loading-overlay">
365
+ <div class="spinner"></div>
366
+ <div id="loadingMessage" class="loading-message">Saving configuration...</div>
367
+ </div>
368
+ <h1>🔐 eGain MCP Configuration</h1>
369
+ <p class="subtitle">Enter details from your eGain <strong>Admin Console</strong></p>
370
+ <form id="configForm">
371
+ <div class="form-group">
372
+ <label for="egainUrl">
373
+ <span>eGain Environment URL</span>
374
+ <span class="tooltip" onmouseenter="showTooltip(event, 'egainUrl')" onmouseleave="hideTooltip(event, 'egainUrl')">?</span>
375
+ </label>
376
+ <input type="text" id="egainUrl" name="egainUrl" placeholder="https://your-environment.egain.cloud" required>
377
+ </div>
378
+ <div class="form-group">
379
+ <label for="authUrl">
380
+ <span>Authorization URL</span>
381
+ <span class="tooltip" onmouseenter="showTooltip(event, 'authUrl')" onmouseleave="hideTooltip(event, 'authUrl')">?</span>
382
+ </label>
383
+ <input type="text" id="authUrl" name="authUrl" placeholder="https://login.egain.cloud/.../oauth2/authorize" required>
384
+ </div>
385
+ <div class="form-group">
386
+ <label for="accessTokenUrl">
387
+ <span>Access Token URL</span>
388
+ <span class="tooltip" onmouseenter="showTooltip(event, 'accessTokenUrl')" onmouseleave="hideTooltip(event, 'accessTokenUrl')">?</span>
389
+ </label>
390
+ <input type="text" id="accessTokenUrl" name="accessTokenUrl" placeholder="https://login.egain.cloud/.../oauth2/token" required>
391
+ </div>
392
+ <div class="form-group">
393
+ <label for="clientId">
394
+ <span>Client ID</span>
395
+ <span class="tooltip" onmouseenter="showTooltip(event, 'clientId')" onmouseleave="hideTooltip(event, 'clientId')">?</span>
396
+ </label>
397
+ <input type="text" id="clientId" name="clientId" placeholder="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" required>
398
+ </div>
399
+ <div class="form-group">
400
+ <label for="redirectUrl">
401
+ <span>Redirect URL</span>
402
+ <span class="tooltip" onmouseenter="showTooltip(event, 'redirectUrl')" onmouseleave="hideTooltip(event, 'redirectUrl')">?</span>
403
+ </label>
404
+ <input type="text" id="redirectUrl" name="redirectUrl" placeholder="https://your-redirect-url.com/" required>
405
+ </div>
406
+ <div class="form-group">
407
+ <label for="scopePrefix">
408
+ <span>Scope Prefix</span>
409
+ <span class="tooltip" onmouseenter="showTooltip(event, 'scopePrefix')" onmouseleave="hideTooltip(event, 'scopePrefix')">?</span>
410
+ <span class="optional">(Fill if in Metadata)</span>
411
+ </label>
412
+ <input type="text" id="scopePrefix" name="scopePrefix" placeholder="https://your.scope-prefix.cloud/auth/">
413
+ </div>
414
+ <div style="font-size: 11px; color: #999; margin: 12px 0 0 0; line-height: 1.4;">
415
+ 🔒 Your configuration will be securely saved to your <code style="background: #f0f0f0; padding: 2px 4px; border-radius: 3px; font-size: 10px;">~/.egain-mcp/config.json</code>.
416
+ </div>
417
+ <div class="button-group">
418
+ <button type="button" class="btn-secondary" onclick="cancelForm()">Cancel</button>
419
+ <button type="submit" class="btn-primary">Save & Authenticate</button>
420
+ </div>
421
+ </form>
422
+ </div>
423
+ <div id="status" class="status"></div>
424
+ </div>
425
+
426
+ <!-- Confirmation Modal -->
427
+ <div id="confirmModal" class="modal-overlay" onclick="if(event.target === this) closeModal(false)">
428
+ <div class="modal-content">
429
+ <div class="modal-title" id="modalTitle">Confirm Action</div>
430
+ <div class="modal-message" id="modalMessage">Are you sure?</div>
431
+ <div class="modal-buttons">
432
+ <button type="button" class="btn-secondary" onclick="closeModal(false)">Cancel</button>
433
+ <button type="button" class="btn-danger" id="modalConfirmBtn" onclick="closeModal(true)">Confirm</button>
434
+ </div>
435
+ </div>
436
+ </div>
437
+
438
+ <!-- Tooltip Popups (outside container for proper fixed positioning) -->
439
+ <div id="tooltip-egainUrl" class="tooltip-content">
440
+ <div class="tooltip-header">eGain Environment URL</div>
441
+ <div class="tooltip-body">
442
+ <img src="/img/env-tooltip.png" class="tooltip-image" alt="eGain Environment URL" onerror="this.style.display='none'">
443
+ <div class="tooltip-text">Enter the domain URL displayed in your browser when accessing the eGain application.</div>
444
+ </div>
445
+ </div>
446
+
447
+ <div id="tooltip-authUrl" class="tooltip-content">
448
+ <div class="tooltip-header">Authorization URL</div>
449
+ <div class="tooltip-body">
450
+ <img src="/img/authurl-tooltip.png" class="tooltip-image" alt="Authorization URL" onerror="this.style.display='none'">
451
+ <div class="tooltip-text">In the Partition space, go to Integration → Client Application → Metadata, and copy the Authorization URL.</div>
452
+ </div>
453
+ </div>
454
+
455
+ <div id="tooltip-accessTokenUrl" class="tooltip-content">
456
+ <div class="tooltip-header">Access Token URL</div>
457
+ <div class="tooltip-body">
458
+ <img src="/img/accesstoken-tooltip.png" class="tooltip-image" alt="Access Token URL" onerror="this.style.display='none'">
459
+ <div class="tooltip-text">In the Partition space, go to Integration → Client Application → Metadata, and copy the Access Token URL.</div>
460
+ </div>
461
+ </div>
462
+
463
+ <div id="tooltip-clientId" class="tooltip-content">
464
+ <div class="tooltip-header">Client ID</div>
465
+ <div class="tooltip-body">
466
+ <img src="/img/clientid-tooltip.png" class="tooltip-image" alt="Client ID" onerror="this.style.display='none'">
467
+ <div class="tooltip-text">In the Partition space, go to Integration → Client Application, select your client app, and copy the Client ID.</div>
468
+ </div>
469
+ </div>
470
+
471
+ <div id="tooltip-redirectUrl" class="tooltip-content">
472
+ <div class="tooltip-header">Redirect URL</div>
473
+ <div class="tooltip-body">
474
+ <img src="/img/redirect-tooltip.png" class="tooltip-image" alt="Redirect URL" onerror="this.style.display='none'">
475
+ <div class="tooltip-text">In the Partition space, go to Integration → Client Application, select your client app, and copy the Redirect URL.</div>
476
+ </div>
477
+ </div>
478
+
479
+ <div id="tooltip-scopePrefix" class="tooltip-content">
480
+ <div class="tooltip-header">Scope Prefix (Leave empty unless shown in Metadata)</div>
481
+ <div class="tooltip-body">
482
+ <img src="/img/scopeprefix-tooltip.png" class="tooltip-image" alt="Scope Prefix" onerror="this.style.display='none'">
483
+ <div class="tooltip-text">In the Partition space, go to Integration → Client Application → Metadata, and copy the API Permission Prefix.</div>
484
+ </div>
485
+ </div>
486
+
487
+ <script src="/config-page.js"></script>
488
+ </body>
489
+ </html>
490
+
@@ -1,7 +1,7 @@
1
- const FIELDS = ['egainUrl', 'authUrl', 'accessTokenUrl', 'clientId', 'redirectUrl', 'clientSecret', 'scopePrefix'];
1
+ const FIELDS = ['egainUrl', 'authUrl', 'accessTokenUrl', 'clientId', 'redirectUrl', 'scopePrefix'];
2
2
  const FIELD_LABELS = {
3
3
  egainUrl: 'eGain URL', authUrl: 'Auth URL', accessTokenUrl: 'Token URL',
4
- clientId: 'Client ID', redirectUrl: 'Redirect URL', clientSecret: 'Client Secret',
4
+ clientId: 'Client ID', redirectUrl: 'Redirect URL',
5
5
  scopePrefix: 'Scope Prefix'
6
6
  };
7
7
 
@@ -52,10 +52,7 @@ function displaySavedConfig() {
52
52
  label.textContent = FIELD_LABELS[field];
53
53
  const valueSpan = document.createElement('span');
54
54
  valueSpan.className = 'config-value';
55
- if (field === 'clientSecret') {
56
- valueSpan.classList.add('masked');
57
- valueSpan.textContent = '••••••••';
58
- } else if (field === 'clientId') {
55
+ if (field === 'clientId') {
59
56
  valueSpan.textContent = value.substring(0, 8) + '...';
60
57
  } else {
61
58
  valueSpan.textContent = value.length > 40 ? value.substring(0, 40) + '...' : value;
@@ -87,11 +84,6 @@ function loadFormValues() {
87
84
  const value = savedConfigData[field];
88
85
  if (value) document.getElementById(field).value = value;
89
86
  });
90
-
91
- // Show advanced settings if clientSecret or scopePrefix exist
92
- if (savedConfigData.clientSecret || savedConfigData.scopePrefix) {
93
- toggleAdvancedSettings();
94
- }
95
87
  }
96
88
 
97
89
  async function clearConfigAndShowForm() {
@@ -197,7 +189,7 @@ function showStatus(message, type) {
197
189
 
198
190
  function configValuesEqual(config1, config2) {
199
191
  // Compare all fields that matter
200
- const fieldsToCompare = ['egainUrl', 'authUrl', 'accessTokenUrl', 'clientId', 'redirectUrl', 'clientSecret', 'scopePrefix'];
192
+ const fieldsToCompare = ['egainUrl', 'authUrl', 'accessTokenUrl', 'clientId', 'redirectUrl', 'scopePrefix'];
201
193
  for (const field of fieldsToCompare) {
202
194
  const val1 = (config1[field] || '').trim();
203
195
  const val2 = (config2[field] || '').trim();
@@ -362,20 +354,6 @@ function closeModal(confirmed) {
362
354
  }
363
355
  }
364
356
 
365
- // Advanced settings toggle
366
- function toggleAdvancedSettings() {
367
- const advancedSection = document.getElementById('advancedSettings');
368
- const toggleIcon = document.getElementById('advancedToggleIcon');
369
-
370
- if (advancedSection.style.display === 'none') {
371
- advancedSection.style.display = 'block';
372
- toggleIcon.textContent = '▼';
373
- } else {
374
- advancedSection.style.display = 'none';
375
- toggleIcon.textContent = '▶';
376
- }
377
- }
378
-
379
357
  // Tooltip functions
380
358
  function showTooltip(event, fieldName) {
381
359
  event.preventDefault(); // Prevent label from focusing input
Binary file
package/src/lib/config.ts CHANGED
@@ -82,8 +82,8 @@ export function serverURLFromOptions(options: SDKOptions): URL | null {
82
82
  export const SDK_METADATA = {
83
83
  language: "typescript",
84
84
  openapiDocVersion: "1.0.0",
85
- sdkVersion: "1.0.13",
85
+ sdkVersion: "1.0.16",
86
86
  genVersion: "2.723.8",
87
87
  userAgent:
88
- "speakeasy-sdk/mcp-typescript 1.0.13 2.723.8 1.0.0 @egain/egain-mcp-server",
88
+ "speakeasy-sdk/mcp-typescript 1.0.16 2.723.8 1.0.0 @egain/egain-mcp-server",
89
89
  } as const;
@@ -19,7 +19,7 @@ const routes = buildRouteMap({
19
19
  export const app = buildApplication(routes, {
20
20
  name: "mcp",
21
21
  versionInfo: {
22
- currentVersion: "1.0.13",
22
+ currentVersion: "1.0.16",
23
23
  },
24
24
  });
25
25
 
@@ -34,7 +34,7 @@ export function createMCPServer(deps: {
34
34
  }) {
35
35
  const server = new McpServer({
36
36
  name: "EgainMcp",
37
- version: "1.0.13",
37
+ version: "1.0.16",
38
38
  });
39
39
 
40
40
  const getClient = deps.getSDK || (() =>