@phi-longevity/mcp-server 0.6.4 → 0.6.6

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 +49 -2
  2. package/package.json +11 -4
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).");
@@ -120,7 +137,7 @@ async function callEngine(body) {
120
137
  }
121
138
  return res.json();
122
139
  }
123
- const server = new McpServer({ name: "phi-longevity", version: "0.6.3" }, {
140
+ const server = new McpServer({ name: "phi-longevity", version: "0.6.6" }, {
124
141
  instructions: "Phi Longevity PRISM — longevity-optimized analysis of biomarker panels. " + SYNTHETIC_WARNING,
125
142
  });
126
143
  // ── Tool 1: analyze_biomarkers (the core) ─────────────────────────────────────────────────────
@@ -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: 3 });
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,7 +1,7 @@
1
1
  {
2
2
  "name": "@phi-longevity/mcp-server",
3
- "version": "0.6.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.",
3
+ "version": "0.6.6",
4
+ "description": "MCP server for Phi Longevity PRISM: analyze a biomarker panel with an MD-led, guideline-cited clinical engine — built for agents helping people manage chronic conditions like diabetes, cancer survivorship, lupus, and thyroid disease. Synthetic/de-identified data only; no PHI; stateless.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "bin": {
@@ -34,7 +34,14 @@
34
34
  "longevity",
35
35
  "health",
36
36
  "biomarkers",
37
- "phi-longevity"
37
+ "phi-longevity",
38
+ "diabetes",
39
+ "cancer-survivorship",
40
+ "lupus",
41
+ "thyroid",
42
+ "chronic-disease",
43
+ "x402",
44
+ "prism"
38
45
  ],
39
46
  "mcpName": "io.github.Philongevity/phi-longevity-prism",
40
47
  "repository": {
@@ -42,4 +49,4 @@
42
49
  "url": "git+https://github.com/Philongevity/phi-mcp-server.git"
43
50
  },
44
51
  "homepage": "https://philongevity.com/for-agents"
45
- }
52
+ }