simplepractice-mcp 1.1.2 → 1.1.3
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/bundle.js +63 -9
- package/dist/version.js +1 -1
- package/package.json +3 -3
- package/server.json +2 -2
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "SimplePractice Client Portal tools for Claude",
|
|
9
|
-
"version": "1.1.
|
|
9
|
+
"version": "1.1.3"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "simplepractice",
|
|
14
14
|
"source": "./",
|
|
15
15
|
"description": "Read a SimplePractice Client Portal — appointments, invoices and superbills, documents to sign, and practice announcements. Signs in with the portal's own passwordless emailed link; requests go straight to the portal's JSON:API over your own session.",
|
|
16
|
-
"version": "1.1.
|
|
16
|
+
"version": "1.1.3",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "Chris Chall",
|
|
19
19
|
"url": "https://github.com/chrischall"
|
package/dist/bundle.js
CHANGED
|
@@ -34362,13 +34362,28 @@ var API_KEY_RE = new RegExp([
|
|
|
34362
34362
|
"whsec_[A-Za-z0-9]{16,}\\b"
|
|
34363
34363
|
// webhook signing secret (Stripe-style)
|
|
34364
34364
|
].map((p) => `\\b${p}`).join("|"), "g");
|
|
34365
|
-
var QUERY_SECRET_RE = /([?&](?:
|
|
34365
|
+
var QUERY_SECRET_RE = /([?&](?:(?:access|refresh|id|auth|session|csrf|xsrf)[_-]?token|client[_-]?secret|api[_-]?secret|api[_-]?key|password|passwd|signature|token|key|sig)=)[^&#\s"'<>`]+/gi;
|
|
34366
|
+
var OAUTH_CODE_RE = /([?&]code=)(?=[^&#\s"'<>`]{16,})[^&#\s"'<>`]+/gi;
|
|
34367
|
+
var FORM_PASSWORD_RE = /((?:^|[\s,;:"'(\[{])(?:password|passwd)=)[^&#\s"'<>`]+/gim;
|
|
34368
|
+
var HEADER_SECRET_RE = /(\b(?:x[-_][a-z0-9_-]*?(?:api[-_]?key|token|secret|auth)[a-z0-9_-]*|api[-_]?key)\s*:\s*)[^\s,;"'<>`]+/gi;
|
|
34366
34369
|
var AWS_SIGV4_RE = /([?&]X-Amz-(?:Signature|Security-Token|Credential)=)[^&#\s"'<>`]+/gi;
|
|
34367
|
-
var JSON_SECRET_KEYS =
|
|
34368
|
-
|
|
34369
|
-
|
|
34370
|
+
var JSON_SECRET_KEYS = [
|
|
34371
|
+
"(?:access|refresh|id|auth|session|bearer|csrf|xsrf)[_-]?token",
|
|
34372
|
+
"client[_-]?secret",
|
|
34373
|
+
"api[_-]?secret",
|
|
34374
|
+
"(?:x[_-])?api[_-]?key",
|
|
34375
|
+
"private[_-]?key",
|
|
34376
|
+
"x[_-][a-z0-9_-]*?(?:api[_-]?key|token|secret|auth)[a-z0-9_-]*",
|
|
34377
|
+
"(?:proxy-)?authorization",
|
|
34378
|
+
"password",
|
|
34379
|
+
"passwd",
|
|
34380
|
+
"secret",
|
|
34381
|
+
"token"
|
|
34382
|
+
].join("|");
|
|
34383
|
+
var JSON_SECRET_DQ_RE = new RegExp(`("(?:${JSON_SECRET_KEYS})"\\s*:\\s*")(?:[^"\\\\]|\\\\.)*(")`, "gi");
|
|
34384
|
+
var JSON_SECRET_SQ_RE = new RegExp(`('(?:${JSON_SECRET_KEYS})'\\s*:\\s*')(?:[^'\\\\]|\\\\.)*(')`, "gi");
|
|
34370
34385
|
function redactSecrets(text) {
|
|
34371
|
-
return text.replace(BEARER_RE, "$1[REDACTED]").replace(BASIC_AUTH_RE, "$1[REDACTED]").replace(SET_COOKIE_RE, "$1$2=[REDACTED]").replace(COOKIE_HEADER_RE, (_m, prefix, pairs) => `${prefix}${pairs.replace(/=[^;,\s]*/g, "=[REDACTED]")}`).replace(API_KEY_RE, "[REDACTED]").replace(QUERY_SECRET_RE, "$1[REDACTED]").replace(AWS_SIGV4_RE, "$1[REDACTED]").replace(JSON_SECRET_DQ_RE, "$1[REDACTED]$2").replace(JSON_SECRET_SQ_RE, "$1[REDACTED]$2").replace(JWT_RE, "[REDACTED]");
|
|
34386
|
+
return text.replace(BEARER_RE, "$1[REDACTED]").replace(BASIC_AUTH_RE, "$1[REDACTED]").replace(SET_COOKIE_RE, "$1$2=[REDACTED]").replace(COOKIE_HEADER_RE, (_m, prefix, pairs) => `${prefix}${pairs.replace(/=[^;,\s]*/g, "=[REDACTED]")}`).replace(API_KEY_RE, "[REDACTED]").replace(HEADER_SECRET_RE, "$1[REDACTED]").replace(QUERY_SECRET_RE, "$1[REDACTED]").replace(OAUTH_CODE_RE, "$1[REDACTED]").replace(FORM_PASSWORD_RE, "$1[REDACTED]").replace(AWS_SIGV4_RE, "$1[REDACTED]").replace(JSON_SECRET_DQ_RE, "$1[REDACTED]$2").replace(JSON_SECRET_SQ_RE, "$1[REDACTED]$2").replace(JWT_RE, "[REDACTED]");
|
|
34372
34387
|
}
|
|
34373
34388
|
function truncateErrorMessage(text, max = DEFAULT_ERROR_MESSAGE_MAX) {
|
|
34374
34389
|
const str = text === null || text === void 0 ? "" : String(text);
|
|
@@ -34560,13 +34575,47 @@ async function createMcpServer(opts) {
|
|
|
34560
34575
|
}
|
|
34561
34576
|
return server;
|
|
34562
34577
|
}
|
|
34578
|
+
var DEFAULT_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
34579
|
+
var DEFAULT_REPEAT_SIGNAL_GRACE_MS = 500;
|
|
34563
34580
|
function withGracefulShutdown(target, opts = {}) {
|
|
34564
34581
|
const shouldExit = opts.exit ?? true;
|
|
34582
|
+
if (opts.timeoutMs !== void 0 && !(Number.isFinite(opts.timeoutMs) && opts.timeoutMs > 0)) {
|
|
34583
|
+
throw new RangeError("withGracefulShutdown: timeoutMs must be a finite number greater than 0.");
|
|
34584
|
+
}
|
|
34585
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS;
|
|
34586
|
+
if (opts.repeatSignalGraceMs !== void 0 && !(Number.isFinite(opts.repeatSignalGraceMs) && opts.repeatSignalGraceMs >= 0)) {
|
|
34587
|
+
throw new RangeError("withGracefulShutdown: repeatSignalGraceMs must be a finite number >= 0.");
|
|
34588
|
+
}
|
|
34589
|
+
const repeatGraceMs = opts.repeatSignalGraceMs ?? DEFAULT_REPEAT_SIGNAL_GRACE_MS;
|
|
34565
34590
|
let shuttingDown = false;
|
|
34591
|
+
let firstSignalAt = 0;
|
|
34592
|
+
let exited = false;
|
|
34593
|
+
const exitOnce = () => {
|
|
34594
|
+
if (exited)
|
|
34595
|
+
return;
|
|
34596
|
+
exited = true;
|
|
34597
|
+
process.exit(0);
|
|
34598
|
+
};
|
|
34566
34599
|
const handler = (signal) => {
|
|
34567
|
-
if (shuttingDown)
|
|
34600
|
+
if (shuttingDown) {
|
|
34601
|
+
if (Date.now() - firstSignalAt < repeatGraceMs)
|
|
34602
|
+
return;
|
|
34603
|
+
if (shouldExit) {
|
|
34604
|
+
console.error(`[mcp-utils] second ${signal} during shutdown \u2014 exiting now`);
|
|
34605
|
+
exitOnce();
|
|
34606
|
+
}
|
|
34568
34607
|
return;
|
|
34608
|
+
}
|
|
34569
34609
|
shuttingDown = true;
|
|
34610
|
+
firstSignalAt = Date.now();
|
|
34611
|
+
let timer;
|
|
34612
|
+
if (shouldExit) {
|
|
34613
|
+
timer = setTimeout(() => {
|
|
34614
|
+
console.error(`[mcp-utils] graceful shutdown on ${signal} did not finish in ${timeoutMs}ms \u2014 exiting`);
|
|
34615
|
+
exitOnce();
|
|
34616
|
+
}, timeoutMs);
|
|
34617
|
+
timer.unref?.();
|
|
34618
|
+
}
|
|
34570
34619
|
void (async () => {
|
|
34571
34620
|
try {
|
|
34572
34621
|
if (opts.onSignal)
|
|
@@ -34575,8 +34624,10 @@ function withGracefulShutdown(target, opts = {}) {
|
|
|
34575
34624
|
} catch (err) {
|
|
34576
34625
|
console.error(`[mcp-utils] error during graceful shutdown on ${signal}: ${err instanceof Error ? err.message : String(err)}`);
|
|
34577
34626
|
} finally {
|
|
34627
|
+
if (timer !== void 0)
|
|
34628
|
+
clearTimeout(timer);
|
|
34578
34629
|
if (shouldExit)
|
|
34579
|
-
|
|
34630
|
+
exitOnce();
|
|
34580
34631
|
}
|
|
34581
34632
|
})();
|
|
34582
34633
|
};
|
|
@@ -34718,9 +34769,12 @@ var pageSchema = {
|
|
|
34718
34769
|
page_size: external_exports.number().int().min(1).max(200).default(50).describe("Number of items per page (1-200).")
|
|
34719
34770
|
};
|
|
34720
34771
|
function toolAnnotations(opts = {}) {
|
|
34772
|
+
if (opts.readOnly === true && opts.destructive === true) {
|
|
34773
|
+
throw new Error("toolAnnotations: readOnly: true contradicts destructive: true \u2014 a destructive tool is not read-only.");
|
|
34774
|
+
}
|
|
34721
34775
|
return {
|
|
34722
34776
|
...opts.title !== void 0 ? { title: opts.title } : {},
|
|
34723
|
-
readOnlyHint: opts.readOnly ??
|
|
34777
|
+
readOnlyHint: opts.readOnly ?? opts.destructive === void 0,
|
|
34724
34778
|
...opts.idempotent !== void 0 ? { idempotentHint: opts.idempotent } : {},
|
|
34725
34779
|
...opts.destructive !== void 0 ? { destructiveHint: opts.destructive } : {},
|
|
34726
34780
|
...opts.openWorld !== void 0 ? { openWorldHint: opts.openWorld } : {}
|
|
@@ -34728,7 +34782,7 @@ function toolAnnotations(opts = {}) {
|
|
|
34728
34782
|
}
|
|
34729
34783
|
|
|
34730
34784
|
// src/version.ts
|
|
34731
|
-
var VERSION = "1.1.
|
|
34785
|
+
var VERSION = "1.1.3";
|
|
34732
34786
|
|
|
34733
34787
|
// node_modules/@chrischall/mcp-utils/dist/session/index.js
|
|
34734
34788
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, chmodSync, renameSync, unlinkSync } from "node:fs";
|
package/dist/version.js
CHANGED
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* Single source of truth for the server version. release-please rewrites the
|
|
3
3
|
* literal below; every other file imports VERSION rather than repeating it.
|
|
4
4
|
*/
|
|
5
|
-
export const VERSION = '1.1.
|
|
5
|
+
export const VERSION = '1.1.3'; // x-release-please-version
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "simplepractice-mcp",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"mcpName": "io.github.chrischall/simplepractice-mcp",
|
|
6
6
|
"description": "SimplePractice Client Portal MCP server for Claude — developed and maintained by AI (Claude Code)",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"test:watch": "vitest"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@chrischall/mcp-utils": "^2.
|
|
37
|
+
"@chrischall/mcp-utils": "^2.4.0",
|
|
38
38
|
"@modelcontextprotocol/server": "^2.0.0",
|
|
39
39
|
"dotenv": "^18.0.0",
|
|
40
|
-
"zod": "^4.6.
|
|
40
|
+
"zod": "^4.6.5"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@modelcontextprotocol/client": "^2.0.0",
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/chrischall/simplepractice-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "1.1.
|
|
9
|
+
"version": "1.1.3",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "simplepractice-mcp",
|
|
14
|
-
"version": "1.1.
|
|
14
|
+
"version": "1.1.3",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|