{"_id":"@goke/mcp","_rev":"13-6e38e66e93feb89f982ac00e50131d3c","name":"@goke/mcp","dist-tags":{"latest":"0.1.2"},"versions":{"0.0.4":{"name":"@goke/mcp","version":"0.0.4","keywords":["mcp","cli","goke"],"author":{"name":"Tommaso De Rossi, morse","email":"beats.by.morse@gmail.com"},"license":"MIT","_id":"@goke/mcp@0.0.4","maintainers":[{"name":"xmorse","email":"beats.by.morse@gmail.com"}],"dist":{"shasum":"d5f9735597966161a1c255ff1c296644482c75ef","tarball":"https://registry.npmjs.org/@goke/mcp/-/mcp-0.0.4.tgz","fileCount":22,"integrity":"sha512-z75+Cfso+NFcYlF/9CR43z1F6k+j9v5otHr886OVzlaRid1+16NCJ0RA+NuaN5Bl0xA6GP9rZiHT8o8Q/7FEOw==","signatures":[{"sig":"MEUCIQC50sqm70d8FhKKYvVRKwOMIsidPNAogOMtatB8pY6wkgIgQYeiwnR6GE49geg6ybNEModY2zdczH3ITo1H16y7W/4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":77876},"main":"dist/index.js","type":"module","_from":"file:goke-mcp-0.0.4.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./src/index.js":{"types":"./src/index.ts","import":"./src/index.ts"}},"scripts":{"build":"tsc","watch":"tsc -w"},"_npmUser":{"name":"xmorse","email":"beats.by.morse@gmail.com"},"_resolved":"/private/var/folders/8w/wvmrpgms5hngywvs8s99xnmm0000gn/T/b4b97e932f02c4895a25353ad64dd15b/goke-mcp-0.0.4.tgz","_integrity":"sha512-z75+Cfso+NFcYlF/9CR43z1F6k+j9v5otHr886OVzlaRid1+16NCJ0RA+NuaN5Bl0xA6GP9rZiHT8o8Q/7FEOw==","_npmVersion":"10.9.4","description":"Dynamically generate CLI commands from MCP server tools","directories":{},"_nodeVersion":"22.21.1","dependencies":{"js-yaml":"^4.1.1","@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"goke":"6.1.0","@types/node":"^22.19.7","@types/js-yaml":"^4.0.9"},"peerDependencies":{"goke":"*"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.0.4_1770569344422_0.7795270659403661","host":"s3://npm-registry-packages-npm-production"}},"0.0.5":{"name":"@goke/mcp","version":"0.0.5","keywords":["mcp","cli","goke"],"author":{"name":"Tommaso De Rossi, morse","email":"beats.by.morse@gmail.com"},"license":"MIT","_id":"@goke/mcp@0.0.5","maintainers":[{"name":"xmorse","email":"beats.by.morse@gmail.com"}],"dist":{"shasum":"12d095c0143218b2cb3a31c09c2226b9f034a8ad","tarball":"https://registry.npmjs.org/@goke/mcp/-/mcp-0.0.5.tgz","fileCount":22,"integrity":"sha512-OxusNyTcnVSF7WyoVkC1C0w/4hLsy+z0lIHLkdoOpd9jNUKkuZx9MPIfH8JSbQNdHowrb4efnoi7ifJ7PB1J1g==","signatures":[{"sig":"MEUCIQCAAtv4qlrwuDrdQfzK52DLV3AhVZHfAdBmqZiRM2MVKgIgSCMFK77/Rz+uGcaWk3oDCmJnSkoj344lcGsaNUd+qkg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":77918},"main":"dist/index.js","type":"module","_from":"file:goke-mcp-0.0.5.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./src/index.js":{"types":"./src/index.ts","import":"./src/index.ts"}},"scripts":{"build":"pnpm clean && tsc","clean":"rm -rf dist","watch":"tsc -w"},"_npmUser":{"name":"xmorse","email":"beats.by.morse@gmail.com"},"_resolved":"/private/var/folders/8w/wvmrpgms5hngywvs8s99xnmm0000gn/T/a5993283406e4758fe84889e68244971/goke-mcp-0.0.5.tgz","_integrity":"sha512-OxusNyTcnVSF7WyoVkC1C0w/4hLsy+z0lIHLkdoOpd9jNUKkuZx9MPIfH8JSbQNdHowrb4efnoi7ifJ7PB1J1g==","_npmVersion":"10.9.4","description":"Dynamically generate CLI commands from MCP server tools","directories":{},"_nodeVersion":"22.21.1","dependencies":{"js-yaml":"^4.1.1","@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"goke":"6.1.2","@types/node":"^22.19.7","@types/js-yaml":"^4.0.9"},"peerDependencies":{"goke":"*"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.0.5_1770644423882_0.0973179781586011","host":"s3://npm-registry-packages-npm-production"}},"0.0.6":{"name":"@goke/mcp","version":"0.0.6","keywords":["mcp","cli","goke"],"author":{"name":"Tommaso De Rossi, morse","email":"beats.by.morse@gmail.com"},"license":"MIT","_id":"@goke/mcp@0.0.6","maintainers":[{"name":"xmorse","email":"beats.by.morse@gmail.com"}],"dist":{"shasum":"db892b0ec4403f2f3e35de995759aa4f79f480d8","tarball":"https://registry.npmjs.org/@goke/mcp/-/mcp-0.0.6.tgz","fileCount":29,"integrity":"sha512-a+v6ptd0J81eJg3NGTyCKzZsH8SFn8SyLkWJdiNBkwUeKMtrKcu89Xa3XHGxBgX+B3IGukMGE4Yt7zhla2HyKA==","signatures":[{"sig":"MEUCIQDQGsD9Q3JkC4z4yVrbfCST0SgLiJSxQlpn03uvTXeWKQIgUnNybbVSgXFSS0b5MnuANd4ISfU0bIwfYZe115GCg4M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":123013},"main":"dist/index.js","type":"module","_from":"file:goke-mcp-0.0.6.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./src/index.js":{"types":"./src/index.ts","import":"./src/index.ts"}},"scripts":{"test":"vitest --run","build":"pnpm clean && tsc","clean":"rm -rf dist","watch":"tsc -w"},"_npmUser":{"name":"xmorse","email":"beats.by.morse@gmail.com"},"_resolved":"/private/var/folders/8w/wvmrpgms5hngywvs8s99xnmm0000gn/T/c9cf9c7e44baea7fc5cb58f2accbb09f/goke-mcp-0.0.6.tgz","_integrity":"sha512-a+v6ptd0J81eJg3NGTyCKzZsH8SFn8SyLkWJdiNBkwUeKMtrKcu89Xa3XHGxBgX+B3IGukMGE4Yt7zhla2HyKA==","_npmVersion":"10.9.4","description":"Dynamically generate CLI commands from MCP server tools","directories":{},"_nodeVersion":"22.21.1","dependencies":{"js-yaml":"^4.1.1","@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","goke":"^6.2.0","vitest":"^3.1.0","@types/node":"^22.19.7","@types/js-yaml":"^4.0.9"},"peerDependencies":{"goke":"*"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.0.6_1772800625003_0.3725096194996189","host":"s3://npm-registry-packages-npm-production"}},"0.0.7":{"name":"@goke/mcp","version":"0.0.7","keywords":["mcp","cli","goke"],"author":{"name":"Tommaso De Rossi, morse","email":"beats.by.morse@gmail.com"},"license":"MIT","_id":"@goke/mcp@0.0.7","maintainers":[{"name":"xmorse","email":"beats.by.morse@gmail.com"}],"dist":{"shasum":"54d3f126d78e2a2cd58077b4acdb82fd173fe8a3","tarball":"https://registry.npmjs.org/@goke/mcp/-/mcp-0.0.7.tgz","fileCount":26,"integrity":"sha512-0bFCEQqQAUXWaltRg9nqzOTpWJ9wNGVjc45kV7x5Ll05uEkRDQQW1My+fQwDhlWt+4dbTGLowbFbzckWQhJB5A==","signatures":[{"sig":"MEUCIAOdc+fpcP/2M4z7746/54ZVlZseSdFMArQvGPd5Lqv7AiEAze0WBGAbr8D2KZSdAWGqU9efYkkWb+ME2zhPtyNncrk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":108751},"main":"dist/index.js","type":"module","_from":"file:goke-mcp-0.0.7.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./src/index.js":{"types":"./src/index.ts","import":"./src/index.ts"}},"scripts":{"test":"vitest --run","build":"pnpm clean && tsc -p tsconfig.build.json","clean":"rm -rf dist","watch":"tsc -w"},"_npmUser":{"name":"xmorse","email":"beats.by.morse@gmail.com"},"_resolved":"/private/var/folders/8w/wvmrpgms5hngywvs8s99xnmm0000gn/T/a43740e45d1ef57c3806eedf27fa5ff8/goke-mcp-0.0.7.tgz","_integrity":"sha512-0bFCEQqQAUXWaltRg9nqzOTpWJ9wNGVjc45kV7x5Ll05uEkRDQQW1My+fQwDhlWt+4dbTGLowbFbzckWQhJB5A==","_npmVersion":"10.9.4","description":"Dynamically generate CLI commands from MCP server tools","directories":{},"_nodeVersion":"22.21.1","dependencies":{"js-yaml":"^4.1.1","@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","goke":"^6.2.0","vitest":"^3.1.0","@types/node":"^22.19.7","@types/js-yaml":"^4.0.9"},"peerDependencies":{"goke":"*"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.0.7_1772800679747_0.043378430701612736","host":"s3://npm-registry-packages-npm-production"}},"0.0.8":{"name":"@goke/mcp","version":"0.0.8","keywords":["mcp","cli","goke","model-context-protocol"],"author":{"name":"Tommaso De Rossi, morse","email":"beats.by.morse@gmail.com"},"license":"MIT","_id":"@goke/mcp@0.0.8","maintainers":[{"name":"xmorse","email":"beats.by.morse@gmail.com"}],"homepage":"https://github.com/remorses/goke/tree/main/mcp","bugs":{"url":"https://github.com/remorses/goke/issues"},"dist":{"shasum":"504b019d4f33984af0601e869648194cbc3fab5a","tarball":"https://registry.npmjs.org/@goke/mcp/-/mcp-0.0.8.tgz","fileCount":30,"integrity":"sha512-DQqWHND3pQS2GtyQbCzuIvsLUb76M8L0+yqn11sbUlxxKML4VgFsIbro6lY070Ew5YvXzrJ1U3hzZfosz1n1gA==","signatures":[{"sig":"MEUCIQCd1c8zcGNI0SJVcoX3vk5efl6/W2YvXaN/0+/rdEmHlAIgGPTRs6Pj5xcxEdRcBCrdemppfTX5Dl63Wpg30zRe6L4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":137153},"main":"./dist/index.js","type":"module","_from":"file:goke-mcp-0.0.8.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./src":{"types":"./src/index.ts","default":"./src/index.ts"},"./src/*":{"types":"./src/*.ts","default":"./src/*.ts"},"./package.json":"./package.json"},"scripts":{"test":"vitest --run","build":"pnpm clean && tsc","clean":"rm -rf dist"},"_npmUser":{"name":"xmorse","email":"beats.by.morse@gmail.com"},"_resolved":"/private/var/folders/8w/wvmrpgms5hngywvs8s99xnmm0000gn/T/bab87d8af9584bba2e431b5c5fe2ef5a/goke-mcp-0.0.8.tgz","_integrity":"sha512-DQqWHND3pQS2GtyQbCzuIvsLUb76M8L0+yqn11sbUlxxKML4VgFsIbro6lY070Ew5YvXzrJ1U3hzZfosz1n1gA==","repository":{"url":"git+https://github.com/remorses/goke.git","type":"git","directory":"mcp"},"_npmVersion":"10.9.4","description":"Dynamically generate CLI commands from MCP server tools","directories":{},"_nodeVersion":"22.21.1","dependencies":{"js-yaml":"^4.1.1","@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","goke":"^6.2.3","vitest":"^3.1.0","@types/node":"^22.19.7","@types/js-yaml":"^4.0.9"},"peerDependencies":{"goke":"*"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.0.8_1772812602061_0.23930022991235567","host":"s3://npm-registry-packages-npm-production"}},"0.0.9":{"name":"@goke/mcp","version":"0.0.9","keywords":["mcp","cli","goke","model-context-protocol"],"author":{"name":"Tommaso De Rossi, morse","email":"beats.by.morse@gmail.com"},"license":"MIT","_id":"@goke/mcp@0.0.9","maintainers":[{"name":"xmorse","email":"beats.by.morse@gmail.com"}],"homepage":"https://github.com/remorses/goke/tree/main/mcp","bugs":{"url":"https://github.com/remorses/goke/issues"},"dist":{"shasum":"d49468327118cb6f461c28210c81e01dbd63915a","tarball":"https://registry.npmjs.org/@goke/mcp/-/mcp-0.0.9.tgz","fileCount":34,"integrity":"sha512-PYJOHTGjklkhf33jBDdRZiUSyB06OHrDcWxfC/aUJlR5na9+9sDPANpLzldj4Mn1a0Wz0C9aaEvgUSFskqkT5w==","signatures":[{"sig":"MEQCIAVbx3JdsjG4PcMricPDP7hIqYNWJYM8ua3P1Aw012ldAiB6Nk3RUziiTDCTDZJlhkWTn6FQUEpycAe+6O0+8QNszw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":171786},"main":"./dist/index.js","type":"module","_from":"file:goke-mcp-0.0.9.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./src":{"types":"./src/index.ts","default":"./src/index.ts"},"./src/*":{"types":"./src/*.ts","default":"./src/*.ts"},"./package.json":"./package.json"},"scripts":{"test":"vitest --run","build":"pnpm clean && tsc","clean":"rm -rf dist"},"_npmUser":{"name":"xmorse","email":"beats.by.morse@gmail.com"},"_resolved":"/private/var/folders/8w/wvmrpgms5hngywvs8s99xnmm0000gn/T/e0af535f1ea824a517160f295a4797a2/goke-mcp-0.0.9.tgz","_integrity":"sha512-PYJOHTGjklkhf33jBDdRZiUSyB06OHrDcWxfC/aUJlR5na9+9sDPANpLzldj4Mn1a0Wz0C9aaEvgUSFskqkT5w==","repository":{"url":"git+https://github.com/remorses/goke.git","type":"git","directory":"mcp"},"_npmVersion":"10.9.4","description":"Dynamically generate CLI commands from MCP server tools","directories":{},"_nodeVersion":"22.21.1","dependencies":{"js-yaml":"^4.1.1","@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","goke":"^6.3.0","vitest":"^3.1.0","@types/node":"^22.19.7","@types/js-yaml":"^4.0.9"},"peerDependencies":{"goke":"*"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.0.9_1772987210844_0.9403771907527403","host":"s3://npm-registry-packages-npm-production"}},"0.0.10":{"name":"@goke/mcp","version":"0.0.10","keywords":["mcp","cli","goke","model-context-protocol"],"author":{"name":"Tommaso De Rossi, morse","email":"beats.by.morse@gmail.com"},"license":"MIT","_id":"@goke/mcp@0.0.10","maintainers":[{"name":"xmorse","email":"beats.by.morse@gmail.com"}],"homepage":"https://github.com/remorses/goke/tree/main/mcp","bugs":{"url":"https://github.com/remorses/goke/issues"},"dist":{"shasum":"dbb8a4839fd674d5b0dd526b1277ae66859af211","tarball":"https://registry.npmjs.org/@goke/mcp/-/mcp-0.0.10.tgz","fileCount":38,"integrity":"sha512-BKDVBo1bhGtJwCXFkWMJe0cgcZutEjt5o04RspJu8v7w4I/PVJ8AAlcqjvUKEo6CqA/jmrcp5xvnAkHMbdoD4Q==","signatures":[{"sig":"MEYCIQDIFeORisDDTczT2xLsEiqVmpTY62NLtdUxvLh02kvJOwIhAP8eegTx3/7EiHbhQ2HZHW46LTd0YBC16hFCjh7dZtOd","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":240186},"main":"./dist/index.js","type":"module","_from":"file:goke-mcp-0.0.10.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./src":{"types":"./src/index.ts","default":"./src/index.ts"},"./src/*":{"types":"./src/*.ts","default":"./src/*.ts"},"./package.json":"./package.json"},"scripts":{"test":"vitest --run","build":"pnpm clean && tsc","clean":"rm -rf dist"},"_npmUser":{"name":"xmorse","email":"beats.by.morse@gmail.com"},"_resolved":"/private/var/folders/8w/wvmrpgms5hngywvs8s99xnmm0000gn/T/e9b3020abb78c33041dee63afd5a3e7a/goke-mcp-0.0.10.tgz","_integrity":"sha512-BKDVBo1bhGtJwCXFkWMJe0cgcZutEjt5o04RspJu8v7w4I/PVJ8AAlcqjvUKEo6CqA/jmrcp5xvnAkHMbdoD4Q==","repository":{"url":"git+https://github.com/remorses/goke.git","type":"git","directory":"mcp"},"_npmVersion":"11.9.0","description":"Dynamically generate CLI commands from MCP server tools","directories":{},"_nodeVersion":"24.14.0","dependencies":{"js-yaml":"^4.1.1","@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","goke":"^6.8.0","vitest":"^3.1.0","@types/node":"^22.19.7","@types/js-yaml":"^4.0.9"},"peerDependencies":{"goke":"*"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.0.10_1775924829395_0.9430845378470862","host":"s3://npm-registry-packages-npm-production"}},"0.0.11":{"name":"@goke/mcp","version":"0.0.11","keywords":["mcp","cli","goke","model-context-protocol"],"author":{"name":"Tommaso De Rossi, morse","email":"beats.by.morse@gmail.com"},"license":"MIT","_id":"@goke/mcp@0.0.11","maintainers":[{"name":"xmorse","email":"beats.by.morse@gmail.com"}],"homepage":"https://github.com/remorses/goke/tree/main/mcp","bugs":{"url":"https://github.com/remorses/goke/issues"},"dist":{"shasum":"c320bc37c8df9cd9d2ad3945d705f493ee1303d9","tarball":"https://registry.npmjs.org/@goke/mcp/-/mcp-0.0.11.tgz","fileCount":38,"integrity":"sha512-bl64ebV5fgWy6ICkRtCQZx3QU0X2RWGU0SPaznz4BLDUOl1ifroGmkf+tXtMRmvqduvYox3yMLlKj2O/nc0QPA==","signatures":[{"sig":"MEUCIHnF7uLFPjMx22zEXjOQYUrSB4ZV18tej9eGtxZTKJMNAiEAptsRsmE466exFY8TRlhNtzuNMLwrJC0DsSFcQQTTZ5E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":240635},"main":"./dist/index.js","type":"module","_from":"file:goke-mcp-0.0.11.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./src":{"types":"./src/index.ts","default":"./src/index.ts"},"./src/*":{"types":"./src/*.ts","default":"./src/*.ts"},"./package.json":"./package.json"},"scripts":{"test":"vitest --run","build":"pnpm clean && tsc","clean":"rm -rf dist"},"_npmUser":{"name":"xmorse","email":"beats.by.morse@gmail.com"},"_resolved":"/private/var/folders/8w/wvmrpgms5hngywvs8s99xnmm0000gn/T/662ac5a280d72a84bb704efa5e3723bb/goke-mcp-0.0.11.tgz","_integrity":"sha512-bl64ebV5fgWy6ICkRtCQZx3QU0X2RWGU0SPaznz4BLDUOl1ifroGmkf+tXtMRmvqduvYox3yMLlKj2O/nc0QPA==","repository":{"url":"git+https://github.com/remorses/goke.git","type":"git","directory":"mcp"},"_npmVersion":"11.12.1","description":"Dynamically generate CLI commands from MCP server tools","directories":{},"_nodeVersion":"24.15.0","dependencies":{"js-yaml":"^4.1.1","@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","goke":"^6.13.0","vitest":"^3.1.0","@types/node":"^22.19.7","@types/js-yaml":"^4.0.9"},"peerDependencies":{"goke":"*"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.0.11_1782554592599_0.6777084617446856","host":"s3://npm-registry-packages-npm-production"}},"0.0.12":{"name":"@goke/mcp","version":"0.0.12","keywords":["mcp","cli","goke","model-context-protocol"],"author":{"name":"Tommaso De Rossi, morse","email":"beats.by.morse@gmail.com"},"license":"MIT","_id":"@goke/mcp@0.0.12","maintainers":[{"name":"xmorse","email":"beats.by.morse@gmail.com"}],"homepage":"https://github.com/remorses/goke/tree/main/mcp","bugs":{"url":"https://github.com/remorses/goke/issues"},"dist":{"shasum":"2cdc0ec83d27c1b3472ea3a03be60250a911edb2","tarball":"https://registry.npmjs.org/@goke/mcp/-/mcp-0.0.12.tgz","fileCount":42,"integrity":"sha512-FxlXB/3g3Uglij8penZsHNq9+cvPf34i1KnWyrrIEkj8nTulxKdOlHgXejczvgkXV6xy8QbdB353gxpR86YOtg==","signatures":[{"sig":"MEQCICOApFwaa6/+j/39+KuMHlRDUulbodJAWOOcxGqVKjEjAiAaZrbrT8wBRrhpJBSBPNIGsD+jrEtqgg3jxKERw0S9CQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":249363},"main":"./dist/index.js","type":"module","_from":"file:goke-mcp-0.0.12.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./src":{"types":"./src/index.ts","default":"./src/index.ts"},"./src/*":{"types":"./src/*.ts","default":"./src/*.ts"},"./package.json":"./package.json"},"scripts":{"test":"vitest --run","build":"pnpm clean && tsc","clean":"rm -rf dist"},"_npmUser":{"name":"xmorse","email":"beats.by.morse@gmail.com"},"_resolved":"/private/var/folders/8w/wvmrpgms5hngywvs8s99xnmm0000gn/T/f1da8b64534103bc46fff083039a549c/goke-mcp-0.0.12.tgz","_integrity":"sha512-FxlXB/3g3Uglij8penZsHNq9+cvPf34i1KnWyrrIEkj8nTulxKdOlHgXejczvgkXV6xy8QbdB353gxpR86YOtg==","repository":{"url":"git+https://github.com/remorses/goke.git","type":"git","directory":"mcp"},"_npmVersion":"11.12.1","description":"Dynamically generate CLI commands from MCP server tools","directories":{},"_nodeVersion":"24.15.0","dependencies":{"js-yaml":"^4.1.1","@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","goke":"^6.12.1","vitest":"^3.1.0","@types/node":"^22.19.7","@types/js-yaml":"^4.0.9"},"peerDependencies":{"goke":"*"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.0.12_1786801930965_0.7750231465780619","host":"s3://npm-registry-packages-npm-production"}},"0.0.13":{"name":"@goke/mcp","version":"0.0.13","keywords":["mcp","cli","goke","model-context-protocol"],"author":{"name":"Tommaso De Rossi, morse","email":"beats.by.morse@gmail.com"},"license":"MIT","_id":"@goke/mcp@0.0.13","maintainers":[{"name":"xmorse","email":"beats.by.morse@gmail.com"}],"homepage":"https://github.com/remorses/goke/tree/main/mcp","bugs":{"url":"https://github.com/remorses/goke/issues"},"dist":{"shasum":"2a82e2acec2e07eb910e2b69bde86f72aa40a5ba","tarball":"https://registry.npmjs.org/@goke/mcp/-/mcp-0.0.13.tgz","fileCount":42,"integrity":"sha512-kn48iJYU4Td8zbaib6Dzx62dV+h3Y6vL+uVMXuCDaMVa4NlIcoiwN5q6l4ePufiuUYBdGaincWIk71BzwLfAew==","signatures":[{"sig":"MEUCIQDAa0t+lcoxNll2HLEuXmMg9KqGVCIEoy8VVXcEyhcWoAIgCNYDF8Vo2rqzwgFK5VUEPEcWHG1iBO4C3Lm2JFvsOho=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":252930},"main":"./dist/index.js","type":"module","_from":"file:goke-mcp-0.0.13.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./src":{"types":"./src/index.ts","default":"./src/index.ts"},"./src/*":{"types":"./src/*.ts","default":"./src/*.ts"},"./package.json":"./package.json"},"scripts":{"test":"vitest --run","build":"pnpm clean && tsc","clean":"rm -rf dist"},"_npmUser":{"name":"xmorse","email":"beats.by.morse@gmail.com"},"_resolved":"/private/var/folders/8w/wvmrpgms5hngywvs8s99xnmm0000gn/T/8690c6ceca803cdde81467cc23e3bf52/goke-mcp-0.0.13.tgz","_integrity":"sha512-kn48iJYU4Td8zbaib6Dzx62dV+h3Y6vL+uVMXuCDaMVa4NlIcoiwN5q6l4ePufiuUYBdGaincWIk71BzwLfAew==","repository":{"url":"git+https://github.com/remorses/goke.git","type":"git","directory":"mcp"},"_npmVersion":"11.12.1","description":"Dynamically generate CLI commands from MCP server tools","directories":{},"_nodeVersion":"24.15.0","dependencies":{"js-yaml":"^4.1.1","@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","goke":"^6.12.1","vitest":"^3.1.0","@types/node":"^22.19.7","@types/js-yaml":"^4.0.9"},"peerDependencies":{"goke":"*"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.0.13_1786802535683_0.893947860398179","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@goke/mcp","version":"0.1.0","keywords":["mcp","cli","goke","model-context-protocol"],"author":{"name":"Tommaso De Rossi, morse","email":"beats.by.morse@gmail.com"},"license":"MIT","_id":"@goke/mcp@0.1.0","maintainers":[{"name":"xmorse","email":"beats.by.morse@gmail.com"}],"homepage":"https://github.com/remorses/goke/tree/main/mcp","bugs":{"url":"https://github.com/remorses/goke/issues"},"dist":{"shasum":"6ac35b2515a5112eba9fe94a8d0c228c9a7482d7","tarball":"https://registry.npmjs.org/@goke/mcp/-/mcp-0.1.0.tgz","fileCount":42,"integrity":"sha512-Ok+MRSDA9M0qlm2z7DheqlIu7sK3c8M/B/yzp0hLHxBmig8hIRqnJIz2J7YTROdtnOsLebC5kFaLsjVFGu4y5A==","signatures":[{"sig":"MEQCIFqwOv+lyCR+zy/oWJTSD9Sa80pfinl7Es8cNCd096t9AiAihk+f59kUJoQbS0SMd6lXl6G2Ech3Whm9T7Mqe7VFgw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCPoxOi+lUZiDHwwRPlhlKqDDiUguP58RfQUsR3AZVgBQIgCFSj3weJNDWbcdgxaK5992T87usv5FO6vbXj94yQLN8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":252202},"main":"./dist/index.js","type":"module","_from":"file:goke-mcp-0.1.0.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./src":{"types":"./src/index.ts","default":"./src/index.ts"},"./src/*":{"types":"./src/*.ts","default":"./src/*.ts"},"./package.json":"./package.json"},"scripts":{"test":"vitest --run","build":"pnpm clean && tsc","clean":"rm -rf dist"},"_npmUser":{"name":"xmorse","email":"beats.by.morse@gmail.com"},"_resolved":"/private/var/folders/8w/wvmrpgms5hngywvs8s99xnmm0000gn/T/f909988baee3b4fa68ddc853b0b7578e/goke-mcp-0.1.0.tgz","_integrity":"sha512-Ok+MRSDA9M0qlm2z7DheqlIu7sK3c8M/B/yzp0hLHxBmig8hIRqnJIz2J7YTROdtnOsLebC5kFaLsjVFGu4y5A==","repository":{"url":"git+https://github.com/remorses/goke.git","type":"git","directory":"mcp"},"_npmVersion":"11.12.1","description":"Dynamically generate CLI commands from MCP server tools","directories":{},"_nodeVersion":"24.15.0","dependencies":{"js-yaml":"^4.1.1","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","goke":"^6.15.1","vitest":"^3.1.0","@types/node":"^22.19.7","@types/js-yaml":"^4.0.9"},"peerDependencies":{"goke":"*"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.1.0_1789553692020_0.6231210480943532","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@goke/mcp","version":"0.1.1","keywords":["mcp","cli","goke","model-context-protocol"],"author":{"name":"Tommaso De Rossi, morse","email":"beats.by.morse@gmail.com"},"license":"MIT","_id":"@goke/mcp@0.1.1","maintainers":[{"name":"xmorse","email":"beats.by.morse@gmail.com"}],"homepage":"https://github.com/remorses/goke/tree/main/mcp","bugs":{"url":"https://github.com/remorses/goke/issues"},"dist":{"shasum":"5ac83a0287bd5c52f6e2323ebb3cc1c50901445b","tarball":"https://registry.npmjs.org/@goke/mcp/-/mcp-0.1.1.tgz","fileCount":42,"integrity":"sha512-MUmjII9HfiW+kK5oGzR6K1qCERFPs0x6XRixXAE+K5g4RVTcP8Cxdn4QRqaCBfNKEYO5tfaRVr5ERNyDtdUHtQ==","signatures":[{"sig":"MEUCIQDwMalWZCuVb60+GAklJ5V0izZCMnv2FNj3FUy2M0HxUAIgCHrxw5WK4IzF0bSxKIDZjeM5Rtlj+wi+Gg+QJJCKvKs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCdM+b54YGlHKXOMRBSxvzTQQ2QEXomIPj6DYsv2zPSYAIgYFGw1l/WPzcCOlwcLye4T1zxxt8IlMHcVrOlE3K4H68=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":265997},"main":"./dist/index.js","type":"module","_from":"file:goke-mcp-0.1.1.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./src":{"types":"./src/index.ts","default":"./src/index.ts"},"./src/*":{"types":"./src/*.ts","default":"./src/*.ts"},"./package.json":"./package.json"},"scripts":{"test":"vitest --run","build":"pnpm clean && tsc","clean":"rm -rf dist"},"_npmUser":{"name":"xmorse","email":"beats.by.morse@gmail.com"},"_resolved":"/private/var/folders/8w/wvmrpgms5hngywvs8s99xnmm0000gn/T/7152151c1dbe7da66b41f7b316d3c73e/goke-mcp-0.1.1.tgz","_integrity":"sha512-MUmjII9HfiW+kK5oGzR6K1qCERFPs0x6XRixXAE+K5g4RVTcP8Cxdn4QRqaCBfNKEYO5tfaRVr5ERNyDtdUHtQ==","repository":{"url":"git+https://github.com/remorses/goke.git","type":"git","directory":"mcp"},"_npmVersion":"11.12.1","description":"Dynamically generate CLI commands from MCP server tools","directories":{},"_nodeVersion":"24.15.0","dependencies":{"js-yaml":"^4.1.1","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","goke":"^6.16.0","vitest":"^3.1.0","@types/node":"^22.19.7","@types/js-yaml":"^4.0.9"},"peerDependencies":{"goke":"*"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.1.1_1789554648248_0.41143166589157376","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"_id":"@goke/mcp@0.1.2","bugs":{"url":"https://github.com/remorses/goke/issues"},"dist":{"shasum":"6aafef27980623769d10c66924f36eca92f35ce6","tarball":"https://registry.npmjs.org/@goke/mcp/-/mcp-0.1.2.tgz","fileCount":42,"integrity":"sha512-zJMCGsIaMuHVTZ1L5yzsMP2bBrV+UbcvEquH1wY2nL5sBBpsFENFCjBzq2P7bs4TUt+HYPl2wSrwV2S3yyx5kg==","signatures":[{"sig":"MEUCIGL+D+3GX65lSUQngyYrh60xTQ3fDV0iCIAtCxrFW+kFAiEAqzt3p892eUNicakxj2UcmEUeAcJZoWXtqWQFs3z/NsI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICCx1lOpbtKciTOg+PblYa4zIxcjke66bnt154ARm+aqAiBrr1HUXBN/+zLUtIwCYh2nSF2omRJeszRnfmhIs6PSUA=="}],"unpackedSize":265910},"main":"./dist/index.js","name":"@goke/mcp","type":"module","_from":"file:goke-mcp-0.1.2.tgz","types":"./dist/index.d.ts","author":{"name":"Tommaso De Rossi, morse","email":"beats.by.morse@gmail.com"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./src":{"types":"./src/index.ts","default":"./src/index.ts"},"./src/*":{"types":"./src/*.ts","default":"./src/*.ts"},"./package.json":"./package.json"},"license":"MIT","scripts":{"test":"vitest --run","build":"pnpm clean && tsc","clean":"rm -rf dist"},"version":"0.1.2","_npmUser":{"name":"xmorse","email":"beats.by.morse@gmail.com"},"homepage":"https://github.com/remorses/goke/tree/main/mcp","keywords":["mcp","cli","goke","model-context-protocol"],"_resolved":"/private/var/folders/8w/wvmrpgms5hngywvs8s99xnmm0000gn/T/9946a2282560a88d20bbb7e593745b1f/goke-mcp-0.1.2.tgz","_integrity":"sha512-zJMCGsIaMuHVTZ1L5yzsMP2bBrV+UbcvEquH1wY2nL5sBBpsFENFCjBzq2P7bs4TUt+HYPl2wSrwV2S3yyx5kg==","repository":{"url":"git+https://github.com/remorses/goke.git","type":"git","directory":"mcp"},"_npmVersion":"11.12.1","description":"Dynamically generate CLI commands from MCP server tools","directories":{},"maintainers":[{"name":"xmorse","email":"beats.by.morse@gmail.com"}],"_nodeVersion":"24.15.0","dependencies":{"js-yaml":"^4.1.1","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","goke":"^6.17.0","vitest":"^3.1.0","@types/node":"^22.19.7","@types/js-yaml":"^4.0.9"},"peerDependencies":{"goke":"*"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp_0.1.2_1789559588784_0.5885823245442263"}}},"time":{"created":"2026-02-08T16:49:04.318Z","modified":"2026-09-16T11:53:09.199Z","0.0.4":"2026-02-08T16:49:04.591Z","0.0.5":"2026-02-09T13:40:24.036Z","0.0.6":"2026-03-06T12:37:05.159Z","0.0.7":"2026-03-06T12:37:59.908Z","0.0.8":"2026-03-06T15:56:42.211Z","0.0.9":"2026-03-08T16:26:50.992Z","0.0.10":"2026-04-11T16:27:09.566Z","0.0.11":"2026-06-27T10:03:12.786Z","0.0.12":"2026-08-15T13:52:11.173Z","0.0.13":"2026-08-15T14:02:15.822Z","0.1.0":"2026-09-16T10:14:52.101Z","0.1.1":"2026-09-16T10:30:48.344Z","0.1.2":"2026-09-16T11:53:08.882Z"},"bugs":{"url":"https://github.com/remorses/goke/issues"},"author":{"name":"Tommaso De Rossi, morse","email":"beats.by.morse@gmail.com"},"license":"MIT","homepage":"https://github.com/remorses/goke/tree/main/mcp","keywords":["mcp","cli","goke","model-context-protocol"],"repository":{"url":"git+https://github.com/remorses/goke.git","type":"git","directory":"mcp"},"description":"Dynamically generate CLI commands from MCP server tools","maintainers":[{"name":"xmorse","email":"beats.by.morse@gmail.com"}],"readme":"# @goke/mcp\n\nTurn any [MCP](https://modelcontextprotocol.io) server into a CLI. Connects to the server, discovers tools, and generates CLI commands with typed arguments — automatically.\n\n## Install\n\n```bash\nnpm install @goke/mcp goke\n```\n\n`goke` is a peer dependency (the CLI framework that commands are registered on).\n\n## How it works\n\n```\nMCP server                        Your CLI\n┌──────────────────┐              ┌──────────────────────────┐\n│  tools/list      │──discover──▸ │  mycli notion-search     │\n│  - notion-search │              │  mycli notion-get-page   │\n│  - notion-get-…  │              │  mycli notion-create-…   │\n│  (JSON Schema)   │──coerce───▸ │  --query <string>        │\n│                  │              │  --pageId <string>       │\n└──────────────────┘              └──────────────────────────┘\n```\n\n1. **Discover** — calls `tools/list` on the MCP server to get every tool + its JSON Schema\n2. **Register** — creates a CLI command per tool with `--options` derived from the schema\n3. **Cache** — tool schemas are cached for 1 hour (no network on subsequent runs). Expired cache is still used when a live fetch is impossible (no token, 401 on `--help`)\n4. **Execute** — on invocation, connects to the server and calls the tool with coerced arguments\n5. **OAuth** — if the server returns 401, automatically opens the browser for OAuth, then retries. `--help`, `--version`, `completions`, and no-args never start OAuth\n\n## Quick start\n\n```ts\nimport { goke } from 'goke'\nimport { addMcpCommands } from '@goke/mcp'\nimport type { McpOAuthState, CachedMcpTools } from '@goke/mcp'\n\nconst cli = goke('notion-mcp-cli')\n\nawait addMcpCommands({\n  cli,\n  getMcpUrl: () => 'https://mcp.notion.com/mcp',\n  oauth: {\n    clientName: 'Notion CLI',\n    load: () => loadConfig().oauthState,\n    save: (state) => saveConfig({ oauthState: state }),\n  },\n  loadCache: () => loadConfig().cache,\n  saveCache: (cache) => saveConfig({ cache }),\n})\n\ncli.help()\ncli.completions()\ncli.parse()\n```\n\nIf the MCP server is HTTP, pass `getMcpUrl` even when the user has no token. `--help` and no-args must still run so the CLI can show `config` / login instructions. Use `getMcpTransport` when you need stdio or a custom transport.\n\nFor an HTTP Bearer token, pass `getHeaders`:\n\n```ts\nawait addMcpCommands({\n  cli,\n  getMcpUrl: () => 'https://api.example.com/mcp',\n  getHeaders: () => {\n    const token = process.env.EXAMPLE_TOKEN || loadConfig().token\n    if (!token) return\n    return { Authorization: `Bearer ${token}` }\n  },\n  loadCache: () => loadConfig().cache,\n  saveCache: (cache) => saveConfig({ cache }),\n})\n```\n\nThat's it. Every tool the MCP server exposes becomes a CLI command:\n\n```bash\nnotion-mcp-cli notion-search --query \"meeting notes\"\nnotion-mcp-cli notion-retrieve-page --page_id \"abc123\"\nnotion-mcp-cli notion-list-users\n```\n\n## Expose a CLI as an MCP server\n\n`createMcpAction()` turns your entire CLI into a stdio MCP server with one line. Every CLI command becomes an MCP tool automatically. The command you attach it to is excluded from the tool list.\n\n```ts\nimport { goke } from \"goke\"\nimport { z } from \"zod\"\nimport { createMcpAction } from \"@goke/mcp\"\n\nconst cli = goke(\"my-cli\")\n\ncli\n  .command(\"search\", \"Search pages\")\n  .option(\"--query <query>\", z.string().describe(\"Search query\"))\n  .required()\n  .option(\"--limit [limit]\", z.number().default(10).describe(\"Max results\"))\n  .action((options) => {\n    return { results: findPages(options.query, options.limit) }\n  })\n\ncli\n  .command(\"deploy <env>\", \"Deploy to environment\")\n  .option(\"--dry-run\", z.boolean().default(false).describe(\"Simulate\"))\n  .action((env, options) => {\n    return options.dryRun ? `would deploy to ${env}` : deploy(env)\n  })\n\n// Add MCP support — runs a stdio MCP server when the user invokes `my-cli mcp`\ncli.command(\"mcp\", \"Start MCP server over stdio\")\n  .action(createMcpAction({ cli }))\n\ncli.help()\ncli.completions()\ncli.parse()\n```\n\nNow users can use your CLI directly **or** connect it as an MCP server:\n\n```bash\n# Use as a normal CLI\nmy-cli search --query \"meeting notes\"\nmy-cli deploy staging --dry-run\n\n# Use as an MCP server (e.g. from Claude Desktop, Cursor, etc.)\nmy-cli mcp\n```\n\nWhen running as MCP, the server exposes `search` and `deploy` as tools. The `mcp` command itself is excluded. Options with Zod schemas (or any Standard Schema) become typed `inputSchema` properties in the MCP tool definition.\n\n**`inputSchema.required` is not the CLI `<value>` syntax.** `--query <query>` means the flag needs a value if it is present. The flag itself is still optional unless you chain `.required()`. Required **positionals** like `<env>` always go in `required`. `.required()` flags go in `required` too.\n\n### Installing the MCP server in clients\n\nUsers can install your CLI as an MCP server in any client using [`@playwriter/install-mcp`](https://github.com/nicepkg/install-mcp) — a cross-platform tool that handles config file locations for every major MCP client:\n\n```bash\n# Install in Claude Desktop\nnpx @playwriter/install-mcp my-cli --client claude-desktop\n\n# Install in Cursor\nnpx @playwriter/install-mcp my-cli --client cursor\n\n# Install in VS Code\nnpx @playwriter/install-mcp my-cli --client vscode\n```\n\nThis works with any client: `claude-desktop`, `cursor`, `vscode`, `windsurf`, `claude-code`, `opencode`, `zed`, `goose`, `cline`, `codex`, `gemini-cli`, and [more](https://github.com/supermemoryai/install-mcp#supported-clients). If the command needs custom arguments, pass the full command string:\n\n```bash\nnpx @playwriter/install-mcp 'npx my-cli mcp' --client cursor\n```\n\n`createMcpAction` accepts the same filtering options as `addCliToolsToMcp`:\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `cli` | `Goke` | **required** | The CLI instance to expose |\n| `commandFilter` | `(name) => boolean` | — | Additional filter (MCP command is always excluded) |\n| `sanitizeToolName` | `(name) => string` | — | Custom tool name sanitizer |\n| `serverName` | `string` | CLI name | MCP server name |\n| `serverVersion` | `string` | `'1.0.0'` | MCP server version |\n| `createTransport` | `() => Transport` | stdio | Custom transport factory |\n\n### Advanced: `addCliToolsToMcp`\n\nFor more control (composing with existing MCP tools, using a custom server), use `addCliToolsToMcp()` directly:\n\n```ts\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\"\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\"\nimport { addCliToolsToMcp } from \"@goke/mcp\"\n\nconst server = new Server(\n  { name: \"my-cli-mcp\", version: \"1.0.0\" },\n  { capabilities: {} },\n)\n\n// Mount CLI commands as tools alongside your own\naddCliToolsToMcp({ cli, server })\n\nconst transport = new StdioServerTransport()\nawait server.connect(transport)\n```\n\nAlso works with the high-level `McpServer`:\n\n```ts\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\n\nconst mcp = new McpServer({ name: \"my-cli-mcp\", version: \"1.0.0\" })\nmcp.tool(\"custom-tool\", \"A tool defined directly\", async () => ({ ... }))\naddCliToolsToMcp({ cli, server: mcp })\n```\n\n## Multi-tenant remote MCP over HTTP\n\nWhen you expose a cli as a **remote** MCP over HTTP, one process handles many concurrent users. Each request must run against that user's own filesystem, working directory, environment, and stdin — otherwise tenants see each other's state and stdio writes trample the JSON-RPC channel.\n\nDo **not** keep MCP session IDs. Streamable HTTP can run **stateless**: `sessionIdGenerator: undefined`. Each POST builds a fresh `Server` and transport, then closes them. That works on Cloudflare Workers and any other isolate that does not keep process memory.\n\nThe recipe is:\n\n1. Define the cli **once**.\n2. On **every POST**, resolve the tenant from the request (JWT, cookie, header), **clone** the cli with `{ cwd, env, fs }`, and mount it on a fresh `Server` via `addCliToolsToMcp({ cli: tenantClone, server })`.\n3. Inside command actions, always use the **injected** `ctx` — `ctx.fs`, `ctx.process.cwd`, `ctx.process.env`, `ctx.console.log` — instead of the Node globals. `@goke/mcp` wires each tool call into the tenant's cloned context, but only code that goes through `ctx` participates in that isolation.\n\n### Write commands against `ctx`\n\n```ts\nimport { goke } from \"goke\"\nimport { z } from \"zod\"\nimport path from \"node:path\"\n\nconst cli = goke(\"notes-app\")\n\ncli\n  .command(\"save <filename>\", \"Save content into the user's workspace\")\n  .option(\"--content <content>\", z.string().describe(\"File content\"))\n  .action(async (filename, options, ctx) => {\n    const full = path.posix.join(ctx.process.cwd, filename)\n    await ctx.fs.writeFile(full, options.content)\n    return { saved: full, tenant: ctx.process.env.TENANT_ID }\n  })\n\ncli\n  .command(\"load <filename>\", \"Load a file from the user's workspace\")\n  .action(async (filename, _options, ctx) => {\n    const full = path.posix.join(ctx.process.cwd, filename)\n    const text = await ctx.fs.readFile(full, \"utf8\")\n    return { path: full, text }\n  })\n```\n\n`ctx.fs` satisfies the `GokeFs` interface — a Node-compatible async filesystem API. You can point it at a real directory, a virtual in-memory store, an S3 bucket adapter, a `memfs`, or anything else you can wrap behind that interface.\n\n### Clone the cli per request\n\nThe MCP SDK ships `WebStandardStreamableHTTPServerTransport`, which accepts a Web-Standard `Request` and returns a `Response`. That one shape plugs directly into **any** web framework that speaks web-standard: [Spiceflow](https://github.com/remorses/spiceflow), Cloudflare Workers, Deno, Bun, Next.js route handlers, SvelteKit endpoints, or a raw `fetch`-based handler. No Express, no `node:http` wiring, no framework lock-in.\n\nPass `sessionIdGenerator: undefined` so the transport does not emit or expect `mcp-session-id`. Do not store transports in a `Map`. JSON-RPC `initialize`, `tools/list`, and `tools/call` are separate POSTs. Each one clones the cli from the request's tenant identity.\n\nThis is MCP SDK v1 Streamable HTTP **without optional transport sessions** (protocol revisions through `2025-11-25`). It is not the later `2026-07-28` protocol, which drops `initialize`. Session IDs are optional in `2025-11-25`. Stateless servers omit them.\n\nThe Streamable HTTP spec requires **Origin** checks on every request (DNS rebinding). Reject a present, disallowed `Origin` with **403**. Missing `Origin` is normal for non-browser MCP clients.\n\n```\nPOST /mcp  (JWT / x-tenant-id)\n        │\n        v\nresolveTenant(id) ──> baseCli.clone({ cwd, env, fs })\n                           │\n                           v\n                    fresh Server + transport\n                    sessionIdGenerator: undefined\n                           │\n                           v\naddCliToolsToMcp ──> handleRequest\n                           │\n                           v\n                        Response\n                           │\n                           v\n             close transport + server ──> nothing stored\n```\n\nYou build one `handleMcpRequest(request: Request): Promise<Response>` function and mount it wherever you route HTTP:\n\n```ts\nimport { Server as McpServer } from \"@modelcontextprotocol/sdk/server/index.js\"\nimport { WebStandardStreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js\"\nimport { addCliToolsToMcp } from \"@goke/mcp\"\nimport type { GokeFs } from \"goke\"\n\ndeclare function resolveTenant(tenantId: string): {\n  cwd: string\n  env: Record<string, string>\n  fs: GokeFs\n}\n\ndeclare function isAllowedOrigin(origin: string): boolean\n\nexport async function handleMcpRequest(request: Request): Promise<Response> {\n  const origin = request.headers.get(\"origin\")\n  if (origin && !isAllowedOrigin(origin)) {\n    return new Response(null, { status: 403 })\n  }\n\n  if (request.method !== \"POST\") {\n    return new Response(null, { status: 405, headers: { Allow: \"POST\" } })\n  }\n\n  const parsedBody = await request.clone().json().catch(() => undefined)\n\n  const tenantId = request.headers.get(\"x-tenant-id\")\n  if (!tenantId) return new Response(\"missing x-tenant-id\", { status: 401 })\n  const tenant = resolveTenant(tenantId)\n\n  const tenantCli = baseCli.clone({\n    cwd: tenant.cwd,\n    env: { ...tenant.env, TENANT_ID: tenantId },\n    fs: tenant.fs,\n  })\n\n  const mcpServer = new McpServer(\n    { name: \"notes-app-mcp\", version: \"1.0.0\" },\n    { capabilities: {} },\n  )\n  addCliToolsToMcp({ cli: tenantCli, server: mcpServer })\n\n  const transport = new WebStandardStreamableHTTPServerTransport({\n    sessionIdGenerator: undefined,\n    enableJsonResponse: true,\n  })\n  await mcpServer.connect(transport)\n  try {\n    return await transport.handleRequest(request, { parsedBody })\n  } finally {\n    await transport.close()\n    await mcpServer.close()\n  }\n}\n```\n\nNow plug `handleMcpRequest` into whichever web runtime you use:\n\n```ts\n// Spiceflow — runs on Node, Bun, and Cloudflare Workers with the same code\nimport { Spiceflow } from \"spiceflow\"\n\nexport const app = new Spiceflow()\n  .route({\n    method: \"*\",\n    path: \"/mcp\",\n    handler: ({ request }) => handleMcpRequest(request),\n  })\n\napp.listen(3000)\n\n// Cloudflare Workers / Deno / Bun\nexport default {\n  async fetch(request: Request): Promise<Response> {\n    const url = new URL(request.url)\n    if (url.pathname === \"/mcp\") return handleMcpRequest(request)\n    return new Response(\"not found\", { status: 404 })\n  },\n}\n\n// Next.js app router\nexport async function POST(request: Request) {\n  return handleMcpRequest(request)\n}\n```\n\n**Key guarantees**\n\n- Every request runs against `tenantCli`'s `cwd` / `env` / `fs` — not the base cli's and not another tenant's.\n- `ctx.console.log` / `ctx.console.error` / `ctx.process.stdout.write` / `ctx.process.stderr.write` are captured into the `CallToolResult.content`. They never reach the host process stdio, so they can't corrupt the JSON-RPC channel or leak between users.\n- `ctx.process.exit(code)` throws `GokeProcessExit` instead of killing the server. The tool call resolves as `{ isError: code !== 0, content: [captured output] }` and the next request keeps running.\n- Actions that `throw` are caught and returned as `{ isError: true, content: [message, stderr] }`.\n\n**Bypass hazards**\n\nOnly code that flows through `ctx` participates in the isolation. The following **bypass** it and will leak across tenants or kill the host process:\n\n- `import fs from \"node:fs\"` inside a command action — reads/writes the real disk.\n- `console.log(...)` / `console.error(...)` — writes to the real server stdio.\n- `process.exit(1)` — terminates the entire host process.\n- `process.cwd()` / `process.env.X` at module load time — snapshots the server's values, not the tenant's.\n\nPort those to `ctx.fs`, `ctx.console`, `ctx.process.*` and you're multi-tenant-safe.\n\nFor a runnable end-to-end example (including two concurrent in-memory-fs tenants writing separate files, with a new server per POST), see [`src/__test__/http-multi-tenant.test.ts`](./src/__test__/http-multi-tenant.test.ts).\n\n### Lower-level primitive: `cli.createExecutionContext(override)`\n\nIf you're building a custom transport or a non-HTTP multi-tenant adapter, the underlying goke primitive is:\n\n```ts\nimport { GokeProcessExit, type GokeExecutionContextOverride } from \"goke\"\n\nconst override: GokeExecutionContextOverride = {\n  cwd: tenant.cwd,\n  env: tenant.env,\n  fs: tenant.fs,\n  stdin: tenant.stdin,\n  stdout: captureStdoutStream,\n  stderr: captureStderrStream,\n  exit: () => {}, // throw-only: the wrapper still throws GokeProcessExit\n}\n\nconst ctx = cli.createExecutionContext(override)\n\ntry {\n  await action(...positionalArgs, options, ctx)\n} catch (err) {\n  if (err instanceof GokeProcessExit) {\n    // handle the exit code — the host process is untouched\n  } else {\n    throw err\n  }\n}\n```\n\n`addCliToolsToMcp` builds this context for you on every tool call. Call it yourself if you need finer control (e.g. per-request capture streams for custom routing, synthetic `argv`, or serving MCP from a non-Node runtime that implements `GokeFs` differently).\n\n## Full example (with config persistence)\n\nThis is the pattern used by [notion-mcp-cli](../notion-mcp-cli):\n\n```ts\nimport { goke } from 'goke'\nimport { addMcpCommands } from '@goke/mcp'\nimport type { McpOAuthState, CachedMcpTools } from '@goke/mcp'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\n\n// --- Config persistence (JSON file in ~/.myapp/) ---\n\nconst CONFIG_DIR = path.join(os.homedir(), '.myapp')\nconst CONFIG_FILE = path.join(CONFIG_DIR, 'config.json')\n\ninterface AppConfig {\n  mcpUrl: string\n  oauthState?: McpOAuthState\n  cache?: CachedMcpTools\n}\n\nfunction loadConfig(): AppConfig {\n  try {\n    return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'))\n  } catch {\n    return { mcpUrl: 'https://mcp.notion.com/mcp' }\n  }\n}\n\nfunction saveConfig(partial: Partial<AppConfig>): void {\n  const merged = { ...loadConfig(), ...partial }\n  fs.mkdirSync(CONFIG_DIR, { recursive: true })\n  fs.writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2))\n}\n\n// --- CLI setup ---\n\nconst cli = goke('myapp')\n\nawait addMcpCommands({\n  cli,\n  clientName: 'myapp',\n  getMcpUrl: () => loadConfig().mcpUrl,\n  oauth: {\n    clientName: 'My App',\n    load: () => loadConfig().oauthState,\n    save: (state) => saveConfig({ oauthState: state }),\n  },\n  loadCache: () => loadConfig().cache,\n  saveCache: (cache) => saveConfig({ cache }),\n})\n\n// Custom commands alongside auto-generated MCP commands\ncli\n  .command('login', 'Save MCP URL')\n  .option('--url <url>', 'MCP server URL')\n  .action((options) => {\n    saveConfig({ mcpUrl: options.url })\n    console.log(`Saved: ${options.url}`)\n  })\n\ncli.command('logout', 'Clear tokens').action(() => {\n  saveConfig({ oauthState: undefined, cache: undefined })\n  console.log('Logged out')\n})\n\ncli.help()\ncli.completions()\ncli.parse()\n```\n\n## API\n\n### `addMcpCommands(options)`\n\nRegisters MCP tool commands on a goke CLI instance.\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `cli` | `Goke` | **required** | The goke CLI instance to add commands to |\n| `getMcpUrl` | `() => string \\| undefined` | — | Returns the MCP server URL. Return the URL even when the user is not logged in so `--help` still works |\n| `getMcpTransport` | `() => Transport \\| null` | — | Custom transport. Use for stdio or anything `getMcpUrl` cannot express |\n| `getHeaders` | `() => Record<string, string> \\| undefined` | — | Extra HTTP headers (for example `Authorization`). Used with `getMcpUrl` |\n| `argv` | `string[]` | `process.argv.slice(2)` | Args used to skip live discovery on help and already registered commands |\n| `commandPrefix` | `string` | `''` | Prefix for commands (e.g. `'mcp'` makes `mcp notion-search`) |\n| `clientName` | `string` | `'mcp-cli-client'` | Name sent to the MCP server during connection |\n| `oauth` | `McpOAuthConfig` | — | OAuth config for servers that require authentication |\n| `loadCache` | `() => CachedMcpTools \\| undefined` | **required** | Load cached tools from storage |\n| `saveCache` | `(cache) => void` | **required** | Save cached tools to storage |\n\n### `McpOAuthConfig`\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `clientName` | `string` | Name shown on the OAuth consent screen |\n| `load` | `() => McpOAuthState \\| undefined` | Load persisted OAuth state |\n| `save` | `(state) => void` | Save OAuth state after auth or token refresh |\n| `onAuthUrl` | `(url: string) => void` | Custom handler for auth URL (default: opens browser) |\n| `onAuthSuccess` | `() => void` | Called after successful authentication |\n| `onAuthError` | `(error: string) => void` | Called on authentication failure |\n\n### Exports\n\n```ts\n// MCP server → CLI (consume MCP tools as CLI commands)\nexport { addMcpCommands } from '@goke/mcp'\nexport type { AddMcpCommandsOptions, CachedMcpTools } from '@goke/mcp'\nexport type { McpOAuthConfig, McpOAuthState } from '@goke/mcp'\n\n// CLI → MCP server (expose CLI commands as MCP tools)\nexport { createMcpAction, addCliToolsToMcp } from '@goke/mcp'\nexport type { CreateMcpActionOptions, AddCliToolsToMcpOptions } from '@goke/mcp'\n```\n\n## OAuth flow\n\nOAuth is **lazy** — no auth check happens on startup. The flow is:\n\n```\nUser runs command\n       │\n       ▼\n  Call MCP tool ───── success ──▸ Print result\n       │\n    401 error\n       │\n       ▼\n  Start local server (random port)\n       │\n       ▼\n  Open browser ──▸ User authorizes\n       │\n       ▼\n  Receive callback with auth code\n       │\n       ▼\n  Exchange code for tokens\n       │\n       ▼\n  Save tokens via oauth.save()\n       │\n       ▼\n  Retry the original tool call\n```\n\nTokens are persisted via the `oauth.save()` callback you provide, so subsequent runs skip auth entirely.\n\n## Caching\n\nTool schemas are cached for **1 hour** so `--help` and command registration do not hit the network on every invocation. The cache is managed through the `loadCache`/`saveCache` callbacks. You control where it is stored (file, database, env, etc.). Each tool call still opens a new MCP connection. There is no `Mcp-Session-Id` reuse.\n\nWhen the cache expires or a tool call fails, the cache is cleared and tools are re-fetched on the next run.\n\nIf a live `tools/list` cannot run (no transport, 401 during `--help`), `addMcpCommands` still registers tools from an expired cache so help stays useful.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}