uniqueness-mcp 0.7.3 → 0.8.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/README.md CHANGED
@@ -36,9 +36,10 @@ Requires Node 18+. After changing the pin, start a new client session so the too
36
36
 
37
37
  Hosted and stdio both expose:
38
38
 
39
- - `get_personal_context` (`get_connection_brief`)
39
+ - `get_personal_context` (`get_connection_brief`) — optional `refresh:true` to force a fresh collection. Omit for ordinary repeat reads. Batch tools do not accept refresh.
40
40
  - `resume_personal_context` (`resume_connection_brief`)
41
41
  - `get_billing_status`
42
+ - `request_higher_limits`
42
43
  - `preflight_personal_contexts` (`preflight_connection_briefs`)
43
44
  - `get_connection_brief_job`
44
45
  - `batch_connection_briefs`
@@ -55,4 +56,28 @@ Stdio also exposes `begin_programmatic_signup` and `complete_programmatic_signup
55
56
 
56
57
  MCP has no purchase, payment-method, auto-recharge, or subscription tools. On `402 payment_required`, present checkout URLs only after explicit human consent.
57
58
 
59
+ ## Usage limits
60
+
61
+ Exact current limits are shown on the account page, in `GET /api/account` (`usage_limits`), in `uniqueness account` and in the MCP `get_billing_status` tool.
62
+
63
+ **Public ladder**
64
+ - free: 25 personal contexts per 24h, max batch 25
65
+ - tier_1: 250 personal contexts per 24h, max batch 50
66
+ - tier_2: 1,000 personal contexts per 24h, max batch 100
67
+ - tier_3: 5,000 personal contexts per 24h, max batch 100
68
+ - unlimited: by request, max batch 100
69
+
70
+ **Automatic promotion:**
71
+ - Any real credit pack, subscription or auto-recharge → tier_1.
72
+ - 250 lifetime paid credits → tier_2.
73
+ - 1,000 → tier_3.
74
+ - Intro offers and 5-packs don't count.
75
+ - Limits only go up, never down.
76
+ - Accounts with custom limits we've set don't change automatically.
77
+
78
+ **Window:** 24 hours starting from your first counted personal context. It's not midnight and not rolling. Cache re-serves don't count.
79
+
80
+ How to request more: the account page button, `POST /api/account/usage-limits/request`, `uniqueness limits request`, or the MCP `request_higher_limits` tool.
81
+ A 429 `usage_cap_exceeded` means a pace limit, not credits; honor `Retry-After`.
82
+
58
83
  [MCP quickstart](https://uniquenessengine.com/documentation/mcp/quickstart) · support@uniquenessengine.com
package/dist/server.js CHANGED
@@ -2,7 +2,7 @@ import { randomUUID } from "node:crypto";
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import { z } from "zod";
4
4
  export const MCP_SERVER_NAME = "uniqueness";
5
- export const MCP_SERVER_VERSION = "0.7.3";
5
+ export const MCP_SERVER_VERSION = "0.8.1";
6
6
  export const MCP_TOOL_ALIASES = {
7
7
  get_personal_context: ["get_connection_brief"],
8
8
  resume_personal_context: ["resume_connection_brief"],
@@ -14,6 +14,7 @@ const CORE_TOOL_NAMES = [
14
14
  "resume_personal_context",
15
15
  "resume_connection_brief",
16
16
  "get_billing_status",
17
+ "request_higher_limits",
17
18
  "preflight_personal_contexts",
18
19
  "preflight_connection_briefs",
19
20
  "get_connection_brief_job",
@@ -107,12 +108,18 @@ const briefShape = {
107
108
  company: z.string().optional().describe("Company name (use with name)"),
108
109
  email: z.string().optional().describe("Work email (optional disambiguator)"),
109
110
  detail: detailSchema.describe('Response shape. Defaults to "compact"; use "full" for provenance sub-scores.'),
111
+ refresh: z
112
+ .boolean()
113
+ .optional()
114
+ .describe("Set true only when the user asks to rerun, refresh, run again, look again, re-enrich, or check whether new UE changes are working. Ordinary repeat reads must omit this. Do not resubmit while polling an existing job."),
110
115
  };
111
116
  function cleanBriefArgs(args) {
112
117
  const body = {};
113
118
  for (const key of ["linkedin_url", "name", "company", "email", "detail"])
114
119
  if (args[key])
115
120
  body[key] = args[key];
121
+ if (typeof args.refresh === "boolean")
122
+ body.refresh = args.refresh;
116
123
  if (!body.detail)
117
124
  body.detail = "compact";
118
125
  return body;
@@ -284,7 +291,12 @@ export function createMcpServer(context) {
284
291
  });
285
292
  };
286
293
  const registerBrief = (name, description) => server.registerTool(name, { description, inputSchema: briefShape }, async (args) => submitBrief(args));
287
- registerBrief("get_personal_context", "Submit one full-quality written enrichment. Returns an inline result or a job_id for get_connection_brief_job.");
294
+ registerBrief("get_personal_context", "Submit one full-quality written enrichment. Returns an inline result or a job_id for get_connection_brief_job. " +
295
+ "Use refresh=true only when the user says rerun, refresh, run again, look again, re-enrich, or asks whether new UE changes are working. " +
296
+ "Do not use refresh for ordinary repeat reads. Do not resubmit while polling an existing job. " +
297
+ "A normal repeat lookup is not proof that a fresh enrichment occurred. " +
298
+ "Only claim a rerun happened when there is a new job, usage.refresh_executed=true, or a new generated timestamp/source inventory. " +
299
+ "cache_status=hit means this request served an existing result; cache_status=miss means this request ran collection.");
288
300
  registerBrief(MCP_TOOL_ALIASES.get_personal_context[0], "Deprecated alias for get_personal_context.");
289
301
  const resumeShape = {
290
302
  ...briefShape,
@@ -310,10 +322,10 @@ export function createMcpServer(context) {
310
322
  });
311
323
  return submitBrief(args, args.idempotency_key);
312
324
  });
313
- registerResume("resume_personal_context", "Verify increased spendable credit, then replay the original request with its idempotency key.");
325
+ registerResume("resume_personal_context", "Verify increased spendable credit, then replay the original request with its idempotency key. Pass the same refresh value as the 402 request — a refresh 402 resumed without refresh:true is a 409.");
314
326
  registerResume(MCP_TOOL_ALIASES.resume_personal_context[0], "Deprecated alias for resume_personal_context.");
315
327
  server.registerTool("get_billing_status", {
316
- description: "Read spendable balance and auto-recharge state.",
328
+ description: "Read spendable balance, usage limits (tier, daily limit, used in window, max batch) and auto-recharge state.",
317
329
  inputSchema: {},
318
330
  annotations: { readOnlyHint: true },
319
331
  }, async () => {
@@ -330,6 +342,20 @@ export function createMcpServer(context) {
330
342
  : { error: recharge.body.error || "unavailable" },
331
343
  }, balance.status !== 200);
332
344
  });
345
+ server.registerTool("request_higher_limits", {
346
+ description: "Request an increase to your daily account usage limits.",
347
+ inputSchema: {
348
+ reason: z.string().max(1000).optional(),
349
+ desired_daily_limit: z.number().int().min(1).max(100000).optional(),
350
+ },
351
+ }, async (args) => {
352
+ if (!requireKey())
353
+ return authenticationRequired();
354
+ const response = await api("/api/account/usage-limits/request", {
355
+ body: args,
356
+ });
357
+ return json(response.body, response.status >= 400);
358
+ });
333
359
  const registerPreflight = (name, description) => server.registerTool(name, {
334
360
  description,
335
361
  inputSchema: { profiles: z.array(profileSchema).min(1).max(100) },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uniqueness-mcp",
3
- "version": "0.7.3",
3
+ "version": "0.8.1",
4
4
  "description": "Local stdio fallback for the hosted Uniqueness Engine MCP server.",
5
5
  "type": "module",
6
6
  "bin": {