llmconveyors-mcp 0.3.1 → 0.3.2

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 +62 -62
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -194,7 +194,7 @@ function registerAgentTools(server2, client2) {
194
194
  );
195
195
  server2.tool(
196
196
  "agent-status",
197
- "Check the status of a running agent job. Requires scope: jobs:read or sales:read.",
197
+ "Poll the status of a running agent job to check progress, completion, or if it is awaiting input. Returns status, logs, and artifacts when available. Use this after calling job-hunter-run or b2b-sales-run to monitor the asynchronous job. When status is awaiting_input, use agent-interact to respond. Read-only, no side effects. Requires scope: jobs:read or sales:read.",
198
198
  {
199
199
  agentType: z.enum(["job-hunter", "b2b-sales"]).describe("Agent type"),
200
200
  jobId: z.string().describe("Job ID returned from a generate call"),
@@ -254,7 +254,7 @@ function registerAgentTools(server2, client2) {
254
254
  );
255
255
  server2.tool(
256
256
  "agent-manifest",
257
- "Get the manifest (input fields, capabilities, billing) for an agent type. Requires scope: jobs:read or sales:read.",
257
+ "Get the manifest for an agent type, describing its input fields, capabilities, supported options, and billing information (credit costs per action). Use this to discover what parameters an agent accepts before running it, or to display pricing information. Read-only, no side effects. Requires scope: jobs:read or sales:read.",
258
258
  {
259
259
  agentType: z.enum(["job-hunter", "b2b-sales"]).describe("Agent type")
260
260
  },
@@ -274,7 +274,7 @@ import { z as z2 } from "zod";
274
274
  function registerAtsTools(server2, client2) {
275
275
  server2.tool(
276
276
  "ats-score",
277
- "Score a resume against a job description for ATS compatibility. Returns overall score, grade, keyword matches, and improvement suggestions. Consumes credits. Requires scope: ats:write.",
277
+ "Score a resume against a job description for ATS (Applicant Tracking System) compatibility using a 3-pass hybrid analysis (keyword extraction, deterministic matching, semantic gap analysis). Returns an overall score, letter grade, matched/missing keywords, and actionable improvement suggestions. Use this before job-hunter-run to assess resume fit, or standalone to evaluate how well a resume matches a specific job posting. Consumes credits. Requires scope: ats:write. Use upload-job-text to parse a job description first if you have a URL.",
278
278
  {
279
279
  resumeText: z2.string().describe("Resume as plain text"),
280
280
  jobDescription: z2.string().describe("Job description as plain text"),
@@ -300,7 +300,7 @@ import { z as z3 } from "zod";
300
300
  function registerResumeTools(server2, client2) {
301
301
  server2.tool(
302
302
  "resume-parse",
303
- "Parse a resume file into structured JSON Resume format. Accepts base64-encoded file content. Requires scope: resume:write.",
303
+ "Parse a resume file (PDF, DOCX, or TXT) into structured JSON Resume format. Accepts base64-encoded file content and returns structured data with contact info, work experience, education, and skills. Use this to extract structured data from an existing resume file. For uploading and parsing in one step, use upload-resume instead. Requires scope: resume:write.",
304
304
  {
305
305
  fileBase64: z3.string().describe("Base64-encoded resume file (PDF, DOCX, TXT)"),
306
306
  filename: z3.string().describe("Original filename with extension"),
@@ -323,7 +323,7 @@ function registerResumeTools(server2, client2) {
323
323
  );
324
324
  server2.tool(
325
325
  "resume-validate",
326
- "Validate a resume in JSON Resume format. Returns validation errors and warnings. Requires scope: resume:write.",
326
+ "Validate a resume object against the JSON Resume schema, returning any errors and warnings (missing fields, invalid formats, incomplete sections). Use this after parsing or editing a resume to verify it is well-formed before rendering or submitting to agents. Does not modify the resume. Requires scope: resume:write.",
327
327
  {
328
328
  resume: z3.record(z3.unknown()).describe("Resume object in JSON Resume format")
329
329
  },
@@ -338,7 +338,7 @@ function registerResumeTools(server2, client2) {
338
338
  );
339
339
  server2.tool(
340
340
  "resume-render",
341
- "Render a resume to PDF or HTML. Returns a URL to download the generated file. Requires scope: resume:write.",
341
+ "Render a JSON Resume object to a downloadable PDF or HTML file using a specified theme. Returns a URL to download the generated file. Use this to produce a polished, formatted resume for sharing or printing. Use resume-themes to see available themes. For a quick inline preview without generating a file, use resume-preview instead. Requires scope: resume:write.",
342
342
  {
343
343
  resume: z3.record(z3.unknown()).describe("Resume object in JSON Resume format"),
344
344
  theme: z3.string().describe("Theme name (e.g. even, stackoverflow, class, professional, elegant, macchiato, react, academic)"),
@@ -359,7 +359,7 @@ function registerResumeTools(server2, client2) {
359
359
  );
360
360
  server2.tool(
361
361
  "resume-preview",
362
- "Preview a resume as HTML. Returns rendered HTML string. Requires scope: resume:write.",
362
+ "Preview a JSON Resume object as inline HTML using a specified theme. Returns the rendered HTML string directly (not a URL). Use this for quick visual previews without generating a downloadable file. For producing a downloadable PDF or HTML file, use resume-render instead. Requires scope: resume:write.",
363
363
  {
364
364
  resume: z3.record(z3.unknown()).describe("Resume object in JSON Resume format"),
365
365
  theme: z3.string().describe("Theme name (e.g. even, stackoverflow, class, professional)")
@@ -378,7 +378,7 @@ function registerResumeTools(server2, client2) {
378
378
  );
379
379
  server2.tool(
380
380
  "resume-themes",
381
- "List all available resume themes. Returns theme IDs, names, and descriptions. Requires scope: resume:read.",
381
+ "List all available resume themes with their IDs, names, and descriptions. Use this to discover theme options before calling resume-render or resume-preview, or to let the user choose a theme. Read-only, no side effects. Requires scope: resume:read.",
382
382
  {},
383
383
  async () => {
384
384
  try {
@@ -391,7 +391,7 @@ function registerResumeTools(server2, client2) {
391
391
  );
392
392
  server2.tool(
393
393
  "resume-import-rx",
394
- "Import a resume from Reactive Resume (RxResume) format into JSON Resume format. Requires scope: resume:write.",
394
+ "Convert a resume from Reactive Resume (RxResume) format into JSON Resume format. Use this to import resumes exported from the Reactive Resume application. Returns the converted resume object. Does not store the result; save it with master-resume-upsert if needed. Requires scope: resume:write. For the reverse conversion, use resume-export-rx.",
395
395
  {
396
396
  data: z3.record(z3.unknown()).describe("RxResume data object to import")
397
397
  },
@@ -406,7 +406,7 @@ function registerResumeTools(server2, client2) {
406
406
  );
407
407
  server2.tool(
408
408
  "resume-export-rx",
409
- "Export a JSON Resume to Reactive Resume (RxResume) format. Requires scope: resume:read.",
409
+ "Convert a JSON Resume object to Reactive Resume (RxResume) format for use in the Reactive Resume application. Optionally include design/styling configuration. Read-only conversion, does not modify the source resume. Requires scope: resume:read. For the reverse conversion, use resume-import-rx.",
410
410
  {
411
411
  resume: z3.record(z3.unknown()).describe("Resume object in JSON Resume format"),
412
412
  designBlob: z3.record(z3.unknown()).optional().describe("Optional design/styling configuration")
@@ -425,7 +425,7 @@ function registerResumeTools(server2, client2) {
425
425
  );
426
426
  server2.tool(
427
427
  "master-resume-get",
428
- "Get the user's master resume. Returns the master resume with label, rawText, and structuredData. Requires scope: resume:read.",
428
+ "Get the user's stored master resume, returning its label, raw text, and structured data. The master resume serves as the default resume for agent runs when no other resume is provided. Use this to review the current master resume before running job-hunter-run. Read-only, no side effects. Requires scope: resume:read. Use master-resume-upsert to create or update it.",
429
429
  {},
430
430
  async () => {
431
431
  try {
@@ -438,7 +438,7 @@ function registerResumeTools(server2, client2) {
438
438
  );
439
439
  server2.tool(
440
440
  "master-resume-upsert",
441
- "Create or replace the user's master resume (upsert). Requires scope: resume:write.",
441
+ "Create or replace the user's master resume (upsert). The master resume is used as the default resume for job-hunter-run when no other resume is provided. Overwrites any existing master resume. Requires scope: resume:write. Use master-resume-get to check if one already exists. Use resume-parse to extract structured data from a file before saving.",
442
442
  {
443
443
  label: z3.string().describe("Label for the master resume"),
444
444
  rawText: z3.string().describe("Raw text content of the resume"),
@@ -459,7 +459,7 @@ function registerResumeTools(server2, client2) {
459
459
  );
460
460
  server2.tool(
461
461
  "master-resume-delete",
462
- "Delete the user's master resume. Requires scope: resume:write.",
462
+ "Permanently delete the user's master resume. After deletion, agent runs will require a resume to be provided directly. This is irreversible. Requires scope: resume:write. Use master-resume-get to review the resume before deleting.",
463
463
  {},
464
464
  async () => {
465
465
  try {
@@ -477,7 +477,7 @@ import { z as z4 } from "zod";
477
477
  function registerUploadTools(server2, client2) {
478
478
  server2.tool(
479
479
  "upload-resume",
480
- "Upload and parse a resume file. Accepts base64-encoded file content. Returns parsed resume data. Requires scope: upload:write.",
480
+ "Upload a resume file (PDF, DOCX, TXT) as base64-encoded content and parse it into structured data. Returns extracted contact info, work experience, education, and skills. Use this as the first step in a job application workflow before running ats-score or job-hunter-run. Max file size ~10 MB. Requires scope: upload:write. For parsing without the upload step, use resume-parse instead.",
481
481
  {
482
482
  fileBase64: z4.string().max(13981014).describe("Base64-encoded file content (PDF, DOCX, etc.) \u2014 max ~10 MB"),
483
483
  filename: z4.string().describe("Original filename with extension (e.g. resume.pdf)"),
@@ -498,7 +498,7 @@ function registerUploadTools(server2, client2) {
498
498
  );
499
499
  server2.tool(
500
500
  "upload-job-file",
501
- "Upload and parse a job description file. Accepts base64-encoded file content. Returns parsed job data. Requires scope: upload:write.",
501
+ "Upload a job description file (PDF, DOCX, TXT) as base64-encoded content and parse it into structured job data. Returns extracted job title, requirements, qualifications, and company info. Use this when the job description is in a file rather than plain text. Max file size ~10 MB. Requires scope: upload:write. For plain text or URL-based job descriptions, use upload-job-text instead.",
502
502
  {
503
503
  fileBase64: z4.string().max(13981014).describe("Base64-encoded file content (PDF, DOCX, etc.) \u2014 max ~10 MB"),
504
504
  filename: z4.string().describe("Original filename with extension"),
@@ -519,7 +519,7 @@ function registerUploadTools(server2, client2) {
519
519
  );
520
520
  server2.tool(
521
521
  "upload-job-text",
522
- "Upload a job description as plain text or fetch from a URL. At least one of text or url is required. Returns parsed job data. Requires scope: upload:write.",
522
+ "Parse a job description from plain text or fetch and parse from a URL. Returns structured job data including title, requirements, and qualifications. Use this when you have the job description as text or a URL to a job posting page. At least one of text or url is required. Requires scope: upload:write. For file-based job descriptions (PDF, DOCX), use upload-job-file instead.",
523
523
  {
524
524
  text: z4.string().max(5e4).optional().describe("Job description text (max 50K characters). Required if url is not provided."),
525
525
  url: z4.string().url().max(2048).optional().describe("URL to fetch job description from. Required if text is not provided."),
@@ -551,7 +551,7 @@ import { z as z5 } from "zod";
551
551
  function registerSessionTools(server2, client2) {
552
552
  server2.tool(
553
553
  "session-create",
554
- "Create a new session. Returns the created session object with its ID. Requires scope: sessions:write.",
554
+ "Create a new session for grouping agent runs and their artifacts. Returns the session object with its ID. Sessions organize multiple generations (agent runs) into a logical workspace. Use this before running job-hunter-run or b2b-sales-run with a specific sessionId. Requires scope: sessions:write.",
555
555
  {
556
556
  sessionId: z5.string().optional().describe("Optional client-generated session ID"),
557
557
  metadata: z5.record(z5.unknown()).optional().describe("Optional session metadata")
@@ -570,7 +570,7 @@ function registerSessionTools(server2, client2) {
570
570
  );
571
571
  server2.tool(
572
572
  "session-list",
573
- "List sessions with cursor-based pagination. Returns an array of session objects (or paginated envelope when limit is provided). Requires scope: sessions:read.",
573
+ "List sessions with cursor-based pagination. Returns session objects with IDs, creation dates, and metadata. Use this to browse existing sessions or find a session to resume. When limit is provided, returns a paginated envelope with a cursor for the next page. Read-only, no side effects. Requires scope: sessions:read. Use session-get or session-hydrate to get full details for a specific session.",
574
574
  {
575
575
  cursor: z5.string().optional().describe("Cursor for pagination (ISO 8601 datetime string)"),
576
576
  limit: z5.number().min(1).max(50).optional().describe("Number of sessions per page (1-50)")
@@ -589,7 +589,7 @@ function registerSessionTools(server2, client2) {
589
589
  );
590
590
  server2.tool(
591
591
  "session-get",
592
- "Get a session by ID. Returns the session object with generation history. Requires scope: sessions:read.",
592
+ "Get a session by ID, returning the session object with its generation history (list of agent runs). Use this to check what generations exist in a session without loading full artifacts. Read-only, no side effects. Requires scope: sessions:read. For full session data including all artifacts and logs, use session-hydrate instead.",
593
593
  {
594
594
  id: z5.string().describe("Session ID")
595
595
  },
@@ -604,7 +604,7 @@ function registerSessionTools(server2, client2) {
604
604
  );
605
605
  server2.tool(
606
606
  "session-hydrate",
607
- "Hydrate a session \u2014 returns the full session with all artifacts and logs. Requires scope: sessions:read.",
607
+ "Load a session with all its artifacts, logs, and generation details. Returns the complete session state including generated CVs, cover letters, emails, and conversation history. Use this to review full agent outputs or prepare artifacts for download. Heavier than session-get, so prefer session-get for lightweight lookups. Read-only, no side effects. Requires scope: sessions:read.",
608
608
  {
609
609
  id: z5.string().describe("Session ID")
610
610
  },
@@ -619,7 +619,7 @@ function registerSessionTools(server2, client2) {
619
619
  );
620
620
  server2.tool(
621
621
  "session-download",
622
- "Download an artifact from a session by its storage key. Returns base64-encoded content for binary files (PDF, DOCX, images) or plain text for text files. Requires scope: sessions:read.",
622
+ "Download a specific artifact from a session by its storage key. Returns base64-encoded content for binary files (PDF, DOCX, images) or plain text for text files. Use this to retrieve individual generated files like a rendered PDF resume or cover letter. Get artifact keys from session-hydrate first. Read-only, no side effects. Requires scope: sessions:read. For downloading by storage path instead of session context, use document-download.",
623
623
  {
624
624
  id: z5.string().describe("Session ID"),
625
625
  key: z5.string().describe("Artifact storage key from session hydration")
@@ -651,7 +651,7 @@ function registerSessionTools(server2, client2) {
651
651
  );
652
652
  server2.tool(
653
653
  "session-delete",
654
- "Delete a session by ID. Requires scope: sessions:write.",
654
+ "Permanently delete a session and all its generations, artifacts, and logs. This is irreversible. Use this to clean up completed or unwanted sessions. Requires scope: sessions:write. Use session-list to find sessions, and session-hydrate to review contents before deleting.",
655
655
  {
656
656
  id: z5.string().describe("Session ID")
657
657
  },
@@ -666,7 +666,7 @@ function registerSessionTools(server2, client2) {
666
666
  );
667
667
  server2.tool(
668
668
  "session-init",
669
- "Initialize session configuration \u2014 returns default settings and capabilities. Requires scope: sessions:read.",
669
+ "Get the default session configuration, including available agent types, supported features, and default settings. Use this to discover what agents and capabilities are available before creating sessions. Read-only, no side effects. Requires scope: sessions:read.",
670
670
  {},
671
671
  async () => {
672
672
  try {
@@ -679,7 +679,7 @@ function registerSessionTools(server2, client2) {
679
679
  );
680
680
  server2.tool(
681
681
  "session-log",
682
- "Append a log entry to a session. Used for tracking conversation history and tool usage. Requires scope: sessions:write.",
682
+ "Append a log entry to an existing session for tracking conversation history, tool usage, or status updates. Creates a new log record in the session. Use this to maintain an audit trail of actions taken during a session. Requires scope: sessions:write. Use session-hydrate to read back the full log history.",
683
683
  {
684
684
  id: z5.string().describe("Session ID"),
685
685
  role: z5.enum(["user", "assistant", "system", "tool", "status"]).describe("Log entry role"),
@@ -701,7 +701,7 @@ function registerSessionTools(server2, client2) {
701
701
  );
702
702
  server2.tool(
703
703
  "session-stats",
704
- "Get session statistics (total sessions, active sequences, emails drafted, reply rate, credits used). Requires scope: sessions:read.",
704
+ "Get aggregate session statistics for an agent type, including total sessions, active sequences, emails drafted, reply rate, and credits consumed. Use this to review overall usage and performance metrics for job-hunter or b2b-sales workflows. Read-only, no side effects. Requires scope: sessions:read.",
705
705
  {
706
706
  agentType: z5.enum(["job-hunter", "b2b-sales"]).describe("Agent type to get stats for")
707
707
  },
@@ -723,7 +723,7 @@ import { z as z6 } from "zod";
723
723
  function registerSettingsTools(server2, client2) {
724
724
  server2.tool(
725
725
  "settings-profile",
726
- "Get the current user's profile. Returns email, name, plan, and credit balance. Requires scope: settings:read.",
726
+ "Get the current user's profile including email, name, subscription plan, and remaining credit balance. Use this to check available credits before running agents (job-hunter-run, b2b-sales-run) or to verify account identity. Read-only, no side effects. Requires scope: settings:read. For detailed usage breakdown, use settings-usage-summary instead.",
727
727
  {},
728
728
  async () => {
729
729
  try {
@@ -736,7 +736,7 @@ function registerSettingsTools(server2, client2) {
736
736
  );
737
737
  server2.tool(
738
738
  "settings-preferences-get",
739
- "Get the current user's preferences. Requires scope: settings:read.",
739
+ "Get the current user's preferences, optionally filtered by agent type. Returns configuration like default themes, generation settings, and notification preferences. Read-only, no side effects. Requires scope: settings:read. Use settings-preferences-update to modify preferences.",
740
740
  {
741
741
  agentType: z6.string().optional().describe("Filter preferences by agent type (e.g. job-hunter, b2b-sales)")
742
742
  },
@@ -753,7 +753,7 @@ function registerSettingsTools(server2, client2) {
753
753
  );
754
754
  server2.tool(
755
755
  "settings-preferences-update",
756
- "Update the current user's preferences. Returns the updated preferences. Requires scope: settings:write.",
756
+ "Update the current user's preferences, optionally scoped to a specific agent type. Modifies stored preferences and returns the updated values. Use this to configure default themes, generation settings, or notification preferences. Requires scope: settings:write. Use settings-preferences-get first to see current values before updating.",
757
757
  {
758
758
  preferences: z6.record(z6.unknown()).describe("Preferences object to update"),
759
759
  agentType: z6.string().optional().describe("Agent type to scope preferences to (e.g. job-hunter, b2b-sales)")
@@ -772,7 +772,7 @@ function registerSettingsTools(server2, client2) {
772
772
  );
773
773
  server2.tool(
774
774
  "settings-usage-summary",
775
- "Get a summary of the user's API usage and credit consumption. Requires scope: settings:read.",
775
+ "Get an aggregate summary of the user's API usage and credit consumption, including total credits used, remaining balance, and usage by category. Use this to check credit balance before running agents or to monitor spending. Read-only, no side effects. Requires scope: settings:read. For individual usage entries with timestamps, use settings-usage-logs instead.",
776
776
  {},
777
777
  async () => {
778
778
  try {
@@ -785,7 +785,7 @@ function registerSettingsTools(server2, client2) {
785
785
  );
786
786
  server2.tool(
787
787
  "settings-usage-logs",
788
- "Get paginated usage logs. Returns individual usage entries with action, credits, and timestamps. Requires scope: settings:read.",
788
+ "Get paginated usage logs showing individual entries with action type, credits consumed, and timestamps. Use this to audit specific credit charges or investigate unexpected usage. Read-only, no side effects. Requires scope: settings:read. For an aggregate overview, use settings-usage-summary instead.",
789
789
  {
790
790
  offset: z6.number().optional().describe("Offset for pagination"),
791
791
  limit: z6.number().max(100).optional().describe("Number of entries to return (max 100)")
@@ -804,7 +804,7 @@ function registerSettingsTools(server2, client2) {
804
804
  );
805
805
  server2.tool(
806
806
  "api-key-create",
807
- "Create a new platform API key. The key value is shown ONLY in this response -- save it immediately. Requires scope: settings:write.",
807
+ "Create a new platform API key with specified permission scopes. The key value is returned ONLY in this response and cannot be retrieved later, so save it immediately. Creates a new key record. Requires scope: settings:write. Use api-key-list to see existing keys. Use api-key-revoke to delete keys you no longer need.",
808
808
  {
809
809
  label: z6.string().describe("Human-readable label for the API key"),
810
810
  scopes: z6.array(z6.enum([
@@ -845,7 +845,7 @@ function registerSettingsTools(server2, client2) {
845
845
  );
846
846
  server2.tool(
847
847
  "api-key-list",
848
- "List all platform API keys. Returns key metadata (hash, name, scopes) -- NOT the key values. Requires scope: settings:read.",
848
+ "List all platform API keys for the current user. Returns key metadata (hash, label, scopes, creation date) but NOT the actual key values (those are only shown at creation time). Use this to find key hashes for revocation, rotation, or usage queries. Read-only, no side effects. Requires scope: settings:read.",
849
849
  {},
850
850
  async () => {
851
851
  try {
@@ -858,7 +858,7 @@ function registerSettingsTools(server2, client2) {
858
858
  );
859
859
  server2.tool(
860
860
  "api-key-revoke",
861
- "Revoke (delete) a platform API key by its hash. Requires scope: settings:write.",
861
+ "Permanently revoke and delete a platform API key by its hash. The key immediately stops working for all API calls. This is irreversible. Use this to remove compromised or unused keys. Requires scope: settings:write. Use api-key-list first to find the key hash. For replacing a key with a new one, use api-key-rotate instead.",
862
862
  {
863
863
  hash: z6.string().describe("API key hash to revoke")
864
864
  },
@@ -873,7 +873,7 @@ function registerSettingsTools(server2, client2) {
873
873
  );
874
874
  server2.tool(
875
875
  "api-key-rotate",
876
- "Rotate a platform API key -- revokes the old key and returns a new one. Save the new key immediately. Requires scope: settings:write.",
876
+ "Rotate a platform API key by revoking the old key and issuing a new one. The new key value is returned ONLY in this response, so save it immediately. An optional grace period keeps the old key valid during transition. Use this for periodic key rotation or when a key may be compromised but you need continuity. Requires scope: settings:write. For immediate revocation without replacement, use api-key-revoke instead.",
877
877
  {
878
878
  hash: z6.string().describe("API key hash to rotate"),
879
879
  gracePeriodHours: z6.number().optional().describe("Hours the old key remains valid after rotation (default: 24)")
@@ -892,7 +892,7 @@ function registerSettingsTools(server2, client2) {
892
892
  );
893
893
  server2.tool(
894
894
  "api-key-usage",
895
- "Get usage statistics for a specific API key by its hash. Requires scope: settings:read.",
895
+ "Get usage statistics for a specific API key by its hash, including request counts and credit consumption. Use this to monitor per-key usage or identify which key is consuming the most credits. Read-only, no side effects. Requires scope: settings:read. Use api-key-list to find key hashes.",
896
896
  {
897
897
  hash: z6.string().describe("API key hash")
898
898
  },
@@ -907,7 +907,7 @@ function registerSettingsTools(server2, client2) {
907
907
  );
908
908
  server2.tool(
909
909
  "byo-key-get",
910
- "Get the status of all configured BYO provider keys. Returns provider names and their configuration status. Requires scope: settings:read.",
910
+ "Check the configuration status of all Bring Your Own (BYO) API keys. Returns each provider name and whether a key is configured. Use this to verify BYO key setup before running agents with tier=byo. Read-only, no side effects. Requires scope: settings:read. Use settings-supported-providers to see which providers are available. Use byo-key-set to configure a key.",
911
911
  {},
912
912
  async () => {
913
913
  try {
@@ -920,7 +920,7 @@ function registerSettingsTools(server2, client2) {
920
920
  );
921
921
  server2.tool(
922
922
  "byo-key-set",
923
- "Set a Bring Your Own API key for a provider (e.g. gemini). BYO tier users get unlimited AI generation but still pay for contact enrichment. Requires scope: settings:write.",
923
+ "Configure a Bring Your Own (BYO) API key for an AI provider (e.g. gemini). BYO tier users get unlimited AI generation but still pay for contact enrichment credits. Stores the key securely on the platform. Requires scope: settings:write. Use settings-supported-providers to see available providers. Use byo-key-get to check current configuration. Use byo-key-remove to delete a configured key.",
924
924
  {
925
925
  provider: z6.string().describe("Provider name (e.g. gemini)"),
926
926
  apiKey: z6.string().describe("The API key to set"),
@@ -940,7 +940,7 @@ function registerSettingsTools(server2, client2) {
940
940
  );
941
941
  server2.tool(
942
942
  "byo-key-remove",
943
- "Remove the configured BYO API key for a provider. Requires scope: settings:write.",
943
+ "Remove a configured Bring Your Own (BYO) API key for a provider. After removal, agent runs will use platform credits instead of the BYO key. Requires scope: settings:write. Use byo-key-get to check which providers have keys configured before removing.",
944
944
  {
945
945
  provider: z6.string().describe("Provider name to remove the key for (e.g. gemini)")
946
946
  },
@@ -955,7 +955,7 @@ function registerSettingsTools(server2, client2) {
955
955
  );
956
956
  server2.tool(
957
957
  "settings-supported-providers",
958
- "List supported BYO key providers. Returns provider names and status. Requires scope: settings:read.",
958
+ "List all AI providers that support Bring Your Own (BYO) API keys, including provider names and availability status. Use this to discover which providers can be configured with byo-key-set before setting up BYO keys. Read-only, no side effects. Requires scope: settings:read.",
959
959
  {},
960
960
  async () => {
961
961
  try {
@@ -968,7 +968,7 @@ function registerSettingsTools(server2, client2) {
968
968
  );
969
969
  server2.tool(
970
970
  "webhook-secret-get",
971
- "Get the current webhook secret for verifying webhook signatures. Requires scope: webhook:read.",
971
+ "Get the current webhook signing secret used to verify webhook payloads from the LLM Conveyors platform. Use this when setting up webhook receivers to validate that incoming webhooks are authentic. Read-only, no side effects. Requires scope: webhook:read. Use webhook-secret-rotate to generate a new secret if the current one is compromised.",
972
972
  {},
973
973
  async () => {
974
974
  try {
@@ -981,7 +981,7 @@ function registerSettingsTools(server2, client2) {
981
981
  );
982
982
  server2.tool(
983
983
  "webhook-secret-rotate",
984
- "Rotate the webhook secret. Returns the new secret. The old secret is immediately invalidated. Rate limited: 5 per hour. Requires scope: webhook:write.",
984
+ "Rotate the webhook signing secret, generating a new one and immediately invalidating the old secret. All existing webhook receivers must be updated with the new secret or they will reject incoming payloads. Rate limited: 5 per hour. Requires scope: webhook:write. Use webhook-secret-get to retrieve the current secret before rotating.",
985
985
  {},
986
986
  async () => {
987
987
  try {
@@ -999,7 +999,7 @@ import { z as z7 } from "zod";
999
999
  function registerContentTools(server2, client2) {
1000
1000
  server2.tool(
1001
1001
  "content-save",
1002
- "Save a source document for use as context in AI generation. Returns success status. Requires scope: sessions:write.",
1002
+ "Save a source document that will be used as context in future AI generation runs (job-hunter-run, b2b-sales-run). Overwrites any existing document of the same type. Use this to store your CV, cover letter templates, or strategy documents before running agents. Requires scope: sessions:write. Use content-list-sources to see what is already saved. Use content-get-source to read a specific saved document.",
1003
1003
  {
1004
1004
  docType: z7.enum([
1005
1005
  "original_cv",
@@ -1027,7 +1027,7 @@ function registerContentTools(server2, client2) {
1027
1027
  );
1028
1028
  server2.tool(
1029
1029
  "content-delete-generation",
1030
- "Delete a generation and all its artifacts from a session. Requires scope: sessions:write.",
1030
+ "Permanently delete a generation and all its artifacts (CV, cover letter, emails) from a session. This is irreversible and removes all files associated with that generation. Use this to clean up unwanted outputs. Requires scope: sessions:write. Use session-hydrate first to review the generation before deleting.",
1031
1031
  {
1032
1032
  id: z7.string().describe("Generation ID to delete"),
1033
1033
  sessionId: z7.string().describe("Session ID that owns the generation")
@@ -1043,7 +1043,7 @@ function registerContentTools(server2, client2) {
1043
1043
  );
1044
1044
  server2.tool(
1045
1045
  "content-research-sender",
1046
- "Research and create a sender profile for content generation. Returns sender context. Requires scope: sessions:write. At least one of companyWebsite or companyName must be provided.",
1046
+ "Research a company and create a sender profile for personalized content generation. Returns structured sender context (company info, positioning, value propositions). Use this before b2b-sales-run to pre-populate sender context for better outreach personalization. Consumes credits. At least one of companyWebsite or companyName must be provided. Requires scope: sessions:write.",
1047
1047
  {
1048
1048
  companyWebsite: z7.string().optional().describe("Company website to research"),
1049
1049
  companyName: z7.string().optional().describe("Company name for context")
@@ -1068,7 +1068,7 @@ function registerContentTools(server2, client2) {
1068
1068
  );
1069
1069
  server2.tool(
1070
1070
  "content-list-sources",
1071
- "List all saved source documents used as context for AI generation. Requires scope: sessions:read.",
1071
+ "List all saved source documents used as context for AI generation, showing document types and metadata. Use this to check what context documents are available before running agents. Read-only, no side effects. Requires scope: sessions:read. Use content-get-source to read a specific document. Use content-save to add or update documents.",
1072
1072
  {},
1073
1073
  async () => {
1074
1074
  try {
@@ -1081,7 +1081,7 @@ function registerContentTools(server2, client2) {
1081
1081
  );
1082
1082
  server2.tool(
1083
1083
  "content-get-source",
1084
- "Get a specific source document by type. Requires scope: sessions:read.",
1084
+ "Retrieve the full content of a specific saved source document by type (e.g. original_cv, cv_strategy, cold_email_strategy). Use this to review or display a previously saved context document. Read-only, no side effects. Requires scope: sessions:read. Use content-list-sources to see all available document types.",
1085
1085
  {
1086
1086
  docType: z7.enum([
1087
1087
  "original_cv",
@@ -1105,7 +1105,7 @@ function registerContentTools(server2, client2) {
1105
1105
  );
1106
1106
  server2.tool(
1107
1107
  "content-delete-source",
1108
- "Delete a source document by type. Requires scope: sessions:write.",
1108
+ "Permanently delete a saved source document by type. Future agent runs will no longer use this document as context. Use this to remove outdated context documents before saving new ones. Requires scope: sessions:write. Use content-list-sources to verify which documents exist before deleting.",
1109
1109
  {
1110
1110
  docType: z7.enum([
1111
1111
  "original_cv",
@@ -1134,7 +1134,7 @@ import { z as z8 } from "zod";
1134
1134
  function registerSharesTools(server2, client2) {
1135
1135
  server2.tool(
1136
1136
  "share-create",
1137
- "Create a shareable public link for a generation's artifacts. Returns a slug and public URL. Requires scope: sessions:read.",
1137
+ "Create a shareable public link for a generation's artifacts (resume, cover letter, emails). Returns a slug and public URL that anyone can view without authentication. Creates a new share record. Requires scope: sessions:read. Use after running job-hunter-run or b2b-sales-run to share the output. Use share-slug-stats to track views.",
1138
1138
  {
1139
1139
  sessionId: z8.string().describe("Session ID containing the generation"),
1140
1140
  generationId: z8.string().describe("Generation ID to share")
@@ -1153,7 +1153,7 @@ function registerSharesTools(server2, client2) {
1153
1153
  );
1154
1154
  server2.tool(
1155
1155
  "share-stats",
1156
- "Get statistics about your shared links (view counts, etc.). Requires scope: sessions:read.",
1156
+ "Get aggregate statistics about all shared links for the current user, including total shares and total views. Use this for an overview of sharing activity. Read-only, no side effects. Requires scope: sessions:read. For per-link stats, use share-slug-stats with a specific slug.",
1157
1157
  {},
1158
1158
  async () => {
1159
1159
  try {
@@ -1166,7 +1166,7 @@ function registerSharesTools(server2, client2) {
1166
1166
  );
1167
1167
  server2.tool(
1168
1168
  "share-get-public",
1169
- "Get a publicly shared resource by its slug. No auth required (public endpoint).",
1169
+ "Retrieve a publicly shared resource by its slug. Returns the shared artifacts (resume, cover letter, emails) without requiring authentication. Use this to view what a share link contains. Read-only, no side effects. No auth required (public endpoint).",
1170
1170
  {
1171
1171
  slug: z8.string().describe("Public share slug")
1172
1172
  },
@@ -1181,7 +1181,7 @@ function registerSharesTools(server2, client2) {
1181
1181
  );
1182
1182
  server2.tool(
1183
1183
  "share-slug-stats",
1184
- "Get visit statistics for a specific share link (owner only). Requires scope: sessions:read.",
1184
+ "Get visit statistics for a specific share link, including view count and visit timestamps. Only accessible by the share owner. Use this to track engagement on a specific shared artifact. Read-only, no side effects. Requires scope: sessions:read. For aggregate stats across all shares, use share-stats instead.",
1185
1185
  {
1186
1186
  slug: z8.string().describe("Share link slug")
1187
1187
  },
@@ -1201,7 +1201,7 @@ import { z as z9 } from "zod";
1201
1201
  function registerDocumentTools(server2, client2) {
1202
1202
  server2.tool(
1203
1203
  "document-download",
1204
- "Download a document by its storage path. Returns base64-encoded content for binary files (PDF, DOCX, images) or plain text for text files. Requires scope: sessions:read.",
1204
+ "Download a document artifact by its storage path. Returns base64-encoded content for binary files (PDF, DOCX, images) or plain text for text files. Use this to retrieve generated artifacts like rendered resumes or reports when you have the storage path. For downloading artifacts from a specific session, use session-download instead (which takes a session ID and artifact key). Read-only, no side effects. Requires scope: sessions:read.",
1205
1205
  {
1206
1206
  path: z9.string().describe("Document storage path")
1207
1207
  },
@@ -1237,7 +1237,7 @@ import { z as z10 } from "zod";
1237
1237
  function registerReferralTools(server2, client2) {
1238
1238
  server2.tool(
1239
1239
  "referral-stats",
1240
- "Get referral program statistics including total referrals and credits earned. Requires scope: settings:read.",
1240
+ "Get referral program statistics for the current user, including total referrals, successful conversions, and credits earned. Use this to check referral performance or display earnings. Read-only, no side effects. Requires scope: settings:read. Use referral-code to get the shareable referral link.",
1241
1241
  {},
1242
1242
  async () => {
1243
1243
  try {
@@ -1250,7 +1250,7 @@ function registerReferralTools(server2, client2) {
1250
1250
  );
1251
1251
  server2.tool(
1252
1252
  "referral-code",
1253
- "Get your referral code for sharing with others. Requires scope: settings:read.",
1253
+ "Get the current user's referral code and shareable referral link. Use this to retrieve the code for sharing with others. Read-only, no side effects. Requires scope: settings:read. To customize the code, use referral-vanity-code. To check referral performance, use referral-stats.",
1254
1254
  {},
1255
1255
  async () => {
1256
1256
  try {
@@ -1263,7 +1263,7 @@ function registerReferralTools(server2, client2) {
1263
1263
  );
1264
1264
  server2.tool(
1265
1265
  "referral-vanity-code",
1266
- "Set a custom vanity code for your referral link. Rate limited: 5 per hour. Requires scope: settings:write.",
1266
+ "Set a custom vanity code for the user's referral link, replacing the auto-generated code. This permanently changes the referral URL. Rate limited: 5 per hour. Requires scope: settings:write. Use referral-code first to see the current code before changing it.",
1267
1267
  {
1268
1268
  code: z10.string().describe("Custom vanity code to set")
1269
1269
  },
@@ -1291,7 +1291,7 @@ var CONSENT_PURPOSES = [
1291
1291
  function registerPrivacyTools(server2, client2) {
1292
1292
  server2.tool(
1293
1293
  "privacy-list-consents",
1294
- "List all privacy consent statuses for the current user. Returns consent purposes and their granted/revoked status. Requires scope: settings:read.",
1294
+ "List all privacy consent records for the current user, showing each data processing purpose and whether consent is granted or revoked. Use this to check consent status before running tools that require specific consents (e.g. ai-generation, contact-enrichment). Read-only, no side effects. Requires scope: settings:read.",
1295
1295
  {},
1296
1296
  async () => {
1297
1297
  try {
@@ -1304,7 +1304,7 @@ function registerPrivacyTools(server2, client2) {
1304
1304
  );
1305
1305
  server2.tool(
1306
1306
  "privacy-grant-consent",
1307
- "Grant consent for a specific data processing purpose. Requires scope: settings:write.",
1307
+ "Grant consent for a specific data processing purpose. This enables the platform to process data for that purpose (e.g. ai-generation enables agent runs, contact-enrichment enables contact lookups). Modifies the user's consent record. Requires scope: settings:write. Use privacy-list-consents to check current status first. Use privacy-revoke-consent to undo.",
1308
1308
  {
1309
1309
  purpose: z11.enum(CONSENT_PURPOSES).describe("Consent purpose to grant")
1310
1310
  },
@@ -1319,7 +1319,7 @@ function registerPrivacyTools(server2, client2) {
1319
1319
  );
1320
1320
  server2.tool(
1321
1321
  "privacy-revoke-consent",
1322
- "Revoke consent for a specific data processing purpose. Requires scope: settings:write.",
1322
+ "Revoke a previously granted consent for a specific data processing purpose. This may disable platform features that depend on that consent (e.g. revoking ai-generation prevents agent runs). Modifies the user's consent record. Requires scope: settings:write. Use privacy-list-consents to check current status first.",
1323
1323
  {
1324
1324
  purpose: z11.enum(CONSENT_PURPOSES).describe("Consent purpose to revoke")
1325
1325
  },
@@ -1338,7 +1338,7 @@ function registerPrivacyTools(server2, client2) {
1338
1338
  function registerHealthTools(server2, client2) {
1339
1339
  server2.tool(
1340
1340
  "health-root",
1341
- "Get API root info (name, version). Public endpoint, no auth required.",
1341
+ "Get the LLM Conveyors API server name and version. Use this to verify the MCP server is connected and reachable before running other tools. No authentication required. Returns JSON with name and version fields. For deeper diagnostics, use health-check instead.",
1342
1342
  {},
1343
1343
  async () => {
1344
1344
  try {
@@ -1351,7 +1351,7 @@ function registerHealthTools(server2, client2) {
1351
1351
  );
1352
1352
  server2.tool(
1353
1353
  "health-check",
1354
- "Check API health status \u2014 returns status, timestamp, uptime, version, checks, memory. Public endpoint, no auth required.",
1354
+ "Run a detailed health check on the LLM Conveyors API, returning status, uptime, version, dependency checks, and memory usage. Use this to diagnose connectivity or performance issues before retrying failed tool calls. No authentication required. For a simple alive/dead check, use health-live instead.",
1355
1355
  {},
1356
1356
  async () => {
1357
1357
  try {
@@ -1364,7 +1364,7 @@ function registerHealthTools(server2, client2) {
1364
1364
  );
1365
1365
  server2.tool(
1366
1366
  "health-ready",
1367
- "Check API readiness. Public endpoint, no auth required.",
1367
+ "Check whether the LLM Conveyors API is ready to accept requests (all dependencies initialized). Use this in automation pipelines to wait for readiness before sending agent runs. No authentication required. Returns a simple ready/not-ready status. For process liveness only, use health-live instead.",
1368
1368
  {},
1369
1369
  async () => {
1370
1370
  try {
@@ -1377,7 +1377,7 @@ function registerHealthTools(server2, client2) {
1377
1377
  );
1378
1378
  server2.tool(
1379
1379
  "health-live",
1380
- "Check API liveness. Public endpoint, no auth required.",
1380
+ "Check whether the LLM Conveyors API process is alive and responding. Use this as a lightweight heartbeat check in monitoring or retry loops. No authentication required. Returns a simple alive status. For dependency-level diagnostics, use health-check instead.",
1381
1381
  {},
1382
1382
  async () => {
1383
1383
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llmconveyors-mcp",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "mcpName": "io.github.ebenezer-isaac/llmconveyors",
5
5
  "description": "MCP server that connects AI agents to LLM Conveyors — run Job Hunter, B2B Sales, and other AI agents from Claude, Cursor, or any MCP client",
6
6
  "type": "module",