trackly-cli 0.22.0 → 0.22.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.
@@ -73,7 +73,7 @@ API-key creation attempts.
73
73
  ### Available Tools
74
74
 
75
75
  - **get_more_tools** — Report what the agent wanted to do when no Trackly tool fit, so Trackly can improve its MCP surface. The tool is always available; report delivery is best-effort and occurs only when usage analytics are enabled.
76
- - **trackly_search_jobs** — Search/filter jobs.
76
+ - **trackly_search_jobs** — Search/filter jobs. A successful page may have `total: null`, `pagination.total: null` and `countStatus: "unavailable"` when its total cannot be computed. The returned jobs remain valid: explain `countGuidance`, use `hasMore` and pagination to continue, and avoid retrying just to obtain a total. Zero is a known count; null is unknown. Genuine page failures remain tool errors.
77
77
  - `function` (one value) or `jobFunctions` (nonempty array, OR; use one spelling only). The 14 values are: `product`, `engineering`, `design`, `data`, `marketing`, `sales`, `partnerships`, `finance`, `strategy`, `operations`, `people`, `legal`, `support`, `other`
78
78
  - `region`: nonempty array of `us`, `europe`, `latam`, `middle_east`, `asia`, `africa`, `canada`, `oceania`, `remote`, `unknown`, combined with OR. Use instead of `locationFilter`; unlike its legacy list form, this supports US plus other regions.
79
79
  - `usStates`: nonempty array of US codes `AL`, `AK`, `AZ`, `AR`, `CA`, `CO`, `CT`, `DC`, `DE`, `FL`, `GA`, `HI`, `ID`, `IL`, `IN`, `IA`, `KS`, `KY`, `LA`, `ME`, `MD`, `MA`, `MI`, `MN`, `MS`, `MO`, `MT`, `NE`, `NV`, `NH`, `NJ`, `NM`, `NY`, `NC`, `ND`, `OH`, `OK`, `OR`, `PA`, `RI`, `SC`, `SD`, `TN`, `TX`, `UT`, `VT`, `VA`, `WA`, `WV`, `WI`, `WY`, `PR`, `REMOTE`.
