@phi-longevity/mcp-server 0.6.4 → 0.6.5
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/index.js +48 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -103,6 +103,23 @@ function attributionWithAid(aid) {
|
|
|
103
103
|
get_full_report_url: `https://philongevity.com/signup?utm_source=agent&utm_medium=mcp&utm_campaign=analyze_biomarkers&aid=${aid}`,
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
|
+
// AC-3 (2026-08-14): fast, LOCAL, zero-round-trip biomarker range flags — the "easiest first call".
|
|
107
|
+
const _norm = (s) => String(s).toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
108
|
+
const _ALIASES = { hemoglobina1c: "hba1c", a1c: "hba1c", ldl: "ldlc",
|
|
109
|
+
ldlcholesterol: "ldlc", hdl: "hdlc", hdlcholesterol: "hdlc", crp: "hscrp", hscrp: "hscrp",
|
|
110
|
+
testosterone: "totaltestosterone", vitd: "vitamind", vitamind3: "vitamind", "25ohvitamind": "vitamind" };
|
|
111
|
+
const CATALOG_INDEX = new Map(BIOMARKER_CATALOG.map((b) => [_norm(b.name), b]));
|
|
112
|
+
function catalogLookup(name) {
|
|
113
|
+
const n = _norm(name);
|
|
114
|
+
return CATALOG_INDEX.get(n) || CATALOG_INDEX.get(_ALIASES[n] || "") || null;
|
|
115
|
+
}
|
|
116
|
+
function flagValue(b, value) {
|
|
117
|
+
if (typeof b.refLow === "number" && value < b.refLow)
|
|
118
|
+
return "below longevity-optimized range";
|
|
119
|
+
if (typeof b.refHigh === "number" && value > b.refHigh)
|
|
120
|
+
return "above longevity-optimized range";
|
|
121
|
+
return "within longevity-optimized range";
|
|
122
|
+
}
|
|
106
123
|
async function callEngine(body) {
|
|
107
124
|
if (!MCP_KEY) {
|
|
108
125
|
throw new Error("Server not configured: set PHI_MCP_KEY (your @phi-longevity access key).");
|
|
@@ -199,10 +216,40 @@ server.tool("get_methodology", "Summarize how the Phi Score works (5 clinical pi
|
|
|
199
216
|
source: "Phi Longevity (philongevity.com)",
|
|
200
217
|
}, null, 2));
|
|
201
218
|
});
|
|
219
|
+
// ── Tool 4: quick_check (fast local range flags — the "easiest first call") ────────────────────
|
|
220
|
+
server.tool("quick_check", "FASTEST first call: instantly flag a few biomarker values against PRISM's longevity-optimized " +
|
|
221
|
+
"reference ranges (local, no engine round-trip). Ideal for \"what does my <value> mean?\". For tiered, " +
|
|
222
|
+
"guideline-cited recommendations call analyze_biomarkers; for a full scored report, full_prism_report. " +
|
|
223
|
+
SYNTHETIC_WARNING, {
|
|
224
|
+
biomarkers: z
|
|
225
|
+
.record(z.string(), z.number())
|
|
226
|
+
.describe('Map of biomarker name -> value, e.g. { "HbA1c": 6.1, "LDL-C": 145 }. SYNTHETIC ONLY.'),
|
|
227
|
+
}, async (args) => {
|
|
228
|
+
const t0 = Date.now();
|
|
229
|
+
const aid = newAid();
|
|
230
|
+
const flags = [];
|
|
231
|
+
const unmatched = [];
|
|
232
|
+
for (const [name, value] of Object.entries(args.biomarkers || {})) {
|
|
233
|
+
const b = catalogLookup(name);
|
|
234
|
+
if (!b) {
|
|
235
|
+
unmatched.push(name);
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
flags.push({ name: b.name, value, unit: b.unit, pillar: b.pillar, status: flagValue(b, value) });
|
|
239
|
+
}
|
|
240
|
+
telemetry({ tool: "quick_check", n: Object.keys(args.biomarkers || {}).length, matched: flags.length, aid, elapsed_ms: Date.now() - t0 });
|
|
241
|
+
return textResult(JSON.stringify({
|
|
242
|
+
flags,
|
|
243
|
+
unmatched: unmatched.length ? unmatched : undefined,
|
|
244
|
+
note: "Quick range flags vs PRISM's longevity-optimized ranges — NOT a diagnosis or the full Phi analysis. " +
|
|
245
|
+
"For tiered guideline-cited recommendations call analyze_biomarkers; for a scored report call full_prism_report.",
|
|
246
|
+
full_report: attributionWithAid(aid),
|
|
247
|
+
}, null, 2));
|
|
248
|
+
});
|
|
202
249
|
async function main() {
|
|
203
250
|
const transport = new StdioServerTransport();
|
|
204
251
|
await server.connect(transport);
|
|
205
|
-
telemetry({ event: "phi-mcp-server started", tools:
|
|
252
|
+
telemetry({ event: "phi-mcp-server started", tools: 4 });
|
|
206
253
|
}
|
|
207
254
|
main().catch((e) => {
|
|
208
255
|
telemetry({ event: "fatal", error: e.message });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phi-longevity/mcp-server",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.5",
|
|
4
4
|
"description": "Model Context Protocol server for Phi Longevity \u2014 agents can call the PRISM longevity recommendation engine on SYNTHETIC biomarker panels. Synthetic/de-identified data only; no PHI; stateless.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|