@cite42/mcp 0.3.0 → 0.4.0

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
@@ -6,7 +6,7 @@ Once connected, Claude Code, Claude Desktop, Codex CLI, or Cursor can:
6
6
 
7
7
  - **Query AI models** (ChatGPT, Claude, Perplexity, Gemini, Google AI Overviews) and see each model's answer and the sources it cites
8
8
  - **Track brand visibility** in AI answers: rankings, head-to-head comparisons, and sentiment
9
- - **Schedule daily or weekly trackers**: one measurement — rankings, comparisons, citations, or sentiment — over a list of prompts, with email when something changes, then ask your agent for stored run history
9
+ - **Schedule weekly or monthly trackers**: one measurement — rankings, comparisons, citations, or sentiment — over a list of prompts, with email when something changes, then ask your agent for stored run history
10
10
  - **Pull SEO data**: keyword search volume, CPC, competition, and Google Trends
11
11
  - **Mine Reddit and YouTube** for audience questions, pain points, and rising content
12
12
  - **Run full research workflows**: content gaps, topic demand, AI prompt maps, competitor analysis, and content briefs in a single call
@@ -128,7 +128,7 @@ That is the three default surfaces; ask for `fullSweep` to add Claude and Google
128
128
 
129
129
  ## Tools
130
130
 
131
- Cite42 exposes 26 MCP tools: 3 free account tools, 9 primitive data tools, 6 research workflows, and 8 tracker tools.
131
+ Cite42 exposes 26 MCP tools: 3 free account tools, 9 data tools, 6 research workflows, and 8 tracker tools.
132
132
 
133
133
  ### Account & pricing (free)
134
134
 
@@ -162,12 +162,12 @@ Cite42 exposes 26 MCP tools: 3 free account tools, 9 primitive data tools, 6 res
162
162
 
163
163
  ### Trackers
164
164
 
165
- - `cite42_tracker_create`: create a draft daily or weekly tracker — one measurement applied to a list of prompts. No prompt list yet? Run `cite42_map_ai_prompts` first. Creating a draft is free and does not schedule calls.
165
+ - `cite42_tracker_create`: create a draft weekly or monthly tracker — one measurement applied to a list of prompts. No prompt list yet? Run `cite42_map_ai_prompts` first. Creating a draft is free and does not schedule calls.
166
166
  - `cite42_tracker_update`: replace the whole tracker definition — name, cadence, measurement, prompts and configuration. A tracker read returns the same shape, so read it, change what you need, and send it back. Updating is free.
167
167
  - `cite42_tracker_activate`: activate or resume recurring runs. You must pass the exact `estimatedCostMicroPerRun` from the latest tracker record as `maxCostMicroPerRun`; activation authorizes billed scheduled runs until the tracker is paused. The response carries the balance, the cost per run and `runsDryAt` — the date the balance stops covering your active trackers — and activation is refused when the balance cannot cover even the next run.
168
168
  - `cite42_tracker_pause`: stop future scheduled runs while preserving configuration and history. Pausing is free.
169
169
  - `cite42_tracker_delete`: permanently delete a draft or paused tracker and its run history. Active trackers must be paused first, and deletion is rejected while a run is queued or running. Financial usage records remain available.
170
- - `cite42_tracker_run`: queue one manual run of every saved prompt. Each prompt is billed as its own primitive call at the normal rate.
170
+ - `cite42_tracker_run`: queue one manual run of every saved prompt. Each prompt is billed as its own tool call at the normal rate.
171
171
  - `cite42_trackers`: list trackers, schedules, statuses, cost estimates, and last/next run times. Reading the list is free.
172
172
  - `cite42_tracker_report`: read bounded stored run history with results, changes, status, sampled time, and costs (latest 8 by default, up to 20). Reading stored reports is free.
173
173
 
@@ -184,7 +184,7 @@ npx -y @cite42/mcp --api-key=cite42_live_your_key_here --api-base=https://www.ci
184
184
 
185
185
  ## Billing
186
186
 
