onlymcp 0.25.7 → 0.25.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cli.js +3 -3
- package/dist/bin/mcp.js +3 -3
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import{cancel as Er,confirm as Rr,intro as Ut,isCancel as Mt,log as y,multiselect as Ps,outro as de,spinner as Ye}from"@clack/prompts";import{Command as Is}from"commander";import _s from"open";import Ns from"qrcode";import{homedir as Lr}from"node:os";import{createWriteStream as Es,existsSync as D,mkdirSync as Rs}from"node:fs";import{pipeline as Os}from"node:stream/promises";import{Readable as Ls}from"node:stream";import{dirname as Ms,join as Or}from"node:path";import{hostname as ri}from"node:os";import{execFile as qr}from"node:child_process";import{hostname as Zr}from"node:os";import{readFile as Xr}from"node:fs/promises";import{promisify as Qr}from"node:util";import{randomUUID as Wt}from"node:crypto";import{link as Ur,mkdir as zr,readFile as Fr,rename as Gr,rm as Hr,writeFile as Bt}from"node:fs/promises";import{basename as Wr,dirname as Vt,join as Br}from"node:path";import{existsSync as jr}from"node:fs";import{homedir as Ft}from"node:os";import{join as Z}from"node:path";function Se(){return process.env.ONLYMCP_HOME??Z(Ft(),".claude","onlymcp")}function zt(){return process.env.ONLYMCP_HOME??Ft()}function Gt(){return Z(Se(),"device-id")}function Ht(){return Z(Se(),"cache")}function Ce(){return Z(Se(),"stub-ignore")}function $e(){let e=[];process.env.CLAUDE_PLUGIN_ROOT&&e.push(process.env.CLAUDE_PLUGIN_ROOT);for(let t of(process.env.ONLYMCP_STUB_DIRS??"").split(":"))t&&e.push(t);for(let t of[Z(zt(),".claude"),Z(zt(),".codex")])jr(t)&&!e.includes(t)&&e.push(t);return e.length>0?e:[Z(Se(),"plugin")]}var Kr=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/,Kt;function Jt(){return Kt??=Vr(),Kt}async function qe(e){try{let t=(await Fr(e,"utf8")).trim().toLowerCase();return Kr.test(t)?t:null}catch{return null}}async function Vr(){let e=Gt(),t=await qe(e);if(t)return t;try{return await zr(Vt(e),{recursive:!0}),await Yr(e)}catch{return null}}var Jr=new Set(["EPERM","ENOTSUP","EOPNOTSUPP","ENOSYS","EXDEV"]);async function Yr(e){let t=Wt(),n=Br(Vt(e),`.${Wr(e)}.${process.pid}.${Wt()}.tmp`);try{await Bt(n,`${t}
|
|
3
3
|
`,{flag:"wx",mode:384});try{return await Ur(n,e),t}catch(i){let o=i.code;if(o!=="EEXIST"&&!Jr.has(o??""))throw i;if(o!=="EEXIST")try{return await Bt(e,`${t}
|
|
4
|
-
`,{flag:"wx",mode:384}),t}catch(s){if(s.code!=="EEXIST")throw s}}let r=await qe(e);return r||(await Gr(n,e),await qe(e)??t)}finally{await Hr(n,{force:!0}).catch(()=>{})}}var ie="0.25.
|
|
4
|
+
`,{flag:"wx",mode:384}),t}catch(s){if(s.code!=="EEXIST")throw s}}let r=await qe(e);return r||(await Gr(n,e),await qe(e)??t)}finally{await Hr(n,{force:!0}).catch(()=>{})}}var ie="0.25.8";var ei=Qr(qr),ti=`onlymcp-cli/${ie} (${process.platform} ${process.arch}; node ${process.versions.node})`,Yt=200;async function qt(e,t){let n;try{return await Promise.race([e,new Promise(r=>{n=setTimeout(()=>r(null),t),n.unref?.()})])}catch{return null}finally{n&&clearTimeout(n)}}async function ni(){try{if(process.platform==="linux"){let e=Xr("/sys/class/dmi/id/product_version","utf8"),n=(await qt(e,Yt))?.trim();return!n||/^(to be filled|default string|system version|none|n\/a)/i.test(n)?null:n}if(process.platform==="darwin"){let e=ei("sysctl",["-n","hw.model"]);return(await qt(e,Yt))?.stdout.trim()||null}}catch{}return null}async function Ze(){let e="unknown";try{e=Zr()||"unknown"}catch{}let t=await ni();return(t&&t!==e?`${e} (${t})`:e).slice(0,60)}var Zt=null;async function pe(){Zt??=await Ze();let e=await Jt();return{"user-agent":ti,"x-onlymcp-device":Zt,...e?{"x-onlymcp-device-id":e}:{}}}var b=class extends Error{constructor(n,r={},i=0){super(n);this.code=n;this.params=r;this.status=i;this.name="ApiError"}code;params;status},z=class{constructor(t,n){this.baseUrl=t;this.token=n}baseUrl;token;async call(t,n={}){let r=this.token();if(!r)throw new b("errors.NOT_LOGGED_IN");let i=await fetch(`${this.baseUrl}${t}`,{...n,headers:{...await pe(),...n.headers??{},authorization:`Bearer ${r}`,"content-type":"application/json"}});if(i.status===204)return;let o=await i.json().catch(()=>({}));if(!i.ok)throw new b(o.code??"errors.UNKNOWN",o.params??{},i.status);return o}getMe(){return this.call("/api/me")}reportRun(t,n){return this.call("/api/devices/current/run",{method:"POST",body:JSON.stringify({kind:t,files:n}),signal:AbortSignal.timeout(5e3)})}signOut(){return this.call("/api/auth/sign-out",{method:"POST",body:"{}",signal:AbortSignal.timeout(5e3)})}listSkills(){return this.call("/api/skills")}getSkill(t,n){return this.call(`/api/skills/${encodeURIComponent(t)}${this.teamQuery(n)}`)}putSkill(t,n,r={}){return this.call(`/api/skills/${encodeURIComponent(t)}`,{method:"PUT",body:JSON.stringify({body:n,...r})})}skillFileUrl(t,n){let r=n.split("/").map(encodeURIComponent).join("/");return`/api/skills/${encodeURIComponent(t)}/files/${r}`}getSkillFile(t,n){return this.call(this.skillFileUrl(t,n))}putSkillFile(t,n,r,i="utf8"){return this.call(this.skillFileUrl(t,n),{method:"PUT",body:JSON.stringify({content:r,encoding:i})})}listAgents(){return this.call("/api/agents")}putAgent(t,n){return this.call(`/api/agents/${encodeURIComponent(t)}`,{method:"PUT",body:JSON.stringify(n)})}getAgent(t,{use:n=!1,team:r}={}){let i=[n?"use=1":null,r===void 0?null:`team=${encodeURIComponent(r)}`].filter(Boolean);return this.call(`/api/agents/${encodeURIComponent(t)}${i.length?`?${i.join("&")}`:""}`)}readMemory(t,n){return this.call(`${this.memoryUrl(t)}${this.teamQuery(n)}`)}writeMemory(t,n,r,i){return this.call(this.memoryUrl(t),{method:"PUT",body:JSON.stringify({content:n,deviceLabel:r,...i===void 0?{}:{ifMatch:i}})})}memoryUrl(t){return`/api/memory/${t.split("/").map(encodeURIComponent).join("/")}`}teamQuery(t,n="?"){return t===void 0?"":`${n}team=${encodeURIComponent(t)}`}listMemory(){return this.call("/api/memory")}searchContent(t,n={}){let r=new URLSearchParams({q:t});n.types?.length&&r.set("types",n.types.join(",")),n.limit&&r.set("limit",String(n.limit));for(let i of["type","project","tag"])n[i]!==void 0&&r.set(i,n[i]);return this.call(`/api/search?${r.toString()}`)}graphNodeByRid(t,n){return this.call(`/api/graph/rid/${t}/${encodeURIComponent(n)}`)}graphAround(t,n,r={}){let i=new URLSearchParams({scope:"all",focus:t,depth:String(n),walk:"links"});return r.types?.length&&i.set("types",r.types.join(",")),r.folder!==void 0&&i.set("folder",r.folder),r.project!==void 0&&i.set("project",r.project),this.call(`/api/graph?${i.toString()}`)}memoryTree(t="all"){return this.call(`/api/memory/tree?scope=${encodeURIComponent(t)}`)}moveMemory(t,n,r=!0,i=ri()){return this.call("/api/memory/move",{method:"POST",body:JSON.stringify({from:t,to:n,updateLinks:r,deviceLabel:i})})}async exportArchive(t={}){let n=this.token();if(!n)throw new b("errors.NOT_LOGGED_IN");let r=new URLSearchParams;t.scope&&r.set("scope",t.scope),t.types?.length&&r.set("types",t.types.join(","));let i=r.size>0?`?${r.toString()}`:"",o=await fetch(`${this.baseUrl}/api/export${i}`,{headers:{...await pe(),authorization:`Bearer ${n}`}});if(!o.ok){let s=await o.json().catch(()=>({}));throw new b(s.code??"errors.UNKNOWN",s.params??{},o.status)}return o}deleteMemory(t){return this.call(this.memoryUrl(t),{method:"DELETE"})}deleteSkill(t){return this.call(`/api/skills/${encodeURIComponent(t)}`,{method:"DELETE"})}deleteSkillFile(t,n){return this.call(this.skillFileUrl(t,n),{method:"DELETE"})}deleteAgent(t){return this.call(`/api/agents/${encodeURIComponent(t)}`,{method:"DELETE"})}listConnections(){return this.call("/api/mcp-connections")}listTeams(){return this.call("/api/teams")}shareWithTeam(t,n){return this.call(`/api/teams/${encodeURIComponent(t)}/share`,{method:"POST",body:JSON.stringify(n)})}returnFromTeam(t,n){return this.call(`/api/teams/${encodeURIComponent(t)}/unshare`,{method:"POST",body:JSON.stringify(n)})}createConnection(t){return this.call("/api/mcp-connections",{method:"POST",body:JSON.stringify(t)})}updateConnection(t,n){return this.call(`/api/mcp-connections/${t}`,{method:"PATCH",body:JSON.stringify(n)})}deleteConnection(t){return this.call(`/api/mcp-connections/${t}`,{method:"DELETE"})}listCapabilities(t){return this.call(`/api/mcp-connections/${t}/capabilities`)}toggleCapability(t,n,r){return this.call(`/api/mcp-connections/${t}/capabilities/${n}`,{method:"PATCH",body:JSON.stringify({enabled:r})})}};import{Entry as ii}from"@napi-rs/keyring";function oi(e,t){let n=()=>new ii(e,t);return{save(r){n().setPassword(r)},read(){try{return n().getPassword()}catch{return null}},clear(){try{n().deletePassword()}catch{}}}}var j=oi("onlymcp","session-token");var si={sleep:e=>new Promise(t=>setTimeout(t,e))};async function Xt(e,t,n,r=si){let i=n;for(;;){await r.sleep(i*1e3);let s=await(await fetch(`${e}/api/auth/device/token`,{method:"POST",headers:{...await pe(),"content-type":"application/json"},body:JSON.stringify({grant_type:"urn:ietf:params:oauth:grant-type:device_code",device_code:t,client_id:"onlymcp-cli"})})).json().catch(()=>({}));if(s.access_token)return s.access_token;switch(s.error){case"authorization_pending":break;case"slow_down":i+=5;break;case"access_denied":throw new b("errors.DEVICE_ACCESS_DENIED");case"expired_token":throw new b("errors.DEVICE_CODE_EXPIRED");default:throw new b("errors.DEVICE_LOGIN_FAILED",{error:s.error})}}}import Ae from"cacache";var ai=Number(process.env.ONLYMCP_TTL_SECONDS??360*60),oe=class{constructor(t=Ht()){this.dir=t}dir;async get(t){try{let n=await Ae.get(this.dir,t),r=n.metadata;return!r||r.expiresAt<=Date.now()?(await Ae.rm.entry(this.dir,t),null):n.data.toString("utf8")}catch{return null}}async set(t,n,r=ai){await Ae.put(this.dir,t,n,{metadata:{expiresAt:Date.now()+r*1e3}})}async clear(){await Ae.rm.all(this.dir)}};import{appendFileSync as Hi,existsSync as Le,mkdirSync as cn,readFileSync as pn,writeFileSync as Wi}from"node:fs";import{dirname as mn,join as Bi}from"node:path";function Qt(e){return{language:"bash",text:e}}function Y(e,t){return{language:"json",text:JSON.stringify(e,null,2),path:t}}var li={id:"claude-code",name:"Claude Code",category:"coding",brand:"claudecode",methods:["remote-header","remote-oauth","stdio"],docsUrl:"https://code.claude.com/docs/en/mcp-quickstart",verifiedOn:"2026-09-25",caveats:["clients.caveat.claudeCodeConnectorSynced"],install:{configPath:"~/.claude.json",format:"json",stubDir:null},remote:e=>[Qt(`claude mcp add --transport http --scope user onlymcp ${e.endpoint} --header "Authorization: Bearer ${e.token}"`)]},ci={id:"claude-app",name:"Claude",category:"chat",brand:"claude",methods:["remote-oauth"],docsUrl:"https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp",verifiedOn:"2026-09-25",caveats:["clients.caveat.claudeHeaderBeta"],install:null,oauthRedirectHosts:["claude.ai","claude.com"],remote:()=>null},di={id:"chatgpt",name:"ChatGPT",category:"chat",brand:"openai",methods:["remote-oauth"],docsUrl:"https://help.openai.com/en/articles/12584461-developer-mode-and-mcp-apps-in-chatgpt",verifiedOn:"2026-09-25",caveats:["clients.caveat.chatgptDeveloperMode"],install:null,oauthRedirectHosts:["chatgpt.com"],remote:()=>null},pi={id:"codex",name:"Codex",category:"coding",brand:"openai",methods:["remote-header","remote-oauth","stdio"],docsUrl:"https://learn.chatgpt.com/docs/extend/mcp?surface=cli",verifiedOn:"2026-09-25",caveats:["clients.caveat.codexTokenEnv"],install:{configPath:"~/.codex/config.toml",format:"toml",stubDir:"~/.codex/skills"},remote:e=>[Qt([`export ONLYMCP_TOKEN=${e.token}`,`codex mcp add onlymcp --url ${e.endpoint} --bearer-token-env-var ONLYMCP_TOKEN`].join(`
|
|
5
5
|
`))]},mi={id:"antigravity",aliases:["gemini-cli"],name:"Antigravity",category:"coding",brand:"antigravity",methods:["remote-oauth","remote-header","stdio"],docsUrl:"https://antigravity.google/docs/mcp",verifiedOn:"2026-10-29",caveats:[],install:{configPath:"~/.gemini/config/mcp_config.json",format:"json",stubDir:null},oauthRedirectHosts:["antigravity.google"],remote:e=>[Y({mcpServers:{onlymcp:{serverUrl:e.endpoint,headers:{Authorization:`Bearer ${e.token}`}}}},"~/.gemini/config/mcp_config.json")]},ui={id:"gemini-app",name:"Gemini",category:"chat",brand:"googlegemini",methods:["remote-oauth"],docsUrl:"https://support.google.com/gemini/answer/17209137",verifiedOn:"2026-10-10",caveats:["clients.caveat.geminiAppSpark"],install:null,remote:()=>null},gi={id:"grok",name:"Grok",category:"chat",brand:"grok",methods:["remote-oauth"],docsUrl:"https://docs.x.ai/grok/connectors",verifiedOn:"2026-10-17",caveats:["clients.caveat.grokConnectors","clients.caveat.grokBusinessAdmin"],install:null,oauthRedirectHosts:["grok.com"],remote:()=>null},fi={id:"copilot-vscode",name:"GitHub Copilot (VS Code)",category:"ide",brand:"githubcopilot",oauthClientNames:["GitHub Copilot"],methods:["remote-header","remote-oauth","stdio"],docsUrl:"https://code.visualstudio.com/docs/agents/reference/mcp-configuration",verifiedOn:"2026-10-29",caveats:["clients.caveat.copilotPolicy"],install:null,deepLink:"vscode",remote:e=>[Y({servers:{onlymcp:{type:"http",url:e.endpoint,headers:{Authorization:`Bearer ${e.token}`}}}},".vscode/mcp.json")]},hi={id:"cursor",name:"Cursor",category:"ide",brand:"cursor",methods:["remote-header","remote-oauth","stdio"],docsUrl:"https://cursor.com/docs/mcp",verifiedOn:"2026-09-25",caveats:[],install:null,deepLink:"cursor",remote:e=>[Y({mcpServers:{onlymcp:{url:e.endpoint,headers:{Authorization:`Bearer ${e.token}`}}}},"~/.cursor/mcp.json")]},yi={id:"windsurf",name:"Devin Desktop (Windsurf)",category:"ide",brand:null,methods:["remote-header","stdio"],docsUrl:"https://docs.devin.ai/desktop/cascade/mcp",verifiedOn:"2026-10-29",caveats:["clients.caveat.windsurfAllowlist"],install:null,remote:e=>[Y({mcpServers:{onlymcp:{url:e.endpoint,headers:{Authorization:`Bearer ${e.token}`}}}},"~/.config/devin/mcp_config.json")]},bi={id:"cline",name:"Cline",category:"ide",brand:"cline",methods:["remote-header","stdio"],docsUrl:"https://docs.cline.bot/mcp/mcp-overview",verifiedOn:"2026-10-29",caveats:[],install:null,remote:e=>[Y({mcpServers:{onlymcp:{type:"streamableHttp",url:e.endpoint,headers:{Authorization:`Bearer ${e.token}`}}}},"~/.cline/data/settings/cline_mcp_settings.json")]},ki={id:"zed",name:"Zed",category:"ide",brand:"zedindustries",methods:["remote-header","remote-oauth","stdio"],docsUrl:"https://zed.dev/docs/ai/mcp",verifiedOn:"2026-09-25",caveats:[],install:null,remote:e=>[Y({context_servers:{onlymcp:{url:e.endpoint,headers:{Authorization:`Bearer ${e.token}`}}}},"settings.json")]},xi={id:"opencode",name:"opencode",category:"coding",brand:"opencode",methods:["remote-header","remote-oauth","stdio"],docsUrl:"https://opencode.ai/docs/mcp-servers/",verifiedOn:"2026-10-29",caveats:[],install:null,remote:e=>[Y({mcp:{onlymcp:{type:"remote",url:e.endpoint,headers:{Authorization:`Bearer ${e.token}`}}}},"opencode.json")]},wi={id:"gitlab-duo",name:"GitLab Duo",category:"ide",brand:"gitlab",methods:["remote-oauth"],docsUrl:"https://docs.gitlab.com/user/gitlab_duo/model_context_protocol/mcp_clients",verifiedOn:"2026-10-29",caveats:["clients.caveat.gitlabDuoUserFile"],install:null,remote:e=>[Y({mcpServers:{onlymcp:{type:"http",url:e.endpoint}}},"~/.gitlab/duo/mcp.json")]},Te=[ci,di,ui,gi,li,pi,mi,xi,fi,hi,yi,bi,ki,wi];function Xe(e){return Te.find(t=>t.id===e||t.aliases?.includes(e))}var vi=/^[a-z0-9][a-z0-9._-]*(\/[a-z0-9][a-z0-9._-]*)*\.md$/i;function A(e){return vi.test(e)&&!e.split("/").includes("..")}var Si=/^[A-Za-z0-9][A-Za-z0-9._-]*$/,Ci=8,$i=200;function q(e){if(e.length===0||e.length>$i||e==="SKILL.md")return!1;let t=e.split("/");return t.length>Ci?!1:t.every(n=>Si.test(n)&&n!==".."&&n!==".")}function Ai(e){return e.includes("\\")||/^[A-Za-z]:/.test(e)?!0:e.split("/").some(t=>t===""||t==="."||t==="..")}var Ti=[/^\.env(\..+)?$/i,/^\.credentials\.json$/i,/^id_(rsa|dsa|ecdsa|ed25519)(\.pub)?$/i,/\.(pem|key|p12|pfx|jks|keystore)$/i,/^\.(npmrc|netrc|pgpass|htpasswd)$/i,/^\.git-credentials$/i];function Ie(e){return Ti.some(t=>t.test(e))}var Pi=new Set([".git","node_modules","__pycache__",".venv","venv",".pytest_cache",".mypy_cache","dist","build",".next",".cache"]);function Qe(e){return Pi.has(e)}var Ii=[{rule:"anthropic",re:/\bsk-ant-[A-Za-z0-9_-]{20,}/},{rule:"openai",re:/\bsk-(?!ant-)[A-Za-z0-9_-]{20,}/},{rule:"github",re:/\bgh[pousr]_[A-Za-z0-9]{36,}/},{rule:"aws",re:/\bAKIA[0-9A-Z]{16}\b/},{rule:"slack",re:/\bxox[baprs]-[A-Za-z0-9-]{10,}/},{rule:"google",re:/\bAIza[0-9A-Za-z_-]{35}\b/},{rule:"jwt",re:/\beyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\./},{rule:"private-key",re:/-----BEGIN [A-Z ]*PRIVATE KEY-----/},{rule:"url-credentials",re:/\b[a-z][a-z0-9+.-]*:\/\/[^\s:/@]+:[^\s:/@]{6,}@/i},{rule:"assignment",re:/\b(api[_-]?key|secret|passwd|password|token|credential)\b\s*[:=]\s*['"][^'"\s]{16,}['"]/i}];function _i(e,t){let n=e.indexOf(t);return`${e.slice(Math.max(0,n-24),n)}\u2026${t.slice(0,4)}\u2026 (${t.length} characters)`}function nn(e){let t=[],n=e.split(`
|
|
6
6
|
`);for(let r=0;r<n.length;r+=1){let i=n[r];for(let{rule:o,re:s}of Ii){let d=s.exec(i);if(d){t.push({rule:o,line:r+1,excerpt:_i(i,d[0])});break}}}return t}function Q(e){if(!e.startsWith(`---
|
|
7
7
|
`))return null;let t=e.indexOf(`
|
|
@@ -60,10 +60,10 @@ ${d}`:s}).join(`
|
|
|
60
60
|
`))}catch(n){return M(ke(n))}}}}var To=T.object({path:T.string().min(3).max(256).describe("Path of the memory file to start from."),depth:T.number().int().min(1).max(3).optional().describe("Hops to walk, 1 to 3. Default 1."),types:T.string().max(128).optional().describe("Comma-separated node kinds to list: memory, skill, agent, mcp, tool, folder, type, project, tag, collection."),folder:T.string().max(256).optional().describe("Only memory files and folders under this folder (full path, or its last part)."),project:He.describe("Only nodes about this project (and the project itself).")});function Kn(e){return{name:"memory_graph",description:"The graph around one memory file, up to three hops. Depth 1: the files, skills, agents and servers it links to or is linked from, its folder, type, project and tags, and links that land on nothing (\u2192 links to (missing) name). From depth 2 on only links out of a file reached by a link are followed: a backlink, folder, type, project or tag is listed at depth 1 and never walked through. Pick the depth yourself; 1 is the default and usually enough, 2-3 follow a chain of links further, the files most of the previous depth links to first. Grouped by depth; each line names the edge and, from depth 2, the node it was reached through. types, folder and project narrow what is listed, not the walk.",inputSchema:To,async handler(t){if(!A(t.path))return M("errors.INVALID_PATH");let n=t.depth??1,r=t.types===void 0||t.types.trim()===""?void 0:mt(t.types);if(r===null)return M(`Invalid types: ${t.types}`);let i=(t.folder??"").trim().replace(/^\/+|\/+$/g,"");if(i!==""&&!A(`${i}/x.md`))return M("errors.INVALID_PATH");try{let o=await e.readMemory(t.path);if(!o.id)return M("This server is too old for memory_graph: it does not send a file id.");let s;try{s=(await e.graphNodeByRid("memory",o.id)).node.id}catch(f){if(f instanceof b&&f.code==="errors.NODE_NOT_FOUND")return U(`${o.path} is not in the graph yet (it is added on its next save).`);throw f}let d=i===""?null:Oe(i,Vn((await e.memoryTree("all")).nodes));if(d&&"error"in d)return U(d.error);let a=await e.graphAround(s,n),c={...r?{types:r}:{},...d?{folder:d.folder}:{},...t.project!==void 0?{project:t.project}:{}},p=Object.keys(c).length>0?new Set((await e.graphAround(s,n,c)).nodes.map(f=>f.id)):null,g=ct(c)?a.missing??[]:[];return U(ut({path:o.path,focus:s,depth:n,nodes:a.nodes,edges:a.edges,truncated:a.truncated,kept:p,missing:g}))}catch(o){return M(ke(o))}}}}function Vn(e){let t=new Set;for(let n of e){n.kind==="folder"&&t.add(n.path);let r=n.path.split("/");for(let i=1;i<r.length;i+=1)t.add(r.slice(0,i).join("/"))}return[...t]}import{z as S}from"zod";var Po=e=>({content:[{type:"text",text:e}]}),Jn=e=>({content:[{type:"text",text:e}],isError:!0});async function ce(e){try{return Po(await e())}catch(t){if(t instanceof b){let n=Object.keys(t.params).length?` ${JSON.stringify(t.params)}`:"";return Jn(`${t.code}${n}`)}return Jn("errors.UNKNOWN")}}var xe=S.string().min(1).max(32).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/,"errors.INVALID_SLUG");async function We(e,t){let{connections:n}=await e.listConnections(),r=n.filter(i=>i.slug===t);return r.find(i=>i.scope==="personal")??r[0]??null}function _t(e){let t=e.authType==="none"?"no auth":`${e.authType}, secret ...${e.secretHint??"?"}`;return`${e.slug} \u2014 ${e.name} (${e.scope}, ${e.enabled?e.status:"disabled"}, ${t})
|
|
61
61
|
${e.url}${e.statusError?`
|
|
62
62
|
last error: ${e.statusError}`:""}`}var Io=S.object({});function Yn(e){return{name:"list_connections",description:"List the MCP servers connected through this OnlyMCP account, with the tool-name prefix each one uses.",inputSchema:Io,handler:()=>ce(async()=>{let{connections:t}=await e.listConnections();return t.length===0?"No MCP servers are connected yet. Add one with connection_create.":t.map(_t).join(`
|
|
63
|
-
`)})}}var _o=S.object({name:S.string().min(1).max(80),slug:xe,url:S.string().url().max(2e3),transport:S.enum(["http","sse"]).default("http"),authType:S.enum(["none","bearer","header"]).default("none"),authHeaderName:S.string().max(80).optional(),secret:S.string().max(4e3).optional(),teamId:S.string().max(64).optional()});function qn(e){return{name:"connection_create",description:"Connect a remote MCP server (http or sse only - a stdio server cannot be started on somebody else's behalf). It is probed straight away. Passing a secret here puts it into this conversation; leave it out and set it in the dashboard if that matters.",inputSchema:_o,handler:t=>ce(async()=>{let{connection:n}=await e.createConnection(t);return`Connected.
|
|
63
|
+
`)})}}var _o=S.object({name:S.string().min(1).max(80),slug:xe,url:S.string().url().max(2e3),transport:S.enum(["http","sse"]).default("http"),authType:S.enum(["none","bearer","header","basic"]).default("none"),authHeaderName:S.string().max(80).optional(),secret:S.string().max(4e3).optional(),teamId:S.string().max(64).optional()});function qn(e){return{name:"connection_create",description:"Connect a remote MCP server (http or sse only - a stdio server cannot be started on somebody else's behalf). It is probed straight away. Passing a secret here puts it into this conversation; leave it out and set it in the dashboard if that matters.",inputSchema:_o,handler:t=>ce(async()=>{let{connection:n}=await e.createConnection(t);return`Connected.
|
|
64
64
|
${_t(n)}
|
|
65
65
|
|
|
66
|
-
Its tools are now available as "${n.slug}__<tool>".`})}}var No=S.object({slug:xe,name:S.string().min(1).max(80).optional(),url:S.string().url().max(2e3).optional(),transport:S.enum(["http","sse"]).optional(),authType:S.enum(["none","bearer","header"]).optional(),authHeaderName:S.string().max(80).optional(),secret:S.string().max(4e3).optional(),enabled:S.boolean().optional()});function Zn(e){return{name:"connection_update",description:"Change a connected MCP server. Only the fields you pass are touched; url, transport, authType and secret trigger a fresh probe.",inputSchema:No,handler:t=>ce(async()=>{let n=await We(e,t.slug);if(!n)return`Connection not found: ${t.slug}`;let{slug:r,...i}=t,{connection:o}=await e.updateConnection(n.id,i);return`Updated.
|
|
66
|
+
Its tools are now available as "${n.slug}__<tool>".`})}}var No=S.object({slug:xe,name:S.string().min(1).max(80).optional(),url:S.string().url().max(2e3).optional(),transport:S.enum(["http","sse"]).optional(),authType:S.enum(["none","bearer","header","basic"]).optional(),authHeaderName:S.string().max(80).optional(),secret:S.string().max(4e3).optional(),enabled:S.boolean().optional()});function Zn(e){return{name:"connection_update",description:"Change a connected MCP server. Only the fields you pass are touched; url, transport, authType and secret trigger a fresh probe.",inputSchema:No,handler:t=>ce(async()=>{let n=await We(e,t.slug);if(!n)return`Connection not found: ${t.slug}`;let{slug:r,...i}=t,{connection:o}=await e.updateConnection(n.id,i);return`Updated.
|
|
67
67
|
${_t(o)}`})}}var Eo=S.object({slug:xe});function Xn(e){return{name:"connection_delete",description:"Disconnect a remote MCP server and forget its stored credential. Its tools disappear from the gateway.",inputSchema:Eo,handler:t=>ce(async()=>{let n=await We(e,t.slug);return n?(await e.deleteConnection(n.id),`Disconnected ${t.slug}.`):`Connection not found: ${t.slug}`})}}var Ro=S.object({slug:xe});function Qn(e){return{name:"connection_tools",description:"List what one connected server offers, and whether each tool is switched on for the gateway.",inputSchema:Ro,handler:t=>ce(async()=>{let n=await We(e,t.slug);if(!n)return`Connection not found: ${t.slug}`;let{capabilities:r}=await e.listCapabilities(n.id);return r.length===0?`${t.slug} has nothing on record yet. Its status is "${n.status}".`:r.map(i=>`${i.enabled?"[on] ":"[off]"} ${i.kind} ${i.name}${i.exposedAs?` -> ${i.exposedAs}`:""}${i.description?` \u2014 ${i.description}`:""}`).join(`
|
|
68
68
|
`)})}}var Oo=S.object({slug:xe,tool:S.string().min(1).max(200),enabled:S.boolean()});function er(e){return{name:"connection_tool_toggle",description:"Switch one tool of a connected server on or off. A tool that is off costs no room in any client's tool list.",inputSchema:Oo,handler:t=>ce(async()=>{let n=await We(e,t.slug);if(!n)return`Connection not found: ${t.slug}`;let{capabilities:r}=await e.listCapabilities(n.id),i=r.find(o=>o.kind==="tool"&&o.name===t.tool);return i?(await e.toggleCapability(n.id,i.id,t.enabled),`${t.slug}__${i.name} is now ${t.enabled?"on":"off"}.`):`${t.slug} offers no tool called ${t.tool}.`})}}import{z as $}from"zod";var Lo=e=>({content:[{type:"text",text:e}]}),we=e=>({content:[{type:"text",text:e}],isError:!0});async function H(e){try{return Lo(await e())}catch(t){if(t instanceof b){let n=Object.keys(t.params).length?` ${JSON.stringify(t.params)}`:"";return we(`${t.code}${n}`)}return we("errors.UNKNOWN")}}var ne=$.string().min(1).max(64).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/,"errors.INVALID_NAME"),Mo=$.object({name:ne,body:$.string().max(2e5)});function tr(e){return{name:"skill_write",description:"Create a skill or replace the body of an existing one. The body is the whole SKILL.md, frontmatter included.",inputSchema:Mo,handler:t=>H(async()=>{let n=await e.putSkill(t.name,t.body);return`${n.name} ${n.updatedAt}`})}}var Do=$.object({name:ne});function nr(e){return{name:"skill_delete",description:"Delete one skill and every file that belongs to it. Moves it to the trash; it can be restored in the dashboard for the trash period (default 7 days).",inputSchema:Do,handler:t=>H(async()=>(await e.deleteSkill(t.name),`Deleted skill ${t.name}`))}}var jo=$.object({skill:ne});function rr(e){return{name:"list_skill_files",description:"List the companion files of one skill, with their size in bytes.",inputSchema:jo,handler:t=>H(async()=>{let{files:n}=await e.getSkill(t.skill);return n.length===0?`${t.skill} has no companion files.`:n.map(r=>`${r.path} (${r.size} bytes, ${r.encoding})`).join(`
|
|
69
69
|
`)})}}var Uo=$.object({skill:ne,path:$.string().min(1).max(256),content:$.string().max(3e6),encoding:$.enum(["utf8","base64"]).default("utf8")});function ir(e){return{name:"skill_file_write",description:"Create or replace one companion file of a skill. Use encoding base64 for anything that is not text.",inputSchema:Uo,handler:t=>q(t.path)?H(async()=>{let n=await e.putSkillFile(t.skill,t.path,t.content,t.encoding);return`${t.skill}/${n.path} ${n.size} bytes`}):Promise.resolve(we("errors.INVALID_PATH"))}}var zo=$.object({skill:ne,path:$.string().min(1).max(256)});function or(e){return{name:"skill_file_delete",description:"Delete one companion file of a skill. The skill itself stays.",inputSchema:zo,handler:t=>q(t.path)?H(async()=>(await e.deleteSkillFile(t.skill,t.path),`Deleted ${t.skill}/${t.path}`)):Promise.resolve(we("errors.INVALID_PATH"))}}var Fo=$.object({name:ne,description:$.string().min(1).max(1e3),body:$.string().max(2e5),model:$.string().max(64).optional(),tools:$.array($.string().max(128)).max(200).optional()});function sr(e){return{name:"agent_write",description:"Create an agent or replace an existing one. Leave model out to keep the one it already has.",inputSchema:Fo,handler:t=>H(async()=>{let n=await e.getAgent(t.name).catch(()=>null),r=await e.putAgent(t.name,{description:t.description,body:t.body,model:t.model??n?.model??void 0,tools:t.tools??n?.tools??[]});return`${r.name} ${r.updatedAt}`})}}var Go=$.object({name:ne});function ar(e){return{name:"agent_delete",description:"Delete one agent. Moves it to the trash; it can be restored in the dashboard for the trash period (default 7 days).",inputSchema:Go,handler:t=>H(async()=>(await e.deleteAgent(t.name),`Deleted agent ${t.name}`))}}var Ho=$.object({});function lr(e){return{name:"list_memory",description:"List the paths of every memory file in this account, private and team, sorted by path.",inputSchema:Ho,handler:()=>H(async()=>{let{files:t}=await e.listMemory();return t.length===0?"(none)":t.map(n=>n.path+te(n)).sort().join(`
|
package/dist/bin/mcp.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import{Server as oo}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as io}from"@modelcontextprotocol/sdk/server/stdio.js";import{CallToolRequestSchema as so,GetPromptRequestSchema as ao,ListPromptsRequestSchema as lo,ListResourceTemplatesRequestSchema as co,ListResourcesRequestSchema as po,ListToolsRequestSchema as mo,ReadResourceRequestSchema as uo}from"@modelcontextprotocol/sdk/types.js";import{hostname as Wn}from"node:os";import{execFile as Mn}from"node:child_process";import{hostname as Un}from"node:os";import{readFile as Dn}from"node:fs/promises";import{promisify as jn}from"node:util";import{randomUUID as ot}from"node:crypto";import{link as An,mkdir as Tn,readFile as $n,rename as In,rm as _n,writeFile as it}from"node:fs/promises";import{basename as Nn,dirname as at,join as En}from"node:path";import{existsSync as Cn}from"node:fs";import{homedir as Qe}from"node:os";import{join as O}from"node:path";function ne(){return process.env.ONLYMCP_HOME??O(Qe(),".claude","onlymcp")}function Xe(){return process.env.ONLYMCP_HOME??Qe()}function et(){return O(ne(),"device-id")}function tt(){return O(ne(),"cache")}function nt(){return O(ne(),"stub-ignore")}function rt(){let t=[];process.env.CLAUDE_PLUGIN_ROOT&&t.push(process.env.CLAUDE_PLUGIN_ROOT);for(let e of(process.env.ONLYMCP_STUB_DIRS??"").split(":"))e&&t.push(e);for(let e of[O(Xe(),".claude"),O(Xe(),".codex")])Cn(e)&&!t.includes(e)&&t.push(e);return t.length>0?t:[O(ne(),"plugin")]}var Ln=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/,st;function lt(){return st??=Rn(),st}async function Se(t){try{let e=(await $n(t,"utf8")).trim().toLowerCase();return Ln.test(e)?e:null}catch{return null}}async function Rn(){let t=et(),e=await Se(t);if(e)return e;try{return await Tn(at(t),{recursive:!0}),await On(t)}catch{return null}}var Pn=new Set(["EPERM","ENOTSUP","EOPNOTSUPP","ENOSYS","EXDEV"]);async function On(t){let e=ot(),n=En(at(t),`.${Nn(t)}.${process.pid}.${ot()}.tmp`);try{await it(n,`${e}
|
|
3
3
|
`,{flag:"wx",mode:384});try{return await An(n,t),e}catch(o){let i=o.code;if(i!=="EEXIST"&&!Pn.has(i??""))throw o;if(i!=="EEXIST")try{return await it(t,`${e}
|
|
4
|
-
`,{flag:"wx",mode:384}),e}catch(s){if(s.code!=="EEXIST")throw s}}let r=await Se(t);return r||(await In(n,t),await Se(t)??e)}finally{await _n(n,{force:!0}).catch(()=>{})}}var re="0.25.
|
|
4
|
+
`,{flag:"wx",mode:384}),e}catch(s){if(s.code!=="EEXIST")throw s}}let r=await Se(t);return r||(await In(n,t),await Se(t)??e)}finally{await _n(n,{force:!0}).catch(()=>{})}}var re="0.25.8";var zn=jn(Mn),Gn=`onlymcp-cli/${re} (${process.platform} ${process.arch}; node ${process.versions.node})`,ct=200;async function dt(t,e){let n;try{return await Promise.race([t,new Promise(r=>{n=setTimeout(()=>r(null),e),n.unref?.()})])}catch{return null}finally{n&&clearTimeout(n)}}async function Fn(){try{if(process.platform==="linux"){let t=Dn("/sys/class/dmi/id/product_version","utf8"),n=(await dt(t,ct))?.trim();return!n||/^(to be filled|default string|system version|none|n\/a)/i.test(n)?null:n}if(process.platform==="darwin"){let t=zn("sysctl",["-n","hw.model"]);return(await dt(t,ct))?.stdout.trim()||null}}catch{}return null}async function Hn(){let t="unknown";try{t=Un()||"unknown"}catch{}let e=await Fn();return(e&&e!==t?`${t} (${e})`:t).slice(0,60)}var pt=null;async function we(){pt??=await Hn();let t=await lt();return{"user-agent":Gn,"x-onlymcp-device":pt,...t?{"x-onlymcp-device-id":t}:{}}}var m=class extends Error{constructor(n,r={},o=0){super(n);this.code=n;this.params=r;this.status=o;this.name="ApiError"}code;params;status},oe=class{constructor(e,n){this.baseUrl=e;this.token=n}baseUrl;token;async call(e,n={}){let r=this.token();if(!r)throw new m("errors.NOT_LOGGED_IN");let o=await fetch(`${this.baseUrl}${e}`,{...n,headers:{...await we(),...n.headers??{},authorization:`Bearer ${r}`,"content-type":"application/json"}});if(o.status===204)return;let i=await o.json().catch(()=>({}));if(!o.ok)throw new m(i.code??"errors.UNKNOWN",i.params??{},o.status);return i}getMe(){return this.call("/api/me")}reportRun(e,n){return this.call("/api/devices/current/run",{method:"POST",body:JSON.stringify({kind:e,files:n}),signal:AbortSignal.timeout(5e3)})}signOut(){return this.call("/api/auth/sign-out",{method:"POST",body:"{}",signal:AbortSignal.timeout(5e3)})}listSkills(){return this.call("/api/skills")}getSkill(e,n){return this.call(`/api/skills/${encodeURIComponent(e)}${this.teamQuery(n)}`)}putSkill(e,n,r={}){return this.call(`/api/skills/${encodeURIComponent(e)}`,{method:"PUT",body:JSON.stringify({body:n,...r})})}skillFileUrl(e,n){let r=n.split("/").map(encodeURIComponent).join("/");return`/api/skills/${encodeURIComponent(e)}/files/${r}`}getSkillFile(e,n){return this.call(this.skillFileUrl(e,n))}putSkillFile(e,n,r,o="utf8"){return this.call(this.skillFileUrl(e,n),{method:"PUT",body:JSON.stringify({content:r,encoding:o})})}listAgents(){return this.call("/api/agents")}putAgent(e,n){return this.call(`/api/agents/${encodeURIComponent(e)}`,{method:"PUT",body:JSON.stringify(n)})}getAgent(e,{use:n=!1,team:r}={}){let o=[n?"use=1":null,r===void 0?null:`team=${encodeURIComponent(r)}`].filter(Boolean);return this.call(`/api/agents/${encodeURIComponent(e)}${o.length?`?${o.join("&")}`:""}`)}readMemory(e,n){return this.call(`${this.memoryUrl(e)}${this.teamQuery(n)}`)}writeMemory(e,n,r,o){return this.call(this.memoryUrl(e),{method:"PUT",body:JSON.stringify({content:n,deviceLabel:r,...o===void 0?{}:{ifMatch:o}})})}memoryUrl(e){return`/api/memory/${e.split("/").map(encodeURIComponent).join("/")}`}teamQuery(e,n="?"){return e===void 0?"":`${n}team=${encodeURIComponent(e)}`}listMemory(){return this.call("/api/memory")}searchContent(e,n={}){let r=new URLSearchParams({q:e});n.types?.length&&r.set("types",n.types.join(",")),n.limit&&r.set("limit",String(n.limit));for(let o of["type","project","tag"])n[o]!==void 0&&r.set(o,n[o]);return this.call(`/api/search?${r.toString()}`)}graphNodeByRid(e,n){return this.call(`/api/graph/rid/${e}/${encodeURIComponent(n)}`)}graphAround(e,n,r={}){let o=new URLSearchParams({scope:"all",focus:e,depth:String(n),walk:"links"});return r.types?.length&&o.set("types",r.types.join(",")),r.folder!==void 0&&o.set("folder",r.folder),r.project!==void 0&&o.set("project",r.project),this.call(`/api/graph?${o.toString()}`)}memoryTree(e="all"){return this.call(`/api/memory/tree?scope=${encodeURIComponent(e)}`)}moveMemory(e,n,r=!0,o=Wn()){return this.call("/api/memory/move",{method:"POST",body:JSON.stringify({from:e,to:n,updateLinks:r,deviceLabel:o})})}async exportArchive(e={}){let n=this.token();if(!n)throw new m("errors.NOT_LOGGED_IN");let r=new URLSearchParams;e.scope&&r.set("scope",e.scope),e.types?.length&&r.set("types",e.types.join(","));let o=r.size>0?`?${r.toString()}`:"",i=await fetch(`${this.baseUrl}/api/export${o}`,{headers:{...await we(),authorization:`Bearer ${n}`}});if(!i.ok){let s=await i.json().catch(()=>({}));throw new m(s.code??"errors.UNKNOWN",s.params??{},i.status)}return i}deleteMemory(e){return this.call(this.memoryUrl(e),{method:"DELETE"})}deleteSkill(e){return this.call(`/api/skills/${encodeURIComponent(e)}`,{method:"DELETE"})}deleteSkillFile(e,n){return this.call(this.skillFileUrl(e,n),{method:"DELETE"})}deleteAgent(e){return this.call(`/api/agents/${encodeURIComponent(e)}`,{method:"DELETE"})}listConnections(){return this.call("/api/mcp-connections")}listTeams(){return this.call("/api/teams")}shareWithTeam(e,n){return this.call(`/api/teams/${encodeURIComponent(e)}/share`,{method:"POST",body:JSON.stringify(n)})}returnFromTeam(e,n){return this.call(`/api/teams/${encodeURIComponent(e)}/unshare`,{method:"POST",body:JSON.stringify(n)})}createConnection(e){return this.call("/api/mcp-connections",{method:"POST",body:JSON.stringify(e)})}updateConnection(e,n){return this.call(`/api/mcp-connections/${e}`,{method:"PATCH",body:JSON.stringify(n)})}deleteConnection(e){return this.call(`/api/mcp-connections/${e}`,{method:"DELETE"})}listCapabilities(e){return this.call(`/api/mcp-connections/${e}/capabilities`)}toggleCapability(e,n,r){return this.call(`/api/mcp-connections/${e}/capabilities/${n}`,{method:"PATCH",body:JSON.stringify({enabled:r})})}};var Bn="https://only-mcp.com";function mt(t=process.env.ONLYMCP_API_URL){if(t===void 0)return Bn;let e;try{e=new URL(t).protocol}catch{}if(e!=="http:"&&e!=="https:"){let n=t.replace(/\/\/[^/@]*@/,"//***@");throw new Error(`ONLYMCP_API_URL is not a valid http(s) URL: ${JSON.stringify(n)}`)}return t}import{Entry as Kn}from"@napi-rs/keyring";function Vn(t,e){let n=()=>new Kn(t,e);return{save(r){n().setPassword(r)},read(){try{return n().getPassword()}catch{return null}},clear(){try{n().deletePassword()}catch{}}}}var ut=Vn("onlymcp","session-token");import ie from"cacache";var Jn=Number(process.env.ONLYMCP_TTL_SECONDS??360*60),se=class{constructor(e=tt()){this.dir=e}dir;async get(e){try{let n=await ie.get(this.dir,e),r=n.metadata;return!r||r.expiresAt<=Date.now()?(await ie.rm.entry(this.dir,e),null):n.data.toString("utf8")}catch{return null}}async set(e,n,r=Jn){await ie.put(this.dir,e,n,{metadata:{expiresAt:Date.now()+r*1e3}})}async clear(){await ie.rm.all(this.dir)}};var ft=["OnlyMCP holds this user's skills, agents and memory in the cloud, identical","on every machine. The names below are names only, not content: call","get_skill(name) to load a skill before following it, and","get_agent_definition(name) for an agent. Call list_skills or list_agents for","anything not named here. Memory is live: memory_read(path) and","memory_write(path, content). All of it is writable, not just readable:","skill_write, agent_write and the matching *_delete tools; connection_create","adds another MCP server to this account.","Link with [[name]] or typed: [[skill:name]], [[agent:name]], [[mcp:slug]], [[memory:path]]."].join(" "),qn=["Memory is a vault, not a scratch file: read MEMORY.md first, it is the index.","After finishing a task, write one solutions/sol-*.md for what was not obvious","and one entry in history/YYYY-MM-DD.md. Link related files with [[name]];","memory_links(path) says which of a file's links point nowhere yet."].join(" ");function gt(t,e,n,r){if(n.length===0)return"";let o=[];for(let c of n){let a=n.length-o.length-1,f=a>0?` (+${a} more, call ${e})`:"",g=`
|
|
5
5
|
|
|
6
6
|
${t}: ${[...o,c].join(", ")}${f}`;if(r+g.length>1800)break;o.push(c)}if(o.length===0)return`
|
|
7
7
|
|
|
@@ -51,10 +51,10 @@ ${c}`:s}).join(`
|
|
|
51
51
|
`))}catch(n){return T(X(n))}}}}var Mr=x.object({path:x.string().min(3).max(256).describe("Path of the memory file to start from."),depth:x.number().int().min(1).max(3).optional().describe("Hops to walk, 1 to 3. Default 1."),types:x.string().max(128).optional().describe("Comma-separated node kinds to list: memory, skill, agent, mcp, tool, folder, type, project, tag, collection."),folder:x.string().max(256).optional().describe("Only memory files and folders under this folder (full path, or its last part)."),project:be.describe("Only nodes about this project (and the project itself).")});function Vt(t){return{name:"memory_graph",description:"The graph around one memory file, up to three hops. Depth 1: the files, skills, agents and servers it links to or is linked from, its folder, type, project and tags, and links that land on nothing (\u2192 links to (missing) name). From depth 2 on only links out of a file reached by a link are followed: a backlink, folder, type, project or tag is listed at depth 1 and never walked through. Pick the depth yourself; 1 is the default and usually enough, 2-3 follow a chain of links further, the files most of the previous depth links to first. Grouped by depth; each line names the edge and, from depth 2, the node it was reached through. types, folder and project narrow what is listed, not the walk.",inputSchema:Mr,async handler(e){if(!k(e.path))return T("errors.INVALID_PATH");let n=e.depth??1,r=e.types===void 0||e.types.trim()===""?void 0:Oe(e.types);if(r===null)return T(`Invalid types: ${e.types}`);let o=(e.folder??"").trim().replace(/^\/+|\/+$/g,"");if(o!==""&&!k(`${o}/x.md`))return T("errors.INVALID_PATH");try{let i=await t.readMemory(e.path);if(!i.id)return T("This server is too old for memory_graph: it does not send a file id.");let s;try{s=(await t.graphNodeByRid("memory",i.id)).node.id}catch(d){if(d instanceof m&&d.code==="errors.NODE_NOT_FOUND")return I(`${i.path} is not in the graph yet (it is added on its next save).`);throw d}let c=o===""?null:me(o,Jt((await t.memoryTree("all")).nodes));if(c&&"error"in c)return I(c.error);let a=await t.graphAround(s,n),f={...r?{types:r}:{},...c?{folder:c.folder}:{},...e.project!==void 0?{project:e.project}:{}},g=Object.keys(f).length>0?new Set((await t.graphAround(s,n,f)).nodes.map(d=>d.id)):null,p=Le(f)?a.missing??[]:[];return I(Me({path:i.path,focus:s,depth:n,nodes:a.nodes,edges:a.edges,truncated:a.truncated,kept:g,missing:p}))}catch(i){return T(X(i))}}}}function Jt(t){let e=new Set;for(let n of t){n.kind==="folder"&&e.add(n.path);let r=n.path.split("/");for(let o=1;o<r.length;o+=1)e.add(r.slice(0,o).join("/"))}return[...e]}import{z as y}from"zod";var Ur=t=>({content:[{type:"text",text:t}]}),qt=t=>({content:[{type:"text",text:t}],isError:!0});async function F(t){try{return Ur(await t())}catch(e){if(e instanceof m){let n=Object.keys(e.params).length?` ${JSON.stringify(e.params)}`:"";return qt(`${e.code}${n}`)}return qt("errors.UNKNOWN")}}var Q=y.string().min(1).max(32).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/,"errors.INVALID_SLUG");async function xe(t,e){let{connections:n}=await t.listConnections(),r=n.filter(o=>o.slug===e);return r.find(o=>o.scope==="personal")??r[0]??null}function qe(t){let e=t.authType==="none"?"no auth":`${t.authType}, secret ...${t.secretHint??"?"}`;return`${t.slug} \u2014 ${t.name} (${t.scope}, ${t.enabled?t.status:"disabled"}, ${e})
|
|
52
52
|
${t.url}${t.statusError?`
|
|
53
53
|
last error: ${t.statusError}`:""}`}var Dr=y.object({});function Yt(t){return{name:"list_connections",description:"List the MCP servers connected through this OnlyMCP account, with the tool-name prefix each one uses.",inputSchema:Dr,handler:()=>F(async()=>{let{connections:e}=await t.listConnections();return e.length===0?"No MCP servers are connected yet. Add one with connection_create.":e.map(qe).join(`
|
|
54
|
-
`)})}}var jr=y.object({name:y.string().min(1).max(80),slug:Q,url:y.string().url().max(2e3),transport:y.enum(["http","sse"]).default("http"),authType:y.enum(["none","bearer","header"]).default("none"),authHeaderName:y.string().max(80).optional(),secret:y.string().max(4e3).optional(),teamId:y.string().max(64).optional()});function Zt(t){return{name:"connection_create",description:"Connect a remote MCP server (http or sse only - a stdio server cannot be started on somebody else's behalf). It is probed straight away. Passing a secret here puts it into this conversation; leave it out and set it in the dashboard if that matters.",inputSchema:jr,handler:e=>F(async()=>{let{connection:n}=await t.createConnection(e);return`Connected.
|
|
54
|
+
`)})}}var jr=y.object({name:y.string().min(1).max(80),slug:Q,url:y.string().url().max(2e3),transport:y.enum(["http","sse"]).default("http"),authType:y.enum(["none","bearer","header","basic"]).default("none"),authHeaderName:y.string().max(80).optional(),secret:y.string().max(4e3).optional(),teamId:y.string().max(64).optional()});function Zt(t){return{name:"connection_create",description:"Connect a remote MCP server (http or sse only - a stdio server cannot be started on somebody else's behalf). It is probed straight away. Passing a secret here puts it into this conversation; leave it out and set it in the dashboard if that matters.",inputSchema:jr,handler:e=>F(async()=>{let{connection:n}=await t.createConnection(e);return`Connected.
|
|
55
55
|
${qe(n)}
|
|
56
56
|
|
|
57
|
-
Its tools are now available as "${n.slug}__<tool>".`})}}var zr=y.object({slug:Q,name:y.string().min(1).max(80).optional(),url:y.string().url().max(2e3).optional(),transport:y.enum(["http","sse"]).optional(),authType:y.enum(["none","bearer","header"]).optional(),authHeaderName:y.string().max(80).optional(),secret:y.string().max(4e3).optional(),enabled:y.boolean().optional()});function Xt(t){return{name:"connection_update",description:"Change a connected MCP server. Only the fields you pass are touched; url, transport, authType and secret trigger a fresh probe.",inputSchema:zr,handler:e=>F(async()=>{let n=await xe(t,e.slug);if(!n)return`Connection not found: ${e.slug}`;let{slug:r,...o}=e,{connection:i}=await t.updateConnection(n.id,o);return`Updated.
|
|
57
|
+
Its tools are now available as "${n.slug}__<tool>".`})}}var zr=y.object({slug:Q,name:y.string().min(1).max(80).optional(),url:y.string().url().max(2e3).optional(),transport:y.enum(["http","sse"]).optional(),authType:y.enum(["none","bearer","header","basic"]).optional(),authHeaderName:y.string().max(80).optional(),secret:y.string().max(4e3).optional(),enabled:y.boolean().optional()});function Xt(t){return{name:"connection_update",description:"Change a connected MCP server. Only the fields you pass are touched; url, transport, authType and secret trigger a fresh probe.",inputSchema:zr,handler:e=>F(async()=>{let n=await xe(t,e.slug);if(!n)return`Connection not found: ${e.slug}`;let{slug:r,...o}=e,{connection:i}=await t.updateConnection(n.id,o);return`Updated.
|
|
58
58
|
${qe(i)}`})}}var Gr=y.object({slug:Q});function Qt(t){return{name:"connection_delete",description:"Disconnect a remote MCP server and forget its stored credential. Its tools disappear from the gateway.",inputSchema:Gr,handler:e=>F(async()=>{let n=await xe(t,e.slug);return n?(await t.deleteConnection(n.id),`Disconnected ${e.slug}.`):`Connection not found: ${e.slug}`})}}var Fr=y.object({slug:Q});function en(t){return{name:"connection_tools",description:"List what one connected server offers, and whether each tool is switched on for the gateway.",inputSchema:Fr,handler:e=>F(async()=>{let n=await xe(t,e.slug);if(!n)return`Connection not found: ${e.slug}`;let{capabilities:r}=await t.listCapabilities(n.id);return r.length===0?`${e.slug} has nothing on record yet. Its status is "${n.status}".`:r.map(o=>`${o.enabled?"[on] ":"[off]"} ${o.kind} ${o.name}${o.exposedAs?` -> ${o.exposedAs}`:""}${o.description?` \u2014 ${o.description}`:""}`).join(`
|
|
59
59
|
`)})}}var Hr=y.object({slug:Q,tool:y.string().min(1).max(200),enabled:y.boolean()});function tn(t){return{name:"connection_tool_toggle",description:"Switch one tool of a connected server on or off. A tool that is off costs no room in any client's tool list.",inputSchema:Hr,handler:e=>F(async()=>{let n=await xe(t,e.slug);if(!n)return`Connection not found: ${e.slug}`;let{capabilities:r}=await t.listCapabilities(n.id),o=r.find(i=>i.kind==="tool"&&i.name===e.tool);return o?(await t.toggleCapability(n.id,o.id,e.enabled),`${e.slug}__${o.name} is now ${e.enabled?"on":"off"}.`):`${e.slug} offers no tool called ${e.tool}.`})}}import{z as b}from"zod";var Wr=t=>({content:[{type:"text",text:t}]}),ee=t=>({content:[{type:"text",text:t}],isError:!0});async function E(t){try{return Wr(await t())}catch(e){if(e instanceof m){let n=Object.keys(e.params).length?` ${JSON.stringify(e.params)}`:"";return ee(`${e.code}${n}`)}return ee("errors.UNKNOWN")}}var j=b.string().min(1).max(64).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/,"errors.INVALID_NAME"),Br=b.object({name:j,body:b.string().max(2e5)});function nn(t){return{name:"skill_write",description:"Create a skill or replace the body of an existing one. The body is the whole SKILL.md, frontmatter included.",inputSchema:Br,handler:e=>E(async()=>{let n=await t.putSkill(e.name,e.body);return`${n.name} ${n.updatedAt}`})}}var Kr=b.object({name:j});function rn(t){return{name:"skill_delete",description:"Delete one skill and every file that belongs to it. Moves it to the trash; it can be restored in the dashboard for the trash period (default 7 days).",inputSchema:Kr,handler:e=>E(async()=>(await t.deleteSkill(e.name),`Deleted skill ${e.name}`))}}var Vr=b.object({skill:j});function on(t){return{name:"list_skill_files",description:"List the companion files of one skill, with their size in bytes.",inputSchema:Vr,handler:e=>E(async()=>{let{files:n}=await t.getSkill(e.skill);return n.length===0?`${e.skill} has no companion files.`:n.map(r=>`${r.path} (${r.size} bytes, ${r.encoding})`).join(`
|
|
60
60
|
`)})}}var Jr=b.object({skill:j,path:b.string().min(1).max(256),content:b.string().max(3e6),encoding:b.enum(["utf8","base64"]).default("utf8")});function sn(t){return{name:"skill_file_write",description:"Create or replace one companion file of a skill. Use encoding base64 for anything that is not text.",inputSchema:Jr,handler:e=>M(e.path)?E(async()=>{let n=await t.putSkillFile(e.skill,e.path,e.content,e.encoding);return`${e.skill}/${n.path} ${n.size} bytes`}):Promise.resolve(ee("errors.INVALID_PATH"))}}var qr=b.object({skill:j,path:b.string().min(1).max(256)});function an(t){return{name:"skill_file_delete",description:"Delete one companion file of a skill. The skill itself stays.",inputSchema:qr,handler:e=>M(e.path)?E(async()=>(await t.deleteSkillFile(e.skill,e.path),`Deleted ${e.skill}/${e.path}`)):Promise.resolve(ee("errors.INVALID_PATH"))}}var Yr=b.object({name:j,description:b.string().min(1).max(1e3),body:b.string().max(2e5),model:b.string().max(64).optional(),tools:b.array(b.string().max(128)).max(200).optional()});function ln(t){return{name:"agent_write",description:"Create an agent or replace an existing one. Leave model out to keep the one it already has.",inputSchema:Yr,handler:e=>E(async()=>{let n=await t.getAgent(e.name).catch(()=>null),r=await t.putAgent(e.name,{description:e.description,body:e.body,model:e.model??n?.model??void 0,tools:e.tools??n?.tools??[]});return`${r.name} ${r.updatedAt}`})}}var Zr=b.object({name:j});function cn(t){return{name:"agent_delete",description:"Delete one agent. Moves it to the trash; it can be restored in the dashboard for the trash period (default 7 days).",inputSchema:Zr,handler:e=>E(async()=>(await t.deleteAgent(e.name),`Deleted agent ${e.name}`))}}var Xr=b.object({});function dn(t){return{name:"list_memory",description:"List the paths of every memory file in this account, private and team, sorted by path.",inputSchema:Xr,handler:()=>E(async()=>{let{files:e}=await t.listMemory();return e.length===0?"(none)":e.map(n=>n.path+D(n)).sort().join(`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "onlymcp",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.8",
|
|
4
4
|
"description": "Skills, agents and memory from the OnlyMCP cloud in every MCP client. Ships the stdio MCP server and the CLI that sets up Claude Code, Codex and Antigravity.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Francesco Palazzo",
|