@amplis/mcp-server 0.3.2 → 0.4.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 (2) hide show
  1. package/dist/index.js +268 -74
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -431,22 +431,22 @@ async function handleMemorySearch(query) {
431
431
  return result;
432
432
  }
433
433
  async function handleRead5(uri) {
434
- const projectContextMatch = uri.match(/^context:\/\/project\/(.+)$/);
434
+ const projectContextMatch = uri.match(/^context:\/\/project\/([^/]+)$/);
435
435
  if (projectContextMatch) {
436
436
  return resourceContent(uri, await handleProjectContext(projectContextMatch[1]));
437
437
  }
438
- const clientContextMatch = uri.match(/^context:\/\/client\/(.+)$/);
438
+ const clientContextMatch = uri.match(/^context:\/\/client\/([^/]+)$/);
439
439
  if (clientContextMatch) {
440
440
  return resourceContent(uri, await handleClientContext(clientContextMatch[1]));
441
441
  }
442
- const projectDecisionsMatch = uri.match(/^decisions:\/\/project\/(.+)$/);
442
+ const projectDecisionsMatch = uri.match(/^decisions:\/\/project\/([^/]+)$/);
443
443
  if (projectDecisionsMatch) {
444
444
  return resourceContent(uri, await handleProjectDecisions(projectDecisionsMatch[1]));
445
445
  }
446
446
  if (uri === "decisions://org") {
447
447
  return resourceContent(uri, await handleOrgDecisions());
448
448
  }
449
- const projectMeetingsMatch = uri.match(/^meetings:\/\/project\/(.+)$/);
449
+ const projectMeetingsMatch = uri.match(/^meetings:\/\/project\/([^/]+)$/);
450
450
  if (projectMeetingsMatch) {
451
451
  return resourceContent(uri, await handleProjectMeetings(projectMeetingsMatch[1]));
452
452
  }
@@ -1244,8 +1244,8 @@ var tools4 = [
1244
1244
  { name: "pipeline_move", description: "Move an opportunity to a different pipeline stage", inputSchema: { type: "object", properties: { opportunityId: { type: "string" }, stage: { type: "string", enum: ["lead", "discovery", "qualified", "proposal_draft", "proposal_submitted", "negotiation", "won", "lost"] }, notes: { type: "string" } }, required: ["opportunityId", "stage"] } }
1245
1245
  ];
1246
1246
  async function handlePipelineMove(args) {
1247
- const input = PipelineMoveSchema.parse(args);
1248
- return await apiPatch(`/pipeline/${input.opportunityId}/stage`, input);
1247
+ const { opportunityId, ...data } = PipelineMoveSchema.parse(args);
1248
+ return await apiPatch(`/pipeline/${encodeURIComponent(opportunityId)}/stage`, data);
1249
1249
  }
1250
1250
  async function handleToolCall4(name, args) {
1251
1251
  try {
@@ -1335,8 +1335,8 @@ async function handleSiteVisitLog(args) {
1335
1335
  return await apiPost("/compliance/site-visits", input);
1336
1336
  }
1337
1337
  async function handleComplianceUpdate(args) {
1338
- const input = ComplianceUpdateSchema.parse(args);
1339
- const updated = await apiPatch(`/compliance/${input.complianceId}`, input);
1338
+ const { complianceId, ...data } = ComplianceUpdateSchema.parse(args);
1339
+ const updated = await apiPatch(`/compliance/${encodeURIComponent(complianceId)}`, data);
1340
1340
  return { id: updated.id, name: updated.name, status: updated.status };
1341
1341
  }
1342
1342
  async function handleToolCall6(name, args) {
@@ -1698,8 +1698,8 @@ async function handleCredentialCreate(args) {
1698
1698
  return { id: cred.id, name: cred.name, type: cred.type, status: cred.status };
1699
1699
  }
1700
1700
  async function handleCredentialUpdate(args) {
1701
- const input = CredentialUpdateSchema.parse(args);
1702
- const updated = await apiPatch(`/credentials/${input.credentialId}`, input);
1701
+ const { credentialId, ...data } = CredentialUpdateSchema.parse(args);
1702
+ const updated = await apiPatch(`/credentials/${encodeURIComponent(credentialId)}`, data);
1703
1703
  return { id: updated.id, name: updated.name, status: updated.status, expiresAt: updated.expiresAt };
1704
1704
  }
1705
1705
  async function handleCredentialSearch(args) {
@@ -1763,13 +1763,14 @@ async function handleCapabilityAdd(args) {
1763
1763
  return { id: cap.id, name: cap.name, category: cap.category, proficiency: cap.proficiency };
1764
1764
  }
1765
1765
  async function handleCapabilityUpdate(args) {
1766
- const input = CapabilityUpdateSchema.parse(args);
1767
- const updated = await apiPatch(`/capabilities/${input.capabilityId}`, input);
1766
+ const { capabilityId, ...data } = CapabilityUpdateSchema.parse(args);
1767
+ const updated = await apiPatch(`/capabilities/${encodeURIComponent(capabilityId)}`, data);
1768
1768
  return { id: updated.id, name: updated.name, proficiency: updated.proficiency };
1769
1769
  }
1770
1770
  async function handleCapabilityEvidenceAdd(args) {
1771
1771
  const input = CapabilityEvidenceAddSchema.parse(args);
1772
- const evidence = await apiPost(`/capabilities/${input.capabilityId}/evidence`, input);
1772
+ const { capabilityId, ...data } = input;
1773
+ const evidence = await apiPost(`/capabilities/${encodeURIComponent(capabilityId)}/evidence`, data);
1773
1774
  return evidence;
1774
1775
  }
1775
1776
  async function handleToolCall13(name, args) {
@@ -1894,7 +1895,7 @@ var tools15 = [
1894
1895
  notes: { type: "string", description: "Notes" },
1895
1896
  linkedInUrl: { type: "string", description: "LinkedIn URL" }
1896
1897
  },
1897
- required: ["firstName"]
1898
+ required: ["firstName", "lastName"]
1898
1899
  }
1899
1900
  }
1900
1901
  ];
@@ -1950,8 +1951,8 @@ async function handleDeliverableCreate(args) {
1950
1951
  return { id: d.id, name: d.name, type: d.type, status: d.status };
1951
1952
  }
1952
1953
  async function handleDeliverableUpdate(args) {
1953
- const input = DeliverableUpdateSchema.parse(args);
1954
- const updated = await apiPatch(`/deliverables/${input.deliverableId}`, input);
1954
+ const { deliverableId, ...data } = DeliverableUpdateSchema.parse(args);
1955
+ const updated = await apiPatch(`/deliverables/${encodeURIComponent(deliverableId)}`, data);
1955
1956
  return { id: updated.id, name: updated.name, status: updated.status, percentComplete: updated.percentComplete };
1956
1957
  }
1957
1958
  async function handleToolCall16(name, args) {
@@ -2033,6 +2034,182 @@ async function handleToolCall17(name, args) {
2033
2034
  }
2034
2035
  }
2035
2036
 
2037
+ // src/tools/asset-tools.ts
2038
+ var asset_tools_exports = {};
2039
+ __export(asset_tools_exports, {
2040
+ handleToolCall: () => handleToolCall18,
2041
+ tools: () => tools18
2042
+ });
2043
+ import { z as z19 } from "zod";
2044
+ var SiteListSchema = z19.object({
2045
+ query: z19.string().optional(),
2046
+ limit: z19.number().optional()
2047
+ });
2048
+ var SiteGetSchema = z19.object({
2049
+ siteId: z19.string()
2050
+ });
2051
+ var AssetSearchSchema = z19.object({
2052
+ query: z19.string().optional(),
2053
+ siteId: z19.string().optional(),
2054
+ assetClass: z19.string().optional(),
2055
+ assetType: z19.string().optional(),
2056
+ limit: z19.number().optional()
2057
+ });
2058
+ var AssetGetSchema = z19.object({
2059
+ assetId: z19.string()
2060
+ });
2061
+ var AssetDocSearchSchema = z19.object({
2062
+ query: z19.string(),
2063
+ assetId: z19.string().optional(),
2064
+ siteId: z19.string().optional(),
2065
+ limit: z19.number().optional()
2066
+ });
2067
+ var AssetDocListSchema = z19.object({
2068
+ assetId: z19.string().optional(),
2069
+ siteId: z19.string().optional(),
2070
+ limit: z19.number().optional()
2071
+ });
2072
+ var tools18 = [
2073
+ {
2074
+ name: "site_list",
2075
+ description: "List or search sites by name",
2076
+ inputSchema: {
2077
+ type: "object",
2078
+ properties: {
2079
+ query: { type: "string", description: "Search site names" },
2080
+ limit: { type: "number", description: "Max results (default 50)" }
2081
+ }
2082
+ }
2083
+ },
2084
+ {
2085
+ name: "site_get",
2086
+ description: "Get site details including asset/area counts",
2087
+ inputSchema: {
2088
+ type: "object",
2089
+ properties: {
2090
+ siteId: { type: "string", description: "Site ID" }
2091
+ },
2092
+ required: ["siteId"]
2093
+ }
2094
+ },
2095
+ {
2096
+ name: "asset_search",
2097
+ description: "Search physical assets by name, tag, class, or type. Optionally scope to a site.",
2098
+ inputSchema: {
2099
+ type: "object",
2100
+ properties: {
2101
+ query: { type: "string", description: "Search asset names, tags, descriptions" },
2102
+ siteId: { type: "string", description: "Filter to assets at this site" },
2103
+ assetClass: { type: "string", description: "Filter by asset class (e.g., Rotating Equipment)" },
2104
+ assetType: { type: "string", description: "Filter by asset type (e.g., Pump, Motor)" },
2105
+ limit: { type: "number", description: "Max results (default 50)" }
2106
+ }
2107
+ }
2108
+ },
2109
+ {
2110
+ name: "asset_get",
2111
+ description: "Get full asset details with hierarchy, failure modes, and reliability metrics",
2112
+ inputSchema: {
2113
+ type: "object",
2114
+ properties: {
2115
+ assetId: { type: "string", description: "Asset ID" }
2116
+ },
2117
+ required: ["assetId"]
2118
+ }
2119
+ },
2120
+ {
2121
+ name: "asset_documentation_search",
2122
+ description: "Semantic search across documents indexed for a specific asset or site",
2123
+ inputSchema: {
2124
+ type: "object",
2125
+ properties: {
2126
+ query: { type: "string", description: "Search query" },
2127
+ assetId: { type: "string", description: "Scope to this asset" },
2128
+ siteId: { type: "string", description: "Scope to this site" },
2129
+ limit: { type: "number", description: "Max results (default 10)" }
2130
+ },
2131
+ required: ["query"]
2132
+ }
2133
+ },
2134
+ {
2135
+ name: "asset_documentation_list",
2136
+ description: "List all indexed documents for an asset or site",
2137
+ inputSchema: {
2138
+ type: "object",
2139
+ properties: {
2140
+ assetId: { type: "string", description: "List docs for this asset" },
2141
+ siteId: { type: "string", description: "List docs for this site" },
2142
+ limit: { type: "number", description: "Max results (default 50)" }
2143
+ }
2144
+ }
2145
+ }
2146
+ ];
2147
+ async function handleSiteList(args) {
2148
+ const input = SiteListSchema.parse(args);
2149
+ return apiGet("/sites", {
2150
+ query: input.query,
2151
+ limit: input.limit ?? 50
2152
+ });
2153
+ }
2154
+ async function handleSiteGet(args) {
2155
+ const input = SiteGetSchema.parse(args);
2156
+ return apiGet(`/sites/${encodeURIComponent(input.siteId)}`);
2157
+ }
2158
+ async function handleAssetSearch(args) {
2159
+ const input = AssetSearchSchema.parse(args);
2160
+ return apiGet("/physical-assets", {
2161
+ query: input.query,
2162
+ siteId: input.siteId,
2163
+ assetClass: input.assetClass,
2164
+ assetType: input.assetType,
2165
+ limit: input.limit ?? 50
2166
+ });
2167
+ }
2168
+ async function handleAssetGet(args) {
2169
+ const input = AssetGetSchema.parse(args);
2170
+ return apiGet(`/physical-assets/${encodeURIComponent(input.assetId)}`);
2171
+ }
2172
+ async function handleAssetDocSearch(args) {
2173
+ const input = AssetDocSearchSchema.parse(args);
2174
+ return apiGet("/physical-assets/documentation", {
2175
+ query: input.query,
2176
+ assetId: input.assetId,
2177
+ siteId: input.siteId,
2178
+ limit: input.limit ?? 10
2179
+ });
2180
+ }
2181
+ async function handleAssetDocList(args) {
2182
+ const input = AssetDocListSchema.parse(args);
2183
+ return apiGet("/physical-assets/documentation", {
2184
+ assetId: input.assetId,
2185
+ siteId: input.siteId,
2186
+ limit: input.limit ?? 50
2187
+ });
2188
+ }
2189
+ async function handleToolCall18(name, args) {
2190
+ try {
2191
+ switch (name) {
2192
+ case "site_list":
2193
+ return success(await handleSiteList(args));
2194
+ case "site_get":
2195
+ return success(await handleSiteGet(args));
2196
+ case "asset_search":
2197
+ return success(await handleAssetSearch(args));
2198
+ case "asset_get":
2199
+ return success(await handleAssetGet(args));
2200
+ case "asset_documentation_search":
2201
+ return success(await handleAssetDocSearch(args));
2202
+ case "asset_documentation_list":
2203
+ return success(await handleAssetDocList(args));
2204
+ default:
2205
+ return null;
2206
+ }
2207
+ } catch (err) {
2208
+ console.error(`Tool ${name} failed:`, err instanceof Error ? err.message : err);
2209
+ return safeError(err);
2210
+ }
2211
+ }
2212
+
2036
2213
  // src/tools/index.ts
2037
2214
  var modules2 = [
2038
2215
  task_tools_exports,
@@ -2051,10 +2228,11 @@ var modules2 = [
2051
2228
  availability_tools_exports,
2052
2229
  contact_tools_exports,
2053
2230
  deliverable_tools_exports,
2054
- memory_tools_exports
2231
+ memory_tools_exports,
2232
+ asset_tools_exports
2055
2233
  ];
2056
- var tools18 = modules2.flatMap((m) => [...m.tools]);
2057
- async function handleToolCall18(name, args) {
2234
+ var tools19 = modules2.flatMap((m) => [...m.tools]);
2235
+ async function handleToolCall19(name, args) {
2058
2236
  try {
2059
2237
  checkRateLimit(name);
2060
2238
  } catch (err) {
@@ -3267,11 +3445,11 @@ async function generatePromptContent(name, args) {
3267
3445
  }
3268
3446
 
3269
3447
  // src/auth/api-key.ts
3270
- import { z as z19 } from "zod";
3271
- var apiKeyPayloadSchema = z19.object({
3272
- orgId: z19.string(),
3273
- permissions: z19.array(z19.enum(["read", "write", "admin"])),
3274
- expiresAt: z19.date().optional()
3448
+ import { z as z20 } from "zod";
3449
+ var apiKeyPayloadSchema = z20.object({
3450
+ orgId: z20.string(),
3451
+ permissions: z20.array(z20.enum(["read", "write", "admin"])),
3452
+ expiresAt: z20.date().optional()
3275
3453
  });
3276
3454
  function isValidApiKeyFormat(key) {
3277
3455
  return /^amplis_[a-f0-9]{64}$/.test(key);
@@ -3446,8 +3624,48 @@ import open from "open";
3446
3624
  var DEFAULT_API_URL2 = "https://app.amplis.com.au";
3447
3625
  var CALLBACK_PORT = 19284;
3448
3626
  var TIMEOUT_MS = 12e4;
3627
+ function escapeHtml(s) {
3628
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
3629
+ }
3630
+ function renderPage(opts) {
3631
+ const iconSvg = opts.success ? '<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>' : '<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>';
3632
+ const permissionBadges = opts.permissions ? `<div style="display:flex;gap:8px;justify-content:center;margin-top:16px">${opts.permissions.map((p) => {
3633
+ const colors = p === "admin" ? "background:rgba(251,191,36,0.15);color:#f59e0b" : p === "write" ? "background:rgba(74,141,255,0.15);color:#4A8DFF" : "background:rgba(52,211,153,0.15);color:#34d399";
3634
+ return `<span style="padding:4px 12px;border-radius:9999px;font-size:12px;font-weight:500;${colors}">${escapeHtml(p)}</span>`;
3635
+ }).join("")}</div>` : "";
3636
+ const orgLine = opts.orgName ? `<p style="font-size:15px;color:#cbd5e1;line-height:1.5">Logged in to <strong style="color:#f1f5f9">${escapeHtml(opts.orgName)}</strong></p>` : `<p style="font-size:15px;color:#cbd5e1;line-height:1.5">${escapeHtml(opts.message)}</p>`;
3637
+ const autoCloseScript = opts.autoClose ? `<p id="countdown" style="font-size:13px;color:#64748b;margin-top:20px">This window will close in <span id="secs">5</span>s</p>
3638
+ <script>let s=5;const el=document.getElementById('secs');setInterval(()=>{s--;if(el)el.textContent=String(s);if(s<=0)window.close();},1000);</script>` : "";
3639
+ return `<!DOCTYPE html>
3640
+ <html lang="en">
3641
+ <head>
3642
+ <meta charset="utf-8">
3643
+ <meta name="viewport" content="width=device-width, initial-scale=1">
3644
+ <title>AMPLIS - ${escapeHtml(opts.title)}</title>
3645
+ <style>
3646
+ *{margin:0;padding:0;box-sizing:border-box}
3647
+ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;min-height:100vh;display:flex;align-items:center;justify-content:center;background:#0a0e1a}
3648
+ .card{background:#111827;border:1px solid rgba(255,255,255,0.08);border-radius:16px;padding:48px 40px;max-width:420px;width:100%;text-align:center;box-shadow:0 25px 50px rgba(0,0,0,0.4)}
3649
+ .icon{margin:0 auto 24px}
3650
+ h1{font-size:22px;font-weight:700;color:${opts.success ? "#22c55e" : "#ef4444"};margin-bottom:12px}
3651
+ .hint{font-size:13px;color:#64748b;margin-top:20px}
3652
+ .brand{margin-top:32px;padding-top:20px;border-top:1px solid rgba(255,255,255,0.06);font-size:12px;color:#475569;letter-spacing:0.5px}
3653
+ </style>
3654
+ </head>
3655
+ <body>
3656
+ <div class="card">
3657
+ <div class="icon">${iconSvg}</div>
3658
+ <h1>${escapeHtml(opts.title)}</h1>
3659
+ ${orgLine}
3660
+ ${permissionBadges}
3661
+ ${opts.success ? `<p class="hint">You can close this window and return to your terminal.</p>${autoCloseScript}` : '<p class="hint">Please close this window and try again.</p>'}
3662
+ <div class="brand">AMPLIS</div>
3663
+ </div>
3664
+ </body>
3665
+ </html>`;
3666
+ }
3449
3667
  async function browserLoginCommand() {
3450
- console.log("\n \u{1F510} AMPLIS MCP Server \u2014 Browser Authentication\n");
3668
+ console.log("\n AMPLIS MCP Server - Browser Authentication\n");
3451
3669
  const apiUrl = process.env.AMPLIS_API_URL || DEFAULT_API_URL2;
3452
3670
  const state = crypto.randomBytes(32).toString("hex");
3453
3671
  const callbackUrl = `http://localhost:${CALLBACK_PORT}/callback`;
@@ -3459,40 +3677,22 @@ async function browserLoginCommand() {
3459
3677
  const returnedState = url.searchParams.get("state");
3460
3678
  const error2 = url.searchParams.get("error");
3461
3679
  if (error2) {
3462
- res.writeHead(400, { "Content-Type": "text/html" });
3463
- res.end(`
3464
- <html><body style="font-family: system-ui; padding: 40px; text-align: center;">
3465
- <h1 style="color: #dc2626;">\u274C Authentication Failed</h1>
3466
- <p>${error2}</p>
3467
- <p>You can close this window.</p>
3468
- </body></html>
3469
- `);
3680
+ res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
3681
+ res.end(renderPage({ success: false, title: "Authentication Failed", message: error2 }));
3470
3682
  server.close();
3471
3683
  reject(new Error(error2));
3472
3684
  return;
3473
3685
  }
3474
3686
  if (returnedState !== state) {
3475
- res.writeHead(400, { "Content-Type": "text/html" });
3476
- res.end(`
3477
- <html><body style="font-family: system-ui; padding: 40px; text-align: center;">
3478
- <h1 style="color: #dc2626;">\u274C Invalid State</h1>
3479
- <p>Security validation failed. Please try again.</p>
3480
- <p>You can close this window.</p>
3481
- </body></html>
3482
- `);
3687
+ res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
3688
+ res.end(renderPage({ success: false, title: "Invalid State", message: "Security validation failed. Please try again." }));
3483
3689
  server.close();
3484
3690
  reject(new Error("Invalid state parameter"));
3485
3691
  return;
3486
3692
  }
3487
3693
  if (!code) {
3488
- res.writeHead(400, { "Content-Type": "text/html" });
3489
- res.end(`
3490
- <html><body style="font-family: system-ui; padding: 40px; text-align: center;">
3491
- <h1 style="color: #dc2626;">\u274C Missing Code</h1>
3492
- <p>No authorization code received.</p>
3493
- <p>You can close this window.</p>
3494
- </body></html>
3495
- `);
3694
+ res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
3695
+ res.end(renderPage({ success: false, title: "Missing Code", message: "No authorization code received." }));
3496
3696
  server.close();
3497
3697
  reject(new Error("Missing authorization code"));
3498
3698
  return;
@@ -3508,26 +3708,20 @@ async function browserLoginCommand() {
3508
3708
  throw new Error(errorBody.error || `HTTP ${exchangeResponse.status}`);
3509
3709
  }
3510
3710
  const result = await exchangeResponse.json();
3511
- res.writeHead(200, { "Content-Type": "text/html" });
3512
- res.end(`
3513
- <html><body style="font-family: system-ui; padding: 40px; text-align: center;">
3514
- <h1 style="color: #16a34a;">\u2705 Authentication Successful!</h1>
3515
- <p>Logged in to <strong>${result.orgName}</strong></p>
3516
- <p>You can close this window and return to your terminal.</p>
3517
- <script>setTimeout(() => window.close(), 3000);</script>
3518
- </body></html>
3519
- `);
3711
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
3712
+ res.end(renderPage({
3713
+ success: true,
3714
+ title: "Authentication Successful",
3715
+ orgName: result.orgName,
3716
+ message: "",
3717
+ permissions: result.permissions,
3718
+ autoClose: true
3719
+ }));
3520
3720
  server.close();
3521
3721
  resolve(result);
3522
3722
  } catch (err) {
3523
- res.writeHead(500, { "Content-Type": "text/html" });
3524
- res.end(`
3525
- <html><body style="font-family: system-ui; padding: 40px; text-align: center;">
3526
- <h1 style="color: #dc2626;">\u274C Exchange Failed</h1>
3527
- <p>${err instanceof Error ? err.message : "Unknown error"}</p>
3528
- <p>You can close this window.</p>
3529
- </body></html>
3530
- `);
3723
+ res.writeHead(500, { "Content-Type": "text/html; charset=utf-8" });
3724
+ res.end(renderPage({ success: false, title: "Exchange Failed", message: err instanceof Error ? err.message : "Unknown error" }));
3531
3725
  server.close();
3532
3726
  reject(err);
3533
3727
  }
@@ -3537,7 +3731,7 @@ async function browserLoginCommand() {
3537
3731
  }
3538
3732
  });
3539
3733
  server.listen(CALLBACK_PORT, "127.0.0.1", () => {
3540
- console.log(` \u{1F4E1} Callback server listening on port ${CALLBACK_PORT}`);
3734
+ console.log(` Callback server listening on port ${CALLBACK_PORT}`);
3541
3735
  });
3542
3736
  server.on("error", (err) => {
3543
3737
  reject(new Error(`Failed to start callback server: ${err.message}`));
@@ -3550,7 +3744,7 @@ async function browserLoginCommand() {
3550
3744
  const authUrl = new URL(`${apiUrl}/auth/mcp`);
3551
3745
  authUrl.searchParams.set("callback", callbackUrl);
3552
3746
  authUrl.searchParams.set("state", state);
3553
- console.log(` \u{1F310} Opening browser to authenticate...
3747
+ console.log(` Opening browser to authenticate...
3554
3748
  `);
3555
3749
  console.log(` If the browser doesn't open, visit:`);
3556
3750
  console.log(` ${authUrl.toString()}
@@ -3559,7 +3753,7 @@ async function browserLoginCommand() {
3559
3753
  await open(authUrl.toString());
3560
3754
  } catch {
3561
3755
  }
3562
- console.log(" \u23F3 Waiting for authentication...\n");
3756
+ console.log(" Waiting for authentication...\n");
3563
3757
  try {
3564
3758
  const result = await authPromise;
3565
3759
  saveCredentials({
@@ -3569,14 +3763,14 @@ async function browserLoginCommand() {
3569
3763
  userId: result.userId,
3570
3764
  permissions: result.permissions
3571
3765
  });
3572
- console.log(" \u2705 Authentication successful!\n");
3766
+ console.log(" Authentication successful!\n");
3573
3767
  console.log(` Organization : ${result.orgName}`);
3574
3768
  console.log(` Permissions : ${result.permissions.join(", ")}`);
3575
3769
  console.log(` Key prefix : ${result.apiKey.substring(0, 16)}...`);
3576
3770
  console.log("\n Credentials saved to ~/.amplis/credentials.json\n");
3577
3771
  } catch (err) {
3578
3772
  console.error(`
3579
- \u274C Authentication failed: ${err instanceof Error ? err.message : "Unknown error"}
3773
+ Authentication failed: ${err instanceof Error ? err.message : "Unknown error"}
3580
3774
  `);
3581
3775
  process.exit(1);
3582
3776
  }
@@ -3694,7 +3888,7 @@ if (command !== "serve") {
3694
3888
  const server = new Server(
3695
3889
  {
3696
3890
  name: "amplis-mcp-server",
3697
- version: "0.3.0"
3891
+ version: "0.4.0"
3698
3892
  },
3699
3893
  {
3700
3894
  capabilities: {
@@ -3714,10 +3908,10 @@ if (command !== "serve") {
3714
3908
  return handleReadResource(request.params.uri);
3715
3909
  });
3716
3910
  server.setRequestHandler(ListToolsRequestSchema, async () => {
3717
- return { tools: tools18 };
3911
+ return { tools: tools19 };
3718
3912
  });
3719
3913
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
3720
- return handleToolCall18(request.params.name, request.params.arguments);
3914
+ return handleToolCall19(request.params.name, request.params.arguments);
3721
3915
  });
3722
3916
  server.setRequestHandler(ListPromptsRequestSchema, async () => {
3723
3917
  return { prompts };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amplis/mcp-server",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "MCP server for AMPLIS - connect Claude, Cursor, and other AI tools to your live consulting data",
5
5
  "author": "AMPLIS (https://amplis.com.au)",
6
6
  "license": "MIT",