187
- Primitive and workflow calls consume Cite42 credits from your account. Tracker management and stored-history reads are free; every scheduled or manual tracker run bills one call per saved prompt at the normal rate. Activating or resuming a tracker requires explicit confirmation of the current maximum credits per run and authorizes recurring billed calls until you pause it. Calls fail with a clear error if the API key is missing or credits run out. See [www.cite42.dev/pricing](https://www.cite42.dev/pricing).
187
+ Tool and workflow calls consume Cite42 credits from your account. Tracker management and stored-history reads are free; every scheduled or manual tracker run bills one call per saved prompt at the normal rate. Activating or resuming a tracker requires explicit confirmation of the current maximum credits per run and authorizes recurring billed calls until you pause it. Calls fail with a clear error if the API key is missing or credits run out. See [www.cite42.dev/pricing](https://www.cite42.dev/pricing).
188
188
 
189
189
  ## Troubleshooting
190
190
 
package/dist/stdio.cjs CHANGED
@@ -17,10 +17,14 @@ function formatCredits(microCredits) {
17
17
  Number.isInteger(credits) ? { maximumFractionDigits: 0 } : { minimumFractionDigits: 0, maximumFractionDigits: 2 }
18
18
  );
19
19
  }
20
+ function isTrackerCommitment(billing) {
21
+ return typeof billing.balanceMicro === "number" && typeof billing.costMicroPerRun === "number";
22
+ }
20
23
  function toCite42McpResult(value) {
21
24
  if (!isJsonObject(value)) return value;
22
25
  const { billing, warning, ...result } = value;
23
26
  if (!isJsonObject(billing)) return value;
27
+ if (isTrackerCommitment(billing)) return { ...result, billing };
24
28
  const cost = isJsonObject(billing.cost) ? billing.cost.microCredits : void 0;
25
29
  const balance = isJsonObject(billing.balance) ? billing.balance.microCredits : void 0;
26
30
  if (typeof cost !== "number" || !Number.isFinite(cost) || typeof balance !== "number" || !Number.isFinite(balance)) {
@@ -148,7 +152,7 @@ var FULL_SWEEP_DESCRIPTION = "Query all five AI surfaces instead of the three de
148
152
  var MCP_USAGE_GUIDANCE = "Covers AI-search, citation, SEO, keyword, trend, and market-research data. If a plan needs more than 20 endpoint calls or may use more than 500 Cite42 credits, estimate the credits and ask the user before continuing. When a result contains cite42Credits, that figure is Cite42 credits, not a model or host balance. Free (0 credits): cite42_credits for the remaining balance, cite42_pricing for exact per-tool prices and cost estimates, cite42_usage for recent calls.";
149
153
  var MODEL_PRICING = "Pricing is per selected AI surface. Omitting models queries the three default surfaces (chatgpt, perplexity, gemini); fullSweep: true queries all five, adding claude and google_ai_overview for more credits. Use the models field when the user names a surface or asks to reduce credit use, and call cite42_pricing for exact current rates.";
150
154
  var DATA_PRICING = "Data tools have flat per-call prices; call cite42_pricing for exact current rates.";
151
- var WORKFLOW_PRICING = "Pricing: workflow cost is calculated from the primitive endpoints that run successfully and the selected model rates.";
155
+ var WORKFLOW_PRICING = "Pricing: workflow cost is calculated from the tools that run successfully and the selected model rates.";
152
156
  function workflowDescription(description) {
153
157
  return `${description} ${MCP_USAGE_GUIDANCE} ${MODEL_PRICING} ${DATA_PRICING} ${WORKFLOW_PRICING}`;
154
158
  }
@@ -235,7 +239,7 @@ var aivSearch = (0, import_tools.createTool)({
235
239
  var aivCitations = (0, import_tools.createTool)({
236
240
  id: "cite42_citations",
237
241
  mcp: readOnly("Find AI citations"),
238
- description: `Find which sources AI models cite for a query. Aggregates cited URLs across models with per-model counts; optionally checks whether a specific URL is cited. ${MODEL_PRICING} ${MCP_USAGE_GUIDANCE}`,
242
+ description: `Find which sources a model's web search surfaces for a query. Aggregates cited URLs across models with per-model counts; optionally checks whether a specific URL is cited. Measures the retrieval corpus behind a prompt \u2014 which domains own your category in AI search, and where your content is missing \u2014 not the citation links a consumer chat UI renders for a logged-in user. ${MODEL_PRICING} ${MCP_USAGE_GUIDANCE}`,
239
243
  inputSchema: import_zod.z.object({
240
244
  query: queryText("The concise query to look up cited sources for."),
241
245
  url: import_zod.z.string().trim().max(500).optional().describe("Optional URL to check whether it was cited."),
@@ -420,7 +424,7 @@ var aivGenerateContentBrief = (0, import_tools.createTool)({
420
424
  });
421
425
  var trackerIdInput = import_zod.z.string().trim().min(1).max(128).describe("Cite42 tracker ID returned by a tracker management or report tool.");
422
426
  var trackerCadenceInput = import_zod.z.object({
423
- frequency: import_zod.z.enum(["daily", "weekly"]),
427
+ frequency: import_zod.z.enum(["weekly", "monthly"]),
424
428
  timezone: import_zod.z.string().trim().min(1).max(100).refine((timezone) => {
425
429
  try {
426
430
  new Intl.DateTimeFormat("en-US", { timeZone: timezone }).format();
@@ -430,7 +434,10 @@ var trackerCadenceInput = import_zod.z.object({
430
434
  }
431
435
  }, "Timezone must be a valid IANA timezone.").describe("IANA timezone, for example Europe/London or America/New_York."),
432
436
  time: import_zod.z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/).describe("Local run time in 24-hour HH:mm format."),
433
- weekday: import_zod.z.number().int().min(0).max(6).optional().describe("Weekly day, where 0 is Sunday and 6 is Saturday.")
437
+ weekday: import_zod.z.number().int().min(0).max(6).optional().describe("Weekly trackers only. Day of week, where 0 is Sunday and 6 is Saturday."),
438
+ monthday: import_zod.z.number().int().min(1).max(31).optional().describe(
439
+ `Monthly trackers only. Day of month 1-31; a value past the end of a shorter month runs on that month's last day, so 31 always means "month end".`
440
+ )
434
441
  }).superRefine((cadence, context) => {
435
442
  if (cadence.frequency === "weekly" && cadence.weekday === void 0) {
436
443
  context.addIssue({
@@ -439,12 +446,19 @@ var trackerCadenceInput = import_zod.z.object({
439
446
  message: "weekday is required for a weekly tracker"
440
447
  });
441
448
  }
449
+ if (cadence.frequency === "monthly" && cadence.monthday === void 0) {
450
+ context.addIssue({
451
+ code: "custom",
452
+ path: ["monthday"],
453
+ message: "monthday is required for a monthly tracker"
454
+ });
455
+ }
442
456
  });
443
457
  var trackerPrimitiveInput = import_zod.z.enum(["rankings", "compare", "citations", "sentiment"]).describe(
444
458
  "What to measure on every prompt: rankings (which brands get named), compare (the brand against named competitors), citations (which sources are cited), or sentiment (how one brand is described). One measurement per tracker."
445
459
  );
446
460
  var trackerPromptsInput = import_zod.z.array(queryText("A prompt to run on every scheduled run.")).min(1).max(25).describe(
447
- "Prompts to track, up to 25. Each is billed as its own call on every run. Keep the wording stable so runs stay comparable, avoid dates, and do not repeat a prompt."
461
+ "Prompts to track, up to 30. Each is billed as its own call on every run. Keep the wording stable so runs stay comparable, avoid dates, and do not repeat a prompt."
448
462
  );
449
463
  var trackerDefinitionFields = {
450
464
  name: import_zod.z.string().trim().min(1).max(100).describe("Human-readable tracker name."),
@@ -464,7 +478,7 @@ var TRACKER_BILLING_DESCRIPTION = "Tracker management and stored-report reads ar
464
478
  var aivTrackerCreate = (0, import_tools.createTool)({
465
479
  id: "cite42_tracker_create",
466
480
  mcp: mutation("Create Cite42 tracker draft"),
467
- description: "Create a draft daily or weekly tracker: one measurement \u2014 rankings, compare, citations, or sentiment \u2014 applied to a list of prompts, with the brand, competitors and AI surfaces set once for all of them. When the user has no prompt list yet, run cite42_map_ai_prompts first and track the prompts it recommends. Creation does not start recurring calls. " + TRACKER_BILLING_DESCRIPTION,
481
+ description: "Create a draft weekly or monthly tracker: one measurement \u2014 rankings, compare, citations, or sentiment \u2014 applied to a list of prompts, with the brand, competitors and AI surfaces set once for all of them. When the user has no prompt list yet, run cite42_map_ai_prompts first and track the prompts it recommends. Creation does not start recurring calls. " + TRACKER_BILLING_DESCRIPTION,
468
482
  inputSchema: import_zod.z.object(trackerDefinitionFields),
469
483
  execute: async (input) => aivPost("/trackers", input)
470
484
  });
@@ -481,7 +495,7 @@ var aivTrackerActivate = (0, import_tools.createTool)({
481
495
  openWorldHint: true,
482
496
  idempotentHint: true
483
497
  }),
484
- description: `Activate or resume recurring daily or weekly primitive calls. maxCostMicroPerRun must equal the tracker estimate being accepted; activation authorizes future billed calls until the tracker is paused. The response carries a billing block with the balance, the cost per run, and runsDryAt \u2014 the date the balance stops covering the account's active trackers \u2014 so relay it. Activation is refused when the balance cannot cover even the next run; tell the user to top up at cite42.dev/app/billing. ${TRACKER_BILLING_DESCRIPTION}`,
498
+ description: `Activate or resume recurring weekly or monthly tool calls. maxCostMicroPerRun must equal the tracker estimate being accepted; activation authorizes future billed calls until the tracker is paused. The response carries a billing block with the balance, the cost per run, and runsDryAt \u2014 the date the balance stops covering the account's active trackers \u2014 so relay it. Activation is refused when the balance cannot cover even the next run; tell the user to top up at cite42.dev/app/billing. ${TRACKER_BILLING_DESCRIPTION}`,
485
499
  inputSchema: import_zod.z.object({
486
500
  trackerId: trackerIdInput,
487
501
  maxCostMicroPerRun: import_zod.z.number().int().nonnegative().describe("Exact estimatedCostMicroPerRun returned by the latest tracker record.")
@@ -511,7 +525,7 @@ var aivTrackerRun = (0, import_tools.createTool)({
511
525
  openWorldHint: true,
512
526
  idempotentHint: true
513
527
  }),
514
- description: `Queue one manual run using the tracker\u2019s saved primitive inputs. A repeated requestToken returns the same logical run. ${TRACKER_BILLING_DESCRIPTION}`,
528
+ description: `Queue one manual run using the tracker\u2019s saved tool inputs. A repeated requestToken returns the same logical run. ${TRACKER_BILLING_DESCRIPTION}`,
515
529
  inputSchema: import_zod.z.object({
516
530
  trackerId: trackerIdInput,
517
531
  requestToken: import_zod.z.string().trim().min(1).max(200).describe("Stable caller-generated token used to deduplicate a retried manual run.")
@@ -521,14 +535,14 @@ var aivTrackerRun = (0, import_tools.createTool)({
521
535
  var aivTrackers = (0, import_tools.createTool)({
522
536
  id: "cite42_trackers",
523
537
  mcp: readOnly("List Cite42 trackers", false),
524
- description: "List the connected account\u2019s trackers with status, cadence, primitive configuration, cost estimate, accepted per-run maximum, and next/last run times. Free: costs 0 credits.",
538
+ description: "List the connected account\u2019s trackers with status, cadence, tool configuration, cost estimate, accepted per-run maximum, and next/last run times. Free: costs 0 credits.",
525
539
  inputSchema: import_zod.z.object({}),
526
540
  execute: async () => aivGet("/trackers")
527
541
  });
528
542
  var aivTrackerReport = (0, import_tools.createTool)({
529
543
  id: "cite42_tracker_report",
530
544
  mcp: readOnly("Read Cite42 tracker report", false),
531
- description: "Read bounded stored run history for one tracker, including per-primitive results, changes from the prior comparable observation, statuses, sampled times, and costs. Free: costs 0 credits.",
545
+ description: "Read bounded stored run history for one tracker, including per-tool results, changes from the prior comparable observation, statuses, sampled times, and costs. Free: costs 0 credits.",
532
546
  inputSchema: import_zod.z.object({
533
547
  trackerId: trackerIdInput,
534
548
  limit: import_zod.z.number().int().min(1).max(20).optional().default(8).describe("Most recent runs to return, capped for LLM context.")
@@ -582,7 +596,7 @@ if (!resolveApiKey()) {
582
596
  );
583
597
  process.exit(1);
584
598
  }
585
- buildCite42Server("0.3.0").startStdio().catch((error) => {
599
+ buildCite42Server("0.4.0").startStdio().catch((error) => {
586
600
  console.error("[@cite42/mcp] Fatal error:", error);
587
601
  process.exit(1);
588
602
  });
package/dist/stdio.mjs CHANGED
@@ -16,10 +16,14 @@ function formatCredits(microCredits) {
16
16
  Number.isInteger(credits) ? { maximumFractionDigits: 0 } : { minimumFractionDigits: 0, maximumFractionDigits: 2 }
17
17
  );
18
18
  }
19
+ function isTrackerCommitment(billing) {
20
+ return typeof billing.balanceMicro === "number" && typeof billing.costMicroPerRun === "number";
21
+ }
19
22
  function toCite42McpResult(value) {
20
23
  if (!isJsonObject(value)) return value;
21
24
  const { billing, warning, ...result } = value;
22
25
  if (!isJsonObject(billing)) return value;
26
+ if (isTrackerCommitment(billing)) return { ...result, billing };
23
27
  const cost = isJsonObject(billing.cost) ? billing.cost.microCredits : void 0;
24
28
  const balance = isJsonObject(billing.balance) ? billing.balance.microCredits : void 0;
25
29
  if (typeof cost !== "number" || !Number.isFinite(cost) || typeof balance !== "number" || !Number.isFinite(balance)) {
@@ -147,7 +151,7 @@ var FULL_SWEEP_DESCRIPTION = "Query all five AI surfaces instead of the three de
147
151
  var MCP_USAGE_GUIDANCE = "Covers AI-search, citation, SEO, keyword, trend, and market-research data. If a plan needs more than 20 endpoint calls or may use more than 500 Cite42 credits, estimate the credits and ask the user before continuing. When a result contains cite42Credits, that figure is Cite42 credits, not a model or host balance. Free (0 credits): cite42_credits for the remaining balance, cite42_pricing for exact per-tool prices and cost estimates, cite42_usage for recent calls.";
148
152
  var MODEL_PRICING = "Pricing is per selected AI surface. Omitting models queries the three default surfaces (chatgpt, perplexity, gemini); fullSweep: true queries all five, adding claude and google_ai_overview for more credits. Use the models field when the user names a surface or asks to reduce credit use, and call cite42_pricing for exact current rates.";
149
153
  var DATA_PRICING = "Data tools have flat per-call prices; call cite42_pricing for exact current rates.";
150
- var WORKFLOW_PRICING = "Pricing: workflow cost is calculated from the primitive endpoints that run successfully and the selected model rates.";
154
+ var WORKFLOW_PRICING = "Pricing: workflow cost is calculated from the tools that run successfully and the selected model rates.";
151
155
  function workflowDescription(description) {
152
156
  return `${description} ${MCP_USAGE_GUIDANCE} ${MODEL_PRICING} ${DATA_PRICING} ${WORKFLOW_PRICING}`;
153
157
  }
@@ -234,7 +238,7 @@ var aivSearch = createTool({
234
238
  var aivCitations = createTool({
235
239
  id: "cite42_citations",
236
240
  mcp: readOnly("Find AI citations"),
237
- description: `Find which sources AI models cite for a query. Aggregates cited URLs across models with per-model counts; optionally checks whether a specific URL is cited. ${MODEL_PRICING} ${MCP_USAGE_GUIDANCE}`,
241
+ description: `Find which sources a model's web search surfaces for a query. Aggregates cited URLs across models with per-model counts; optionally checks whether a specific URL is cited. Measures the retrieval corpus behind a prompt \u2014 which domains own your category in AI search, and where your content is missing \u2014 not the citation links a consumer chat UI renders for a logged-in user. ${MODEL_PRICING} ${MCP_USAGE_GUIDANCE}`,
238
242
  inputSchema: z.object({
239
243
  query: queryText("The concise query to look up cited sources for."),
240
244
  url: z.string().trim().max(500).optional().describe("Optional URL to check whether it was cited."),
@@ -419,7 +423,7 @@ var aivGenerateContentBrief = createTool({
419
423
  });
420
424
  var trackerIdInput = z.string().trim().min(1).max(128).describe("Cite42 tracker ID returned by a tracker management or report tool.");
421
425
  var trackerCadenceInput = z.object({
422
- frequency: z.enum(["daily", "weekly"]),
426
+ frequency: z.enum(["weekly", "monthly"]),
423
427
  timezone: z.string().trim().min(1).max(100).refine((timezone) => {
424
428
  try {
425
429
  new Intl.DateTimeFormat("en-US", { timeZone: timezone }).format();
@@ -429,7 +433,10 @@ var trackerCadenceInput = z.object({
429
433
  }
430
434
  }, "Timezone must be a valid IANA timezone.").describe("IANA timezone, for example Europe/London or America/New_York."),
431
435
  time: z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/).describe("Local run time in 24-hour HH:mm format."),
432
- weekday: z.number().int().min(0).max(6).optional().describe("Weekly day, where 0 is Sunday and 6 is Saturday.")
436
+ weekday: z.number().int().min(0).max(6).optional().describe("Weekly trackers only. Day of week, where 0 is Sunday and 6 is Saturday."),
437
+ monthday: z.number().int().min(1).max(31).optional().describe(
438
+ `Monthly trackers only. Day of month 1-31; a value past the end of a shorter month runs on that month's last day, so 31 always means "month end".`
439
+ )
433
440
  }).superRefine((cadence, context) => {
434
441
  if (cadence.frequency === "weekly" && cadence.weekday === void 0) {
435
442
  context.addIssue({
@@ -438,12 +445,19 @@ var trackerCadenceInput = z.object({
438
445
  message: "weekday is required for a weekly tracker"
439
446
  });
440
447
  }
448
+ if (cadence.frequency === "monthly" && cadence.monthday === void 0) {
449
+ context.addIssue({
450
+ code: "custom",
451
+ path: ["monthday"],
452
+ message: "monthday is required for a monthly tracker"
453
+ });
454
+ }
441
455
  });
442
456
  var trackerPrimitiveInput = z.enum(["rankings", "compare", "citations", "sentiment"]).describe(
443
457
  "What to measure on every prompt: rankings (which brands get named), compare (the brand against named competitors), citations (which sources are cited), or sentiment (how one brand is described). One measurement per tracker."
444
458
  );
445
459
  var trackerPromptsInput = z.array(queryText("A prompt to run on every scheduled run.")).min(1).max(25).describe(
446
- "Prompts to track, up to 25. Each is billed as its own call on every run. Keep the wording stable so runs stay comparable, avoid dates, and do not repeat a prompt."
460
+ "Prompts to track, up to 30. Each is billed as its own call on every run. Keep the wording stable so runs stay comparable, avoid dates, and do not repeat a prompt."
447
461
  );
448
462
  var trackerDefinitionFields = {
449
463
  name: z.string().trim().min(1).max(100).describe("Human-readable tracker name."),
@@ -463,7 +477,7 @@ var TRACKER_BILLING_DESCRIPTION = "Tracker management and stored-report reads ar
463
477
  var aivTrackerCreate = createTool({
464
478
  id: "cite42_tracker_create",
465
479
  mcp: mutation("Create Cite42 tracker draft"),
466
- description: "Create a draft daily or weekly tracker: one measurement \u2014 rankings, compare, citations, or sentiment \u2014 applied to a list of prompts, with the brand, competitors and AI surfaces set once for all of them. When the user has no prompt list yet, run cite42_map_ai_prompts first and track the prompts it recommends. Creation does not start recurring calls. " + TRACKER_BILLING_DESCRIPTION,
480
+ description: "Create a draft weekly or monthly tracker: one measurement \u2014 rankings, compare, citations, or sentiment \u2014 applied to a list of prompts, with the brand, competitors and AI surfaces set once for all of them. When the user has no prompt list yet, run cite42_map_ai_prompts first and track the prompts it recommends. Creation does not start recurring calls. " + TRACKER_BILLING_DESCRIPTION,
467
481
  inputSchema: z.object(trackerDefinitionFields),
468
482
  execute: async (input) => aivPost("/trackers", input)
469
483
  });
@@ -480,7 +494,7 @@ var aivTrackerActivate = createTool({
480
494
  openWorldHint: true,
481
495
  idempotentHint: true
482
496
  }),
483
- description: `Activate or resume recurring daily or weekly primitive calls. maxCostMicroPerRun must equal the tracker estimate being accepted; activation authorizes future billed calls until the tracker is paused. The response carries a billing block with the balance, the cost per run, and runsDryAt \u2014 the date the balance stops covering the account's active trackers \u2014 so relay it. Activation is refused when the balance cannot cover even the next run; tell the user to top up at cite42.dev/app/billing. ${TRACKER_BILLING_DESCRIPTION}`,
497
+ description: `Activate or resume recurring weekly or monthly tool calls. maxCostMicroPerRun must equal the tracker estimate being accepted; activation authorizes future billed calls until the tracker is paused. The response carries a billing block with the balance, the cost per run, and runsDryAt \u2014 the date the balance stops covering the account's active trackers \u2014 so relay it. Activation is refused when the balance cannot cover even the next run; tell the user to top up at cite42.dev/app/billing. ${TRACKER_BILLING_DESCRIPTION}`,
484
498
  inputSchema: z.object({
485
499
  trackerId: trackerIdInput,
486
500
  maxCostMicroPerRun: z.number().int().nonnegative().describe("Exact estimatedCostMicroPerRun returned by the latest tracker record.")
@@ -510,7 +524,7 @@ var aivTrackerRun = createTool({
510
524
  openWorldHint: true,
511
525
  idempotentHint: true
512
526
  }),
513
- description: `Queue one manual run using the tracker\u2019s saved primitive inputs. A repeated requestToken returns the same logical run. ${TRACKER_BILLING_DESCRIPTION}`,
527
+ description: `Queue one manual run using the tracker\u2019s saved tool inputs. A repeated requestToken returns the same logical run. ${TRACKER_BILLING_DESCRIPTION}`,
514
528
  inputSchema: z.object({
515
529
  trackerId: trackerIdInput,
516
530
  requestToken: z.string().trim().min(1).max(200).describe("Stable caller-generated token used to deduplicate a retried manual run.")
@@ -520,14 +534,14 @@ var aivTrackerRun = createTool({
520
534
  var aivTrackers = createTool({
521
535
  id: "cite42_trackers",
522
536
  mcp: readOnly("List Cite42 trackers", false),
523
- description: "List the connected account\u2019s trackers with status, cadence, primitive configuration, cost estimate, accepted per-run maximum, and next/last run times. Free: costs 0 credits.",
537
+ description: "List the connected account\u2019s trackers with status, cadence, tool configuration, cost estimate, accepted per-run maximum, and next/last run times. Free: costs 0 credits.",
524
538
  inputSchema: z.object({}),
525
539
  execute: async () => aivGet("/trackers")
526
540
  });
527
541
  var aivTrackerReport = createTool({
528
542
  id: "cite42_tracker_report",
529
543
  mcp: readOnly("Read Cite42 tracker report", false),
530
- description: "Read bounded stored run history for one tracker, including per-primitive results, changes from the prior comparable observation, statuses, sampled times, and costs. Free: costs 0 credits.",
544
+ description: "Read bounded stored run history for one tracker, including per-tool results, changes from the prior comparable observation, statuses, sampled times, and costs. Free: costs 0 credits.",
531
545
  inputSchema: z.object({
532
546
  trackerId: trackerIdInput,
533
547
  limit: z.number().int().min(1).max(20).optional().default(8).describe("Most recent runs to return, capped for LLM context.")
@@ -581,7 +595,7 @@ if (!resolveApiKey()) {
581
595
  );
582
596
  process.exit(1);
583
597
  }
584
- buildCite42Server("0.3.0").startStdio().catch((error) => {
598
+ buildCite42Server("0.4.0").startStdio().catch((error) => {
585
599
  console.error("[@cite42/mcp] Fatal error:", error);
586
600
  process.exit(1);
587
601
  });
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@cite42/mcp",
3
3
  "mcpName": "dev.cite42/mcp",
4
- "version": "0.3.0",
5
- "description": "Cite42 MCP server: query ChatGPT, Claude, Perplexity, Gemini & Google AI Overviews for brand rankings, AI citations, SEO keyword data, and Reddit/YouTube trends, and schedule daily or weekly trackers that watch a list of prompts over time. Works with Claude Code, Claude Desktop, Codex CLI, Cursor, and any MCP client.",
4
+ "version": "0.4.0",
5
+ "description": "Cite42 MCP server: query the models behind ChatGPT, Claude, Perplexity & Gemini, plus Google AI Overviews, for brand rankings, AI citations, SEO keyword data, and Reddit/YouTube trends, and schedule weekly or monthly trackers that watch a list of prompts over time. Works with Claude Code, Claude Desktop, Codex CLI, Cursor, and any MCP client.",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "bin": {