@sonisoft/now-sdk-ext-mcp 4.5.0 → 4.6.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/README.md +9 -1
- package/dist/common/connection.d.ts.map +1 -1
- package/dist/common/connection.js +6 -2
- package/dist/common/connection.js.map +1 -1
- package/dist/common/logging.d.ts +48 -0
- package/dist/common/logging.d.ts.map +1 -0
- package/dist/common/logging.js +65 -0
- package/dist/common/logging.js.map +1 -0
- package/dist/common/progress.d.ts.map +1 -1
- package/dist/common/progress.js +5 -3
- package/dist/common/progress.js.map +1 -1
- package/dist/common/tool-packages.d.ts +3 -1
- package/dist/common/tool-packages.d.ts.map +1 -1
- package/dist/common/tool-packages.js +8 -4
- package/dist/common/tool-packages.js.map +1 -1
- package/dist/index.js +66 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -398,7 +398,15 @@ Since stdout is reserved for JSON-RPC, **never use `console.log()` in server cod
|
|
|
398
398
|
|
|
399
399
|
- **`console.error()`** — writes to stderr, which is safe and visible in the MCP Inspector's Notifications pane and in Claude Desktop's log files (`~/Library/Logs/Claude/mcp*.log`).
|
|
400
400
|
- **MCP Inspector** — run the server under the inspector to see all JSON-RPC messages and stderr output in real time.
|
|
401
|
-
- **File logging** —
|
|
401
|
+
- **File logging** — off by default. This server's working directory is chosen by whoever launched it, so it writes no files unless asked. Configure with environment variables:
|
|
402
|
+
|
|
403
|
+
| Variable | Effect |
|
|
404
|
+
| --- | --- |
|
|
405
|
+
| `NEX_LOG_FILE` | `1`/`true` writes a log file to `$XDG_STATE_HOME/now-sdk-ext/logs` (`~/.local/state/...`) |
|
|
406
|
+
| `NEX_LOG_DIR` | Write log files to this directory instead. Implies `NEX_LOG_FILE` |
|
|
407
|
+
| `NEX_LOG_LEVEL` | `error`, `warn`, `info` (default), `http`, `verbose`, `debug`, `silly` |
|
|
408
|
+
|
|
409
|
+
Diagnostics always go to **stderr**, never stdout — stdout carries JSON-RPC. Credential material is stripped from both metadata and message text before anything is written.
|
|
402
410
|
|
|
403
411
|
### Code Conventions
|
|
404
412
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/common/connection.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAEnB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/common/connection.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAEnB,MAAM,4BAA4B,CAAC;AA+BpC;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,kBAAkB,CAAC,CAgD7B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAKtD;AAED,0EAA0E;AAC1E,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,6BAA6B,CAAC;AAEjE;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAeD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GACpE,OAAO,CAIT;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC,CAAC,GACtD,OAAO,CAAC,CAAC,CAAC,CAeZ"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { getCredentials } from "@servicenow/sdk-cli/dist/auth/index.js";
|
|
2
2
|
import { ServiceNowInstance, } from "@sonisoft/now-sdk-ext-core";
|
|
3
|
+
import { getLogger } from "./logging.js";
|
|
4
|
+
const log = getLogger("connection");
|
|
3
5
|
/** Cache TTL — 30 minutes. ServiceNow sessions typically expire after idle time. */
|
|
4
6
|
const CACHE_TTL_MS = 30 * 60 * 1000;
|
|
5
7
|
const instanceCache = new Map();
|
|
@@ -36,7 +38,7 @@ export async function getServiceNowInstance(authAlias) {
|
|
|
36
38
|
return cached.instance;
|
|
37
39
|
}
|
|
38
40
|
// TTL expired — evict and create fresh
|
|
39
|
-
|
|
41
|
+
log.debug("Cache TTL expired, refreshing session", { alias: resolvedAlias });
|
|
40
42
|
instanceCache.delete(resolvedAlias);
|
|
41
43
|
}
|
|
42
44
|
const credential = await getCredentials(resolvedAlias);
|
|
@@ -134,7 +136,9 @@ export async function withConnectionRetry(authAlias, operation) {
|
|
|
134
136
|
}
|
|
135
137
|
catch (error) {
|
|
136
138
|
if (isRetryableError(error)) {
|
|
137
|
-
|
|
139
|
+
// The error went into the message before, unredacted — an auth or HTTP failure
|
|
140
|
+
// here carries a live session. As metadata it goes through redaction.
|
|
141
|
+
log.warn("Retryable error, refreshing session and retrying", { error });
|
|
138
142
|
clearInstance(authAlias);
|
|
139
143
|
const freshInstance = await getServiceNowInstance(authAlias);
|
|
140
144
|
return await operation(freshInstance);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/common/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AACxE,OAAO,EACL,kBAAkB,GAEnB,MAAM,4BAA4B,CAAC;AAQpC,oFAAoF;AACpF,MAAM,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEpC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAsB,CAAC;AAEpD;;;GAGG;AACH,SAAS,YAAY,CAAC,SAAkB;IACtC,MAAM,QAAQ,GAAG,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,uDAAuD;YACrD,oFAAoF,CACvF,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,SAAkB;IAElB,MAAM,aAAa,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAE9C,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAChD,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC;QAC1C,IAAI,GAAG,GAAG,YAAY,EAAE,CAAC;YACvB,OAAO,MAAM,CAAC,QAAQ,CAAC;QACzB,CAAC;QACD,uCAAuC;QACvC,
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/common/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging setup for the MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Two things make this different from the CLI.
|
|
5
|
+
*
|
|
6
|
+
* First, there are no flags — an MCP server is launched by a client with an argv it
|
|
7
|
+
* does not control — so configuration is environment only: NEX_LOG_FILE, NEX_LOG_DIR,
|
|
8
|
+
* NEX_LOG_LEVEL, read by core itself.
|
|
9
|
+
*
|
|
10
|
+
* Second, this process is the reason file logging had to become opt-in at all. The
|
|
11
|
+
* server's working directory is chosen by whoever launched it, and core used to create
|
|
12
|
+
* ./logs/ there on import, unconditionally, without this server ever asking to log
|
|
13
|
+
* anything (NEX-3).
|
|
14
|
+
*
|
|
15
|
+
* stdout is the JSON-RPC transport. Everything here goes to stderr, and nothing in this
|
|
16
|
+
* process may ever write to fd 1.
|
|
17
|
+
*/
|
|
18
|
+
import { Logger } from "@sonisoft/now-sdk-ext-core";
|
|
19
|
+
/**
|
|
20
|
+
* Configures process-wide logging. Call once, before anything constructs a manager.
|
|
21
|
+
*
|
|
22
|
+
* Explicit rather than relying on core reading the environment on its own: the
|
|
23
|
+
* stderr-only guarantee is this server's to make, so it should be stated here where it
|
|
24
|
+
* can be read and tested, not inherited by accident.
|
|
25
|
+
*/
|
|
26
|
+
export declare function initLogging(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Returns a named logger.
|
|
29
|
+
*
|
|
30
|
+
* Safe to call before `initLogging()`, and several modules do: ES modules evaluate
|
|
31
|
+
* every import before the importing module's own top-level statements, so the
|
|
32
|
+
* `const log = getLogger(...)` in connection.ts, progress.ts and tool-packages.ts all
|
|
33
|
+
* run BEFORE the `initLogging()` call in index.ts, even though it sits above them in
|
|
34
|
+
* source order.
|
|
35
|
+
*
|
|
36
|
+
* That is fine because nothing is decided at construction time. `Logger` only stores a
|
|
37
|
+
* label; core builds the underlying winston logger on the first WRITE, resolves config
|
|
38
|
+
* lazily at that point, and rebuilds when configuration changes. So a logger built
|
|
39
|
+
* during import picks up whatever `initLogging()` sets, provided nothing logs during
|
|
40
|
+
* module evaluation — and nothing does.
|
|
41
|
+
*
|
|
42
|
+
* This is not left to inspection: the "still reports startup breadcrumbs on stderr"
|
|
43
|
+
* case in test/unit/common/logging.test.ts only passes if `consoleLevel: info` from
|
|
44
|
+
* `initLogging()` reached a logger that was constructed before it ran. Core's default
|
|
45
|
+
* is `warn`, which would suppress those lines.
|
|
46
|
+
*/
|
|
47
|
+
export declare function getLogger(name: string): Logger;
|
|
48
|
+
//# sourceMappingURL=logging.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../src/common/logging.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,EAAoB,MAAM,4BAA4B,CAAC;AAItE;;;;;;GAMG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAelC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging setup for the MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Two things make this different from the CLI.
|
|
5
|
+
*
|
|
6
|
+
* First, there are no flags — an MCP server is launched by a client with an argv it
|
|
7
|
+
* does not control — so configuration is environment only: NEX_LOG_FILE, NEX_LOG_DIR,
|
|
8
|
+
* NEX_LOG_LEVEL, read by core itself.
|
|
9
|
+
*
|
|
10
|
+
* Second, this process is the reason file logging had to become opt-in at all. The
|
|
11
|
+
* server's working directory is chosen by whoever launched it, and core used to create
|
|
12
|
+
* ./logs/ there on import, unconditionally, without this server ever asking to log
|
|
13
|
+
* anything (NEX-3).
|
|
14
|
+
*
|
|
15
|
+
* stdout is the JSON-RPC transport. Everything here goes to stderr, and nothing in this
|
|
16
|
+
* process may ever write to fd 1.
|
|
17
|
+
*/
|
|
18
|
+
import { Logger, configureLogging } from "@sonisoft/now-sdk-ext-core";
|
|
19
|
+
let configured = false;
|
|
20
|
+
/**
|
|
21
|
+
* Configures process-wide logging. Call once, before anything constructs a manager.
|
|
22
|
+
*
|
|
23
|
+
* Explicit rather than relying on core reading the environment on its own: the
|
|
24
|
+
* stderr-only guarantee is this server's to make, so it should be stated here where it
|
|
25
|
+
* can be read and tested, not inherited by accident.
|
|
26
|
+
*/
|
|
27
|
+
export function initLogging() {
|
|
28
|
+
if (configured) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
configured = true;
|
|
32
|
+
configureLogging({
|
|
33
|
+
// stderr IS this server's log channel — an operator reading `docker logs` or a
|
|
34
|
+
// client's server pane sees only this. `warn` (core's default, right for a CLI
|
|
35
|
+
// where the terminal is the user's) would silence the startup breadcrumbs that
|
|
36
|
+
// say which tool package loaded and whether credentials resolved.
|
|
37
|
+
consoleLevel: process.env.NEX_LOG_LEVEL?.trim() || "info",
|
|
38
|
+
// File logging stays off unless NEX_LOG_FILE/NEX_LOG_DIR asks for it. Core
|
|
39
|
+
// resolves those; naming them here would override an operator's NEX_LOG_FILE=0.
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Returns a named logger.
|
|
44
|
+
*
|
|
45
|
+
* Safe to call before `initLogging()`, and several modules do: ES modules evaluate
|
|
46
|
+
* every import before the importing module's own top-level statements, so the
|
|
47
|
+
* `const log = getLogger(...)` in connection.ts, progress.ts and tool-packages.ts all
|
|
48
|
+
* run BEFORE the `initLogging()` call in index.ts, even though it sits above them in
|
|
49
|
+
* source order.
|
|
50
|
+
*
|
|
51
|
+
* That is fine because nothing is decided at construction time. `Logger` only stores a
|
|
52
|
+
* label; core builds the underlying winston logger on the first WRITE, resolves config
|
|
53
|
+
* lazily at that point, and rebuilds when configuration changes. So a logger built
|
|
54
|
+
* during import picks up whatever `initLogging()` sets, provided nothing logs during
|
|
55
|
+
* module evaluation — and nothing does.
|
|
56
|
+
*
|
|
57
|
+
* This is not left to inspection: the "still reports startup breadcrumbs on stderr"
|
|
58
|
+
* case in test/unit/common/logging.test.ts only passes if `consoleLevel: info` from
|
|
59
|
+
* `initLogging()` reached a logger that was constructed before it ran. Core's default
|
|
60
|
+
* is `warn`, which would suppress those lines.
|
|
61
|
+
*/
|
|
62
|
+
export function getLogger(name) {
|
|
63
|
+
return new Logger(name);
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=logging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.js","sourceRoot":"","sources":["../../src/common/logging.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,IAAI,UAAU,GAAG,KAAK,CAAC;AAEvB;;;;;;GAMG;AACH,MAAM,UAAU,WAAW;IACvB,IAAI,UAAU,EAAE,CAAC;QACb,OAAO;IACX,CAAC;IACD,UAAU,GAAG,IAAI,CAAC;IAElB,gBAAgB,CAAC;QACb,+EAA+E;QAC/E,+EAA+E;QAC/E,+EAA+E;QAC/E,kEAAkE;QAClE,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,MAAM;QACzD,2EAA2E;QAC3E,gFAAgF;KACnF,CAAC,CAAC;AACP,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IAClC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/common/progress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAC;AACxF,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/common/progress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAC;AACxF,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAM5F,MAAM,MAAM,SAAS,GAAG,mBAAmB,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;AAE/E,iFAAiF;AACjF,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAEzD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,gBAAgB,GAAG,SAAS,CA8B3F"}
|
package/dist/common/progress.js
CHANGED
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
* left undefined. Inventing a percentage from a message count would be a lie that
|
|
17
17
|
* gets less accurate the longer an operation runs.
|
|
18
18
|
*/
|
|
19
|
+
import { getLogger } from "./logging.js";
|
|
20
|
+
const log = getLogger("progress");
|
|
19
21
|
/**
|
|
20
22
|
* Returns an `onProgress` callback to hand to core, or `undefined` when the client
|
|
21
23
|
* did not request progress.
|
|
@@ -48,9 +50,9 @@ export function progressReporter(extra) {
|
|
|
48
50
|
message,
|
|
49
51
|
},
|
|
50
52
|
}).catch((error) => {
|
|
51
|
-
|
|
52
|
-
//
|
|
53
|
-
|
|
53
|
+
// stderr, never stdout: stdout is the JSON-RPC transport. Via the logger
|
|
54
|
+
// so the error is redacted rather than stringified into the message.
|
|
55
|
+
log.debug("Failed to send progress notification", { error });
|
|
54
56
|
});
|
|
55
57
|
};
|
|
56
58
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/common/progress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/common/progress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,GAAG,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;AAOlC;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA4B;IACzD,MAAM,KAAK,GAAG,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC;IAC1C,2EAA2E;IAC3E,oEAAoE;IACpE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QACvC,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,4EAA4E;IAC5E,uEAAuE;IACvE,uBAAuB;IACvB,MAAM,IAAI,GAAG,KAAK,CAAC;IACnB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,OAAO,CAAC,OAAe,EAAE,EAAE;QACvB,IAAI,IAAI,CAAC,CAAC;QACV,4EAA4E;QAC5E,yEAAyE;QACzE,KAAK,IAAI,CAAC,gBAAgB,CAAC;YACvB,MAAM,EAAE,wBAAwB;YAChC,MAAM,EAAE;gBACJ,aAAa,EAAE,KAAK;gBACpB,QAAQ,EAAE,IAAI;gBACd,OAAO;aACV;SACJ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACxB,yEAAyE;YACzE,qEAAqE;YACrE,GAAG,CAAC,KAAK,CAAC,sCAAsC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -31,7 +31,9 @@ export declare function resolveToolPackage(selection: string | undefined): Resol
|
|
|
31
31
|
* Reports the resolution on stderr.
|
|
32
32
|
*
|
|
33
33
|
* stderr, never stdout — stdout is the JSON-RPC transport, and a stray byte
|
|
34
|
-
* there breaks the client's parser.
|
|
34
|
+
* there breaks the client's parser. Goes through the logger so it obeys
|
|
35
|
+
* NEX_LOG_LEVEL and reaches the log file when one is configured; these are the
|
|
36
|
+
* breadcrumbs that explain why a client sees the tools it sees.
|
|
35
37
|
*/
|
|
36
38
|
export declare function reportResolution(resolved: ResolvedPackage): void;
|
|
37
39
|
//# sourceMappingURL=tool-packages.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-packages.d.ts","sourceRoot":"","sources":["../../src/common/tool-packages.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"tool-packages.d.ts","sourceRoot":"","sources":["../../src/common/tool-packages.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgBH,MAAM,WAAW,eAAe;IAC5B,gDAAgD;IAChD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,mEAAmE;IACnE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,+CAA+C;IAC/C,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,+DAA+D;IAC/D,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,sFAAsF;IACtF,QAAQ,EAAE,OAAO,CAAC;CACrB;AAgBD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,eAAe,CAuEjF;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAuBhE"}
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
import { TOOL_PACKAGES, DEFAULT_PACKAGE } from "../config/tool-packages.js";
|
|
10
10
|
import { TOOL_ANNOTATIONS } from "./annotations.js";
|
|
11
11
|
import { allToolNames } from "../tools/registry.js";
|
|
12
|
+
import { getLogger } from "./logging.js";
|
|
13
|
+
const log = getLogger("tool-packages");
|
|
12
14
|
/** Sentinel in a package's `tools` meaning "everything". */
|
|
13
15
|
const ALL = "*";
|
|
14
16
|
/** Sentinel meaning "every tool annotated readOnlyHint: true". */
|
|
@@ -108,21 +110,23 @@ export function resolveToolPackage(selection) {
|
|
|
108
110
|
* Reports the resolution on stderr.
|
|
109
111
|
*
|
|
110
112
|
* stderr, never stdout — stdout is the JSON-RPC transport, and a stray byte
|
|
111
|
-
* there breaks the client's parser.
|
|
113
|
+
* there breaks the client's parser. Goes through the logger so it obeys
|
|
114
|
+
* NEX_LOG_LEVEL and reaches the log file when one is configured; these are the
|
|
115
|
+
* breadcrumbs that explain why a client sees the tools it sees.
|
|
112
116
|
*/
|
|
113
117
|
export function reportResolution(resolved) {
|
|
114
118
|
const { names, tools, unknownPackages, unknownTools, fellBack } = resolved;
|
|
115
119
|
if (unknownPackages.length > 0) {
|
|
116
120
|
const available = Object.keys(TOOL_PACKAGES).sort().join(", ");
|
|
117
|
-
|
|
121
|
+
log.warn(`Unknown tool package(s): ${unknownPackages.join(", ")}. ` +
|
|
118
122
|
`Available: ${available}.` +
|
|
119
123
|
(fellBack ? ` Falling back to "${DEFAULT_PACKAGE}".` : ""));
|
|
120
124
|
}
|
|
121
125
|
if (unknownTools.length > 0) {
|
|
122
|
-
|
|
126
|
+
log.warn(`${unknownTools.length} tool(s) named by a package do not exist ` +
|
|
123
127
|
`on this server and were skipped: ${unknownTools.join(", ")}. ` +
|
|
124
128
|
`This is expected for tools from work that has not landed yet.`);
|
|
125
129
|
}
|
|
126
|
-
|
|
130
|
+
log.info(`Active tool package(s): ${names.join(", ")} — ${tools.length} of ${allToolNames().length} tools registered`);
|
|
127
131
|
}
|
|
128
132
|
//# sourceMappingURL=tool-packages.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-packages.js","sourceRoot":"","sources":["../../src/common/tool-packages.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"tool-packages.js","sourceRoot":"","sources":["../../src/common/tool-packages.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
// anything can read credentials. An MCP server is always launched as a
|
|
4
4
|
// non-interactive child process, where the keyring cannot be unlocked.
|
|
5
5
|
import "./common/credstore-boot.js";
|
|
6
|
+
// Second, and before anything constructs a core manager: core's loggers are field
|
|
7
|
+
// initializers, and until NEX-3 merely constructing one created ./logs/ in whatever
|
|
8
|
+
// directory the client happened to launch this server from.
|
|
9
|
+
import { flushLogs } from "@sonisoft/now-sdk-ext-core";
|
|
10
|
+
import { initLogging, getLogger } from "./common/logging.js";
|
|
11
|
+
initLogging();
|
|
6
12
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
13
|
import { registerServiceNowResources } from "./resources/servicenow.js";
|
|
8
14
|
import { TOOL_REGISTRY } from "./tools/registry.js";
|
|
@@ -10,6 +16,7 @@ import { registerListToolPackagesTool } from "./tools/tool-packages.js";
|
|
|
10
16
|
import { resolveToolPackage, reportResolution } from "./common/tool-packages.js";
|
|
11
17
|
import { readServerVersion } from "./common/version.js";
|
|
12
18
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
19
|
+
const log = getLogger("mcp");
|
|
13
20
|
const server = new McpServer({
|
|
14
21
|
name: "now-sdk-ext-mcp",
|
|
15
22
|
version: readServerVersion(),
|
|
@@ -40,20 +47,74 @@ for (const name of activePackage.tools) {
|
|
|
40
47
|
registerListToolPackagesTool(server, activePackage);
|
|
41
48
|
// Prevent the process from crashing silently on unexpected errors.
|
|
42
49
|
// Log to stderr (stdout is reserved for JSON-RPC).
|
|
50
|
+
// Through the logger, not console.error: an uncaught error here can be an auth or
|
|
51
|
+
// HTTP failure carrying a live session, and only the logger redacts.
|
|
43
52
|
process.on("uncaughtException", (error) => {
|
|
44
|
-
|
|
53
|
+
log.error("Uncaught exception", { error });
|
|
45
54
|
});
|
|
46
55
|
process.on("unhandledRejection", (reason) => {
|
|
47
|
-
|
|
56
|
+
log.error("Unhandled rejection", { reason });
|
|
48
57
|
});
|
|
58
|
+
/** Longest a shutdown will wait on the logger before giving up on it. */
|
|
59
|
+
const FLUSH_TIMEOUT_MS = 2000;
|
|
60
|
+
/**
|
|
61
|
+
* Flushes buffered log records, then exits — but never lets the flush prevent the exit.
|
|
62
|
+
*
|
|
63
|
+
* Awaiting `flushLogs()` unguarded would make termination depend on that promise
|
|
64
|
+
* settling. Stuck I/O would then turn a graceful SIGTERM into a process that has to be
|
|
65
|
+
* SIGKILLed, which is strictly worse than the lost log lines this exists to save.
|
|
66
|
+
* `unref` so a pending timer cannot itself hold the process open.
|
|
67
|
+
*
|
|
68
|
+
* The rejection is swallowed on purpose: `void p.finally(cb)` re-throws after running
|
|
69
|
+
* the callback, so a failing flush would surface as an unhandled rejection during
|
|
70
|
+
* shutdown. Exiting regardless is the intent, so say so rather than rely on
|
|
71
|
+
* `process.exit` winning the race against the rejection being reported.
|
|
72
|
+
*/
|
|
73
|
+
async function flushAndExit(code) {
|
|
74
|
+
let timer;
|
|
75
|
+
try {
|
|
76
|
+
await Promise.race([
|
|
77
|
+
flushLogs(),
|
|
78
|
+
new Promise((resolve) => {
|
|
79
|
+
timer = setTimeout(resolve, FLUSH_TIMEOUT_MS);
|
|
80
|
+
timer.unref?.();
|
|
81
|
+
}),
|
|
82
|
+
]);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Nothing useful to do while shutting down; the exit below still happens.
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
// Tidy even though process.exit follows: leaving it dangling would be one more
|
|
89
|
+
// thing to reason about if this ever grows a path that does not exit.
|
|
90
|
+
if (timer)
|
|
91
|
+
clearTimeout(timer);
|
|
92
|
+
}
|
|
93
|
+
process.exit(code);
|
|
94
|
+
}
|
|
95
|
+
// A client stops this server by signalling it, which is the ORDINARY way it exits —
|
|
96
|
+
// not an error path. Winston's file transport buffers, so without a flush here the
|
|
97
|
+
// last records before shutdown are lost whenever NEX_LOG_FILE is on, which is exactly
|
|
98
|
+
// when someone is reading the file to find out what happened.
|
|
99
|
+
//
|
|
100
|
+
// `once`, so a second signal from an impatient client still terminates immediately
|
|
101
|
+
// rather than queueing another flush.
|
|
102
|
+
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
103
|
+
process.once(signal, () => {
|
|
104
|
+
void flushAndExit(0);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
49
107
|
// Start the server on stdio transport
|
|
50
108
|
async function main() {
|
|
51
109
|
const transport = new StdioServerTransport();
|
|
52
110
|
await server.connect(transport);
|
|
53
|
-
|
|
111
|
+
log.info("now-sdk-ext-mcp server running on stdio");
|
|
54
112
|
}
|
|
55
113
|
main().catch((error) => {
|
|
56
|
-
|
|
57
|
-
|
|
114
|
+
log.error("Fatal error starting server", { error });
|
|
115
|
+
// Flush before exiting: winston buffers, and this is the line that explains why
|
|
116
|
+
// the server is not there. Same timeout guard — a stuck flush must not leave a
|
|
117
|
+
// failed startup hanging instead of exiting non-zero.
|
|
118
|
+
void flushAndExit(1);
|
|
58
119
|
});
|
|
59
120
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,iFAAiF;AACjF,uEAAuE;AACvE,uEAAuE;AACvE,OAAO,4BAA4B,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sonisoft/now-sdk-ext-mcp",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.0",
|
|
4
4
|
"description": "MCP server for interacting with ServiceNow instances via @sonisoft/now-sdk-ext-core",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"servicenow",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"@servicenow/sdk-cli": "4.9.2",
|
|
48
48
|
"@servicenow/sdk-cli-core": "3.0.3",
|
|
49
49
|
"@servicenow/sdk-core": "4.9.2",
|
|
50
|
-
"@sonisoft/now-sdk-ext-core": "^
|
|
50
|
+
"@sonisoft/now-sdk-ext-core": "^6.0.0",
|
|
51
51
|
"@sonisoft/sn-credstore": "^1.0.0",
|
|
52
52
|
"zod": "^3.23.8"
|
|
53
53
|
},
|