@@ -0,0 +1,131 @@
1
+ {
2
+ "success": true,
3
+ "discovery": {
4
+ "version": 1,
5
+ "available": false,
6
+ "activation": "JOBSCOUT_DISCOVERY_V1_ENABLED=true after production query validation",
7
+ "preferenceWrites": false,
8
+ "sorts": [
9
+ "newest",
10
+ "relevance"
11
+ ],
12
+ "modes": {
13
+ "filters": true,
14
+ "filters_plus_focus": false,
15
+ "focus_only": false
16
+ },
17
+ "keywords": {
18
+ "parameter": "search",
19
+ "fields": [
20
+ "title",
21
+ "company",
22
+ "description",
23
+ "skills"
24
+ ],
25
+ "defaultFields": [
26
+ "title",
27
+ "company",
28
+ "description",
29
+ "skills"
30
+ ],
31
+ "allTerms": true,
32
+ "quotedPhrases": true,
33
+ "leadingMinus": true,
34
+ "maxLength": 500,
35
+ "maxTerms": 8,
36
+ "maxTermLength": 80,
37
+ "matching": "literal_whole_word_case_insensitive_nfkc",
38
+ "positiveMissingEvidence": "no_match",
39
+ "negativeMissingEvidence": "not_checked",
40
+ "descriptionSource": "description_text",
41
+ "skillsSource": [
42
+ "structured_jd.requiredSkills",
43
+ "structured_jd.preferredSkills"
44
+ ],
45
+ "companySource": "employer company row or posting organization; aggregator name is not employer evidence",
46
+ "provider": "postgresql",
47
+ "semanticExpansion": false,
48
+ "indexSupport": "validated_same_row_expression_gin_v1",
49
+ "supportedStrategy": "ascii_anchored_plan_selected_sets_or_exact_regex",
50
+ "unavailableClasses": [
51
+ "non_ascii_query",
52
+ "pure_punctuation"
53
+ ],
54
+ "unicodeSourceSafetyCohort": "included_and_rechecked; worst_case_requires_production_benchmark",
55
+ "performance": "unvalidated_on_azure; readiness_is_not_latency_proof"
56
+ },
57
+ "facets": {
58
+ "jobFunction": {
59
+ "ids": [
60
+ "product",
61
+ "engineering",
62
+ "design",
63
+ "data",
64
+ "marketing",
65
+ "sales",
66
+ "partnerships",
67
+ "finance",
68
+ "strategy",
69
+ "operations",
70
+ "people",
71
+ "legal",
72
+ "support",
73
+ "other"
74
+ ],
75
+ "unknown": "include",
76
+ "source": "job_function"
77
+ },
78
+ "industries": {
79
+ "ids": [
80
+ "fintech",
81
+ "healthtech",
82
+ "ai-ml",
83
+ "cybersecurity",
84
+ "ecommerce",
85
+ "gaming",
86
+ "devtools",
87
+ "edtech",
88
+ "crypto-web3",
89
+ "robotics",
90
+ "aerospace",
91
+ "hr-recruiting",
92
+ "insurance",
93
+ "enterprise-saas",
94
+ "social-media",
95
+ "media-entertainment",
96
+ "logistics-supply-chain",
97
+ "proptech",
98
+ "legaltech",
99
+ "biotech-pharma",
100
+ "climate-cleantech",
101
+ "hardware-semiconductors",
102
+ "telecom",
103
+ "automotive",
104
+ "food-agriculture",
105
+ "travel-hospitality",
106
+ "retail",
107
+ "marketplace",
108
+ "consulting-services",
109
+ "data-analytics",
110
+ "cloud-infrastructure",
111
+ "other"
112
+ ],
113
+ "unknown": "include",
114
+ "includeUnknownParameter": "includeUnknownIndustries",
115
+ "strictSelection": true,
116
+ "source": "employer company.industry; unresolved aggregator parents are unknown"
117
+ },
118
+ "roleSpecializations": {
119
+ "supported": false,
120
+ "reason": "No populated canonical taxonomy"
121
+ },
122
+ "subindustries": {
123
+ "supported": false,
124
+ "reason": "No populated canonical taxonomy"
125
+ }
126
+ },
127
+ "coverage": "unmeasured",
128
+ "counts": "same_sql_predicate; existing countMode and countCap semantics",
129
+ "readiness": "disabled"
130
+ }
131
+ }
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ const { isDeepStrictEqual } = require('node:util');
4
+
5
+ let preparedReadyEnvelope;
6
+
7
+ /**
8
+ * Preparatory parser only: no transport, registration or production activation.
9
+ * The local opt-in defaults off and does not read capability data when off.
10
+ * A ready response proves contract compatibility, never production performance.
11
+ * Any contract drift requires a new reviewed fixture rather than inferred support.
12
+ */
13
+ function parseDiscoveryCapabilities(response, { enabled = false } = {}) {
14
+ if (enabled !== true) return null;
15
+
16
+ if (!preparedReadyEnvelope) {
17
+ // Frozen API contract; test fixtures bind its exact bytes to the reviewed source.
18
+ preparedReadyEnvelope = structuredClone(require('./discovery-capabilities-v1.json'));
19
+ preparedReadyEnvelope.discovery.available = true;
20
+ preparedReadyEnvelope.discovery.readiness = 'ready';
21
+ }
22
+
23
+ if (!isDeepStrictEqual(response, preparedReadyEnvelope)) return null;
24
+ return structuredClone(preparedReadyEnvelope.discovery);
25
+ }
26
+
27
+ module.exports = { parseDiscoveryCapabilities };
package/mcp/server.js CHANGED
@@ -285,7 +285,7 @@ function createServer() {
285
285
 
286
286
  server.registerTool(
287
287
  'trackly_search_jobs',
288
- { description: 'Search and filter job postings. Returns one matching page with title, company, location, structured fields and backend pagination. Use jobFunctions for multiple roles, region for multiple regions, and usStates/caProvinces for geographic detail. Work arrangement is independent from geography and employment type. Unknown sponsorship and non-comparable salary data stay visible with exclude_no and salaryFloorUsd. Never invent industry, specialization, exclusion or literal-search controls; ask when sponsorship intent is ambiguous.',
288
+ { description: 'Search and filter job postings. Returns one matching page with title, company, location, structured fields and backend pagination. Use jobFunctions for multiple roles, region for multiple regions, and usStates/caProvinces for geographic detail. Work arrangement is independent from geography and employment type. Unknown sponsorship and non-comparable salary data stay visible with exclude_no and salaryFloorUsd. Never invent industry, specialization, exclusion or literal-search controls; ask when sponsorship intent is ambiguous. If the total is unavailable, returned matching jobs remain valid. Explain countGuidance and use hasMore/pagination; do not retry just for totals.',
289
289
  inputSchema: z.object({
290
290
  function: z.enum(JOB_FUNCTIONS).optional().describe('Job function filter. One of: ' + JOB_FUNCTIONS.join(', ')),
291
291
  jobFunctions: z.array(z.enum(JOB_FUNCTIONS)).min(1).max(14).optional().describe('Multiple job functions, combined with OR. Use instead of function. Omit both to request all 14 functions.'),
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "trackly-cli",
3
- "version": "0.22.0",
3
+ "version": "0.22.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "trackly-cli",
9
- "version": "0.22.0",
9
+ "version": "0.22.1",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@modelcontextprotocol/sdk": "1.32.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trackly-cli",
3
- "version": "0.22.0",
3
+ "version": "0.22.1",
4
4
  "mcpName": "io.github.trackly-app/trackly",
5
5
  "description": "Search 250K+ jobs across 5,400+ companies with the Trackly CLI and MCP server for Claude, ChatGPT, Codex and Cursor. Filter by role, location, salary and sponsorship; track jobs and prepare applications.",
6
6
  "bin": {
package/server.json CHANGED
@@ -17,12 +17,12 @@
17
17
  ]
18
18
  }
19
19
  ],
20
- "version": "0.22.0",
20
+ "version": "0.22.1",
21
21
  "packages": [
22
22
  {
23
23
  "registryType": "npm",
24
24
  "identifier": "trackly-cli",
25
- "version": "0.22.0",
25
+ "version": "0.22.1",
26
26
  "runtimeHint": "npx",
27
27
  "runtimeArguments": [
28
28
  {