@tpsdev-ai/flair-mcp 0.50.0 → 0.51.1
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 +5 -4
- package/dist/usage.d.ts +7 -18
- package/dist/usage.js +7 -18
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -45,7 +45,7 @@ import { FlairClient, FlairError, formatKeyLookup, inspectKeyLookup } from "@tps
|
|
|
45
45
|
import { z } from "zod";
|
|
46
46
|
import { deriveActivity, postPresenceSafe, resolveHeartbeatIntervalMs, resolvePresenceTimeoutMs, shouldSendHeartbeat, } from "./presence.js";
|
|
47
47
|
import { readEnvOrUnset, stripInterpolationLiteralsFromEnv } from "./env-guard.js";
|
|
48
|
-
import { buildRecordUsageBody, citationIds, withCiteNudge } from "./usage.js";
|
|
48
|
+
import { buildRecordUsageBody, citationIds, withCiteNudge, RECORD_USAGE_ID_MERGE_CONTRACT } from "./usage.js";
|
|
49
49
|
import { serverInfo } from "./version.js";
|
|
50
50
|
// ─── Error helpers ──────────────────────────────────────────────────────────
|
|
51
51
|
export function classifyError(err, flairUrl) {
|
|
@@ -521,9 +521,10 @@ export async function runMcp() {
|
|
|
521
521
|
// the usageCount loop. Identity is taken from the signed request — the body
|
|
522
522
|
// carries only memory id(s) + optional attribution, never agentId.
|
|
523
523
|
server.tool("record_usage", "Report that one or more memories were actually USED — cited or relied on to ground an answer or decision. " +
|
|
524
|
-
"Distinct from search (surfacing a memory is not usage). Dedup'd (you can only count once per memory) and rate-limited."
|
|
525
|
-
|
|
526
|
-
|
|
524
|
+
"Distinct from search (surfacing a memory is not usage). Dedup'd (you can only count once per memory) and rate-limited. " +
|
|
525
|
+
RECORD_USAGE_ID_MERGE_CONTRACT, {
|
|
526
|
+
memoryId: z.string().optional().describe("A single memory id that was used. Merged with memoryIds when both are supplied — not dropped."),
|
|
527
|
+
memoryIds: z.array(z.string()).optional().describe("IDs of the memories that were used (max 20 per call). Merged with memoryId when both are supplied."),
|
|
527
528
|
attribution: z.string().optional().describe("Optional one-line note on how it was used (opaque — stored for audit only)"),
|
|
528
529
|
}, async ({ memoryId, memoryIds, attribution }) => {
|
|
529
530
|
heartbeat(); // auto-presence (flair#598) — fire-and-forget, rate-limited
|
package/dist/usage.d.ts
CHANGED
|
@@ -13,30 +13,19 @@
|
|
|
13
13
|
/** One-line instruction on recalled ids (issue ask #3). Search/bootstrap hits are not usage. */
|
|
14
14
|
export declare const CITE_USAGE_NUDGE = "Cite memories you actually use via record_usage (or memory_store.usedMemoryIds). A search or bootstrap hit is not usage.";
|
|
15
15
|
export declare function withCiteNudge(text: string): string;
|
|
16
|
+
/** Stated on the stdio `record_usage` schema so a caller can predict the merge without reading source. */
|
|
17
|
+
export declare const RECORD_USAGE_ID_MERGE_CONTRACT = "When both memoryId and memoryIds are supplied they are merged (union, then deduped) \u2014 a caller who passes both means both.";
|
|
16
18
|
/**
|
|
17
19
|
* Build the POST /RecordUsage body from the MCP tool args.
|
|
18
20
|
* Accepts singular `memoryId` and/or `memoryIds`. Returns null when there is
|
|
19
21
|
* nothing to send (the tool should fail locally rather than POST an empty list).
|
|
20
22
|
* Never includes agentId — the server attributes from the signature.
|
|
21
23
|
*
|
|
22
|
-
* MERGE
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* `
|
|
26
|
-
*
|
|
27
|
-
* not union. If `memoryIds` is present (even `[]`, which is truthy),
|
|
28
|
-
* `memoryId` is never read.
|
|
29
|
-
*
|
|
30
|
-
* The stdio merge is load-bearing because it flattens first: we send only
|
|
31
|
-
* a single `memoryIds` array, so the server's prefer is never exercised
|
|
32
|
-
* on two fields. A future path that POSTs both fields through to
|
|
33
|
-
* `/RecordUsage` without flattening would silently drop `memoryId`
|
|
34
|
-
* (delivered-but-uncounted; empty `memoryIds: []` alongside a real
|
|
35
|
-
* `memoryId` would 400 rather than fall through).
|
|
36
|
-
*
|
|
37
|
-
* Native prefer is a pre-existing delivered-but-uncounted bug on a
|
|
38
|
-
* different surface, tracked in flair#1410 — not a regression from this
|
|
39
|
-
* PR, and not a blocker for #1147. Do not "align" this helper to prefer.
|
|
24
|
+
* MERGE (flair#1410): this helper unions `memoryId` + `memoryIds`, then
|
|
25
|
+
* dedupes. Native `/mcp` and `POST /RecordUsage` do the same — a caller
|
|
26
|
+
* who passes both means both. Do not "align" this helper to prefer
|
|
27
|
+
* `memoryIds` and drop `memoryId`; that is the delivered-but-uncounted
|
|
28
|
+
* bug #1410 closed.
|
|
40
29
|
*/
|
|
41
30
|
export declare function buildRecordUsageBody(args: {
|
|
42
31
|
memoryId?: string;
|
package/dist/usage.js
CHANGED
|
@@ -17,30 +17,19 @@ export function withCiteNudge(text) {
|
|
|
17
17
|
return text;
|
|
18
18
|
return `${text}\n\n${CITE_USAGE_NUDGE}`;
|
|
19
19
|
}
|
|
20
|
+
/** Stated on the stdio `record_usage` schema so a caller can predict the merge without reading source. */
|
|
21
|
+
export const RECORD_USAGE_ID_MERGE_CONTRACT = "When both memoryId and memoryIds are supplied they are merged (union, then deduped) — a caller who passes both means both.";
|
|
20
22
|
/**
|
|
21
23
|
* Build the POST /RecordUsage body from the MCP tool args.
|
|
22
24
|
* Accepts singular `memoryId` and/or `memoryIds`. Returns null when there is
|
|
23
25
|
* nothing to send (the tool should fail locally rather than POST an empty list).
|
|
24
26
|
* Never includes agentId — the server attributes from the signature.
|
|
25
27
|
*
|
|
26
|
-
* MERGE
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* `
|
|
30
|
-
*
|
|
31
|
-
* not union. If `memoryIds` is present (even `[]`, which is truthy),
|
|
32
|
-
* `memoryId` is never read.
|
|
33
|
-
*
|
|
34
|
-
* The stdio merge is load-bearing because it flattens first: we send only
|
|
35
|
-
* a single `memoryIds` array, so the server's prefer is never exercised
|
|
36
|
-
* on two fields. A future path that POSTs both fields through to
|
|
37
|
-
* `/RecordUsage` without flattening would silently drop `memoryId`
|
|
38
|
-
* (delivered-but-uncounted; empty `memoryIds: []` alongside a real
|
|
39
|
-
* `memoryId` would 400 rather than fall through).
|
|
40
|
-
*
|
|
41
|
-
* Native prefer is a pre-existing delivered-but-uncounted bug on a
|
|
42
|
-
* different surface, tracked in flair#1410 — not a regression from this
|
|
43
|
-
* PR, and not a blocker for #1147. Do not "align" this helper to prefer.
|
|
28
|
+
* MERGE (flair#1410): this helper unions `memoryId` + `memoryIds`, then
|
|
29
|
+
* dedupes. Native `/mcp` and `POST /RecordUsage` do the same — a caller
|
|
30
|
+
* who passes both means both. Do not "align" this helper to prefer
|
|
31
|
+
* `memoryIds` and drop `memoryId`; that is the delivered-but-uncounted
|
|
32
|
+
* bug #1410 closed.
|
|
44
33
|
*/
|
|
45
34
|
export function buildRecordUsageBody(args) {
|
|
46
35
|
const ids = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tpsdev-ai/flair-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.51.1",
|
|
4
4
|
"description": "MCP server for Flair — persistent memory for Claude Code, Cursor, and any MCP client.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@modelcontextprotocol/sdk": "1.27.1",
|
|
31
|
-
"@tpsdev-ai/flair-client": "0.
|
|
31
|
+
"@tpsdev-ai/flair-client": "0.51.1",
|
|
32
32
|
"zod": "4.3.6"
|
|
33
33
|
},
|
|
34
34
|
"license": "Apache-2.0",
|