@loopops/mcp-server 3.2.0 → 3.3.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.
- package/dist/api-client.js +5 -4
- package/dist/index.js +14 -1
- package/dist/tools/identity.d.ts +11 -0
- package/dist/tools/identity.js +21 -0
- package/package.json +1 -1
package/dist/api-client.js
CHANGED
|
@@ -272,10 +272,11 @@ function persistRotatedRefreshToken(newToken) {
|
|
|
272
272
|
*/
|
|
273
273
|
async function diagnoseRefreshFailure(status, body) {
|
|
274
274
|
const head = `Okta refresh failed (HTTP ${status}). Detail: ${body.slice(0, 300)}`;
|
|
275
|
-
const generic = "Your refresh token may be revoked or idle-expired
|
|
276
|
-
"`npx @loopops/mcp-cli@latest
|
|
277
|
-
"npx
|
|
278
|
-
"
|
|
275
|
+
const generic = "Your refresh token may be revoked or idle-expired.\n" +
|
|
276
|
+
" Diagnose: `npx @loopops/mcp-cli@latest doctor` — checks tenant config + token.\n" +
|
|
277
|
+
" Fix: `npx @loopops/mcp-cli@latest login` — re-authenticates from scratch.\n" +
|
|
278
|
+
"(The `@latest` pin matters: bare `npx @loopops/mcp-cli` may serve a " +
|
|
279
|
+
"cached older cli with stale tenant defaults for up to 24h after a publish.)";
|
|
279
280
|
if (!apiUrl)
|
|
280
281
|
return `${head}\n\n${generic}`;
|
|
281
282
|
try {
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
2
5
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
6
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
7
|
import { z } from "zod";
|
|
5
8
|
import { trpcQuery } from "./api-client.js";
|
|
9
|
+
import { registerIdentityTools } from "./tools/identity.js";
|
|
6
10
|
import { registerReportingTools } from "./tools/reporting.js";
|
|
7
11
|
import { registerConfigTools } from "./tools/config.js";
|
|
8
12
|
import { registerEngTools } from "./tools/eng.js";
|
|
9
13
|
import { registerCrmTools } from "./tools/crm.js";
|
|
10
14
|
import { registerEngageTools } from "./tools/engage.js";
|
|
11
15
|
import { registerAccountMasterTools } from "./tools/account-master.js";
|
|
16
|
+
// Read our own package.json at runtime so the version baked into MCP
|
|
17
|
+
// initialize-handshake `serverInfo.version` matches the published npm
|
|
18
|
+
// version. Was hardcoded "1.0.0" — confusing in Claude Desktop logs and
|
|
19
|
+
// any other MCP client that displays server version. `package.json` is
|
|
20
|
+
// always included in npm tarballs, so the relative path `../package.json`
|
|
21
|
+
// (from dist/index.js) resolves cleanly post-publish.
|
|
22
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
|
|
12
24
|
const skillsResponseSchema = z.object({
|
|
13
25
|
role: z.string(),
|
|
14
26
|
skills: z.array(z.string()),
|
|
@@ -34,8 +46,9 @@ const allowedSkills = new Set(skills);
|
|
|
34
46
|
console.error(`[MCP] Connected — role: ${role}, ${skills.length} skills`);
|
|
35
47
|
const server = new McpServer({
|
|
36
48
|
name: "loop-operations",
|
|
37
|
-
version:
|
|
49
|
+
version: pkg.version,
|
|
38
50
|
});
|
|
51
|
+
registerIdentityTools(server, allowedSkills);
|
|
39
52
|
registerReportingTools(server, allowedSkills);
|
|
40
53
|
registerConfigTools(server, allowedSkills);
|
|
41
54
|
registerEngTools(server, allowedSkills);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity / connection-check tools.
|
|
3
|
+
*
|
|
4
|
+
* Currently just `mcp_whoami` — a data-independent first-call sanity check.
|
|
5
|
+
* Returns the caller's email, MCP role, SF user link state, and tool count.
|
|
6
|
+
* Designed for the onboarding flow: after install + restart, asking Claude
|
|
7
|
+
* "are you connected?" should resolve to this and confirm everything wired
|
|
8
|
+
* correctly without depending on having any actual Loop data yet.
|
|
9
|
+
*/
|
|
10
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
|
+
export declare function registerIdentityTools(server: McpServer, allowed: Set<string>): void;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity / connection-check tools.
|
|
3
|
+
*
|
|
4
|
+
* Currently just `mcp_whoami` — a data-independent first-call sanity check.
|
|
5
|
+
* Returns the caller's email, MCP role, SF user link state, and tool count.
|
|
6
|
+
* Designed for the onboarding flow: after install + restart, asking Claude
|
|
7
|
+
* "are you connected?" should resolve to this and confirm everything wired
|
|
8
|
+
* correctly without depending on having any actual Loop data yet.
|
|
9
|
+
*/
|
|
10
|
+
import { trpcQuery } from "../api-client.js";
|
|
11
|
+
import { safeTool } from "./_helpers.js";
|
|
12
|
+
export function registerIdentityTools(server, allowed) {
|
|
13
|
+
if (allowed.has("mcp_whoami")) {
|
|
14
|
+
server.tool("mcp_whoami", [
|
|
15
|
+
"Connection sanity check. Returns your email, MCP role, Salesforce user link state,",
|
|
16
|
+
"and the number of tools available to you. Use as a first-call verification after",
|
|
17
|
+
"install — works regardless of whether you have any Loop data yet, so it's a clean",
|
|
18
|
+
"way to confirm the auth chain (Okta → Loop → role resolution) is wired correctly.",
|
|
19
|
+
].join(" "), {}, safeTool(async () => trpcQuery("mcp.whoami")));
|
|
20
|
+
}
|
|
21
|
+
}
|