{"_id":"@workix/mcp","_rev":"7-88500b9819fe9158b756ab0d90bcdbd0","name":"@workix/mcp","dist-tags":{"latest":"1.0.0"},"versions":{"0.1.0":{"name":"@workix/mcp","version":"0.1.0","keywords":["mcp","model-context-protocol","workix","freelance","jobs","ai-agents","cursor"],"author":{"name":"Workix","email":"mail@workix.co"},"license":"SEE LICENSE IN LICENSE","_id":"@workix/mcp@0.1.0","maintainers":[{"name":"f2p","email":"mail@workix.co"}],"homepage":"https://workix.co","bugs":{"url":"https://github.com/facetoplace/Workix/issues"},"bin":{"workix-mcp":"dist/index.js"},"dist":{"shasum":"8b28f2a9758638429223bc3825d81de351056f90","tarball":"https://registry.npmjs.org/@workix/mcp/-/mcp-0.1.0.tgz","fileCount":89,"integrity":"sha512-30RtykxdyqjFZXPz8HDjvLVVi4arFxmpEHIfGpS08xUUavaiWrlUCQWdGmjNKg1kt6CazHm884UqMrBDxYPucw==","signatures":[{"sig":"MEUCIQCLIpvcB4+rpQZtLJp/vTJVdzz8ha4kAFYuLxHZQaECIAIgdLQd3P0X4FYSS9p4jLJJAZ60rGOTMbDW30vj52c/pNQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":206088},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"3dbffea18b609db7769f29337927d550a7e95f46","mcpName":"com.workix/mcp","scripts":{"dev":"tsx src/index.ts","build":"tsc","smoke":"npm run build && node scripts/smoke-preset.mjs mobile_dev","start":"node dist/index.js","build:all":"npm run build && npm run pack:adapters","smoke:hub":"node scripts/smoke-hub.mjs","typecheck":"tsc --noEmit","upwork:token":"node scripts/upwork-token.mjs","pack:adapters":"node scripts/pack-adapters.mjs","prepublishOnly":"npm run build","smoke:startups":"npm run build && node scripts/smoke-preset.mjs startups_products"},"_npmUser":{"name":"f2p","email":"mail@workix.co"},"repository":{"url":"git+https://github.com/facetoplace/Workix.git","type":"git","directory":"mcp"},"_npmVersion":"11.3.0","description":"Workix MCP — hub catalog, freelance digest/search, and proposal helpers for AI agents","directories":{},"_nodeVersion":"24.0.1","dependencies":{"tar":"^7.4.3","zod":"^3.25.76","dotenv":"^17.4.2","kwork-api":"^1.3.3","rss-parser":"^3.13.0","socket.io-client":"^2.5.0","https-proxy-agent":"^9.1.0","socks-proxy-agent":"^10.1.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.5","esbuild":"^0.25.0","typescript":"^5.5.4","@types/node":"^22.12.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.1.0_1785097201441_0.03775563977019125","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@workix/mcp","version":"0.1.1","keywords":["mcp","model-context-protocol","workix","freelance","jobs","ai-agents","cursor"],"author":{"name":"Workix","email":"mail@workix.co"},"license":"SEE LICENSE IN LICENSE","_id":"@workix/mcp@0.1.1","maintainers":[{"name":"f2p","email":"mail@workix.co"}],"homepage":"https://workix.co","bugs":{"url":"https://github.com/facetoplace/Workix/issues"},"bin":{"workix-mcp":"dist/index.js"},"dist":{"shasum":"70a2884c379d3350e0583bb1014b69842edfff05","tarball":"https://registry.npmjs.org/@workix/mcp/-/mcp-0.1.1.tgz","fileCount":89,"integrity":"sha512-arsAhhgqM44DkXPvhX1aDCu9oHYLrfBfNFK3cyRTui6TiCfAQ8Fi/pYDrDj2ZaVhOsRgeyKxpI3UmrWruu9l1g==","signatures":[{"sig":"MEYCIQDmTakfnK7zzY84Mm/eNvyy8Fs5gVabXXKUnwT3i/wVDAIhAOEm4TxxpKWoeQvre9/IIDtv09rx0W91jYst/8Ad22BG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":206088},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"3dbffea18b609db7769f29337927d550a7e95f46","mcpName":"com.workix/mcp","scripts":{"dev":"tsx src/index.ts","build":"tsc","smoke":"npm run build && node scripts/smoke-preset.mjs mobile_dev","start":"node dist/index.js","build:all":"npm run build && npm run pack:adapters","smoke:hub":"node scripts/smoke-hub.mjs","typecheck":"tsc --noEmit","upwork:token":"node scripts/upwork-token.mjs","pack:adapters":"node scripts/pack-adapters.mjs","prepublishOnly":"npm run build","smoke:startups":"npm run build && node scripts/smoke-preset.mjs startups_products"},"_npmUser":{"name":"f2p","email":"mail@workix.co"},"repository":{"url":"git+https://github.com/facetoplace/Workix.git","type":"git","directory":"mcp"},"_npmVersion":"11.3.0","description":"Workix MCP — hub catalog, freelance digest/search, and proposal helpers for AI agents","directories":{},"_nodeVersion":"24.0.1","dependencies":{"tar":"^7.4.3","zod":"^3.25.76","dotenv":"^17.4.2","kwork-api":"^1.3.3","rss-parser":"^3.13.0","socket.io-client":"^2.5.0","https-proxy-agent":"^9.1.0","socks-proxy-agent":"^10.1.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.5","esbuild":"^0.25.0","typescript":"^5.5.4","@types/node":"^22.12.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.1.1_1785097313792_0.7566095049789647","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@workix/mcp","version":"0.1.2","keywords":["mcp","model-context-protocol","workix","freelance","jobs","ai-agents","cursor"],"author":{"name":"Workix","email":"mail@workix.co"},"license":"SEE LICENSE IN LICENSE","_id":"@workix/mcp@0.1.2","maintainers":[{"name":"f2p","email":"mail@workix.co"}],"homepage":"https://workix.co","bugs":{"url":"https://github.com/facetoplace/Workix/issues"},"bin":{"workix-mcp":"dist/index.js"},"dist":{"shasum":"4d44d1008151e99ccebcdd4034a9dbaaac8bd04b","tarball":"https://registry.npmjs.org/@workix/mcp/-/mcp-0.1.2.tgz","fileCount":89,"integrity":"sha512-2la3XuaE2TBDPVWLbzYmwBnou2i6VMjvL/pTk61u07yb6rhltzQ+ws6OGBL+pdqRJESUFQZLlS0BtSCQXIzNuQ==","signatures":[{"sig":"MEQCIEGqURWziQyYE3Wzssb++NyXCTD/Z/X8npE+CWYq/4+3AiBQ14C6sijuzJq3/CSJ841/uzjZvJUlRLrlFoq2PeCgkw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":206087},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"3dbffea18b609db7769f29337927d550a7e95f46","mcpName":"co.workix/mcp","scripts":{"dev":"tsx src/index.ts","build":"tsc","smoke":"npm run build && node scripts/smoke-preset.mjs mobile_dev","start":"node dist/index.js","build:all":"npm run build && npm run pack:adapters","smoke:hub":"node scripts/smoke-hub.mjs","typecheck":"tsc --noEmit","upwork:token":"node scripts/upwork-token.mjs","pack:adapters":"node scripts/pack-adapters.mjs","prepublishOnly":"npm run build","smoke:startups":"npm run build && node scripts/smoke-preset.mjs startups_products"},"_npmUser":{"name":"f2p","email":"mail@workix.co"},"repository":{"url":"git+https://github.com/facetoplace/Workix.git","type":"git","directory":"mcp"},"_npmVersion":"11.3.0","description":"Workix MCP — hub catalog, freelance digest/search, and proposal helpers for AI agents","directories":{},"_nodeVersion":"24.0.1","dependencies":{"tar":"^7.4.3","zod":"^3.25.76","dotenv":"^17.4.2","kwork-api":"^1.3.3","rss-parser":"^3.13.0","socket.io-client":"^2.5.0","https-proxy-agent":"^9.1.0","socks-proxy-agent":"^10.1.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.5","esbuild":"^0.25.0","typescript":"^5.5.4","@types/node":"^22.12.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.1.2_1785098133828_0.3134654350835211","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@workix/mcp","version":"0.1.3","keywords":["mcp","model-context-protocol","workix","freelance","jobs","ai-agents","cursor"],"author":{"name":"Workix","email":"mail@workix.co"},"license":"SEE LICENSE IN LICENSE","_id":"@workix/mcp@0.1.3","maintainers":[{"name":"f2p","email":"mail@workix.co"}],"homepage":"https://workix.co","bugs":{"url":"https://github.com/facetoplace/Workix/issues"},"bin":{"workix-mcp":"dist/index.js"},"dist":{"shasum":"51152fc9f6b548479c7f6a0036db4b94fbfd91d7","tarball":"https://registry.npmjs.org/@workix/mcp/-/mcp-0.1.3.tgz","fileCount":89,"integrity":"sha512-RFFkR7GINrgnAvzcMlyOq4WGjAkwFAEJzLD7BmmfmQQZ6WH9wURvujWmLmmK1FK9bytuhquopTgYBx0j4X4TIw==","signatures":[{"sig":"MEUCIChd+l56jAgc8gHG4yCl13PeDAI1CRbVtd4iQVuY2afjAiEAxPSurZW9FZRjpzVKZT5CNywAZag/cRuznDBasbw4GJ4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":208206},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"3dbffea18b609db7769f29337927d550a7e95f46","mcpName":"co.workix/mcp","scripts":{"dev":"tsx src/index.ts","build":"tsc","smoke":"npm run build && node scripts/smoke-preset.mjs mobile_dev","start":"node dist/index.js","build:all":"npm run build && npm run pack:adapters","smoke:hub":"node scripts/smoke-hub.mjs","typecheck":"tsc --noEmit","upwork:token":"node scripts/upwork-token.mjs","pack:adapters":"node scripts/pack-adapters.mjs","prepublishOnly":"npm run build","smoke:startups":"npm run build && node scripts/smoke-preset.mjs startups_products"},"_npmUser":{"name":"f2p","email":"mail@workix.co"},"repository":{"url":"git+https://github.com/facetoplace/Workix.git","type":"git","directory":"mcp"},"_npmVersion":"11.3.0","description":"Workix MCP for AI agents: search the Workix hub (projects/startups, roles, orders, performers), create or update your listings and performer profile with WORKIX_AGENT_KEY, collect freelance/job digests from supported boards (adapters stay local — platform","directories":{},"_nodeVersion":"24.0.1","dependencies":{"tar":"^7.4.3","zod":"^3.25.76","dotenv":"^17.4.2","kwork-api":"^1.3.3","rss-parser":"^3.13.0","socket.io-client":"^2.5.0","https-proxy-agent":"^9.1.0","socks-proxy-agent":"^10.1.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.5","esbuild":"^0.25.0","typescript":"^5.5.4","@types/node":"^22.12.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.1.3_1785098534258_0.43256422951037266","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@workix/mcp","version":"0.3.0","keywords":["mcp","model-context-protocol","workix","freelance","jobs","vacancies","job-search","job-board","remote-work","remote-jobs","work-from-home","gigs","hiring","career","ai-agents","cursor","claude","upwork","freelancer","hh","headhunter","kwork","freelancehunt","remoteok","remotive","weworkremotely","himalayas","adzuna","jobicy","arbeitnow","themuse","working-nomads","aquent","telegram"],"author":{"name":"Workix","email":"mail@workix.co"},"license":"SEE LICENSE IN LICENSE","_id":"@workix/mcp@0.3.0","maintainers":[{"name":"f2p","email":"mail@workix.co"}],"homepage":"https://workix.co","bugs":{"url":"https://github.com/facetoplace/Workix/issues"},"bin":{"workix-mcp":"dist/index.js"},"dist":{"shasum":"e564027bfa3034eb9212599cd8de92902fd277c8","tarball":"https://registry.npmjs.org/@workix/mcp/-/mcp-0.3.0.tgz","fileCount":204,"integrity":"sha512-7+bfo8S5H4+4omkqudYQ2ewL9wR+p7TcW71JNWnQN8mX8V5jCvvbQwoMfVURfMbt0FrorWykYjDbBEYrSV3cgA==","signatures":[{"sig":"MEQCIEVfytUl++cymOUV3aerM8bkhUK6BIhvIQ581UcFRtPXAiAUWpQrHR4gnvdoSahAE5yYnG/yQ6qfiCJJNKz3dJDz5Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":449631},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"1c688ac5ad3f2a2bb20c491e57c7cdbe2d70795a","mcpName":"co.workix/mcp","scripts":{"dev":"tsx src/index.ts","build":"tsc","smoke":"npm run build && node scripts/smoke-preset.mjs mobile_dev","start":"node dist/index.js","hh:check":"node scripts/hh-login.mjs --check","hh:login":"npm run build && node scripts/hh-login.mjs","tg:login":"node scripts/tg-login.mjs","build:all":"npm run build && npm run pack:adapters","smoke:hub":"node scripts/smoke-hub.mjs","typecheck":"tsc --noEmit","hh:capture":"node scripts/hh-capture.mjs","upwork:token":"node scripts/upwork-token.mjs","pack:adapters":"node scripts/pack-adapters.mjs","prepublishOnly":"npm run build","smoke:startups":"npm run build && node scripts/smoke-preset.mjs startups_products","validate:tg-channels":"node scripts/validate-telegram-channels.mjs"},"_npmUser":{"name":"f2p","email":"mail@workix.co"},"repository":{"url":"git+https://github.com/facetoplace/Workix.git","type":"git","directory":"mcp"},"_npmVersion":"11.3.0","description":"Workix MCP for AI agents: search the Workix hub (projects/startups, roles, orders, performers), create or update your listings and performer profile with WORKIX_AGENT_KEY, collect freelance/job digests from supported boards (adapters stay local — platform","directories":{},"_nodeVersion":"24.0.1","dependencies":{"tar":"^7.4.3","zod":"^3.25.76","dotenv":"^17.4.2","kwork-api":"^1.3.3","rss-parser":"^3.13.0","socket.io-client":"^2.5.0","https-proxy-agent":"^9.1.0","socks-proxy-agent":"^10.1.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.5","esbuild":"^0.25.0","typescript":"^5.5.4","@types/node":"^22.12.0"},"optionalDependencies":{"tdl":"^8.1.0","telegram":"^2.26.22","prebuilt-tdlib":"^0.1008066.0","puppeteer-core":"^24.43.1"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.3.0_1786209383577_0.7516049312357564","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@workix/mcp","version":"0.3.1","keywords":["mcp","model-context-protocol","workix","freelance","jobs","vacancies","job-search","job-board","remote-work","remote-jobs","work-from-home","gigs","hiring","career","ai-agents","cursor","claude","upwork","freelancer","hh","headhunter","kwork","freelancehunt","remoteok","remotive","weworkremotely","himalayas","adzuna","jobicy","arbeitnow","themuse","working-nomads","aquent","telegram"],"author":{"name":"Workix","email":"mail@workix.co"},"license":"SEE LICENSE IN LICENSE","_id":"@workix/mcp@0.3.1","maintainers":[{"name":"f2p","email":"mail@workix.co"}],"homepage":"https://workix.co","bugs":{"url":"https://github.com/facetoplace/Workix/issues"},"bin":{"workix-mcp":"dist/index.js"},"dist":{"shasum":"9d5a53840c3e257e168f948a3b551a226c746b30","tarball":"https://registry.npmjs.org/@workix/mcp/-/mcp-0.3.1.tgz","fileCount":204,"integrity":"sha512-FHQYgxX4W56S48OPD5LUkMjjTkaV0sIuK8C/EomkIBApR7EdA//23p1Ni/K1eXE6YzxNA+LwEV6bs5s3HoLE3g==","signatures":[{"sig":"MEUCIEf0B216bTVwLWsLCJlFUCsaw4cOR41yOmQQYL6oIBRjAiEA3nVseBNKgy4eDbcm8U4digQvdHdOGR6rnQQPQ7TCyZ8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":449610},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"1c688ac5ad3f2a2bb20c491e57c7cdbe2d70795a","mcpName":"co.workix/mcp","scripts":{"dev":"tsx src/index.ts","build":"tsc","smoke":"npm run build && node scripts/smoke-preset.mjs mobile_dev","start":"node dist/index.js","hh:check":"node scripts/hh-login.mjs --check","hh:login":"npm run build && node scripts/hh-login.mjs","tg:login":"node scripts/tg-login.mjs","build:all":"npm run build && npm run pack:adapters","smoke:hub":"node scripts/smoke-hub.mjs","typecheck":"tsc --noEmit","hh:capture":"node scripts/hh-capture.mjs","upwork:token":"node scripts/upwork-token.mjs","pack:adapters":"node scripts/pack-adapters.mjs","prepublishOnly":"npm run build","smoke:startups":"npm run build && node scripts/smoke-preset.mjs startups_products","validate:tg-channels":"node scripts/validate-telegram-channels.mjs"},"_npmUser":{"name":"f2p","email":"mail@workix.co"},"repository":{"url":"git+https://github.com/facetoplace/Workix.git","type":"git","directory":"mcp"},"_npmVersion":"11.3.0","description":"Remote jobs, freelance gigs and vacancies from 24 boards — Upwork, Freelancer.com, hh.ru, Kwork, RemoteOK, WeWorkRemotely, Adzuna and more — for AI agents over MCP. Search, digest, draft proposals and prepare apply steps; plus the Workix hub of startups, ","directories":{},"_nodeVersion":"24.0.1","dependencies":{"tar":"^7.4.3","zod":"^3.25.76","dotenv":"^17.4.2","kwork-api":"^1.3.3","rss-parser":"^3.13.0","socket.io-client":"^2.5.0","https-proxy-agent":"^9.1.0","socks-proxy-agent":"^10.1.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.5","esbuild":"^0.25.0","typescript":"^5.5.4","@types/node":"^22.12.0"},"optionalDependencies":{"tdl":"^8.1.0","telegram":"^2.26.22","prebuilt-tdlib":"^0.1008066.0","puppeteer-core":"^24.43.1"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.3.1_1786209602413_0.008187180309163322","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@workix/mcp","version":"1.0.0","description":"Remote jobs, freelance gigs and vacancies from 24 boards — Upwork, Freelancer.com, hh.ru, Kwork, RemoteOK, WeWorkRemotely, Adzuna and more — for AI agents over MCP. Search, digest, draft proposals and prepare apply steps; plus the Workix hub of startups, ","type":"module","main":"dist/index.js","types":"dist/index.d.ts","bin":{"workix-mcp":"dist/index.js"},"scripts":{"build":"tsc","prepublishOnly":"npm run build","pack:adapters":"node scripts/pack-adapters.mjs","build:all":"npm run build && npm run pack:adapters","start":"node dist/index.js","dev":"tsx src/index.ts","typecheck":"tsc --noEmit","validate:tg-channels":"node scripts/validate-telegram-channels.mjs","smoke":"npm run build && node scripts/smoke-preset.mjs mobile_dev","smoke:startups":"npm run build && node scripts/smoke-preset.mjs startups_products","smoke:hub":"node scripts/smoke-hub.mjs","upwork:token":"node scripts/upwork-token.mjs","tg:login":"node scripts/tg-login.mjs","hh:login":"npm run build && node scripts/hh-login.mjs","hh:check":"node scripts/hh-login.mjs --check","hh:capture":"node scripts/hh-capture.mjs","workopia:login":"npm run build && node scripts/workopia-login.mjs","hh:apply":"node scripts/hh-apply.mjs","hh:chat":"node scripts/hh-chat-send.mjs"},"engines":{"node":">=22.5"},"keywords":["mcp","model-context-protocol","workix","freelance","jobs","vacancies","job-search","job-board","remote-work","remote-jobs","work-from-home","gigs","hiring","career","ai-agents","cursor","claude","upwork","freelancer","hh","headhunter","kwork","freelancehunt","remoteok","remotive","weworkremotely","himalayas","adzuna","jobicy","arbeitnow","themuse","working-nomads","aquent","telegram"],"author":{"name":"Workix","email":"mail@workix.co"},"homepage":"https://workix.co","repository":{"type":"git","url":"git+https://github.com/facetoplace/Workix.git","directory":"mcp"},"bugs":{"url":"https://github.com/facetoplace/Workix/issues"},"license":"MIT","mcpName":"co.workix/mcp","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"dependencies":{"@modelcontextprotocol/sdk":"^1.29.0","dotenv":"^17.4.2","https-proxy-agent":"^9.1.0","kwork-api":"^1.3.3","rss-parser":"^3.13.0","socket.io-client":"^2.5.0","socks-proxy-agent":"^10.1.0","tar":"^7.4.3","zod":"^3.25.76"},"optionalDependencies":{"prebuilt-tdlib":"^0.1008066.0","puppeteer-core":"^24.43.1","tdl":"^8.1.0","telegram":"^2.26.22"},"devDependencies":{"@types/node":"^22.12.0","esbuild":"^0.25.0","tsx":"^4.16.5","typescript":"^5.5.4"},"_id":"@workix/mcp@1.0.0","gitHead":"1c688ac5ad3f2a2bb20c491e57c7cdbe2d70795a","_nodeVersion":"24.0.1","_npmVersion":"11.3.0","dist":{"integrity":"sha512-uLq3BKPxb6EPO8skzsit2nI7zUYZ2GAp1SBsOfAHeOVIfs0tE9lOSQTk20SRXg+BKuGJDBuCdjAFqDtnvu3gig==","shasum":"e7a196e310e88e8fb7b59de8a5e58510e96cf0be","tarball":"https://registry.npmjs.org/@workix/mcp/-/mcp-1.0.0.tgz","fileCount":281,"unpackedSize":726144,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIG+6CFVquBf/Q+8BiTZa0aeJm9/bG1z92FHGkz7bWYelAiEA86AFstV/PAqjO0HtnwgN8XLeL/atHD4l9dJfvsDWV/g="}]},"_npmUser":{"name":"f2p","email":"mail@workix.co"},"directories":{},"maintainers":[{"name":"f2p","email":"mail@workix.co"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp_1.0.0_1786405399770_0.8171853010306067"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-26T20:20:01.287Z","modified":"2026-08-10T23:43:20.073Z","0.1.0":"2026-07-26T20:20:01.587Z","0.1.1":"2026-07-26T20:21:53.932Z","0.1.2":"2026-07-26T20:35:33.980Z","0.1.3":"2026-07-26T20:42:14.413Z","0.3.0":"2026-08-08T17:16:23.789Z","0.3.1":"2026-08-08T17:20:02.562Z","1.0.0":"2026-08-10T23:43:19.912Z"},"bugs":{"url":"https://github.com/facetoplace/Workix/issues"},"author":{"name":"Workix","email":"mail@workix.co"},"license":"MIT","homepage":"https://workix.co","keywords":["mcp","model-context-protocol","workix","freelance","jobs","vacancies","job-search","job-board","remote-work","remote-jobs","work-from-home","gigs","hiring","career","ai-agents","cursor","claude","upwork","freelancer","hh","headhunter","kwork","freelancehunt","remoteok","remotive","weworkremotely","himalayas","adzuna","jobicy","arbeitnow","themuse","working-nomads","aquent","telegram"],"repository":{"type":"git","url":"git+https://github.com/facetoplace/Workix.git","directory":"mcp"},"description":"Remote jobs, freelance gigs and vacancies from 24 boards — Upwork, Freelancer.com, hh.ru, Kwork, RemoteOK, WeWorkRemotely, Adzuna and more — for AI agents over MCP. Search, digest, draft proposals and prepare apply steps; plus the Workix hub of startups, ","maintainers":[{"name":"f2p","email":"mail@workix.co"}],"readme":"# Workix MCP\n\nLocal MCP server for AI agents ([Cursor](https://cursor.com), Claude, etc.) that work with the [Workix hub](https://workix.co) and freelance boards.\n\nWorkix is a shared catalog where **projects** (startups/products/communities), **roles & orders**, and **performers** find each other. It is not a closed freelance marketplace: listings point to the owner’s preferred contact or apply flow. Agents use this MCP to search that catalog, manage your listings, and also pull opportunities from external boards while keeping platform credentials on the user’s machine.\n\n**Install (recommended):** clone this repo → `mcp/` → `npm install && npm run build` · Docs: [workix.co/agent](https://workix.co/agent) · [api.txt](https://workix.co/api.txt) · [llms.txt](https://workix.co/llms.txt)  \nOptional shortcut: `npx -y @workix/mcp` (npm may lag behind git).\n\n### Where it is published\n\n| Channel | Link / id |\n|---------|-----------|\n| npm | [@workix/mcp](https://www.npmjs.com/package/@workix/mcp) |\n| Official MCP Registry | [`co.workix/mcp`](https://registry.modelcontextprotocol.io/v0.1/servers?search=co.workix/mcp) |\n| Source | [facetoplace/Workix](https://github.com/facetoplace/Workix) → `mcp/` |\n| Dataset | [workix/workix-mcp](https://huggingface.co/datasets/workix/workix-mcp) on Hugging Face |\n| Community catalogs | [mcp.so](https://mcp.so/) · [mcpservers.org](https://mcpservers.org/) · [mcpmarket.com](https://mcpmarket.com/) |\n\n### Dataset\n\n[**workix/workix-mcp**](https://huggingface.co/datasets/workix/workix-mcp) — open dataset generated from this server's own tool definitions (Apache-2.0), in three configs:\n\n| Config | Rows | What |\n|--------|------|------|\n| `qa` | 83 | hand-written Q&A in en/ru/es: what Workix is, what data it exposes, how clients use it |\n| `calls` | 144 | `user prompt → assistant tool_call` in OpenAI messages format |\n| `tools` | 54 | the raw tool catalog: name, description, JSON Schema |\n\n```python\nfrom datasets import load_dataset\nqa = load_dataset(\"workix/workix-mcp\", \"qa\", split=\"train\")\n```\n\nRegenerate after changing the tool surface — it reads `tools/list` off the running server:\n\n```bash\nnode scripts/dump-tools.mjs\nHF_REPO=workix/workix-mcp node scripts/dataset-build.mjs\n```\n\nSources: [`scripts/dump-tools.mjs`](./scripts/dump-tools.mjs) · [`scripts/dataset-build.mjs`](./scripts/dataset-build.mjs) · seeds in [`scripts/dataset-qa.json`](./scripts/dataset-qa.json)\n\n### What you can use it for\n\n- **Discover** — search hub projects, roles, orders, and performers relevant to a skill or niche\n- **Publish / update** — create or edit a startup or role, maintain a performer profile (`WORKIX_AGENT_KEY`)\n- **Freelance workflow** — digests and search across supported boards, draft proposals, prepare browser apply steps (submit only with human confirmation)\n- **Ship a product card** — publish a live site/PWA URL into the dStore catalog and find similar apps\n\n- **Hub tools** — search/list/create projects, roles, profile; feedback/support (needs `WORKIX_AGENT_KEY`)\n- **Board tools** — digest / search / draft / prepare-apply on Upwork, Freelancehunt, Kwork, FL RSS, … (credentials stay in your env)\n- **Downloadable adapters** — heavy board modules are **not** required at install; MCP downloads them from the hub registry on first use and caches locally\n\nOpen contribution: see [CONTRIBUTING.md](./CONTRIBUTING.md) (adapters + **Telegram channels catalog** PRs). Agent prompt & storefront: [../README.md](../README.md).\n\n**Telegram channels:** shared list [`telegram-channels.example.json`](./telegram-channels.example.json) — how to add via PR: [TELEGRAM-CHANNELS.md](./TELEGRAM-CHANNELS.md).\n\n## What the agent remembers, and how to read it\n\nAll local state is in the SQLite file below. It is what stops a second session\nfrom re-applying to a job, re-posting a card, or showing the same digest twice.\n\n| What | Table | Read it with | Written by |\n|------|-------|--------------|------------|\n| Job cards | `jobs` | `workix_search`, `workix_get_job` | `workix_digest` / `workix_search` while collecting |\n| Already shown in a digest | `shown_digest` | `workix_job_state` → `shown_in_digest` | `workix_digest` marks them; `only_new` (default) then hides them |\n| Where we applied, and the status | `outreach` | `workix_outreach_list` (`job_id`, `contact`, `channel`, `status`) | **`workix_outreach_log`** — required after any draft or send |\n| Proposal drafts | `drafts` | `workix_job_state` → `draft` | `workix_draft_proposal` |\n| Already mirrored to workix.co | `hub_shares` | `workix_hub_share_status`, `workix_history` | `workix_share_jobs`, `workix_digest share_to_hub:true` |\n| Where the last session stopped | `checkpoints` | `workix_checkpoint_get` | `workix_checkpoint_set` |\n| Board response cache | `fetch_cache` | `workix_store_status` | collection; `force_refresh:true` bypasses |\n\n**One call before acting on a card:**\n\n```bash\nworkix_job_state {\"job_id\": \"1ca5ff1099b3ca91\"}   # or {\"url\": \"https://…\"}\n```\n\nIt returns whether the card was shown in a digest and when, whether it is already\non workix.co (sid + link), whether a draft exists, every apply attempt with its\nstatus, the hub tracker row (`hub_application`, so an apply made on another\nmachine also counts), and a `next` list of what is left. Call it before\n`workix_draft_proposal`, `workix_submit_proposal` and `workix_share_jobs`.\n\n**Applications live on the hub too.** The local `outreach` table only knows this\nmachine. `workix_track_apply` records the application on workix.co: it publishes\nthe job into the catalog if it is missing, stores status + date + the text that\nwas sent (privately — the listing shows only an anonymous counter), and mirrors\nthe row locally. `workix_submit_proposal` calls it automatically when the agent\nsends the proposal itself. When the human applied by hand, **ask them for the\ntext they sent** and pass it as `text` with `via: \"user\"` — their own wording is\nthe best base for the next proposal, which is what `workix_list_applies` is for.\n`workix_sync_applies` pulls the history back into a fresh local store, and\n`workix_delete_apply` (needs `confirm: true`) removes a row that should not be\nthere — the mirrored job stays in the catalog, since that listing is public board\ncontent rather than part of your private log.\n\n| Funnel status | Meaning |\n|---------------|---------|\n| `draft` | prepared, not sent — excluded from the public counter |\n| `sent` → `viewed` | delivered; the other side opened it |\n| `reply` → `interview` → `offer` → `hired` | it is going somewhere |\n| `rejected` / `closed` | over |\n\n**Mirroring is not applying.** `workix_share_jobs` writes an outreach row with\n`channel: \"hub\"` so the mirror is auditable, but those rows are catalog copies,\nnot messages to a client. `workix_job_state` keeps them out of `outreach` and out\nof `applied`, and reports them under `hub_share` instead — otherwise a reposted\ncard would look like one you had already answered.\n\n**Outreach statuses:** `draft` (written, not sent) · `sent` · `ok` (confirmed\ndelivered/accepted) · `reply` (client answered) · `skip` (decided against it) ·\n`blocked` (the platform refused — KYC, connects, ban). Log `draft` when the text\nis generated, then update the **same id** to `sent`/`ok` once the user approves\nand it actually goes out.\n\n**Session shape:** open with `workix_checkpoint_get` so search resumes instead of\nrestarting; close (or pause, or switch platform) with `workix_checkpoint_set`\ncarrying what was done, what is next, which surfaces are finished, and what is\nblocked.\n\n## Local store and shared cache\n\nEverything local lives in one SQLite file, `$WORKIX_MCP_DATA/workix.db` (default `mcp/data/`):\njob cards, drafts, the outreach log, checkpoints, hub shares, and the board response\ncache. It uses `node:sqlite`, which ships with Node — nothing compiles at install time, but\nit does mean **Node 22.5+**.\n\nAn existing `store.json` is imported on first start and renamed to `store.json.migrated`;\nthe import runs once and the original is left on disk in case you want it back.\n\n**Why not the old JSON file.** Every read parsed the whole store, so a 13MB file cost ~126ms\nper call — and `wasShownInDigest()` sits inside a filter loop, which turned a digest into a\nminute of pure parsing. It was also unsafe with more than one session: each MCP process did\nread-modify-write on the same file, so concurrent writes were lost, and a torn write made the\nloader fall back to an empty store and discard everything on the next save. Measured after\nthe move: 500 `wasShownInDigest` calls went from ~63s to **9ms**.\n\n**The cache is what makes a second session cheap.** Board responses are keyed by source plus\nthe parameters that shaped the request, so two sessions searching the same thing share one\nfetch. Measured on a full `include_jobs` run: **252s cold → 16.5s warm**, and a separate\nprocess sees the same cache because it is on disk rather than in memory.\n\nTTL is per source class, not global — a public RSS feed is cheap to re-read, a metered API is\nnot, so JobsPipe holds results for hours while a feed holds them for minutes. Only successful,\nnon-empty results are cached: a blocked board retries next run instead of staying dark.\n\n```bash\nworkix_store_status                                  # rows, db size, what the cache is serving\nworkix_store_status {\"prune_cache\": true}            # drop expired entries\nworkix_store_status {\"prune_jobs_days\": 30}          # drop old cards with no work attached\nworkix_store_status {\"clear_cache\": \"jobspipe\"}      # or \"all\"\n```\n\n`force_refresh: true` on `workix_digest` / `workix_search` bypasses the cache for one run.\nBoth report `served_from_cache` with each source's age, so a stale-looking digest is\nexplainable rather than mysterious. Pruning never removes a card that carries work — anything\nshared to the hub, drafted, or referenced by an outreach entry stays regardless of age.\n\n## Downloadable platform modules\n\nCore MCP always includes hub tools + **RSS** (FL / Weblancer / Djinni / Jobspresso / Reddit), Freelance.ru HTML (`/task` via RU SOCKS5), Product Radar hiring HTML (`/category/hiring/?page=N`, direct), **Habr Career** (frontend JSON, RSS fallback) and **employer ATS boards** (the company list is a repo file, so it cannot travel in a module).\n\nOther boards ship as modules from the hub — **36** of them, covering **64** catalogued platforms:\n\n| Registry | https://workix.co/mcp/registry.json |\n| Artifacts | https://workix.co/mcp/adapters/`<id>-<version>`.tgz |\n| Local cache | `$WORKIX_MCP_DATA/adapters/<id>/<version>/` (default `mcp/data/adapters`) |\n\nOn `workix_digest` / `workix_search`, MCP calls `ensure` for needed platforms, verifies **sha256**, extracts, and `import()`s the module. Later runs reuse the cache.\n\n**Trust model:** a module is executable code inside the MCP process. Downloads are limited to **https** hosts on an allowlist (`workix.co` + registry host; override with `WORKIX_MCP_TRUSTED_HOSTS`). Size is capped; tarball paths cannot escape the install dir. `sha256` in the registry only proves integrity against that registry — if the hub itself is compromised, treat it as RCE on every client that installs. Mitigations: keep registry on a host you control, prefer bundled `assets/mcp/adapters/*.tgz` when present, set `WORKIX_MCP_REGISTRY` to a local file for air‑gapped installs. Opt-out for custom registries: `WORKIX_MCP_ALLOW_UNTRUSTED_REGISTRY=1`.\n\n| Tool | Role |\n|------|------|\n| `workix_list_platforms` | Catalog + `installed` / `available` / `needs_env` |\n| `workix_ensure_platforms` | Download modules for given platforms |\n| `workix_install_platform` | Force install/update one module |\n| `workix_remove_platform` | Delete from local cache |\n\nOverride registry: `WORKIX_MCP_REGISTRY` (file path or URL). Offline fallback: `assets/mcp/registry.json` next to the repo / `mcp/registry.local.json` after `npm run pack:adapters`.\n\n## Contribute an adapter\n\n```text\nmcp/\n  platforms.json                 # platform id + \"module\": \"<id>\"\n  src/adapters/<id>.ts           # fetch + normalize jobs\n  src/module-entries/<id>.ts     # downloadable entry (meta + fetchJobs)\n  scripts/pack-adapters.mjs      # → assets/mcp/adapters/*.tgz + registry.json\n  src/tools/                     # MCP tool handlers\n  src/index.ts                   # tool registration\n  .env.example                   # document new env keys\n```\n\nAfter changing an adapter:\n\n```bash\nnpm run build\nnpm run pack:adapters\n```\n\nPRs: new boards, better ranking, presets (`presets.json`), tests, docs. Never commit secrets or `data/` dumps.\n\n## Adding or removing a platform — we work with everyone\n\nWorkix plays no favourites. If you run a **job board**, a **freelance marketplace**, your own\n**MCP server**, or a **Telegram channel with vacancies**, we are glad to include it — no\npartnership, contract or payment involved.\n\n**[Open an issue](https://github.com/facetoplace/Workix/issues)** and it goes both ways:\n\n- **Add me** — name the source and how to reach it: public API, RSS feed, MCP endpoint, channel\n  link. That is the whole requirement.\n- **Remove me** — if you own the platform and would rather we did not read it, say so. We take\n  it out, no argument about what your terms do or do not allow.\n- **Fix my entry** — wrong limits, wrong attribution, wrong description of your terms: tell us\n  and we correct it.\n\nWe honour attribution where it is required (Himalayas, Jobicy, Aquent), always link the\nemployer's original apply URL rather than a copy, and never submit an application without an\nexplicit human go-ahead.\n\nThe full catalogue of what is supported today — and of every third-party MCP server we probed,\nintegrated or turned down — lives in\n[`docs/16-sources-and-partners.md`](../docs/16-sources-and-partners.md).\n\n## Install\n\nNeeds **Node 22.5 or newer** — the local store uses the built-in `node:sqlite`, which keeps\nthis dependency-free rather than pulling in a native SQLite module that has to compile on\nevery machine.\n\n```bash\ncd mcp\nnpm install\nnpm run build\n# optional: refresh local registry tarballs from source\nnpm run pack:adapters\n```\n\nOn Windows ARM, native scripts may be disabled (`.npmrc`: `ignore-scripts=true`) because of optional native deps.\n\n## Cursor `mcp.json`\n\nRecommended (from source — always the freshest build):\n\n```json\n{\n  \"mcpServers\": {\n    \"workix\": {\n      \"command\": \"node\",\n      \"args\": [\"FULL/PATH/TO/Workix/mcp/dist/index.js\"],\n      \"env\": {\n        \"WORKIX_API\": \"https://workix.co\",\n        \"WORKIX_AGENT_KEY\": \"wix_…\"\n      }\n    }\n  }\n}\n```\n\nOptional npm shortcut: `\"command\": \"npx\"`, `\"args\": [\"-y\", \"@workix/mcp\"]` (may lag behind the GitHub `mcp/` tree).\n\nOptional board credentials (examples — see `.env.example`):\n\n- `UPWORK_CLIENT_ID` / `UPWORK_CLIENT_SECRET` / OAuth flow tools\n- `FREELANCEHUNT_TOKEN`\n- `KWORK_LOGIN` / `KWORK_PASSWORD` / `KWORK_PHONE4` / `KWORK_PROXY`\n- Proxy pool: `PROXY_1=` (subscription URL or socks/http list)\n\nNever send platform passwords to the hub — only to this local process.\n\n## Profile\n\n```bash\ncp profile.example.md profile.md\n```\n\nOptional: `WORKIX_PROFILE_PATH`, `WORKIX_MCP_DATA`.\n\n## Hub tools (need WORKIX_API; writes need WORKIX_AGENT_KEY)\n\n| Tool | Role |\n|------|------|\n| `workix_hub_health` / `workix_hub_register` / `workix_hub_me` / `workix_hub_rotate_key` | Auth & health (`rotate_key` needs `confirm:true`; writes `mcp/.env` by default) |\n| `workix_list_startups` / `workix_get_startup` / `workix_create_startup` / `workix_update_startup` | Projects — products, startups, early ideas OK (`pending` = publish) |\n| `workix_list_performers` / `workix_get_performer` | Performers (builders + bloggers/creators) + their listings |\n| `workix_list_hub_orders` / `workix_get_hub_order` | Hub orders (`scraped` / `external` → no personal publisher card; detail may include `external`) |\n| `workix_list_roles` / `workix_create_role` / `workix_update_role` | Roles / orders (concrete asks; paid or cofounder) |\n| `workix_share_jobs` | Mirror local board job ids → hub catalog (`POST /orders/share`; prefer digest flag) |\n| `workix_get_profile` / `workix_update_profile` | Create/update own performer card via MCP; claim vanity `slug` → shareable `https://workix.co/{slug}` + free CV PDF `https://workix.co/{slug}/pdf` (also `/{slug}.json`) |\n\nWrite tools echo a short **who can publish** guide: early stage welcome; moderation (`pending`) is normal — do not discourage listing.\n| `workix_hub_apply` | Apply on hub |\n| `workix_feedback` | bug / suggestion / support / other → hub admins (rate-limited) |\n\n**Rate limits (429):** hub and dStore errors include `rateLimited: true`, human `message`, `retryAfterSec`, optional `limits`, and an agent `hint` — do not retry until the cooldown passes.\n\n## Board tools (local credentials)\n\n| Tool | Role |\n|------|------|\n| `workix_dstore_search` / `_similar` / `_get` / `_publish` / `_list` / `_quota` | [dStore](https://dstore.one) catalog — same REST as official **dstore-mcp** ([api.txt](https://dstore.one/api.txt)) |\n| _(optional)_ separate MCP `dstore` | `search_catalog`, `get_app`, `get_similar`, `add_url`, `get_list`, `quota_status` — see api.txt §0 |\n| `workix_digest` / `workix_search` / `workix_get_job` | Read boards (auto-downloads adapters). `share_to_hub:true` on digest batch-mirrors cards to hub (no per-item confirm; needs `WORKIX_AGENT_KEY`) |\n| `workix_draft_proposal` | Draft reply |\n| `workix_outreach_log` / `workix_outreach_list` | Local log: contact, channel, full text, status (`draft`/`sent`/`ok`…). Mirror into `docs/apply-log-*.md` |\n| `workix_track_apply` | The application actually went out → record it on workix.co (publishes the job if missing, stores status + date + the sent text, privately) |\n| `workix_list_applies` / `workix_update_apply` / `workix_sync_applies` | Cross-device apply history and past texts · move the funnel · pull the history into a fresh local store |\n| `workix_checkpoint_set` / `workix_checkpoint_get` | Search pause/resume: where stopped, next, surfaces. Mirror CHECKPOINT in apply-log |\n| `workix_hub_share_status` / `workix_history` | What is already on workix.co vs local-only; unified hubShares + outreach + checkpoints |\n| `workix_submit_proposal` | Submit only with `confirm: true` after human OK |\n| `workix_prepare_browser_apply` | Browser checklist |\n| `workix_sources_status` / `workix_list_platforms` / `workix_open_watch_source` | Status & watch |\n| `workix_ensure_platforms` / `workix_install_platform` / `workix_remove_platform` | Adapter cache |\n| `workix_upwork_auth_url` / `workix_upwork_exchange_code` | Upwork OAuth |\n| `workix_tg_status` / `workix_tg_auth` / `workix_tg_search` | Optional Telegram (GramJS; TDLib where native works). Install: `npm install telegram`. Env: `TG_APP_API_ID` + `TG_APP_API_HASH`. Login: `npm run tg:login`. |\n\n### hh.ru session\n\nПолная инструкция: **[HH.md](./HH.md)**. Логин в браузере, статусы откликов,\nчтение переписки, полуручная отправка.\n\n```bash\ncd mcp\nnpm run hh:login    # логин/пароль вводишь сам в окне Chrome\nnpm run hh:check    # проверить сессию\n```\n\n`api.hh.ru` анонимно отдаёт 403, поэтому поиск идёт через залогиненный сайт;\nкуки и профиль лежат только в `mcp/data/` и на хаб не уходят.\n\nПеред тем как автоматизировать отклики — **прочитай раздел «Три грабли»** в\n[HH.md](./HH.md). Клик по «Откликнуться» может сам по себе быть откликом,\nполе хранит черновик, а `page.type()` отправляет форму на переводах строк.\nКаждая из этих трёх особенностей уже стоила реального отклика.\n\n### Optional Telegram\n\nПолная инструкция: **[TELEGRAM.md](./TELEGRAM.md)**. На **Windows ARM64** — только GramJS (`telegram`), не `prebuilt-tdlib`.\n\n```bash\ncd mcp\nnpm install telegram\n# TG_APP_API_ID + TG_APP_API_HASH in .env\nnpm run tg:login          # phone/code в терминале\n# restart MCP → workix_tg_status → workix_tg_search\n```\n\n### Job boards on `include_jobs` (added 2026-08-09)\n\nNo flag beyond `include_jobs: true`, no key:\n\n| Source | Region | Endpoint |\n|--------|--------|----------|\n| **Trudvsem** (Работа России) | RU | open data `/api/v1/vacancies` — 514k live postings |\n| **Employer ATS boards** | global | Greenhouse · Ashby · Lever · SmartRecruiters · Workable, one call per company |\n| **Djinni** | UA/EU | `djinni.co/jobs/rss/` |\n| **NoFluffJobs** | PL/EU | `/api/joboffers/main` (3.7MB, not the 140MB `/api/posting`) |\n| **Landing.jobs** | PT/EU | `/api/v1/jobs` |\n| **Get on Board** | LATAM | `/api/v0/search/jobs` |\n| **Jobspresso** | global remote | `?feed=job_feed` |\n| **Reddit** | global | Atom only — the JSON API is OAuth-gated and 403s datacenter IPs |\n| **getmatch** (added 2026-08-10) | RU / relocate | `/api/offers` — open salary on most cards, no server-side search |\n| **HN \"Who is hiring?\"** (added 2026-08-10) | global | the monthly thread via `hn.algolia.com/api/v1` |\n\n| **Dice** (added 2026-08-10) | US tech-only | its own MCP server — see below |\n\nTwo notes on getmatch and HN. **getmatch** has no server-side search at all — `q`, `search`,\n`text`, `query` and `sq` are silently dropped, so `keywords` are matched here over a page pulled\nin full (`GETMATCH_LIMIT`, default 100 of 750). **HN** keeps only top-level comments of the\n\"Who is hiring?\" thread: a reply is discussion, not a posting, and the thread's own rule that\nposters must be hiring directly is why it carries no recruiter spam and a live contact in the\nbody. `HN_HIRING_STORY=<id>` reads a specific month instead of the current one.\n\nATS coverage is the company list in [`ats-companies.json`](./ats-companies.json) — add rows to\nwiden it, or override the file with `ATS_COMPANIES=greenhouse:stripe,ashby:linear`. The apply\nURL is the employer's own board, so it never goes stale the way an aggregator copy does.\n\n### Boards that only speak MCP\n\nSome boards ship no public REST API at all — their MCP server *is* the public surface. Workix\ntalks to them as a client through [`src/mcpClient.ts`](./src/mcpClient.ts) (JSON-RPC over\nstreamable HTTP, SSE-aware, session-header aware), the same way the JobSpy bridge talks to\nsomebody else's scrapers instead of reimplementing them.\n\n| Board | Server | Auth | State |\n|-------|--------|------|-------|\n| **Dice** | `mcp.dice.com/mcp` | none | ✅ open — 2 574 hits for \"python\", live apply URLs |\n| **Workopia** | `workopia.io/api/mcp-jobs` | free account | 🔑 `tools/list` is anonymous, `tools/call` is not |\n\n**Dice** is worth naming for two fields nothing else here carries: a salary on most cards, and\n`willingToSponsor` — visa sponsorship as a filter (`DICE_SPONSOR_ONLY=1`, or\n`willing_to_sponsor` per call; 274 of those 2 574 sponsor). Its `posted_date` is a\ncase-sensitive enum — `ONE`/`THREE`/`SEVEN`, and lowercase gets you a pydantic error rather\nthan a coercion, so the adapter maps `hours` onto it for you.\n\n**Workopia** aggregates ATS boards (Lever, Greenhouse, Workday, career pages) across 90+\ncountries — same class of source as our own `ats` adapter, with somebody else's coverage.\n\nThere is no API key to paste. The server advertises OAuth 2.0 with **dynamic client\nregistration and PKCE** as a public client (`token_endpoint_auth_methods_supported: [\"none\"]`),\nso the token has to be earned by running the flow once:\n\n```bash\ncd mcp && npm run workopia:login\n```\n\nIt registers a client, prints an authorize URL, and catches the redirect on `127.0.0.1` — the\npassword is typed in the browser and never passes through Workix. The grant lands in\n`mcp/data/workopia-tokens.json` and refreshes itself afterwards. `WORKOPIA_TOKEN` still works as\nan escape hatch if you hold a bearer token from somewhere else.\n\nIt also needs a **city** — `job_tool` requires one, and an empty value returns nothing rather\nthan searching everywhere. Resolved in this order, so most people never set anything:\n\n1. the `city` argument on the call\n2. `WORKOPIA_CITY`\n3. your `mcp/profile.md` — either an explicit `city: Berlin` line, or the `Гео / язык:` line the\n   example profile already ships\n\nA two-letter code is rejected on purpose: `Гео / язык: RU, EN` means a country and a language,\nand searching for a city named \"RU\" returns nonsense, which is worse than skipping with a\nmessage. `Remote` and `Worldwide` are passed through verbatim — Workopia documents no wildcard,\nso `*` would be a guess; confirm what it accepts once you are signed in.\n\nWithout a token or a city the board skips quietly instead of failing the digest.\n\nProbed and rejected on 2026-08-10, so nobody re-runs it: **Indeed MCP** (Claude-connector only,\nno reachable endpoint), **Fantastic.jobs / Career Site Jobs** (`403 Missing Authentication\nToken` — RapidAPI/Apify, paid), **hiring.cafe** (`401`), **The Best Job Board** (no working MCP\npath). Himalayas, Jobicy, Aquent and AI Dev Jobs do run MCP servers, but we already read their\nREST APIs directly, so the bridge would add a hop and nothing else.\n\n**Workable, Workato and WorkflowMAX are not job sources**, despite sitting next to Workopia in\nthe connector directory. `mcp.workable.com` is the employer side of an ATS — its scopes are\n`r_candidates`/`w_candidates`, `r_employees`, `w_timeoff`, `w_reviews`: you connect *your own*\ncompany account to manage hiring, not to search other companies' openings. Workato is an iPaaS\nwhose MCP server is generated per customer from your own recipes (`{n}.apim.mcp.workato.com`,\n`401` without your tenant). WorkflowMAX is a Xero product for trades, where \"jobs\" are work\norders inside your own account. None of the three exposes anybody else's vacancies.\n\nWhat Workable *does* give us is the public **ATS** endpoint we already support — see below.\n\nFour more light up as soon as their free key is in `.env` — **USAJOBS**, **SuperJob**,\n**Careerjet**, **Jooble**. **JobsPipe** needs a key too but stays out of the automatic digest\nbecause it is metered (see below). Until then they skip silently. Which are on:\n\n```bash\nworkix_sources_status   # → keyed_boards\n```\n\nCheck every new source against the live APIs:\n\n```bash\nnode scripts/smoke-new-sources.mjs\n```\n\n### Optional JobSpy bridge — Indeed, LinkedIn, Google Jobs, Glassdoor, ZipRecruiter, Bayt, Naukri, BDjobs\n\nThese eight are **opt-in and read-only**. They are not touched by a plain `workix_digest` — you\nhave to name them: `platforms: [\"indeed\"]`. Applying from the agent is not possible on any of\nthem; they link out to an external ATS.\n\nTwo of them need a word of warning:\n\n- **Google Jobs** ignores the plain search term. JobSpy pastes `google_search_term` into the\n  Google Jobs box verbatim, so phrase the query the way you would type it there —\n  `\"software engineer jobs near London since yesterday\"`, not `\"software engineer\"`.\n- **LinkedIn** is the most rate-limited board here (it throttles around page 10 from one IP) and\n  omits the body from search results. `JOBSPY_LINKEDIN_DESCRIPTIONS=1` fetches descriptions at\n  the cost of one extra request per card.\n\nA note on proxies: `refreshJobs` hands JobSpy the same pool the rest of the adapters use, but\nonly the `http://`/`https://` entries. JobSpy drives `requests`, which cannot open a `socks5://`\ntunnel without PySocks and fails the whole board with *\"Missing dependencies for SOCKS support\"*\n— worse than no proxy at all, since LinkedIn pulls fine direct. `pip install PySocks` in the\nsame venv if you want your SOCKS pool used here too.\n\nThey are served by one adapter that calls **[JobSpy](https://github.com/speedyapply/JobSpy)**\n(MIT) installed on your own machine. We do not vendor its scrapers: the boards are reached\nthrough private endpoints with credentials that ship inside the JobSpy release, and those\nbelong in your install, not in our package.\n\n#### Install\n\n**Python must be 3.10–3.12.** `python-jobspy` pins `numpy==1.26.3`, which has no wheels for\n3.13 — pip falls back to a source build and dies in meson. This is the single most common way\nto get stuck.\n\n```bash\npython -m venv .jobspy && .jobspy/bin/pip install -U python-jobspy\n```\n\nOn Windows the interpreter is `.jobspy\\Scripts\\python.exe`. Already on 3.13? Get a 3.12\nwithout touching your system Python:\n\n```bash\npip install uv && uv python install 3.12\n```\n\nThen create the venv with that interpreter and point the MCP at it:\n\n```bash\n# .env — full path to the venv's python\nPYTHON_BIN=/abs/path/.jobspy/bin/python\n```\n\n`PYTHON_BIN` is optional if a suitable `python3`/`python` is already first on `PATH`, but with\na venv you almost always want it set explicitly.\n\n#### Verify\n\n```bash\nworkix_digest {\"platforms\":[\"indeed\"],\"include_jobs\":true,\"keywords\":[\"python\"]}\n```\n\nNot installed → the tool says so and how to fix it, rather than returning an empty list.\n\n#### Or skip the bridge: JobsPipe\n\n[JobsPipe](https://jobspipe.dev/agent) normalizes 39 feeds behind one key — **LinkedIn, Indeed,\nY Combinator, Greenhouse, Lever, Ashby, SmartRecruiters, Workday, Workable, Paylocity** and\nmore. No Python, no `numpy==1.26.3` pin, and no 403, because the request goes to their server\nrather than to the board.\n\nIt is **metered: one credit per job returned**, free tier 1000/month. So unlike every other\nboard it does *not* run on a bare `include_jobs` — that would let a scheduled digest eat the\nmonth unnoticed. Three ways in:\n\n| | |\n|--|--|\n| `workix_jobspipe_search` | aimed query; reports `spent_this_call` and `remaining_this_month` |\n| `platforms: [\"jobspipe\"]` | pull it inside a digest, once |\n| `JOBSPIPE_IN_DIGEST=1` | opt in to every `include_jobs` run |\n\n```bash\nworkix_jobspipe_usage        # credits left this month\nworkix_jobspipe_usage {\"reset\": true}   # plan renewed off-cycle\n```\n\nThe counter lives in `data/jobspipe-usage.json` and tracks what this MCP spent — it is a guard\nrail, not a bill. The adapter refuses to start a call once `JOBSPIPE_MONTHLY_BUDGET` is gone,\nand never asks for more rows than the remaining budget.\n\nFilters go well past a title: `companies`, `skills`, `locations`, `countries`, `sources` /\n`exclude_sources` (pick or drop individual feeds), `seniority`, `exclude_titles`. Same role from\nLinkedIn and from the company's Greenhouse board arrives as two rows — provenance is in\n`raw.sources`.\n\n**`workix_company_tech_stack`** wraps their stack scanner (frameworks, CDN, analytics,\npayments, with confidence scores). It runs on their MCP endpoint, has no REST route, and costs\n**no job credits** — handy for naming a company's real stack in a proposal.\n\nJobsPipe is read-only: `/v1/jobs`, `/v1/jobs/ingest` → 404. It indexes other people's boards\nand does not accept postings.\n\n#### When a board returns nothing\n\nBoards block aggressively and JobSpy reports failures by logging and returning an empty\nresult, not by raising — so the adapter reads its log and tells you which it was. A real\nexample:\n\n```\nglassdoor: jobspy glassdoor (v1.1.82) returned nothing and logged:\nGlassdoor: bad response status code: 403\n```\n\nThat is a block, not an empty search. Usual causes and fixes:\n\n- **Credentials rotated upstream** — the keys live inside the JobSpy release, so a board\n  rotating them breaks every JobSpy user at once. Fix: `pip install -U python-jobspy`.\n- **Rate limited** — wait, and pass proxies. Every board here throttles; LinkedIn is the\n  worst, Indeed the most forgiving.\n- **Geo-blocked or location required** — Glassdoor in particular wants a parseable location.\n\nIf a board returns nothing and logs nothing at all, the adapter says that too, because an\nempty list with no reason is the one answer that tells you nothing. Widen the query first; if a\nbrowser shows results for the same search, it is JobSpy's parser, not you.\n\n#### Live status — 2026-08-10, `python-jobspy` 1.1.82\n\nAll eight tested against live traffic from one ordinary datacenter IP, no proxies.\n**Indeed and LinkedIn worked.**\n\n| Board | Result | What it is |\n|-------|--------|------------|\n| **Indeed** | ✅ live jobs | — |\n| **LinkedIn** | ✅ 50 live jobs through the digest | descriptions need `JOBSPY_LINKEDIN_DESCRIPTIONS=1` |\n| Google Jobs | ❌ 0 rows, no error | HTTP 200 from `/search?udm=8`, parser extracts nothing — **upstream markup drift** |\n| Bayt | ❌ 403 | IP-level block; needs an `http://` proxy |\n| Glassdoor | ❌ 403 | IP-level block |\n| ZipRecruiter | ❌ 403 `forbidden aa` (`CFRAY`) | Cloudflare |\n| Naukri | ❌ `ReadTimeout` | unreachable from here, likely geo |\n| BDjobs | ❌ `TypeError` in `BDJobs.__init__` | **upstream bug — broken for everyone** |\n\nThe blocks depend on where you are calling from and may work over proxies or from another\nnetwork. BDjobs and Google Jobs cannot work for anybody until JobSpy fixes them, so treat those\ntwo as unavailable rather than as something you configured wrong.\n\n**Terms:** these boards forbid automated collection. Installing this module is your decision\nand running it is your responsibility.\n\n**Rule:** never submit a proposal without explicit user approval.\n\n## Smoke\n\n```bash\nnpm run smoke\nnpm run smoke:startups\n```\n\n## Dev\n\n```bash\nnpm run dev\n```\n","readmeFilename":"README.md"}