onlymcp 0.24.5 → 0.25.0
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/README.md +5 -3
- package/dist/bin/cli.js +59 -57
- package/dist/bin/mcp.js +48 -46
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -65,9 +65,11 @@ terminal) and stores the token in the operating system keyring, never in a file.
|
|
|
65
65
|
|
|
66
66
|
## What the agent gets
|
|
67
67
|
|
|
68
|
-
This local server offers
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
This local server offers the same tools as the hosted endpoint, except the two that
|
|
69
|
+
call a connected server's tools by name: skills, agents and memory (read, write,
|
|
70
|
+
append, search with filters by type, project and tag, the folder tree, moving files,
|
|
71
|
+
their links and `memory_graph`, which walks what a file is connected to), your
|
|
72
|
+
connections and your teams. They work in every MCP client. Clients with their own skill scanner additionally get stub files so the
|
|
71
73
|
agent knows what exists without asking first. Claude Code can also spawn the agents
|
|
72
74
|
as subagents; elsewhere they stay readable but not spawnable.
|
|
73
75
|
|
package/dist/bin/cli.js
CHANGED
|
@@ -1,83 +1,85 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{cancel as
|
|
3
|
-
`,{flag:"wx",mode:384});try{return await
|
|
4
|
-
`,{flag:"wx",mode:384}),t}catch(s){if(s.code!=="EEXIST")throw s}}let r=await
|
|
5
|
-
`))]},
|
|
6
|
-
`);for(let r=0;r<n.length;r+=1){let i=n[r];for(let{rule:o,re:s}of
|
|
2
|
+
import{cancel as vr,confirm as Sr,intro as _t,isCancel as Tt,log as f,multiselect as bs,outro as oe,spinner as We}from"@clack/prompts";import{Command as ks}from"commander";import xs from"open";import ws from"qrcode";import{homedir as $r}from"node:os";import{createWriteStream as vs,existsSync as E,mkdirSync as Ss}from"node:fs";import{pipeline as Cs}from"node:stream/promises";import{Readable as $s}from"node:stream";import{dirname as As,join as Cr}from"node:path";import{hostname as Vr}from"node:os";import{execFile as zr}from"node:child_process";import{hostname as Fr}from"node:os";import{readFile as Gr}from"node:fs/promises";import{promisify as Hr}from"node:util";import{randomUUID as Lt}from"node:crypto";import{link as Ir,mkdir as _r,readFile as Er,rename as Nr,rm as Rr,writeFile as Mt}from"node:fs/promises";import{basename as Or,dirname as Ut,join as Lr}from"node:path";import{existsSync as Pr}from"node:fs";import{homedir as Nt}from"node:os";import{join as B}from"node:path";function xe(){return process.env.ONLYMCP_HOME??B(Nt(),".claude","onlymcp")}function Et(){return process.env.ONLYMCP_HOME??Nt()}function Rt(){return B(xe(),"device-id")}function Ot(){return B(xe(),"cache")}function we(){return B(xe(),"stub-ignore")}function ve(){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[B(Et(),".claude"),B(Et(),".codex")])Pr(t)&&!e.includes(t)&&e.push(t);return e.length>0?e:[B(xe(),"plugin")]}var Mr=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/,Dt;function jt(){return Dt??=Dr(),Dt}async function Be(e){try{let t=(await Er(e,"utf8")).trim().toLowerCase();return Mr.test(t)?t:null}catch{return null}}async function Dr(){let e=Rt(),t=await Be(e);if(t)return t;try{return await _r(Ut(e),{recursive:!0}),await jr(e)}catch{return null}}var Ur=new Set(["EPERM","ENOTSUP","EOPNOTSUPP","ENOSYS","EXDEV"]);async function jr(e){let t=Lt(),n=Lr(Ut(e),`.${Or(e)}.${process.pid}.${Lt()}.tmp`);try{await Mt(n,`${t}
|
|
3
|
+
`,{flag:"wx",mode:384});try{return await Ir(n,e),t}catch(i){let o=i.code;if(o!=="EEXIST"&&!Ur.has(o??""))throw i;if(o!=="EEXIST")try{return await Mt(e,`${t}
|
|
4
|
+
`,{flag:"wx",mode:384}),t}catch(s){if(s.code!=="EEXIST")throw s}}let r=await Be(e);return r||(await Nr(n,e),await Be(e)??t)}finally{await Rr(n,{force:!0}).catch(()=>{})}}var Q="0.25.0";var Wr=Hr(zr),Br=`onlymcp-cli/${Q} (${process.platform} ${process.arch}; node ${process.versions.node})`,zt=200;async function Ft(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 Kr(){try{if(process.platform==="linux"){let e=Gr("/sys/class/dmi/id/product_version","utf8"),n=(await Ft(e,zt))?.trim();return!n||/^(to be filled|default string|system version|none|n\/a)/i.test(n)?null:n}if(process.platform==="darwin"){let e=Wr("sysctl",["-n","hw.model"]);return(await Ft(e,zt))?.stdout.trim()||null}}catch{}return null}async function Ke(){let e="unknown";try{e=Fr()||"unknown"}catch{}let t=await Kr();return(t&&t!==e?`${e} (${t})`:e).slice(0,60)}var Gt=null;async function le(){Gt??=await Ke();let e=await jt();return{"user-agent":Br,"x-onlymcp-device":Gt,...e?{"x-onlymcp-device-id":e}:{}}}var y=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},O=class{constructor(t,n){this.baseUrl=t;this.token=n}baseUrl;token;async call(t,n={}){let r=this.token();if(!r)throw new y("errors.NOT_LOGGED_IN");let i=await fetch(`${this.baseUrl}${t}`,{...n,headers:{...await le(),...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 y(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)});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=Vr()){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 y("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 le(),authorization:`Bearer ${n}`}});if(!o.ok){let s=await o.json().catch(()=>({}));throw new y(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 Jr}from"@napi-rs/keyring";function Yr(e,t){let n=()=>new Jr(e,t);return{save(r){n().setPassword(r)},read(){try{return n().getPassword()}catch{return null}},clear(){try{n().deletePassword()}catch{}}}}var N=Yr("onlymcp","session-token");var qr={sleep:e=>new Promise(t=>setTimeout(t,e))};async function Ht(e,t,n,r=qr){let i=n;for(;;){await r.sleep(i*1e3);let s=await(await fetch(`${e}/api/auth/device/token`,{method:"POST",headers:{...await le(),"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 y("errors.DEVICE_ACCESS_DENIED");case"expired_token":throw new y("errors.DEVICE_CODE_EXPIRED");default:throw new y("errors.DEVICE_LOGIN_FAILED",{error:s.error})}}}import Se from"cacache";var Xr=Number(process.env.ONLYMCP_TTL_SECONDS??360*60),ee=class{constructor(t=Ot()){this.dir=t}dir;async get(t){try{let n=await Se.get(this.dir,t),r=n.metadata;return!r||r.expiresAt<=Date.now()?(await Se.rm.entry(this.dir,t),null):n.data.toString("utf8")}catch{return null}}async set(t,n,r=Xr){await Se.put(this.dir,t,n,{metadata:{expiresAt:Date.now()+r*1e3}})}async clear(){await Se.rm.all(this.dir)}};import{appendFileSync as Ri,existsSync as _e,mkdirSync as Qt,readFileSync as tn,writeFileSync as Oi}from"node:fs";import{dirname as nn,join as Li}from"node:path";function Wt(e){return{language:"bash",text:e}}function G(e,t){return{language:"json",text:JSON.stringify(e,null,2),path:t}}var Zr={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=>[Wt(`claude mcp add --transport http --scope user onlymcp ${e.endpoint} --header "Authorization: Bearer ${e.token}"`)]},Qr={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},ei={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},ti={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=>[Wt([`export ONLYMCP_TOKEN=${e.token}`,`codex mcp add onlymcp --url ${e.endpoint} --bearer-token-env-var ONLYMCP_TOKEN`].join(`
|
|
5
|
+
`))]},ni={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=>[G({mcpServers:{onlymcp:{serverUrl:e.endpoint,headers:{Authorization:`Bearer ${e.token}`}}}},"~/.gemini/config/mcp_config.json")]},ri={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},ii={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},oi={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=>[G({servers:{onlymcp:{type:"http",url:e.endpoint,headers:{Authorization:`Bearer ${e.token}`}}}},".vscode/mcp.json")]},si={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=>[G({mcpServers:{onlymcp:{url:e.endpoint,headers:{Authorization:`Bearer ${e.token}`}}}},"~/.cursor/mcp.json")]},ai={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=>[G({mcpServers:{onlymcp:{url:e.endpoint,headers:{Authorization:`Bearer ${e.token}`}}}},"~/.config/devin/mcp_config.json")]},li={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=>[G({mcpServers:{onlymcp:{type:"streamableHttp",url:e.endpoint,headers:{Authorization:`Bearer ${e.token}`}}}},"~/.cline/data/settings/cline_mcp_settings.json")]},ci={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=>[G({context_servers:{onlymcp:{url:e.endpoint,headers:{Authorization:`Bearer ${e.token}`}}}},"settings.json")]},pi={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=>[G({mcp:{onlymcp:{type:"remote",url:e.endpoint,headers:{Authorization:`Bearer ${e.token}`}}}},"opencode.json")]},di={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=>[G({mcpServers:{onlymcp:{type:"http",url:e.endpoint}}},"~/.gitlab/duo/mcp.json")]},Ce=[Qr,ei,ri,ii,Zr,ti,ni,pi,oi,si,ai,li,ci,di];function Ve(e){return Ce.find(t=>t.id===e||t.aliases?.includes(e))}var mi=/^[a-z0-9][a-z0-9._-]*(\/[a-z0-9][a-z0-9._-]*)*\.md$/i;function C(e){return mi.test(e)&&!e.split("/").includes("..")}var ui=/^[A-Za-z0-9][A-Za-z0-9._-]*$/,fi=8,gi=200;function H(e){if(e.length===0||e.length>gi||e==="SKILL.md")return!1;let t=e.split("/");return t.length>fi?!1:t.every(n=>ui.test(n)&&n!==".."&&n!==".")}function hi(e){return e.includes("\\")||/^[A-Za-z]:/.test(e)?!0:e.split("/").some(t=>t===""||t==="."||t==="..")}var yi=[/^\.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 Ae(e){return yi.some(t=>t.test(e))}var bi=new Set([".git","node_modules","__pycache__",".venv","venv",".pytest_cache",".mypy_cache","dist","build",".next",".cache"]);function Je(e){return bi.has(e)}var ki=[{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 xi(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 Vt(e){let t=[],n=e.split(`
|
|
6
|
+
`);for(let r=0;r<n.length;r+=1){let i=n[r];for(let{rule:o,re:s}of ki){let p=s.exec(i);if(p){t.push({rule:o,line:r+1,excerpt:xi(i,p[0])});break}}}return t}function V(e){if(!e.startsWith(`---
|
|
7
7
|
`))return null;let t=e.indexOf(`
|
|
8
|
-
---`,3);return t<0?null:e.slice(4,t)}function
|
|
8
|
+
---`,3);return t<0?null:e.slice(4,t)}function L(e,t){if(!/^[a-zA-Z0-9_-]+$/.test(t))return;let n=new RegExp(`^${t}:[ \\t]*(.*)$`,"m").exec(e);if(!n)return;let i=n[1].trim().replace(/^(['"])(.*)\1$/,"$2").trim();return i.length>0?i:void 0}function te(e){let t=V(e);if(t===null)return null;let n=L(t,"description");if(!n)return null;let r=L(t,"tools"),i=r?r.replace(/^\[(.*)\]$/,"$1").split(",").map(s=>s.trim()).filter(s=>s.length>0):[],o=L(t,"model");return o?{description:n,model:o,tools:i}:{description:n,tools:i}}function Ye(e){let t=V(e);return(t===null?void 0:L(t,"description"))??""}function K(e){let t=V(e);return t===null?!1:L(t,"x-onlymcp-stub")==="true"}function ce(e){if(!e.startsWith(`---
|
|
9
9
|
`))return e;let t=e.indexOf(`
|
|
10
10
|
---`,3);if(t<0)return e;let n=e.indexOf(`
|
|
11
|
-
`,t+4);return n<0?"":e.slice(n+1)}var
|
|
11
|
+
`,t+4);return n<0?"":e.slice(n+1)}var Bt=/^[a-z0-9]+(-[a-z0-9]+)*$/,wi=/^[a-z0-9]+(-[a-z0-9]+)*(:[a-z0-9]+(-[a-z0-9]+)*)?$/,Kt=/^[a-z0-9][a-z0-9._-]*$/i;function Jt(e){let t=e.indexOf("skills");return t>=4&&e[t-4]==="cache"&&t+1<e.length-1?{prefix:e.slice(0,t+2).join("/"),name:`${e[t-2]}:${e[t+1]}`,plugin:e[t-2],path:e.slice(t+2).join("/")}:null}function vi(e){let t=Jt(e);return t||(e.length<2?null:{prefix:e[0],name:e[0],plugin:null,path:e.slice(1).join("/")})}var $e=(e,t)=>e.localeCompare(t),Si=e=>e.toLowerCase().endsWith(".md");function qe(e,t={}){let n=t.maxBytes??2097152,r=new Set(t.release??[]),i=a=>!t.kinds||t.kinds.includes(a),o=!t.kinds||t.kinds.length!==1,s=o?null:t.kinds[0],p=[],l=[],c=(a,m,g)=>{p.push({at:a,path:m,reason:g})},d=(a,m)=>{if(a.text===void 0)return!0;let g=Vt(a.text);for(let k of g)l.push({at:m,row:{path:a.path,...k}});return g.length===0||r.has(a.path)},u=[],h=new Set;e.forEach((a,m)=>{let g=w=>{h.add(a.path),c(m,a.path,w)};if(hi(a.path))return g("invalid-path");let k=a.path.split("/");if(Ae(k[k.length-1]))return g("denied-name");if(a.bytes>n)return g("too-large");u.push({e:a,i:m,parts:k})});let b=a=>o&&a.parts[0]==="memory"&&a.parts.length>1,x=new Map,A=new Set,I=(a,m)=>{let g=x.get(m.prefix);g?g.members.push(a):x.set(m.prefix,{prefix:m.prefix,name:m.name,plugin:m.plugin,at:a.i,members:[a]}),A.add(a)};if(i("skills"))if(s==="skills")for(let a of u){let m=vi(a.parts);m?I(a,m):c(a.i,a.e.path,"not-in-a-skill-folder")}else{let a=[];for(let g of u){if(b(g)||g.parts[g.parts.length-1]!=="SKILL.md")continue;let k=Jt(g.parts);if(k&&k.path==="SKILL.md")a.push({prefix:k.prefix,name:k.name,plugin:k.plugin,depth:g.parts.length,i:g.i});else if(g.parts.length>=2){let w=g.parts.slice(0,-1).join("/");a.push({prefix:w,name:g.parts[g.parts.length-2],plugin:null,depth:g.parts.length,i:g.i})}}a.sort((g,k)=>g.depth-k.depth||g.i-k.i);let m=[];for(let g of a)m.some(k=>g.prefix===k.prefix||g.prefix.startsWith(`${k.prefix}/`))||m.push({prefix:g.prefix,name:g.name,plugin:g.plugin,path:""});for(let g of u){if(b(g))continue;let k=m.find(w=>g.e.path.startsWith(`${w.prefix}/`));k&&I(g,k)}}let M=[];for(let a of x.values()){if(!wi.test(a.name)){c(a.at,a.prefix,"invalid-name");continue}let m=a.members.find(w=>w.e.path===`${a.prefix}/SKILL.md`);if(!m){h.has(`${a.prefix}/SKILL.md`)||c(a.at,a.prefix,"no-skill-md");continue}if(m.e.text===void 0){c(m.i,m.e.path,"binary");continue}if(K(m.e.text)){c(m.i,m.e.path,"stub");continue}let g=d(m.e,m.i),k=[];for(let w of a.members){if(w===m)continue;let Z=w.e.path.slice(a.prefix.length+1);if(!H(Z)){c(w.i,w.e.path,"invalid-path");continue}if(w.e.text!==void 0&&Si(Z)&&K(w.e.text)){c(w.i,w.e.path,"stub");continue}d(w.e,w.i)&&k.push(w.e.text===void 0?{path:Z,sourcePath:w.e.path,bytes:w.e.bytes}:{path:Z,sourcePath:w.e.path,bytes:w.e.bytes,text:w.e.text})}g&&(k.sort((w,Z)=>$e(w.path,Z.path)),M.push({name:a.name,sourcePath:m.e.path,bytes:m.e.bytes,text:m.e.text,description:Ye(m.e.text),collection:a.plugin?Kt.test(a.plugin)?{key:a.plugin,kind:"plugin",label:a.plugin}:null:t.collection&&Kt.test(t.collection)?{key:t.collection,kind:"directory",label:t.collection}:null,files:k}))}let R=[],W=u.filter(a=>!A.has(a)),se=[],ke=(a,m,g,k)=>{d(a.e,a.i)&&R.push({name:m,sourcePath:a.e.path,bytes:a.e.bytes,description:g.description,...g.model?{model:g.model}:{},tools:g.tools,body:ce(k)})};for(let a of W){if(s==="agents"){if(a.parts.length>1)c(a.i,a.e.path,"not-at-top-level");else if(!a.e.path.endsWith(".md"))c(a.i,a.e.path,"not-markdown");else if(!Bt.test(a.e.path.slice(0,-3)))c(a.i,a.e.path,"invalid-name");else if(a.e.text===void 0)c(a.i,a.e.path,"binary");else if(K(a.e.text))c(a.i,a.e.path,"stub");else{let g=te(a.e.text);g?ke(a,a.e.path.slice(0,-3),g,a.e.text):c(a.i,a.e.path,"no-description")}continue}let m=a.parts.length>=2&&a.parts[a.parts.length-2]==="agents"&&a.e.path.endsWith(".md");if(o&&i("agents")&&!b(a)&&m&&a.e.text!==void 0&&!K(a.e.text)){let g=te(a.e.text);if(g){let k=a.parts[a.parts.length-1].slice(0,-3);Bt.test(k)?ke(a,k,g,a.e.text):c(a.i,a.e.path,"invalid-name");continue}}se.push(a)}let ae=[];if(i("memory"))for(let a of se){let m=b(a)?a.parts.slice(1).join("/"):a.e.path;C(m)?a.e.text===void 0?c(a.i,a.e.path,"binary"):K(a.e.text)?c(a.i,a.e.path,"stub"):d(a.e,a.i)&&ae.push({path:m,sourcePath:a.e.path,bytes:a.e.bytes,text:a.e.text}):c(a.i,a.e.path,"invalid-path")}return ae.sort((a,m)=>$e(a.path,m.path)),M.sort((a,m)=>$e(a.name,m.name)),R.sort((a,m)=>$e(a.name,m.name)),p.sort((a,m)=>a.at-m.at),l.sort((a,m)=>a.at-m.at),{memory:ae,skills:M,agents:R,skipped:p.map(({path:a,reason:m})=>({path:a,reason:m})),flagged:l.map(({row:a})=>a)}}var Ci={memory:"memory",skill:"skills",agent:"agents"},$i={memory:"memory",skills:"skill",agents:"agent"};function pe(e){let t=e.teamId===null?"":`?team=${encodeURIComponent(e.teamId)}`;return`onlymcp://${Ci[e.kind]}/${e.name}${t}`}var Ai=/^onlymcp:\/\/(memory|skills|agents)\/([^?]+)(?:\?team=([^&]+))?$/;function Xe(e){let t=Ai.exec(e);if(!t)return null;let n=null;if(t[3]!==void 0)try{n=decodeURIComponent(t[3])}catch{return null}return{kind:$i[t[1]],name:t[2],teamId:n}}var Te=[{uriTemplate:"onlymcp://memory/{+path}{?team}",name:"Memory file",description:"One memory file by path; ?team=<id> for a team file.",mimeType:"text/markdown"},{uriTemplate:"onlymcp://skills/{name}{?team}",name:"Skill",description:"The SKILL.md of one skill.",mimeType:"text/markdown"},{uriTemplate:"onlymcp://agents/{name}{?team}",name:"Agent",description:"The definition file of one agent.",mimeType:"text/markdown"}],Pe=(e,t)=>`${e}__${t}`;function Ze(e){let t=/^(skill|agent)__(.+)$/.exec(e);return t?{kind:t[1],name:t[2]}:null}function de(e,t,n,r){let i=0;if(n!==void 0){let p=e.findIndex(l=>t(l)===n);if(p===-1)return null;i=p+1}let o=e.slice(i,i+r),s=i+r<e.length;return{page:o,next:s&&o.length>0?t(o[o.length-1]):void 0}}function Qe(e,t){return e===null||e===""?t:e.endsWith(`
|
|
12
12
|
`)?e+t:`${e}
|
|
13
|
-
${t}`}function
|
|
13
|
+
${t}`}function et(e,t,n){let r=e===""?[]:e.split(`
|
|
14
14
|
`);r.length>0&&e.endsWith(`
|
|
15
15
|
`)&&r.pop();let i=r.length,o=Math.min(t+n-1,i);return{text:t>i?"":r.slice(t-1,o).join(`
|
|
16
|
-
`),totalLines:i,from:t,to:o}}var
|
|
16
|
+
`),totalLines:i,from:t,to:o}}var tt=(e,t)=>`No lines from ${e}: the file has ${t} ${t===1?"line":"lines"}.`;var qt=["memory","folder","project","type","tag","skill","collection","agent","connection","tool"],Ti={connection:"mcp"},Pi=e=>Ti[e]??e;function Ie(e){let t;return e.kind==="memory"&&typeof e.props.path=="string"?t=e.props.path:e.kind==="connection"&&typeof e.props.slug=="string"?t=e.props.slug:t=e.name??e.key,`${Pi(e.kind)} ${t}`}var Ii={links_to:{out:"links to",in:"linked from"},about:{out:"about",in:"also about it:"},has_type:{out:"has",in:"also of this type:"},tagged:{out:"has",in:"also tagged:"},contains:{out:"contains",in:"in"},in_collection:{out:"in collection",in:"in it:"},uses_skill:{out:"uses",in:"used by"},uses_tool:{out:"uses",in:"used by"},provides:{out:"provides",in:"provided by"}},_i={links_to:0,uses_skill:1,uses_tool:1,provides:2,in_collection:2,contains:3},Yt=e=>_i[e]??4;function Ei(e,t){return Ii[e]?.[t]??`${e}${t==="in"?" (in)":""}`}var Ni={out:"\u2192",in:"\u2190"};function rt(e){let t=e.split(",").map(r=>r.trim()).filter(r=>r!=="");if(t.length===0)return null;let n=t.map(r=>r==="mcp"?"connection":r);return n.every(r=>qt.includes(r))?n:null}var nt=(e,t)=>`${e} ${t}${e===1?"":"s"}`;function it(e){let{path:t,focus:n,depth:r,kept:i}=e,o=new Map(e.nodes.map(b=>[b.id,b])),s=new Map,p=(b,x)=>{let A=s.get(b)??[];A.push(x),s.set(b,A)};for(let b of e.edges)p(b.from,{other:b.to,type:b.type,direction:"out"}),p(b.to,{other:b.from,type:b.type,direction:"in"});let l=b=>{if(b===n)return 0;let x=o.get(b);if(!x)return 1/0;if(x.depth!==void 0)return x.depth;let A=(s.get(b)??[]).map(I=>I.other===n?0:o.get(I.other)?.depth??1/0);return Math.min(1/0,...A)+1},c=new Map;for(let b of e.nodes){let x=l(b.id);if(b.id===n||!Number.isFinite(x)||x<1||x>r||i&&!i.has(b.id))continue;let A=c.get(x)??[];A.push(b.id),c.set(x,A)}let d=[],u=0;for(let b=1;b<=r;b+=1){let x=c.get(b)??[];if(x.length===0)continue;u+=x.length;let A=x.map(I=>{let M=o.get(I),R=(s.get(I)??[]).filter(a=>l(a.other)===b-1).sort((a,m)=>+(m.other===n)-+(a.other===n)||Yt(a.type)-Yt(m.type)||a.type.localeCompare(m.type)),W=R[0],se=W?R.filter(a=>a.other===W.other).sort((a,m)=>+(a.direction==="out")-+(m.direction==="out")):[],ke=se.length===0?"\xB7 ":`${se.map(a=>{let m=a.direction==="out"?"in":"out";return`${Ni[m]} ${Ei(a.type,m)}`}).join(" / ")} `,ae=b>1&&W&&o.has(W.other)?` (via ${Ie(o.get(W.other))})`:"";return` ${ke}${Ie(M)}${ae}`}).sort();d.push(`depth ${b}:`),d.push(...A.slice(0,40)),A.length>40&&d.push(` (+${A.length-40} more)`)}if(u===0)return i?`Nothing around ${t} within ${nt(r,"hop")} matches the filter.`:`${t} is connected to nothing yet.`;let h=e.truncated?" (cut at the graph limit)":"";return[`${t}: ${nt(u,"node")} within ${nt(r,"hop")}${h}`,...d].join(`
|
|
17
|
+
`)}function ot(e){let t=[...new Set(e.filter(r=>r.type==="links_to"||r.type==="uses_skill"||r.type==="uses_tool").map(r=>`${r.direction==="in"?"\u2190 ":""}${Ie(r.node)}`))].sort((r,i)=>Number(r.startsWith("\u2190"))-Number(i.startsWith("\u2190"))||r.localeCompare(i));if(t.length===0)return null;let n=t.length>8?` (+${t.length-8} more)`:"";return` \u21B3 ${t.slice(0,8).join(", ")}${n}`}function st(e,t){let n=new URL(e);if(n.protocol!=="http:"&&n.protocol!=="https:")throw new TypeError(`serverInfo: "${e}" is not an http(s) origin`);let r=n.origin;return{name:"onlymcp",title:"OnlyMCP",version:t,websiteUrl:r,icons:[{src:`${r}/brand/connector-512.png`,mimeType:"image/png"},{src:`${r}/brand/favicon.svg`,mimeType:"image/svg+xml"}]}}var P=e=>({title:e,annotations:{title:e,readOnlyHint:!0,openWorldHint:!1}}),T=(e,t)=>({title:e,annotations:{title:e,readOnlyHint:!1,destructiveHint:t.destructive,idempotentHint:t.idempotent,openWorldHint:t.openWorld??!1}}),at={list_memory:P("List memory files"),memory_read:P("Read a memory file"),memory_write:T("Write a memory file",{destructive:!0,idempotent:!0}),memory_append:T("Append to a memory file",{destructive:!1,idempotent:!1}),memory_delete:T("Delete a memory file",{destructive:!0,idempotent:!1}),memory_search:P("Search memory"),memory_tree:P("Show the memory tree"),memory_move:T("Move a memory file",{destructive:!1,idempotent:!1}),memory_links:P("Show memory links"),memory_graph:P("Walk the memory graph"),list_skills:P("List skills"),get_skill:P("Load a skill"),skill_write:T("Write a skill",{destructive:!0,idempotent:!0}),skill_delete:T("Delete a skill",{destructive:!0,idempotent:!1}),list_skill_files:P("List skill files"),get_skill_file:P("Read a skill file"),skill_file_write:T("Write a skill file",{destructive:!0,idempotent:!0}),skill_file_delete:T("Delete a skill file",{destructive:!0,idempotent:!1}),list_agents:P("List agents"),get_agent_definition:P("Load an agent definition"),agent_write:T("Write an agent",{destructive:!0,idempotent:!0}),agent_delete:T("Delete an agent",{destructive:!0,idempotent:!1}),list_connections:P("List connections"),connection_create:T("Add a connection",{destructive:!1,idempotent:!1,openWorld:!0}),connection_update:T("Update a connection",{destructive:!1,idempotent:!0}),connection_delete:T("Delete a connection",{destructive:!0,idempotent:!1}),connection_tools:P("List a connection's tools"),connection_tool_toggle:T("Switch a connection tool on or off",{destructive:!1,idempotent:!0}),connection_tool_schema:P("Show a connection tool's schema"),connection_call:T("Call a connection tool",{destructive:!0,idempotent:!1,openWorld:!0}),list_teams:P("List teams"),team_share:T("Share with a team",{destructive:!1,idempotent:!0}),team_return:T("Return from a team",{destructive:!1,idempotent:!0})};var Mi="onlymcp",ct="npx",pt=["-y","-p",Mi,"onlymcp-mcp"],rn='With the claude.ai connector synced into Claude Code, or the OnlyMCP plugin installed, you need nothing else. This local process is only for skill files on disk: it replaces the remote "onlymcp" entry in ~/.claude.json, and next to the connector or the plugin it would list every tool twice.';function lt(e){return`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}function Di(e){return JSON.stringify({mcpServers:{onlymcp:e?{command:ct,args:pt,env:e}:{command:ct,args:pt}}},null,2)}function Ui(e){let t=["[mcp_servers.onlymcp]",`command = ${lt(ct)}`,`args = [${pt.map(lt).join(", ")}]`];for(let[n,r]of Object.entries(e??{}))t.push(`env = { ${n} = ${lt(r)} }`);return`${t.join(`
|
|
17
18
|
`)}
|
|
18
|
-
`}var
|
|
19
|
-
`,"utf8")}function
|
|
20
|
-
${t}`),"written")}function
|
|
21
|
-
name: ${
|
|
22
|
-
description: ${
|
|
23
|
-
${
|
|
19
|
+
`}var ji={claude:"claude-code",gemini:"antigravity"};function on(){return Ce.filter(e=>e.install!==null)}var zi=new Set(on().map(e=>e.id));function Fi(e){let t=ji[e]??Ve(e)?.id;return t&&zi.has(t)?t:void 0}function en(e,t){return e.startsWith("~/")?Li(t,e.slice(2)):e}function Gi(e){return on().map(t=>{let n=en(t.install.configPath,e),r=t.install.stubDir?en(t.install.stubDir,e):null,i=r?nn(r):null,o=t.install.format==="toml"?Ui(i?{ONLYMCP_STUB_DIRS:i}:void 0):Di();return{id:t.id,name:t.name,configPath:n,format:t.install.format,stubDir:r,stubRoot:i,snippet:o}})}function Hi(e,t,n){let r={};if(_e(e)){let o=tn(e,"utf8").trim();if(o)try{r=JSON.parse(o)}catch{throw new Error(`${e} contains invalid JSON. Nothing written.`)}}let i=r.mcpServers??{};r.mcpServers={...i,[t]:n},Oi(e,`${JSON.stringify(r,null,2)}
|
|
20
|
+
`,"utf8")}function Wi(e,t){return _e(e)&&tn(e,"utf8").includes("[mcp_servers.onlymcp]")?"already-present":(Ri(e,`
|
|
21
|
+
${t}`),"written")}function sn(e,t){let n=Gi(e);if(t.all){if(t.client)return{kind:"conflicting-options"};let o=n.filter(p=>_e(p.configPath)),s=n.filter(p=>!_e(p.configPath));return o.length===0?{kind:"none-present-for-all",targets:n}:{kind:"all",present:o,skipped:s}}if(!t.client)return{kind:"missing-client",targets:n};let r=Fi(t.client),i=r?n.find(o=>o.id===r):void 0;return i?{kind:"single",target:i}:{kind:"unknown-client",targets:n}}function an(e){Qt(nn(e.configPath),{recursive:!0});let t=e.format==="toml"?Wi(e.configPath,e.snippet):(()=>{let n=JSON.parse(e.snippet),r=Object.entries(n.mcpServers)[0];if(!r)throw new Error(`${e.name}: empty mcpServers snippet.`);return Hi(e.configPath,r[0],r[1]),"written"})();return e.stubDir&&Qt(e.stubDir,{recursive:!0}),t}import{access as Ji,mkdir as mt,readFile as Yi,rm as ln,writeFile as Ne}from"node:fs/promises";import{dirname as qi,join as me}from"node:path";import{readFile as Bi}from"node:fs/promises";var dt=()=>!1;function Ki(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Vi(e){let t=e.split(/\r?\n/).map(n=>n.trim()).filter(n=>n!==""&&!n.startsWith("#")).map(n=>new RegExp(`^${n.split("*").map(Ki).join(".*")}$`));return n=>t.some(r=>r.test(n))}async function Ee(e=we()){try{return Vi(await Bi(e,"utf8"))}catch(t){if(t.code==="ENOENT")return dt;throw t}}var Xi=/^[a-z0-9]+(-[a-z0-9]+)*$/,Zi=/^[a-z0-9]+(-[a-z0-9]+)*(:[a-z0-9]+(-[a-z0-9]+)*)?$/,ut="x-onlymcp-stub";function Re(e){return e.replace(/:/g,"-")}function Oe(e){return(e??"").replace(/[\r\n]+/g," ").trim()}async function ft(e,t){let n;try{n=await Yi(e,"utf8")}catch{return!0}let r=V(n);if(r===null||L(r,ut)!=="true")return!1;let i=L(r,"x-onlymcp-name");return i===void 0||i===t}async function cn(e,t){return await Ji(e).then(()=>!0,()=>!1)&&await ft(e,t)}async function Le(e,t,n={}){let r=n.ignore??dt,[{skills:i},{agents:o}]=await Promise.all([e.listSkills(),e.listAgents()]),s=0,p=0,l=[],c=[],d=0;for(let h of i){if(!Zi.test(h.name))continue;let b=me(t,"skills",Re(h.name)),x=me(b,"SKILL.md");if(r(h.name)||r(Re(h.name))){c.push(h.name),await cn(x,h.name)&&(await ln(b,{recursive:!0,force:!0}),d+=1);continue}if(!await ft(x,h.name)){l.push(`skills/${Re(h.name)}`);continue}await mt(b,{recursive:!0}),await Ne(x,`---
|
|
22
|
+
name: ${Re(h.name)}
|
|
23
|
+
description: ${Oe(h.description)||"Synchronisiert ueber OnlyMCP. Inhalt wird bei Bedarf geladen."}
|
|
24
|
+
${ut}: true
|
|
24
25
|
x-onlymcp-name: ${h.name}
|
|
25
26
|
---
|
|
26
27
|
|
|
27
28
|
Call \`get_skill({ name: "${h.name}" })\` on the OnlyMCP server and follow whatever comes back.
|
|
28
|
-
`,"utf8"),p+=1;try{let
|
|
29
|
+
`,"utf8"),p+=1;try{let A=await e.getSkill(h.name);for(let I of A.files??[]){if(!H(I.path))continue;let M=await e.getSkillFile(h.name,I.path),R=me(b,...I.path.split("/"));await mt(qi(R),{recursive:!0}),M.encoding==="base64"?await Ne(R,Buffer.from(M.content,"base64")):await Ne(R,M.content,"utf8"),s+=1}}catch{}}await mt(me(t,"agents"),{recursive:!0});let u=0;for(let h of o){if(!Xi.test(h.name))continue;let b=me(t,"agents",`${h.name}.md`);if(r(h.name)){c.push(h.name),await cn(b,h.name)&&(await ln(b),d+=1);continue}if(!await ft(b,h.name)){l.push(`agents/${h.name}.md`);continue}let x=Oe(h.description),A=h.model?Oe(h.model):"",I=h.tools.map(Oe).join(", ");await Ne(b,`---
|
|
29
30
|
name: ${h.name}
|
|
30
|
-
description: ${
|
|
31
|
-
${
|
|
32
|
-
`:""}tools: ${
|
|
33
|
-
${
|
|
31
|
+
description: ${x}
|
|
32
|
+
${A?`model: ${A}
|
|
33
|
+
`:""}tools: ${I}
|
|
34
|
+
${ut}: true
|
|
34
35
|
x-onlymcp-name: ${h.name}
|
|
35
36
|
---
|
|
36
37
|
|
|
37
38
|
Call \`get_agent_definition({ name: "${h.name}" })\` on the OnlyMCP server and follow whatever comes back.
|
|
38
|
-
`,"utf8"),
|
|
39
|
+
`,"utf8"),u+=1}return{skills:p,agents:u,files:s,kept:l,ignored:c,removed:d}}import{Server as jo}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as zo}from"@modelcontextprotocol/sdk/server/stdio.js";import{CallToolRequestSchema as Fo,GetPromptRequestSchema as Go,ListPromptsRequestSchema as Ho,ListResourceTemplatesRequestSchema as Wo,ListResourcesRequestSchema as Bo,ListToolsRequestSchema as Ko,ReadResourceRequestSchema as Vo}from"@modelcontextprotocol/sdk/types.js";var Qi="https://only-mcp.com";function pn(e=process.env.ONLYMCP_API_URL){if(e===void 0)return Qi;let t;try{t=new URL(e).protocol}catch{}if(t!=="http:"&&t!=="https:"){let n=e.replace(/\/\/[^/@]*@/,"//***@");throw new Error(`ONLYMCP_API_URL is not a valid http(s) URL: ${JSON.stringify(n)}`)}return e}var dn=["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(" "),eo=["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 mn(e,t,n,r){if(n.length===0)return"";let i=[];for(let p of n){let l=n.length-i.length-1,c=l>0?` (+${l} more, call ${t})`:"",d=`
|
|
39
40
|
|
|
40
|
-
${e}: ${[...i,p].join(", ")}${c}`;if(r+
|
|
41
|
+
${e}: ${[...i,p].join(", ")}${c}`;if(r+d.length>1800)break;i.push(p)}if(i.length===0)return`
|
|
41
42
|
|
|
42
43
|
${e}: call ${t}`;let o=n.length-i.length,s=o>0?` (+${o} more, call ${t})`:"";return`
|
|
43
44
|
|
|
44
|
-
${e}: ${i.join(", ")}${s}`}function
|
|
45
|
+
${e}: ${i.join(", ")}${s}`}function gt(e,t,n={}){let r=n.brainvault===!1?dn:`${dn} ${eo}`,i=t.length>0?26:0;return r+=mn("Skills","list_skills",e,r.length+i),r+=mn("Agents","list_agents",t,r.length),r}import{z as un}from"zod";var to=un.object({name:un.string().min(1).max(64)}),ht=e=>e.replace(/[\r\n]+/g," ").trim();function ue(e){let t=e.model?`model: ${ht(e.model)}
|
|
45
46
|
`:"";return`---
|
|
46
47
|
name: ${e.name}
|
|
47
|
-
description: ${
|
|
48
|
-
${t}tools: ${(e.tools??[]).map(
|
|
48
|
+
description: ${ht(e.description??"")}
|
|
49
|
+
${t}tools: ${(e.tools??[]).map(ht).join(", ")}
|
|
49
50
|
---
|
|
50
|
-
${e.body}`}function
|
|
51
|
-
`)}]}}catch(t){return{content:[{type:"text",text:t instanceof y?t.code:"errors.UNKNOWN"}],isError:!0}}}}}function
|
|
52
|
-
`)}]}}catch(t){return{content:[{type:"text",text:t instanceof y?t.code:"errors.UNKNOWN"}],isError:!0}}}}}import{hostname as
|
|
53
|
-
${n.code} ${JSON.stringify(n.params)}`}],isError:!0}}return{content:[{type:"text",text:n instanceof y?n.code:"errors.UNKNOWN"}],isError:!0}}}}}import{z as
|
|
54
|
-
${
|
|
55
|
-
|
|
56
|
-
`))}catch(n){return
|
|
57
|
-
`))}catch(n){return
|
|
51
|
+
${e.body}`}function fn(e,t){return{name:"get_agent_definition",description:"Delivers an agent's system prompt from the OnlyMCP cloud.",inputSchema:to,async handler(n){let r=`agent:${n.name}`,i=await t.get(r);if(i!==null)return{content:[{type:"text",text:i}]};try{let o=await e.getAgent(n.name,{use:!0}),s=ue(o);return await t.set(r,s),{content:[{type:"text",text:s}]}}catch(o){return{content:[{type:"text",text:o instanceof y?o.code:"errors.UNKNOWN"}],isError:!0}}}}}var J=(e,t)=>Object.assign(new Error(t),{code:e}),yt=e=>Buffer.from(e,"utf8").toString("base64url");function bt(e){return/^[A-Za-z0-9_-]+$/.test(e)?Buffer.from(e,"base64url").toString("utf8"):null}var fe=()=>J(-32602,"Invalid cursor."),ne=(e,t)=>e<t?-1:e>t?1:0,gn={memory:0,skill:1,agent:2};function no(e,t){return gn[e.kind]-gn[t.kind]||ne(e.name,t.name)||(e.teamId===t.teamId?0:e.teamId===null?-1:t.teamId===null?1:ne(e.teamId,t.teamId))||ne(t.updatedAt,e.updatedAt)}async function hn(e,t,n=200){let r=t===void 0?void 0:bt(t);if(r===null)throw fe();let[{files:i},{skills:o},{agents:s}]=await Promise.all([e.listMemory(),e.listSkills(),e.listAgents()]),p=[...i.filter(u=>u.archivedAt===null).map(u=>({kind:"memory",name:u.path,teamId:u.teamId,description:"",updatedAt:u.updatedAt})),...o.filter(u=>u.archivedAt===null).map(u=>({kind:"skill",name:u.name,teamId:u.teamId,description:u.description,updatedAt:u.updatedAt})),...s.filter(u=>u.archivedAt===null).map(u=>({kind:"agent",name:u.name,teamId:u.teamId,description:u.description,updatedAt:u.updatedAt}))].sort(no),l=new Set,c=p.filter(u=>{let h=pe(u);return l.has(h)?!1:(l.add(h),!0)}),d=de(c,u=>pe(u),r,n);if(!d)throw fe();return{resources:d.page.map(u=>({uri:pe(u),name:u.name,...u.description?{description:u.description}:{},mimeType:"text/markdown"})),...d.next===void 0?{}:{nextCursor:yt(d.next)}}}function kt(e){return J(-32603,e instanceof y?e.code:"errors.UNKNOWN")}async function yn(e,t){let n=Xe(t);if(!n)throw J(-32002,`Unknown resource: ${t}`);let r=n.teamId??void 0;try{let i=n.kind==="memory"?(await e.readMemory(n.name,r)).content:n.kind==="skill"?(await e.getSkill(n.name,r)).body:ue(await e.getAgent(n.name,{team:r}));return{contents:[{uri:t,mimeType:"text/markdown",text:i}]}}catch(i){throw i instanceof y&&i.status===404?J(-32002,`Unknown resource: ${t}`):kt(i)}}function bn(e){let t=new Map;for(let n of e)n.archivedAt===null&&t.set(n.name,[...t.get(n.name)??[],n]);return[...t.values()].map(n=>n.find(r=>r.isOwn)??[...n].sort((r,i)=>ne(i.updatedAt,r.updatedAt))[0]).sort((n,r)=>ne(n.name,r.name))}async function kn(e,t,n=200){let r=t===void 0?void 0:bt(t);if(r===null)throw fe();let[{skills:i},{agents:o}]=await Promise.all([e.listSkills(),e.listAgents()]),s=[...bn(i).map(l=>({name:Pe("skill",l.name),description:l.description})),...bn(o).map(l=>({name:Pe("agent",l.name),description:l.description}))],p=de(s,l=>l.name,r,n);if(!p)throw fe();return{prompts:p.page.map(l=>({name:l.name,...l.description?{description:l.description}:{}})),...p.next===void 0?{}:{nextCursor:yt(p.next)}}}async function xn(e,t){let n=Ze(t);if(!n)throw J(-32602,`Unknown prompt: ${t}`);let r=(i,o)=>({...i?{description:i}:{},messages:[{role:"user",content:{type:"text",text:o}}]});try{if(n.kind==="skill"){let o=await e.getSkill(n.name);return r(o.description,o.body)}let i=await e.getAgent(n.name,{use:!0});return r(i.description,ue(i))}catch(i){throw i instanceof y&&i.status===404?J(-32602,`Unknown prompt: ${t}`):kt(i)}}import{z as Uo}from"zod";import{z as xt}from"zod";var ro=xt.object({name:xt.string().min(1).max(64),path:xt.string().min(1).max(200)});function wn(e){return{name:"get_skill_file",description:"Delivers a single companion file of a skill from the OnlyMCP cloud, e.g. references/palette.md. Usually not needed: `npx onlymcp sync` places these files next to the SKILL.md.",inputSchema:ro,async handler(t){try{let n=await e.getSkillFile(t.name,t.path);return n.encoding==="base64"?{content:[{type:"text",text:`errors.BINARY_FILE ${n.path} (${n.size} bytes) - fetch it to disk with \`npx onlymcp sync\`.`}],isError:!0}:{content:[{type:"text",text:n.content}]}}catch(n){return{content:[{type:"text",text:n instanceof y?n.code:"errors.UNKNOWN"}],isError:!0}}}}}import{z as vn}from"zod";var io=vn.object({name:vn.string().min(1).max(64)});function Sn(e,t){return{name:"get_skill",description:"Delivers a skill's full content from the OnlyMCP cloud. Called from the stub files.",inputSchema:io,async handler(n){let r=`skill:${n.name}`,i=await t.get(r);if(i!==null)return{content:[{type:"text",text:i}]};try{let o=await e.getSkill(n.name);return await t.set(r,o.body),{content:[{type:"text",text:o.body}]}}catch(o){return{content:[{type:"text",text:o instanceof y?o.code:"errors.UNKNOWN"}],isError:!0}}}}}import{z as oo}from"zod";var Cn=oo.object({}),Y=e=>e.scope==="team"?` (team: ${e.teamName??"unknown"})`:"";function $n(e){return{name:"list_skills",description:"List every skill name available to this user. Use when a skill you need is not named in the server instructions.",inputSchema:Cn,async handler(){try{let{skills:t}=await e.listSkills();return{content:[{type:"text",text:t.map(n=>`${n.name}${Y(n)}`).join(`
|
|
52
|
+
`)}]}}catch(t){return{content:[{type:"text",text:t instanceof y?t.code:"errors.UNKNOWN"}],isError:!0}}}}}function An(e){return{name:"list_agents",description:"List every agent available to this user, with its description. Use when this client has no agent files of its own.",inputSchema:Cn,async handler(){try{let{agents:t}=await e.listAgents();return{content:[{type:"text",text:t.map(r=>`${r.name}${Y(r)}: ${r.description}`).join(`
|
|
53
|
+
`)}]}}catch(t){return{content:[{type:"text",text:t instanceof y?t.code:"errors.UNKNOWN"}],isError:!0}}}}}import{hostname as so}from"node:os";import{z as Me}from"zod";var ao=Me.object({path:Me.string().min(3).max(256),content:Me.string().min(1).max(1e6),ifMatch:Me.string().max(64).optional()}),Tn=e=>({content:[{type:"text",text:e instanceof y?e.code:"errors.UNKNOWN"}],isError:!0});function Pn(e){return{name:"memory_append",description:"Appends text to a memory file, after a newline when the file does not end with one. A missing file is created.",inputSchema:ao,async handler(t){if(!C(t.path))return{content:[{type:"text",text:"errors.INVALID_PATH"}],isError:!0};for(let n=0;;n+=1){let r;try{r=await e.readMemory(t.path)}catch(i){if(!(i instanceof y&&i.code==="errors.MEMORY_NOT_FOUND"))return Tn(i);r=null}try{let i=await e.writeMemory(t.path,r===null?t.content:Qe(r.content,t.content),so(),r===null?void 0:t.ifMatch??r.updatedAt),o=t.content.length,s=i.routedTo?` (created in team ${i.routedTo.teamName})`:"";return{content:[{type:"text",text:`Appended ${o} ${o===1?"character":"characters"} to ${t.path}.${s}`}]}}catch(i){if(i instanceof y&&i.code==="errors.MEMORY_CHANGED"&&t.ifMatch===void 0&&n===0)continue;return Tn(i)}}}}}import{z as re}from"zod";var lo=re.object({path:re.string().min(3).max(256),from:re.string().optional(),lines:re.string().optional()}),In=2e3;function _n(e){let t=new Map;return{name:"memory_read",description:"Reads a memory file live from the OnlyMCP cloud. No disk cache. from (first line, counted from 1) and lines (how many, 1 to 2000) return a range and the total number of lines.",inputSchema:lo,async handler(n){if(!C(n.path))return{content:[{type:"text",text:"errors.INVALID_PATH"}],isError:!0};let r=n.from!==void 0||n.lines!==void 0,i=re.coerce.number().int().min(1).safeParse(n.from??"1"),o=re.coerce.number().int().min(1).max(In).safeParse(n.lines??String(In));if(r&&(!i.success||!o.success))return{content:[{type:"text",text:"errors.INVALID_ARGUMENTS"}],isError:!0};try{let s=t.get(n.path);s||(s=e.readMemory(n.path).then(d=>({content:d.content,updatedAt:d.updatedAt})),t.set(n.path,s),s.finally(()=>t.delete(n.path)));let p=await s;if(!r||!i.success||!o.success)return{content:[{type:"text",text:p.content}],_meta:{updatedAt:p.updatedAt}};let l=et(p.content,i.data,o.data);return{content:[{type:"text",text:i.data>l.totalLines?tt(i.data,l.totalLines):l.text}],_meta:{updatedAt:p.updatedAt,totalLines:l.totalLines,from:l.from,to:l.to}}}catch(s){return{content:[{type:"text",text:s instanceof y?s.code:"errors.UNKNOWN"}],isError:!0}}}}}import{hostname as co}from"node:os";import{z as De}from"zod";var po=De.object({path:De.string().min(3).max(256),content:De.string().max(1e6),ifMatch:De.string().max(64).optional()});function En(e){return{name:"memory_write",description:"Writes a memory file live into the OnlyMCP cloud (write-through).",inputSchema:po,async handler(t){if(!C(t.path))return{content:[{type:"text",text:"errors.INVALID_PATH"}],isError:!0};try{let n=await e.writeMemory(t.path,t.content,co(),t.ifMatch),r=n.warning?`${n.path} ${n.updatedAt} ${n.warning.code} ${JSON.stringify(n.warning.params)}`:`${n.path} ${n.updatedAt}`;return n.routedTo&&(r+=` (created in team ${n.routedTo.teamName})`),{content:[{type:"text",text:r}]}}catch(n){if(n instanceof y&&n.code==="errors.MEMORY_CHANGED"){let{updatedAt:i,by:o}=n.params;return{content:[{type:"text",text:`${`The file changed since you read it (at ${i??"an unknown time"}, by ${o??"a device"}). Read it again, then write.`}
|
|
54
|
+
${n.code} ${JSON.stringify(n.params)}`}],isError:!0}}return{content:[{type:"text",text:n instanceof y?n.code:"errors.UNKNOWN"}],isError:!0}}}}}import{z as $}from"zod";var D=e=>({content:[{type:"text",text:e}]}),_=e=>({content:[{type:"text",text:e}],isError:!0});function ge(e){return e instanceof y?e.code:"errors.UNKNOWN"}var Ue=$.string().trim().min(1).max(128).optional(),mo=$.object({query:$.string().min(1).max(200),types:$.string().max(64).optional(),limit:$.number().int().min(1).max(50).optional(),type:Ue.describe("Only memory files of this metadata.type, e.g. solution, project, feedback."),project:Ue.describe("Only memory files about this project."),tag:Ue.describe("Only memory files carrying this tag."),expand:$.enum(["links","none"]).optional().describe("links: name the direct links of the first five hits.")});async function uo(e,t){let n=new Map;for(let r of t.slice(0,5))try{let i=ot((await e.graphNodeByRid(r.kind,r.id)).neighbours);i&&n.set(`${r.kind}:${r.id}`,i)}catch{}return n}function Rn(e){return{name:"memory_search",description:"Full-text search across memory, skills and agents. Delivers the best hits with a short snippet each; between equally good matches the more recently changed one ranks first. type, project and tag narrow it to memory files whose frontmatter says so. expand=links names, under each of the first five, what it links to and what links to it (\u2190).",inputSchema:mo,async handler(t){try{let{hits:n}=await e.searchContent(t.query,{types:t.types?.split(",").map(o=>o.trim()).filter(o=>o!==""),limit:t.limit,...t.type===void 0?{}:{type:t.type},...t.project===void 0?{}:{project:t.project},...t.tag===void 0?{}:{tag:t.tag}});if(n.length===0)return D(`Nothing found for ${t.query}`);let r=new Map;if(n.some(o=>o.teamId!==null))try{for(let o of(await e.listTeams()).teams)r.set(o.id,o.name)}catch{}let i=t.expand==="links"?await uo(e,n):new Map;return D(n.map(o=>{let s=`${o.kind} ${o.path??o.name}${Y({scope:o.scope,teamName:o.teamId===null?null:r.get(o.teamId)??null})}
|
|
55
|
+
${o.snippet}`,p=i.get(`${o.kind}:${o.id}`);return p?`${s}
|
|
56
|
+
${p}`:s}).join(`
|
|
57
|
+
`))}catch(n){return _(ge(n))}}}}var fo=$.object({scope:$.string().max(96).optional(),folder:$.string().max(256).optional().describe("Only this folder and what is under it, e.g. solutions.")});function On(e){return{name:"memory_tree",description:"This account's folder structure: every folder, empty ones included, and the files in it, each with its frontmatter type in brackets ([solution]). folder narrows it to one folder and what is under it.",inputSchema:fo,async handler(t){try{let n=(t.folder??"").trim().replace(/^\/+|\/+$/g,"");if(n!==""&&!C(`${n}/x.md`))return _("errors.INVALID_PATH");let r=n===""?null:`${n}/`,{nodes:i}=await e.memoryTree(t.scope??"all"),o=r===null?i:i.filter(s=>s.path.startsWith(r)||s.kind==="folder"&&s.path===n);return o.length===0?D(r===null?"(empty)":`No folder ${n}`):D(o.map(s=>{let p=s.path.split("/").length-1,l=s.kind==="folder"?`${s.name}/`:s.name,c=s.kind==="file"&&s.type?` [${s.type}]`:"";return`${" ".repeat(p)}${l}${c}${Y(s)}`}).join(`
|
|
58
|
+
`))}catch(n){return _(ge(n))}}}}var go=$.object({from:$.string().min(3).max(256),to:$.string().min(3).max(256),updateLinks:$.boolean().optional()});function Nn(e){return`${e} ${e===1?"file":"files"}`}function Ln(e){return{name:"memory_move",description:"Moves or renames a memory file. Every [[link]] that would no longer find it follows along, by name or by path, unless turned off.",inputSchema:go,async handler(t){if(!C(t.from)||!C(t.to))return _("errors.INVALID_PATH");let n=t.updateLinks??!0;try{let r=await e.moveMemory(t.from,t.to,n);return D(`${r.from} moved to ${r.to}`+(n?`, links updated in ${Nn(r.rewritten)}, ${Nn(r.skipped)} left unchanged`:""))}catch(r){return _(ge(r))}}}}var ho=$.object({path:$.string().min(3).max(256)});function Mn(e){return{name:"memory_links",description:"A memory file's [[links]], split between the ones that point somewhere and the ones that point nowhere.",inputSchema:ho,async handler(t){if(!C(t.path))return _("errors.INVALID_PATH");try{let n=await e.readMemory(t.path),{resolved:r,unresolved:i}=n.links;return r.length===0&&i.length===0?D(`${t.path} does not link to anything.`):D([r.length>0?`Resolved: ${r.join(", ")}`:"",i.length>0?`Open (no file with this name yet): ${i.join(", ")}`:""].filter(o=>o!=="").join(`
|
|
59
|
+
`))}catch(n){return _(ge(n))}}}}var yo=$.object({path:$.string().min(3).max(256).describe("Path of the memory file to start from."),depth:$.number().int().min(1).max(3).optional().describe("Hops to walk, 1 to 3. Default 1."),types:$.string().max(128).optional().describe("Comma-separated node kinds to list: memory, skill, agent, mcp, tool, folder, type, project, tag, collection."),folder:$.string().max(256).optional().describe("Only memory files and folders under this folder."),project:Ue.describe("Only nodes about this project (and the project itself).")});function Dn(e){return{name:"memory_graph",description:"The graph around one memory file, up to three hops: the files, skills, agents and servers it links to or is linked from, its folder, type, project and tags, and from depth 2 on what those lead to. 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:yo,async handler(t){if(!C(t.path))return _("errors.INVALID_PATH");let n=t.depth??1,r=t.types===void 0||t.types.trim()===""?void 0:rt(t.types);if(r===null)return _(`Invalid types: ${t.types}`);let i=(t.folder??"").trim().replace(/^\/+|\/+$/g,"");if(i!==""&&!C(`${i}/x.md`))return _("errors.INVALID_PATH");try{let o=await e.readMemory(t.path);if(!o.id)return _("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(d){if(d instanceof y&&d.code==="errors.NODE_NOT_FOUND")return D(`${o.path} is not in the graph yet (it is added on its next save).`);throw d}let p=await e.graphAround(s,n),l={...r?{types:r}:{},...i!==""?{folder:i}:{},...t.project!==void 0?{project:t.project}:{}},c=Object.keys(l).length>0?new Set((await e.graphAround(s,n,l)).nodes.map(d=>d.id)):null;return D(it({path:o.path,focus:s,depth:n,nodes:p.nodes,edges:p.edges,truncated:p.truncated,kept:c}))}catch(o){return _(ge(o))}}}}import{z as v}from"zod";var bo=e=>({content:[{type:"text",text:e}]}),Un=e=>({content:[{type:"text",text:e}],isError:!0});async function ie(e){try{return bo(await e())}catch(t){if(t instanceof y){let n=Object.keys(t.params).length?` ${JSON.stringify(t.params)}`:"";return Un(`${t.code}${n}`)}return Un("errors.UNKNOWN")}}var he=v.string().min(1).max(32).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/,"errors.INVALID_SLUG");async function je(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 wt(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})
|
|
58
60
|
${e.url}${e.statusError?`
|
|
59
|
-
last error: ${e.statusError}`:""}`}var
|
|
60
|
-
`)})}}var
|
|
61
|
-
${
|
|
61
|
+
last error: ${e.statusError}`:""}`}var ko=v.object({});function jn(e){return{name:"list_connections",description:"List the MCP servers connected through this OnlyMCP account, with the tool-name prefix each one uses.",inputSchema:ko,handler:()=>ie(async()=>{let{connections:t}=await e.listConnections();return t.length===0?"No MCP servers are connected yet. Add one with connection_create.":t.map(wt).join(`
|
|
62
|
+
`)})}}var xo=v.object({name:v.string().min(1).max(80),slug:he,url:v.string().url().max(2e3),transport:v.enum(["http","sse"]).default("http"),authType:v.enum(["none","bearer","header"]).default("none"),authHeaderName:v.string().max(80).optional(),secret:v.string().max(4e3).optional(),teamId:v.string().max(64).optional()});function zn(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:xo,handler:t=>ie(async()=>{let{connection:n}=await e.createConnection(t);return`Connected.
|
|
63
|
+
${wt(n)}
|
|
62
64
|
|
|
63
|
-
Its tools are now available as "${n.slug}__<tool>".`})}}var
|
|
64
|
-
${
|
|
65
|
-
`)})}}var
|
|
66
|
-
`)})}}var
|
|
67
|
-
`)})}}var
|
|
68
|
-
errors.TEAM_AMBIGUOUS ${JSON.stringify({team:t,ids:s})}`)}return
|
|
69
|
-
errors.NOT_A_MEMBER ${JSON.stringify({team:t})}`)}var
|
|
70
|
-
`))})}}function Vn(e){return{name:"team_share",description:"Move one of your own memory files, skills or agents into a team, so its members can use it. You need the right to create that kind of content in the team, the team must not hold an item of that name already, and a frozen team takes nothing new.",inputSchema:bo,handler:t=>ut(async()=>{let n=await Wn(e,t.team);return Gn(n)?n:(await e.shareWithTeam(n.id,{kind:t.kind,name:t.name}),Oe(`Shared ${t.kind} ${t.name} with the team ${n.name}.`))})}}function Jn(e){return{name:"team_return",description:"Take an item out of a team and back under its owner. Name one of your own items, or pass the id of any item of the team if you may delete that kind of content there. The item keeps its owner, and the return is never refused on a quota.",inputSchema:ko,handler:t=>t.name===void 0==(t.id===void 0)?Promise.resolve(fe("Invalid arguments: pass name or id, not both.")):ut(async()=>{let n=await Wn(e,t.team);return Gn(n)?n:(await e.returnFromTeam(n.id,t.name!==void 0?{kind:t.kind,name:t.name}:{kind:t.kind,id:t.id}),Oe(`Returned ${t.kind} ${t.name??t.id} from the team ${n.name}.`))})}}function Yn(e,t){return[xn(e),wn(e),bn(e),Fn(e),Hn(e),Sn(e),Cn(e),An(e),$n(e),gn(e),un(e,t),On(e),Ln(e),Mn(e),mn(e),Un(e),Dn(e),hn(e),rn(e,t),jn(e),zn(e),Tn(e),In(e),_n(e),En(e),Rn(e),Nn(e),Kn(e),Vn(e),Jn(e)]}function qn(e){return e.map(t=>{let n=Xe[t.name];if(!n)throw new Error(`No title and annotations in the registry table for the tool ${t.name}`);return{name:t.name,title:n.title,description:t.description,inputSchema:xo.toJSONSchema(t.inputSchema),annotations:n.annotations}})}async function Zn(){let e=Qt(),t=new _(e,()=>I.read()),n=new X,r=Yn(t,n),i=await(async()=>{try{let[{skills:s},{agents:p},l]=await Promise.all([t.listSkills(),t.listAgents(),t.getMe().catch(()=>({brainvaultMode:!0}))]);return st(s.map(c=>c.name),p.map(c=>c.name),{brainvault:l.brainvaultMode!==!1})}catch{return st([],[])}})(),o=new wo(Ze(e,Z),{capabilities:{tools:{},resources:{},prompts:{}},instructions:i});o.setRequestHandler(To,async()=>({tools:qn(r)})),o.setRequestHandler(Po,async s=>sn(t,s.params?.cursor)),o.setRequestHandler($o,async()=>({resourceTemplates:[...ve]})),o.setRequestHandler(Io,async s=>an(t,s.params.uri)),o.setRequestHandler(Ao,async s=>cn(t,s.params?.cursor)),o.setRequestHandler(Co,async s=>pn(t,s.params.name)),o.setRequestHandler(So,async s=>{let p=r.find(c=>c.name===s.params.name);if(!p)return{content:[{type:"text",text:"errors.UNKNOWN_TOOL"}],isError:!0};let l=p.inputSchema.safeParse(s.params.arguments??{});return l.success?p.handler(l.data):{content:[{type:"text",text:"errors.INVALID_ARGUMENTS"}],isError:!0}}),Ae().then(s=>{for(let p of ye())Ie(t,p,{ignore:s}).catch(()=>{})}).catch(()=>{}),await o.connect(new vo)}import{readdir as _o,readFile as Eo,realpath as Xn,stat as Ro}from"node:fs/promises";import{join as No,relative as Oo,resolve as Lo,sep as Qn}from"node:path";var Mo=2*1024*1024;function Uo(e){return e.subarray(0,8192).includes(0)}async function Y(e,t={}){let n=t.maxBytes??Mo,r=await Xn(Lo(e)),i=[];async function o(s){let p=await _o(s,{withFileTypes:!0});for(let l of p){let c=No(s,l.name);if(l.isDirectory()){if(Be(l.name))continue;await o(c);continue}let m;try{m=await Xn(c)}catch{continue}if(m!==r&&!m.startsWith(r+Qn))continue;let f=Oo(r,m).split(Qn).join("/");if(we(l.name)){i.push({absolute:m,relative:f,bytes:0,binary:!1,text:null,skip:"denied-name"});continue}let h=await Ro(m);if(!h.isFile())continue;if(h.size>n){i.push({absolute:m,relative:f,bytes:h.size,binary:!1,text:null,skip:"too-large"});continue}let v=await Eo(m),$=Uo(v);i.push({absolute:m,relative:f,bytes:h.size,binary:$,text:$?null:v.toString("utf8"),skip:null})}}return await o(r),i.sort((s,p)=>s.relative.localeCompare(p.relative)),i}import{basename as Do}from"node:path";function jo(e){let t=new Map;return{entries:e.map(r=>{t.set(r.relative,r);let i=r.skip==="too-large"?Math.max(r.bytes,2097153):r.bytes;return r.text===null?{path:r.relative,bytes:i}:{path:r.relative,bytes:i,text:r.text}}),byPath:t}}function zo(e,t){let n=new Map;for(let{path:r,...i}of e){if(t.has(r))continue;let o=n.get(r);o?o.push(i):n.set(r,[i])}return[...n].map(([r,i])=>({relative:r,hits:i}))}function Fo(e,t){let n=zo(e.flagged,t);return{skipped:[...e.skipped.map(r=>({relative:r.path,reason:r.reason})),...n.map(r=>({relative:r.relative,reason:"flagged"}))],flagged:n}}function ft(e,t,n){let{entries:r,byPath:i}=jo(e),o=new Set(n.release??[]),s=Ge(r,{kinds:[t],release:n.release,...n.collection?{collection:n.collection}:{}});return{plan:s,byPath:i,...Fo(s,o)}}function Ho(e,t={}){let n=t.root?Do(t.root.replace(/[/\\]+$/,"")):"",{plan:r,byPath:i,skipped:o,flagged:s}=ft(e,"skills",{...t,collection:n}),p=r.skills.map(l=>({name:l.name,source:i.get(l.sourcePath).absolute,sourcePath:l.sourcePath,description:l.description,collection:l.collection,bytes:l.bytes,files:l.files.map(c=>({path:c.path,absolute:i.get(c.sourcePath).absolute,bytes:c.bytes,binary:c.text===void 0}))}));return{plans:p,skipped:o,noDescription:p.filter(l=>l.description==="").map(l=>l.name).sort(),flagged:s}}function Bo(e,t={}){let{plan:n,byPath:r,skipped:i,flagged:o}=ft(e,"agents",t);return{plans:n.agents.map(s=>({name:s.name,source:r.get(s.sourcePath).absolute,bytes:s.bytes})),skipped:i,flagged:o}}function Wo(e,t={}){let{plan:n,byPath:r,skipped:i,flagged:o}=ft(e,"memory",t);return{plans:n.memory.map(s=>({path:s.path,source:r.get(s.sourcePath).absolute,bytes:s.bytes})),skipped:i,flagged:o}}function gt(e,t={}){let n=Ho(e.skills??[],{root:t.skillsRoot,release:t.release}),r=Bo(e.agents??[],{release:t.release}),i=Wo(e.memory??[],{release:t.release});return{skills:n.plans,agents:r.plans,memory:i.plans,flagged:[...n.flagged,...r.flagged,...i.flagged],skipped:[...n.skipped,...r.skipped,...i.skipped],noDescription:n.noDescription}}import{readFile as Le}from"node:fs/promises";import{hostname as Go}from"node:os";function Me(e){return e instanceof y?e.code:e instanceof Error?e.message:String(e)}function ht(e){return e.skills.length+e.skills.reduce((t,n)=>t+n.files.length,0)+e.agents.length+e.memory.length}async function er(e,t,n){let r={skills:0,skillFiles:0,agents:0,memory:0,failures:[]},i=ht(t),o=0,s=l=>n(o+=1,i,l);for(let l of t.skills){try{await e.putSkill(l.name,await Le(l.source,"utf8"),{...l.description?{description:l.description}:{},sourcePath:l.sourcePath,...l.collection?{collection:l.collection}:{}}),r.skills+=1}catch(c){r.failures.push({what:`skill ${l.name}`,code:Me(c)}),o+=l.files.length,s(l.name);continue}s(l.name);for(let c of l.files){try{let m=await Le(c.absolute);await e.putSkillFile(l.name,c.path,c.binary?m.toString("base64"):m.toString("utf8"),c.binary?"base64":"utf8"),r.skillFiles+=1}catch(m){r.failures.push({what:`${l.name}/${c.path}`,code:Me(m)})}s(`${l.name}/${c.path}`)}}for(let l of t.agents){try{let c=await Le(l.source,"utf8"),m=Q(c);if(!m){r.failures.push({what:`agent ${l.name}`,code:"no-frontmatter"}),s(l.name);continue}await e.putAgent(l.name,{...m,body:se(c)}),r.agents+=1}catch(c){r.failures.push({what:`agent ${l.name}`,code:Me(c)})}s(l.name)}let p=Go();for(let l of t.memory){try{await e.writeMemory(l.path,await Le(l.source,"utf8"),p),r.memory+=1}catch(c){r.failures.push({what:l.path,code:Me(c)})}s(l.path)}return r}function tr(e){return e.skills.length===0&&e.agents.length===0&&e.memory.length===0}function nr(e){return e.skills.length+e.agents.length+e.memory.length}function yt(e){return e.scope==="personal"&&e.isOwn&&e.archivedAt===null}async function rr(e,t,n){let r={skills:[],agents:[],memory:[]};if(n.skills){let i=new Set(t.skills.map(s=>s.name)),{skills:o}=await e.listSkills();r.skills=o.filter(s=>yt(s)&&!i.has(s.name)).map(s=>s.name)}if(n.agents){let i=new Set(t.agents.map(s=>s.name)),{agents:o}=await e.listAgents();r.agents=o.filter(s=>yt(s)&&!i.has(s.name)).map(s=>s.name)}if(n.memory){let i=new Set(t.memory.map(s=>s.path)),{files:o}=await e.listMemory();r.memory=o.filter(s=>yt(s)&&!i.has(s.path)).map(s=>s.path)}return r.skills.sort(),r.agents.sort(),r.memory.sort(),r}function Ko(e){return e instanceof y?e.code:e instanceof Error?e.message:String(e)}async function ir(e,t){let n={deleted:0,failures:[]},r=async(i,o,s)=>{for(let p of i)try{await s(p),n.deleted+=1}catch(l){n.failures.push({what:o(p),code:Ko(l)})}};return await r(t.skills,i=>`skill ${i}`,i=>e.deleteSkill(i)),await r(t.agents,i=>`agent ${i}`,i=>e.deleteAgent(i)),await r(t.memory,i=>i,i=>e.deleteMemory(i)),n}import{mkdir as or,writeFile as Vo}from"node:fs/promises";import{dirname as Jo,resolve as sr,sep as Yo}from"node:path";async function ar(e,t){let n=sr(t);await or(n,{recursive:!0});let r={written:0,refused:[],collisions:[],failures:[]},{files:i}=await e.listMemory(),o=[...i].sort((p,l)=>p.scope===l.scope?p.path.localeCompare(l.path):p.scope==="personal"?-1:1),s=new Set;for(let p of o){if(!S(p.path)){r.refused.push(p.path);continue}let l=sr(n,...p.path.split("/"));if(!l.startsWith(n+Yo)){r.refused.push(p.path);continue}if(s.has(l)){r.collisions.push(p.path);continue}try{let c=await e.readMemory(p.path);await or(Jo(l),{recursive:!0}),await Vo(l,c.content,"utf8"),s.add(l),r.written+=1}catch(c){r.failures.push({what:p.path,code:c instanceof Error?c.message:String(c)})}}return r}import{mkdir as lr,writeFile as qo}from"node:fs/promises";import{dirname as Zo,resolve as cr,sep as Xo}from"node:path";import{unzipSync as Qo}from"fflate";async function pr(e,t){let n=cr(t);await lr(n,{recursive:!0});let r={written:0,refused:[],failed:[]},i=Qo(e);for(let[o,s]of Object.entries(i)){if(o.endsWith("/"))continue;let p=o.split("/");if(o.startsWith("/")||/^[a-zA-Z]:/.test(o)||o.includes("\\")||p.some(m=>m===""||m==="."||m==="..")){r.refused.push(o);continue}let c=cr(n,...p);if(!c.startsWith(n+Xo)){r.refused.push(o);continue}try{await lr(Zo(c),{recursive:!0}),await qo(c,s),r.written+=1}catch(m){r.failed.push({path:o,reason:m instanceof Error?m.message:String(m)})}}return r}var O=process.env.ONLYMCP_API_URL??"https://only-mcp.com",L=new ts().name("onlymcp").version(Z);function cs(e,t){try{let n=new URL(e);return(n.protocol==="https:"||n.protocol==="http:")&&n.origin===t}catch{return!1}}L.command("login").description("Connect this device to OnlyMCP").action(async()=>{wt("OnlyMCP"),u.info(`This device will register itself as: ${await Fe()}`);let t=await(await fetch(`${O}/api/auth/device/code`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({client_id:"onlymcp-cli"})})).json();u.info(`Code: ${t.user_code}`),u.info(t.verification_uri),console.log(await rs.toString(t.verification_uri_complete,{type:"terminal",small:!0})),cs(t.verification_uri_complete,new URL(O).origin)&&await ns(t.verification_uri_complete).catch(()=>{});let n=De();n.start("Waiting for confirmation");let r=await Mt(O,t.device_code,t.interval??5);I.save(r),n.stop("Connected");let i=new _(O,()=>I.read()),o=await gr(i),s=hr(o);s&&u.info(s),ie(`${o.skills} skills, ${o.agents} agents, ${o.files} files ready`)});async function gr(e){let t=await Ae(),n={skills:0,agents:0,files:0,kept:[],ignored:new Set,removed:0};for(let r of ye()){let i=await Ie(e,r,{ignore:t});n.skills+=i.skills,n.agents+=i.agents,n.files+=i.files;for(let o of i.kept)n.kept.push(`${r}/${o}`);for(let o of i.ignored)n.ignored.add(o);n.removed+=i.removed}return n}function hr(e){if(e.ignored.size===0)return null;let t=e.removed>0?`, ${e.removed} earlier stubs removed`:"";return`${e.ignored.size} left out by ${he()}${t}`}async function xt(e,t,n){try{await e.reportRun(t,n)}catch{}}async function ps(e){try{return await new _(O,()=>e).signOut(),null}catch(t){return t instanceof y&&t.status>0?`HTTP ${t.status}`:t instanceof Error?t.message:String(t)}}L.command("logout").description("End this device's session, then remove its login and cache").action(async()=>{let e=I.read(),t=e?await ps(e):null;if(I.clear(),await new X().clear(),t){u.warn(`The session on the server could not be ended (${t}). It counts as a device until it expires, or until you remove it in the dashboard under Sessions and devices.`),u.success("Logged out on this device");return}u.success("Logged out")});L.command("status").description("Show whether this device is logged in").action(()=>{u.info(I.read()?"logged in":"not logged in")});L.command("sync").description("Rewrite the stub files").option("--memory <dir>","Also write memory as files into this folder").action(async e=>{let t=new _(O,()=>I.read()),n=await gr(t);u.success(`${n.skills} skills, ${n.agents} agents, ${n.files} files`);let r=hr(n);r&&u.info(r),n.kept.length>0&&u.warn([`Left untouched, because something of your own is already there (${n.kept.length})`,...n.kept.slice(0,10).map(s=>` ${s}`),...n.kept.length>10?[` ... and ${n.kept.length-10} more`]:[]].join(`
|
|
71
|
-
`));let i=n.skills+n.agents+n.files;if(!e.memory){await
|
|
72
|
-
`)),o.refused.length>0&&
|
|
73
|
-
`)),o.failures.length>0&&(
|
|
74
|
-
`)),process.exitCode=1),o.failures.length===0&&await
|
|
75
|
-
${String(n).padStart(4)} more files across ${r} skills ${
|
|
76
|
-
`))}e.noDescription.length>0&&
|
|
77
|
-
`)),e.flagged.length>0&&
|
|
78
|
-
`))}
|
|
79
|
-
`)),process.exitCode=1):await
|
|
80
|
-
`)),e.dryRun)
|
|
81
|
-
`)),process.exitCode=1)}}}
|
|
82
|
-
`)),o.failed.length>0&&(
|
|
83
|
-
`)),process.exitCode=1),
|
|
65
|
+
Its tools are now available as "${n.slug}__<tool>".`})}}var wo=v.object({slug:he,name:v.string().min(1).max(80).optional(),url:v.string().url().max(2e3).optional(),transport:v.enum(["http","sse"]).optional(),authType:v.enum(["none","bearer","header"]).optional(),authHeaderName:v.string().max(80).optional(),secret:v.string().max(4e3).optional(),enabled:v.boolean().optional()});function Fn(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:wo,handler:t=>ie(async()=>{let n=await je(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
|
+
${wt(o)}`})}}var vo=v.object({slug:he});function Gn(e){return{name:"connection_delete",description:"Disconnect a remote MCP server and forget its stored credential. Its tools disappear from the gateway.",inputSchema:vo,handler:t=>ie(async()=>{let n=await je(e,t.slug);return n?(await e.deleteConnection(n.id),`Disconnected ${t.slug}.`):`Connection not found: ${t.slug}`})}}var So=v.object({slug:he});function Hn(e){return{name:"connection_tools",description:"List what one connected server offers, and whether each tool is switched on for the gateway.",inputSchema:So,handler:t=>ie(async()=>{let n=await je(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(`
|
|
67
|
+
`)})}}var Co=v.object({slug:he,tool:v.string().min(1).max(200),enabled:v.boolean()});function Wn(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:Co,handler:t=>ie(async()=>{let n=await je(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 S}from"zod";var $o=e=>({content:[{type:"text",text:e}]}),ye=e=>({content:[{type:"text",text:e}],isError:!0});async function U(e){try{return $o(await e())}catch(t){if(t instanceof y){let n=Object.keys(t.params).length?` ${JSON.stringify(t.params)}`:"";return ye(`${t.code}${n}`)}return ye("errors.UNKNOWN")}}var q=S.string().min(1).max(64).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/,"errors.INVALID_NAME"),Ao=S.object({name:q,body:S.string().max(2e5)});function Bn(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:Ao,handler:t=>U(async()=>{let n=await e.putSkill(t.name,t.body);return`${n.name} ${n.updatedAt}`})}}var To=S.object({name:q});function Kn(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:To,handler:t=>U(async()=>(await e.deleteSkill(t.name),`Deleted skill ${t.name}`))}}var Po=S.object({skill:q});function Vn(e){return{name:"list_skill_files",description:"List the companion files of one skill, with their size in bytes.",inputSchema:Po,handler:t=>U(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(`
|
|
68
|
+
`)})}}var Io=S.object({skill:q,path:S.string().min(1).max(256),content:S.string().max(3e6),encoding:S.enum(["utf8","base64"]).default("utf8")});function Jn(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:Io,handler:t=>H(t.path)?U(async()=>{let n=await e.putSkillFile(t.skill,t.path,t.content,t.encoding);return`${t.skill}/${n.path} ${n.size} bytes`}):Promise.resolve(ye("errors.INVALID_PATH"))}}var _o=S.object({skill:q,path:S.string().min(1).max(256)});function Yn(e){return{name:"skill_file_delete",description:"Delete one companion file of a skill. The skill itself stays.",inputSchema:_o,handler:t=>H(t.path)?U(async()=>(await e.deleteSkillFile(t.skill,t.path),`Deleted ${t.skill}/${t.path}`)):Promise.resolve(ye("errors.INVALID_PATH"))}}var Eo=S.object({name:q,description:S.string().min(1).max(1e3),body:S.string().max(2e5),model:S.string().max(64).optional(),tools:S.array(S.string().max(128)).max(200).optional()});function qn(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:Eo,handler:t=>U(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 No=S.object({name:q});function Xn(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:No,handler:t=>U(async()=>(await e.deleteAgent(t.name),`Deleted agent ${t.name}`))}}var Ro=S.object({});function Zn(e){return{name:"list_memory",description:"List the paths of every memory file in this account, private and team, sorted by path.",inputSchema:Ro,handler:()=>U(async()=>{let{files:t}=await e.listMemory();return t.length===0?"(none)":t.map(n=>n.path+Y(n)).sort().join(`
|
|
69
|
+
`)})}}var Oo=S.object({path:S.string().min(3).max(256)});function Qn(e){return{name:"memory_delete",description:"Delete one memory file. Moves it to the trash; it can be restored in the dashboard for the trash period (default 7 days).",inputSchema:Oo,handler:t=>C(t.path)?U(async()=>(await e.deleteMemory(t.path),`Deleted ${t.path}`)):Promise.resolve(ye("errors.INVALID_PATH"))}}import{z as j}from"zod";var ze=e=>({content:[{type:"text",text:e}]}),be=e=>({content:[{type:"text",text:e}],isError:!0});async function vt(e){try{return await e()}catch(t){if(t instanceof y){let n=Object.keys(t.params).length?` ${JSON.stringify(t.params)}`:"";return be(`${t.code}${n}`)}return be("errors.UNKNOWN")}}var Lo=j.object({}),er=j.enum(["memory","skill","agent"]),Mo=j.object({kind:er,name:j.string().min(1).max(300),team:j.string().min(1).max(200)}),Do=j.object({kind:er,team:j.string().min(1).max(200),name:j.string().min(1).max(300).optional(),id:j.string().uuid().optional()});async function tr(e,t){let n=t.trim(),{teams:r}=await e.listTeams(),i=r.find(s=>s.id===n);if(i)return i;let o=r.filter(s=>s.name===n);if(o.length===1)return o[0];if(o.length>1){let s=o.map(p=>p.id).sort();return be(`Several of your teams are named "${t}": ${s.join(", ")}. Pass the id as team.
|
|
70
|
+
errors.TEAM_AMBIGUOUS ${JSON.stringify({team:t,ids:s})}`)}return be(`You are not in that team.
|
|
71
|
+
errors.NOT_A_MEMBER ${JSON.stringify({team:t})}`)}var nr=e=>"content"in e;function rr(e){return{name:"list_teams",description:"List the teams this account is in, one per line: the team id, its name and your role in it.",inputSchema:Lo,handler:t=>vt(async()=>{let{teams:n}=await e.listTeams();if(n.length===0)return ze("(none)");let r=(i,o)=>i<o?-1:i>o?1:0;return ze([...n].sort((i,o)=>r(i.name,o.name)||r(i.id,o.id)).map(i=>`${i.id} ${i.name} ${i.role}`).join(`
|
|
72
|
+
`))})}}function ir(e){return{name:"team_share",description:"Move one of your own memory files, skills or agents into a team, so its members can use it. You need the right to create that kind of content in the team, the team must not hold an item of that name already, and a frozen team takes nothing new.",inputSchema:Mo,handler:t=>vt(async()=>{let n=await tr(e,t.team);return nr(n)?n:(await e.shareWithTeam(n.id,{kind:t.kind,name:t.name}),ze(`Shared ${t.kind} ${t.name} with the team ${n.name}.`))})}}function or(e){return{name:"team_return",description:"Take an item out of a team and back under its owner. Name one of your own items, or pass the id of any item of the team if you may delete that kind of content there. The item keeps its owner, and the return is never refused on a quota.",inputSchema:Do,handler:t=>t.name===void 0==(t.id===void 0)?Promise.resolve(be("Invalid arguments: pass name or id, not both.")):vt(async()=>{let n=await tr(e,t.team);return nr(n)?n:(await e.returnFromTeam(n.id,t.name!==void 0?{kind:t.kind,name:t.name}:{kind:t.kind,id:t.id}),ze(`Returned ${t.kind} ${t.name??t.id} from the team ${n.name}.`))})}}function sr(e,t){return[_n(e),En(e),Pn(e),Zn(e),Qn(e),Rn(e),On(e),Ln(e),Mn(e),Dn(e),$n(e),Sn(e,t),Bn(e),Kn(e),Vn(e),wn(e),Jn(e),Yn(e),An(e),fn(e,t),qn(e),Xn(e),jn(e),zn(e),Fn(e),Gn(e),Hn(e),Wn(e),rr(e),ir(e),or(e)]}function ar(e){return e.map(t=>{let n=at[t.name];if(!n)throw new Error(`No title and annotations in the registry table for the tool ${t.name}`);return{name:t.name,title:n.title,description:t.description,inputSchema:Uo.toJSONSchema(t.inputSchema),annotations:n.annotations}})}async function lr(){let e=pn(),t=new O(e,()=>N.read()),n=new ee,r=sr(t,n),i=await(async()=>{try{let[{skills:s},{agents:p},l]=await Promise.all([t.listSkills(),t.listAgents(),t.getMe().catch(()=>({brainvaultMode:!0}))]);return gt(s.map(c=>c.name),p.map(c=>c.name),{brainvault:l.brainvaultMode!==!1})}catch{return gt([],[])}})(),o=new jo(st(e,Q),{capabilities:{tools:{},resources:{},prompts:{}},instructions:i});o.setRequestHandler(Ko,async()=>({tools:ar(r)})),o.setRequestHandler(Bo,async s=>hn(t,s.params?.cursor)),o.setRequestHandler(Wo,async()=>({resourceTemplates:[...Te]})),o.setRequestHandler(Vo,async s=>yn(t,s.params.uri)),o.setRequestHandler(Ho,async s=>kn(t,s.params?.cursor)),o.setRequestHandler(Go,async s=>xn(t,s.params.name)),o.setRequestHandler(Fo,async s=>{let p=r.find(c=>c.name===s.params.name);if(!p)return{content:[{type:"text",text:"errors.UNKNOWN_TOOL"}],isError:!0};let l=p.inputSchema.safeParse(s.params.arguments??{});return l.success?p.handler(l.data):{content:[{type:"text",text:"errors.INVALID_ARGUMENTS"}],isError:!0}}),Ee().then(s=>{for(let p of ve())Le(t,p,{ignore:s}).catch(()=>{})}).catch(()=>{}),await o.connect(new zo)}import{readdir as Jo,readFile as Yo,realpath as cr,stat as qo}from"node:fs/promises";import{join as Xo,relative as Zo,resolve as Qo,sep as pr}from"node:path";var es=2*1024*1024;function ts(e){return e.subarray(0,8192).includes(0)}async function X(e,t={}){let n=t.maxBytes??es,r=await cr(Qo(e)),i=[];async function o(s){let p=await Jo(s,{withFileTypes:!0});for(let l of p){let c=Xo(s,l.name);if(l.isDirectory()){if(Je(l.name))continue;await o(c);continue}let d;try{d=await cr(c)}catch{continue}if(d!==r&&!d.startsWith(r+pr))continue;let u=Zo(r,d).split(pr).join("/");if(Ae(l.name)){i.push({absolute:d,relative:u,bytes:0,binary:!1,text:null,skip:"denied-name"});continue}let h=await qo(d);if(!h.isFile())continue;if(h.size>n){i.push({absolute:d,relative:u,bytes:h.size,binary:!1,text:null,skip:"too-large"});continue}let b=await Yo(d),x=ts(b);i.push({absolute:d,relative:u,bytes:h.size,binary:x,text:x?null:b.toString("utf8"),skip:null})}}return await o(r),i.sort((s,p)=>s.relative.localeCompare(p.relative)),i}import{basename as ns}from"node:path";function rs(e){let t=new Map;return{entries:e.map(r=>{t.set(r.relative,r);let i=r.skip==="too-large"?Math.max(r.bytes,2097153):r.bytes;return r.text===null?{path:r.relative,bytes:i}:{path:r.relative,bytes:i,text:r.text}}),byPath:t}}function is(e,t){let n=new Map;for(let{path:r,...i}of e){if(t.has(r))continue;let o=n.get(r);o?o.push(i):n.set(r,[i])}return[...n].map(([r,i])=>({relative:r,hits:i}))}function os(e,t){let n=is(e.flagged,t);return{skipped:[...e.skipped.map(r=>({relative:r.path,reason:r.reason})),...n.map(r=>({relative:r.relative,reason:"flagged"}))],flagged:n}}function St(e,t,n){let{entries:r,byPath:i}=rs(e),o=new Set(n.release??[]),s=qe(r,{kinds:[t],release:n.release,...n.collection?{collection:n.collection}:{}});return{plan:s,byPath:i,...os(s,o)}}function ss(e,t={}){let n=t.root?ns(t.root.replace(/[/\\]+$/,"")):"",{plan:r,byPath:i,skipped:o,flagged:s}=St(e,"skills",{...t,collection:n}),p=r.skills.map(l=>({name:l.name,source:i.get(l.sourcePath).absolute,sourcePath:l.sourcePath,description:l.description,collection:l.collection,bytes:l.bytes,files:l.files.map(c=>({path:c.path,absolute:i.get(c.sourcePath).absolute,bytes:c.bytes,binary:c.text===void 0}))}));return{plans:p,skipped:o,noDescription:p.filter(l=>l.description==="").map(l=>l.name).sort(),flagged:s}}function as(e,t={}){let{plan:n,byPath:r,skipped:i,flagged:o}=St(e,"agents",t);return{plans:n.agents.map(s=>({name:s.name,source:r.get(s.sourcePath).absolute,bytes:s.bytes})),skipped:i,flagged:o}}function ls(e,t={}){let{plan:n,byPath:r,skipped:i,flagged:o}=St(e,"memory",t);return{plans:n.memory.map(s=>({path:s.path,source:r.get(s.sourcePath).absolute,bytes:s.bytes})),skipped:i,flagged:o}}function Ct(e,t={}){let n=ss(e.skills??[],{root:t.skillsRoot,release:t.release}),r=as(e.agents??[],{release:t.release}),i=ls(e.memory??[],{release:t.release});return{skills:n.plans,agents:r.plans,memory:i.plans,flagged:[...n.flagged,...r.flagged,...i.flagged],skipped:[...n.skipped,...r.skipped,...i.skipped],noDescription:n.noDescription}}import{readFile as Fe}from"node:fs/promises";import{hostname as cs}from"node:os";function Ge(e){return e instanceof y?e.code:e instanceof Error?e.message:String(e)}function $t(e){return e.skills.length+e.skills.reduce((t,n)=>t+n.files.length,0)+e.agents.length+e.memory.length}async function dr(e,t,n){let r={skills:0,skillFiles:0,agents:0,memory:0,failures:[]},i=$t(t),o=0,s=l=>n(o+=1,i,l);for(let l of t.skills){try{await e.putSkill(l.name,await Fe(l.source,"utf8"),{...l.description?{description:l.description}:{},sourcePath:l.sourcePath,...l.collection?{collection:l.collection}:{}}),r.skills+=1}catch(c){r.failures.push({what:`skill ${l.name}`,code:Ge(c)}),o+=l.files.length,s(l.name);continue}s(l.name);for(let c of l.files){try{let d=await Fe(c.absolute);await e.putSkillFile(l.name,c.path,c.binary?d.toString("base64"):d.toString("utf8"),c.binary?"base64":"utf8"),r.skillFiles+=1}catch(d){r.failures.push({what:`${l.name}/${c.path}`,code:Ge(d)})}s(`${l.name}/${c.path}`)}}for(let l of t.agents){try{let c=await Fe(l.source,"utf8"),d=te(c);if(!d){r.failures.push({what:`agent ${l.name}`,code:"no-frontmatter"}),s(l.name);continue}await e.putAgent(l.name,{...d,body:ce(c)}),r.agents+=1}catch(c){r.failures.push({what:`agent ${l.name}`,code:Ge(c)})}s(l.name)}let p=cs();for(let l of t.memory){try{await e.writeMemory(l.path,await Fe(l.source,"utf8"),p),r.memory+=1}catch(c){r.failures.push({what:l.path,code:Ge(c)})}s(l.path)}return r}function mr(e){return e.skills.length===0&&e.agents.length===0&&e.memory.length===0}function ur(e){return e.skills.length+e.agents.length+e.memory.length}function At(e){return e.scope==="personal"&&e.isOwn&&e.archivedAt===null}async function fr(e,t,n){let r={skills:[],agents:[],memory:[]};if(n.skills){let i=new Set(t.skills.map(s=>s.name)),{skills:o}=await e.listSkills();r.skills=o.filter(s=>At(s)&&!i.has(s.name)).map(s=>s.name)}if(n.agents){let i=new Set(t.agents.map(s=>s.name)),{agents:o}=await e.listAgents();r.agents=o.filter(s=>At(s)&&!i.has(s.name)).map(s=>s.name)}if(n.memory){let i=new Set(t.memory.map(s=>s.path)),{files:o}=await e.listMemory();r.memory=o.filter(s=>At(s)&&!i.has(s.path)).map(s=>s.path)}return r.skills.sort(),r.agents.sort(),r.memory.sort(),r}function ps(e){return e instanceof y?e.code:e instanceof Error?e.message:String(e)}async function gr(e,t){let n={deleted:0,failures:[]},r=async(i,o,s)=>{for(let p of i)try{await s(p),n.deleted+=1}catch(l){n.failures.push({what:o(p),code:ps(l)})}};return await r(t.skills,i=>`skill ${i}`,i=>e.deleteSkill(i)),await r(t.agents,i=>`agent ${i}`,i=>e.deleteAgent(i)),await r(t.memory,i=>i,i=>e.deleteMemory(i)),n}import{mkdir as hr,writeFile as ds}from"node:fs/promises";import{dirname as ms,resolve as yr,sep as us}from"node:path";async function br(e,t){let n=yr(t);await hr(n,{recursive:!0});let r={written:0,refused:[],collisions:[],failures:[]},{files:i}=await e.listMemory(),o=[...i].sort((p,l)=>p.scope===l.scope?p.path.localeCompare(l.path):p.scope==="personal"?-1:1),s=new Set;for(let p of o){if(!C(p.path)){r.refused.push(p.path);continue}let l=yr(n,...p.path.split("/"));if(!l.startsWith(n+us)){r.refused.push(p.path);continue}if(s.has(l)){r.collisions.push(p.path);continue}try{let c=await e.readMemory(p.path);await hr(ms(l),{recursive:!0}),await ds(l,c.content,"utf8"),s.add(l),r.written+=1}catch(c){r.failures.push({what:p.path,code:c instanceof Error?c.message:String(c)})}}return r}import{mkdir as kr,writeFile as fs}from"node:fs/promises";import{dirname as gs,resolve as xr,sep as hs}from"node:path";import{unzipSync as ys}from"fflate";async function wr(e,t){let n=xr(t);await kr(n,{recursive:!0});let r={written:0,refused:[],failed:[]},i=ys(e);for(let[o,s]of Object.entries(i)){if(o.endsWith("/"))continue;let p=o.split("/");if(o.startsWith("/")||/^[a-zA-Z]:/.test(o)||o.includes("\\")||p.some(d=>d===""||d==="."||d==="..")){r.refused.push(o);continue}let c=xr(n,...p);if(!c.startsWith(n+hs)){r.refused.push(o);continue}try{await kr(gs(c),{recursive:!0}),await fs(c,s),r.written+=1}catch(d){r.failed.push({path:o,reason:d instanceof Error?d.message:String(d)})}}return r}var z=process.env.ONLYMCP_API_URL??"https://only-mcp.com",F=new ks().name("onlymcp").version(Q);function Ts(e,t){try{let n=new URL(e);return(n.protocol==="https:"||n.protocol==="http:")&&n.origin===t}catch{return!1}}F.command("login").description("Connect this device to OnlyMCP").action(async()=>{_t("OnlyMCP"),f.info(`This device will register itself as: ${await Ke()}`);let t=await(await fetch(`${z}/api/auth/device/code`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({client_id:"onlymcp-cli"})})).json();f.info(`Code: ${t.user_code}`),f.info(t.verification_uri),console.log(await ws.toString(t.verification_uri_complete,{type:"terminal",small:!0})),Ts(t.verification_uri_complete,new URL(z).origin)&&await xs(t.verification_uri_complete).catch(()=>{});let n=We();n.start("Waiting for confirmation");let r=await Ht(z,t.device_code,t.interval??5);N.save(r),n.stop("Connected");let i=new O(z,()=>N.read()),o=await Ar(i),s=Tr(o);s&&f.info(s),oe(`${o.skills} skills, ${o.agents} agents, ${o.files} files ready`)});async function Ar(e){let t=await Ee(),n={skills:0,agents:0,files:0,kept:[],ignored:new Set,removed:0};for(let r of ve()){let i=await Le(e,r,{ignore:t});n.skills+=i.skills,n.agents+=i.agents,n.files+=i.files;for(let o of i.kept)n.kept.push(`${r}/${o}`);for(let o of i.ignored)n.ignored.add(o);n.removed+=i.removed}return n}function Tr(e){if(e.ignored.size===0)return null;let t=e.removed>0?`, ${e.removed} earlier stubs removed`:"";return`${e.ignored.size} left out by ${we()}${t}`}async function It(e,t,n){try{await e.reportRun(t,n)}catch{}}async function Ps(e){try{return await new O(z,()=>e).signOut(),null}catch(t){return t instanceof y&&t.status>0?`HTTP ${t.status}`:t instanceof Error?t.message:String(t)}}F.command("logout").description("End this device's session, then remove its login and cache").action(async()=>{let e=N.read(),t=e?await Ps(e):null;if(N.clear(),await new ee().clear(),t){f.warn(`The session on the server could not be ended (${t}). It counts as a device until it expires, or until you remove it in the dashboard under Sessions and devices.`),f.success("Logged out on this device");return}f.success("Logged out")});F.command("status").description("Show whether this device is logged in").action(()=>{f.info(N.read()?"logged in":"not logged in")});F.command("sync").description("Rewrite the stub files").option("--memory <dir>","Also write memory as files into this folder").action(async e=>{let t=new O(z,()=>N.read()),n=await Ar(t);f.success(`${n.skills} skills, ${n.agents} agents, ${n.files} files`);let r=Tr(n);r&&f.info(r),n.kept.length>0&&f.warn([`Left untouched, because something of your own is already there (${n.kept.length})`,...n.kept.slice(0,10).map(s=>` ${s}`),...n.kept.length>10?[` ... and ${n.kept.length-10} more`]:[]].join(`
|
|
73
|
+
`));let i=n.skills+n.agents+n.files;if(!e.memory){await It(t,"sync",i);return}let o=await br(t,e.memory);f.success(`${o.written} memory files to ${e.memory}`),o.collisions.length>0&&f.warn(["Team files with a path an existing file of yours already has",...o.collisions.map(s=>` ${s}`)].join(`
|
|
74
|
+
`)),o.refused.length>0&&f.warn(["Paths refused",...o.refused.map(s=>` ${s}`)].join(`
|
|
75
|
+
`)),o.failures.length>0&&(f.error([`${o.failures.length} failed`,...o.failures.map(s=>` ${s.what} ${s.code}`)].join(`
|
|
76
|
+
`)),process.exitCode=1),o.failures.length===0&&await It(t,"sync",i+o.written)});F.command("install").description("Register OnlyMCP in an MCP client").option("--client <id>","claude-code, codex or antigravity (aliases: claude, gemini, gemini-cli)").option("--all","Write every config file that already exists on this machine").option("--print","Only print, write nothing").action(e=>{let t=process.env.ONLYMCP_HOME??$r(),n=sn(t,e);function r(i){if(e.print){f.info(`${i.name} -> ${i.configPath}`),console.log(i.snippet);return}try{an(i)==="already-present"?f.info(`${i.name} is already set up: ${i.configPath}`):f.success(`${i.name} set up: ${i.configPath}`),i.id==="claude-code"&&f.info(rn)}catch(o){f.error(o instanceof Error?o.message:String(o)),process.exitCode=1}}switch(n.kind){case"conflicting-options":f.error("Pass either --client <id> or --all, not both."),process.exitCode=2;return;case"missing-client":f.info(`Known clients: ${n.targets.map(i=>i.id).join(", ")}`),f.info("Pass --client <id>, or --all."),process.exitCode=2;return;case"unknown-client":f.error(`Unknown client. Known: ${n.targets.map(i=>i.id).join(", ")}`),process.exitCode=1;return;case"none-present-for-all":f.error("No known client is set up on this machine yet."),f.info(`Pass --client <id> to write its config anyway. Known: ${n.targets.map(i=>i.id).join(", ")}.`),process.exitCode=2;return;case"single":r(n.target);return;case"all":for(let i of n.present)r(i);n.skipped.length>0&&f.info(`Skipped, not set up on this machine: ${n.skipped.map(i=>i.id).join(", ")}`);return}});function Pt(e){return e<1024?`${e} B`:e<1024*1024?`${Math.round(e/1024)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function He(e){return e.reduce((t,n)=>t+n.bytes,0)}function Is(e,t){let n=e.skills.reduce((o,s)=>o+s.files.length,0),r=e.skills.filter(o=>o.files.length>0).length,i=e.skills.reduce((o,s)=>o+He(s.files),0);if(t.skills&&f.message(`Skills ${String(e.skills.length).padStart(4)} from ${t.skills}
|
|
77
|
+
${String(n).padStart(4)} more files across ${r} skills ${Pt(He(e.skills)+i)}`),t.agents&&f.message(`Agents ${String(e.agents.length).padStart(4)} from ${t.agents} ${Pt(He(e.agents))}`),t.memory&&f.message(`Memory ${String(e.memory.length).padStart(4)} from ${t.memory} ${Pt(He(e.memory))}`),e.skipped.length>0){let o=new Map;for(let s of e.skipped)o.set(s.reason,(o.get(s.reason)??0)+1);f.message(["Skipped",...[...o].map(([s,p])=>` ${String(p).padStart(4)} ${s}`)].join(`
|
|
78
|
+
`))}e.noDescription.length>0&&f.warn(["Missing a description in the SKILL.md header",...e.noDescription.map(o=>` ${o}`)].join(`
|
|
79
|
+
`)),e.flagged.length>0&&f.warn(["Held back over possible credentials (none of it left this machine)",...e.flagged.flatMap(o=>[` ${o.relative}`,...o.hits.map(s=>` line ${s.line} rule ${s.rule} ${s.excerpt}`)])].join(`
|
|
80
|
+
`))}F.command("import").description("Bring existing local skills, agents and memory into OnlyMCP").option("--skills <dir>","Folder with skill subfolders, or a plugin cache (~/.claude/skills when no folder is named)").option("--agents <dir>","Folder with agent files (~/.claude/agents when no folder is named)").option("--memory <dir>","Folder with memory files (no default)").option("--dry-run","Only show what would be uploaded, then stop").option("--yes","Upload without asking first").option("--prune","Delete, after confirmation, what the account holds and the source no longer has").action(async e=>{let t=process.env.ONLYMCP_HOME??$r(),n=!!(e.skills||e.agents||e.memory),r={skills:n?e.skills:Cr(t,".claude","skills"),agents:n?e.agents:Cr(t,".claude","agents"),memory:e.memory};_t("OnlyMCP Import");let i=We();i.start("Reading the folders");let o;try{let[l,c,d]=await Promise.all([r.skills&&E(r.skills)?X(r.skills):Promise.resolve([]),r.agents&&E(r.agents)?X(r.agents):Promise.resolve([]),r.memory&&E(r.memory)?X(r.memory):Promise.resolve([])]);o=Ct({skills:l,agents:c,memory:d},{skillsRoot:r.skills})}catch(l){i.stop("Aborted"),f.error(l instanceof Error?l.message:String(l)),process.exitCode=1;return}i.stop("Read"),Is(o,{skills:r.skills&&E(r.skills)?r.skills:void 0,agents:r.agents&&E(r.agents)?r.agents:void 0,memory:r.memory&&E(r.memory)?r.memory:void 0});let s=$t(o);if(s===0&&!e.prune){oe("Nothing to do.");return}if(e.dryRun&&!e.prune){oe("Nothing uploaded (--dry-run).");return}let p=new O(z,()=>N.read());try{let l=await p.getMe();f.info(`Target ${z} as ${l.email} plan ${l.plan.name}`)}catch(l){f.error(`Not logged in, or the server is unreachable (${l instanceof Error?l.message:String(l)}).`),f.info("First: npx onlymcp login"),process.exitCode=1;return}if(s>0&&!e.yes&&!e.dryRun){if(!process.stdin.isTTY){f.error("No terminal for the prompt. Run --dry-run first, then --yes."),process.exitCode=1;return}let l=await Sr({message:`Upload ${s} entries?`,initialValue:!1});if(Tt(l)||!l){vr("Cancelled. Nothing uploaded.");return}if(o.flagged.length>0){let c=await bs({message:"Send the held-back files anyway?",options:o.flagged.map(d=>({value:d.relative,label:d.relative})),required:!1,initialValues:[]});if(Tt(c)){vr("Cancelled. Nothing uploaded.");return}if(c.length>0){let[d,u,h]=await Promise.all([r.skills&&E(r.skills)?X(r.skills):Promise.resolve([]),r.agents&&E(r.agents)?X(r.agents):Promise.resolve([]),r.memory&&E(r.memory)?X(r.memory):Promise.resolve([])]);o=Ct({skills:d,agents:u,memory:h},{skillsRoot:r.skills,release:c})}}}if(s>0&&!e.dryRun){let l=We();l.start("Uploading");let c=await dr(p,o,(d,u,h)=>{l.message(`${d}/${u} ${h}`)});l.stop("Done"),f.success(`${c.skills} skills, ${c.skillFiles} skill files, ${c.agents} agents, ${c.memory} memory files`),c.failures.length>0?(f.error([`${c.failures.length} failed`,...c.failures.map(d=>` ${d.what} ${d.code}`)].join(`
|
|
81
|
+
`)),process.exitCode=1):await It(p,"import",c.skills+c.skillFiles+c.agents+c.memory)}if(e.prune){let l={skills:!!(r.skills&&E(r.skills)),agents:!!(r.agents&&E(r.agents)),memory:!!(r.memory&&E(r.memory))},c=await fr(p,o,l);if(mr(c))f.info("Nothing to delete: the account holds nothing the source does not know.");else if(f.warn(["Would delete (only your own, nothing from a team, nothing archived)",...c.skills.map(d=>` Skill ${d}`),...c.agents.map(d=>` Agent ${d}`),...c.memory.map(d=>` Memory ${d}`)].join(`
|
|
82
|
+
`)),e.dryRun)f.info("Nothing deleted (--dry-run).");else if(!process.stdin.isTTY)f.error("No terminal for the prompt. Nothing deleted."),process.exitCode=1;else{let d=await Sr({message:`Delete ${ur(c)} entries in the account?`,initialValue:!1});if(Tt(d)||!d)f.info("Nothing deleted.");else{let u=await gr(p,c);f.success(`${u.deleted} deleted`),u.failures.length>0&&(f.error([`${u.failures.length} failed`,...u.failures.map(h=>` ${h.what} ${h.code}`)].join(`
|
|
83
|
+
`)),process.exitCode=1)}}}oe(e.dryRun?"Nothing changed (--dry-run).":"Then: npx onlymcp sync on every device.")});F.command("export").description("Get everything out of the account: memory, skills, agents, connections").option("--out <dir>","Unpack the archive into this folder").option("--zip <file>","Keep the archive as a file").option("--scope <scope>","personal, all or team:<id>","all").option("--types <list>","memory,skills,agents,connections").action(async e=>{if((e.out?1:0)+(e.zip?1:0)!=1){f.error("Either --out <folder> or --zip <file>, not both and not neither."),process.exitCode=1;return}_t("OnlyMCP Export");let t=new O(z,()=>N.read()),n=We();n.start("Fetching the archive");let r;try{r=await t.exportArchive({scope:e.scope,types:e.types?.split(",").map(s=>s.trim()).filter(s=>s!=="")})}catch(s){n.stop("Aborted"),f.error(s instanceof Error?s.message:String(s)),f.info("Not logged in? First: npx onlymcp login"),process.exitCode=1;return}if(e.zip){Ss(As(e.zip),{recursive:!0}),await Cs($s.fromWeb(r.body),vs(e.zip)),n.stop("Done"),oe(`Archive: ${e.zip}`);return}let i=new Uint8Array(await r.arrayBuffer()),o=await wr(i,e.out);n.stop("Done"),f.success(`${o.written} files in ${e.out}`),o.refused.length>0&&f.warn(["Not written, path in the archive is not allowed",...o.refused.map(s=>` ${s}`)].join(`
|
|
84
|
+
`)),o.failed.length>0&&(f.warn(["Not written, the filename doesn't work on this system",...o.failed.map(s=>` ${s.path} ${s.reason}`),"With --zip <file> the archive stays unchanged."].join(`
|
|
85
|
+
`)),process.exitCode=1),oe(`Restore: npx onlymcp import --skills ${e.out}/skills --agents ${e.out}/agents --memory ${e.out}/memory`)});F.command("mcp").description("Run the stdio MCP server, the process an MCP client starts").action(lr);await F.parseAsync();
|
package/dist/bin/mcp.js
CHANGED
|
@@ -1,61 +1,63 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Server as
|
|
3
|
-
`,{flag:"wx",mode:384});try{return await
|
|
4
|
-
`,{flag:"wx",mode:384}),e}catch(s){if(s.code!=="EEXIST")throw s}}let
|
|
2
|
+
import{Server as Bo}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as Ko}from"@modelcontextprotocol/sdk/server/stdio.js";import{CallToolRequestSchema as Vo,GetPromptRequestSchema as Jo,ListPromptsRequestSchema as qo,ListResourceTemplatesRequestSchema as Yo,ListResourcesRequestSchema as Xo,ListToolsRequestSchema as Zo,ReadResourceRequestSchema as Qo}from"@modelcontextprotocol/sdk/types.js";import{hostname as Nn}from"node:os";import{execFile as Sn}from"node:child_process";import{hostname as wn}from"node:os";import{readFile as Cn}from"node:fs/promises";import{promisify as An}from"node:util";import{randomUUID as Ke}from"node:crypto";import{link as pn,mkdir as mn,readFile as un,rename as fn,rm as gn,writeFile as Ve}from"node:fs/promises";import{basename as hn,dirname as qe,join as yn}from"node:path";import{existsSync as dn}from"node:fs";import{homedir as Ge}from"node:os";import{join as N}from"node:path";function X(){return process.env.ONLYMCP_HOME??N(Ge(),".claude","onlymcp")}function ze(){return process.env.ONLYMCP_HOME??Ge()}function He(){return N(X(),"device-id")}function Fe(){return N(X(),"cache")}function We(){return N(X(),"stub-ignore")}function Be(){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[N(ze(),".claude"),N(ze(),".codex")])dn(e)&&!t.includes(e)&&t.push(e);return t.length>0?t:[N(X(),"plugin")]}var bn=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/,Je;function Ye(){return Je??=xn(),Je}async function fe(t){try{let e=(await un(t,"utf8")).trim().toLowerCase();return bn.test(e)?e:null}catch{return null}}async function xn(){let t=He(),e=await fe(t);if(e)return e;try{return await mn(qe(t),{recursive:!0}),await vn(t)}catch{return null}}var kn=new Set(["EPERM","ENOTSUP","EOPNOTSUPP","ENOSYS","EXDEV"]);async function vn(t){let e=Ke(),n=yn(qe(t),`.${hn(t)}.${process.pid}.${Ke()}.tmp`);try{await Ve(n,`${e}
|
|
3
|
+
`,{flag:"wx",mode:384});try{return await pn(n,t),e}catch(r){let i=r.code;if(i!=="EEXIST"&&!kn.has(i??""))throw r;if(i!=="EEXIST")try{return await Ve(t,`${e}
|
|
4
|
+
`,{flag:"wx",mode:384}),e}catch(s){if(s.code!=="EEXIST")throw s}}let o=await fe(t);return o||(await fn(n,t),await fe(t)??e)}finally{await gn(n,{force:!0}).catch(()=>{})}}var Z="0.25.0";var Tn=An(Sn),$n=`onlymcp-cli/${Z} (${process.platform} ${process.arch}; node ${process.versions.node})`,Xe=200;async function Ze(t,e){let n;try{return await Promise.race([t,new Promise(o=>{n=setTimeout(()=>o(null),e),n.unref?.()})])}catch{return null}finally{n&&clearTimeout(n)}}async function In(){try{if(process.platform==="linux"){let t=Cn("/sys/class/dmi/id/product_version","utf8"),n=(await Ze(t,Xe))?.trim();return!n||/^(to be filled|default string|system version|none|n\/a)/i.test(n)?null:n}if(process.platform==="darwin"){let t=Tn("sysctl",["-n","hw.model"]);return(await Ze(t,Xe))?.stdout.trim()||null}}catch{}return null}async function _n(){let t="unknown";try{t=wn()||"unknown"}catch{}let e=await In();return(e&&e!==t?`${t} (${e})`:t).slice(0,60)}var Qe=null;async function ge(){Qe??=await _n();let t=await Ye();return{"user-agent":$n,"x-onlymcp-device":Qe,...t?{"x-onlymcp-device-id":t}:{}}}var d=class extends Error{constructor(n,o={},r=0){super(n);this.code=n;this.params=o;this.status=r;this.name="ApiError"}code;params;status},Q=class{constructor(e,n){this.baseUrl=e;this.token=n}baseUrl;token;async call(e,n={}){let o=this.token();if(!o)throw new d("errors.NOT_LOGGED_IN");let r=await fetch(`${this.baseUrl}${e}`,{...n,headers:{...await ge(),...n.headers??{},authorization:`Bearer ${o}`,"content-type":"application/json"}});if(r.status===204)return;let i=await r.json().catch(()=>({}));if(!r.ok)throw new d(i.code??"errors.UNKNOWN",i.params??{},r.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,o={}){return this.call(`/api/skills/${encodeURIComponent(e)}`,{method:"PUT",body:JSON.stringify({body:n,...o})})}skillFileUrl(e,n){let o=n.split("/").map(encodeURIComponent).join("/");return`/api/skills/${encodeURIComponent(e)}/files/${o}`}getSkillFile(e,n){return this.call(this.skillFileUrl(e,n))}putSkillFile(e,n,o,r="utf8"){return this.call(this.skillFileUrl(e,n),{method:"PUT",body:JSON.stringify({content:o,encoding:r})})}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:o}={}){let r=[n?"use=1":null,o===void 0?null:`team=${encodeURIComponent(o)}`].filter(Boolean);return this.call(`/api/agents/${encodeURIComponent(e)}${r.length?`?${r.join("&")}`:""}`)}readMemory(e,n){return this.call(`${this.memoryUrl(e)}${this.teamQuery(n)}`)}writeMemory(e,n,o,r){return this.call(this.memoryUrl(e),{method:"PUT",body:JSON.stringify({content:n,deviceLabel:o,...r===void 0?{}:{ifMatch:r}})})}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 o=new URLSearchParams({q:e});n.types?.length&&o.set("types",n.types.join(",")),n.limit&&o.set("limit",String(n.limit));for(let r of["type","project","tag"])n[r]!==void 0&&o.set(r,n[r]);return this.call(`/api/search?${o.toString()}`)}graphNodeByRid(e,n){return this.call(`/api/graph/rid/${e}/${encodeURIComponent(n)}`)}graphAround(e,n,o={}){let r=new URLSearchParams({scope:"all",focus:e,depth:String(n)});return o.types?.length&&r.set("types",o.types.join(",")),o.folder!==void 0&&r.set("folder",o.folder),o.project!==void 0&&r.set("project",o.project),this.call(`/api/graph?${r.toString()}`)}memoryTree(e="all"){return this.call(`/api/memory/tree?scope=${encodeURIComponent(e)}`)}moveMemory(e,n,o=!0,r=Nn()){return this.call("/api/memory/move",{method:"POST",body:JSON.stringify({from:e,to:n,updateLinks:o,deviceLabel:r})})}async exportArchive(e={}){let n=this.token();if(!n)throw new d("errors.NOT_LOGGED_IN");let o=new URLSearchParams;e.scope&&o.set("scope",e.scope),e.types?.length&&o.set("types",e.types.join(","));let r=o.size>0?`?${o.toString()}`:"",i=await fetch(`${this.baseUrl}/api/export${r}`,{headers:{...await ge(),authorization:`Bearer ${n}`}});if(!i.ok){let s=await i.json().catch(()=>({}));throw new d(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,o){return this.call(`/api/mcp-connections/${e}/capabilities/${n}`,{method:"PATCH",body:JSON.stringify({enabled:o})})}};var En="https://only-mcp.com";function et(t=process.env.ONLYMCP_API_URL){if(t===void 0)return En;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 Pn}from"@napi-rs/keyring";function Rn(t,e){let n=()=>new Pn(t,e);return{save(o){n().setPassword(o)},read(){try{return n().getPassword()}catch{return null}},clear(){try{n().deletePassword()}catch{}}}}var tt=Rn("onlymcp","session-token");import ee from"cacache";var Ln=Number(process.env.ONLYMCP_TTL_SECONDS??360*60),te=class{constructor(e=Fe()){this.dir=e}dir;async get(e){try{let n=await ee.get(this.dir,e),o=n.metadata;return!o||o.expiresAt<=Date.now()?(await ee.rm.entry(this.dir,e),null):n.data.toString("utf8")}catch{return null}}async set(e,n,o=Ln){await ee.put(this.dir,e,n,{metadata:{expiresAt:Date.now()+o*1e3}})}async clear(){await ee.rm.all(this.dir)}};var nt=["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(" "),On=["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 ot(t,e,n,o){if(n.length===0)return"";let r=[];for(let a of n){let l=n.length-r.length-1,g=l>0?` (+${l} more, call ${e})`:"",u=`
|
|
5
5
|
|
|
6
|
-
${t}: ${[...
|
|
6
|
+
${t}: ${[...r,a].join(", ")}${g}`;if(o+u.length>1800)break;r.push(a)}if(r.length===0)return`
|
|
7
7
|
|
|
8
|
-
${t}: call ${e}`;let i=n.length-
|
|
8
|
+
${t}: call ${e}`;let i=n.length-r.length,s=i>0?` (+${i} more, call ${e})`:"";return`
|
|
9
9
|
|
|
10
|
-
${t}: ${
|
|
10
|
+
${t}: ${r.join(", ")}${s}`}function he(t,e,n={}){let o=n.brainvault===!1?nt:`${nt} ${On}`,r=e.length>0?26:0;return o+=ot("Skills","list_skills",t,o.length+r),o+=ot("Agents","list_agents",e,o.length),o}var Mn=/^[a-z0-9][a-z0-9._-]*(\/[a-z0-9][a-z0-9._-]*)*\.md$/i;function x(t){return Mn.test(t)&&!t.split("/").includes("..")}var Un=/^[A-Za-z0-9][A-Za-z0-9._-]*$/,Dn=8,jn=200;function E(t){if(t.length===0||t.length>jn||t==="SKILL.md")return!1;let e=t.split("/");return e.length>Dn?!1:e.every(n=>Un.test(n)&&n!==".."&&n!==".")}function ne(t){if(!t.startsWith(`---
|
|
11
11
|
`))return null;let e=t.indexOf(`
|
|
12
|
-
---`,3);return e<0?null:t.slice(4,e)}function
|
|
12
|
+
---`,3);return e<0?null:t.slice(4,e)}function G(t,e){if(!/^[a-zA-Z0-9_-]+$/.test(e))return;let n=new RegExp(`^${e}:[ \\t]*(.*)$`,"m").exec(t);if(!n)return;let r=n[1].trim().replace(/^(['"])(.*)\1$/,"$2").trim();return r.length>0?r:void 0}var zn={memory:"memory",skill:"skills",agent:"agents"},Gn={memory:"memory",skills:"skill",agents:"agent"};function H(t){let e=t.teamId===null?"":`?team=${encodeURIComponent(t.teamId)}`;return`onlymcp://${zn[t.kind]}/${t.name}${e}`}var Hn=/^onlymcp:\/\/(memory|skills|agents)\/([^?]+)(?:\?team=([^&]+))?$/;function ye(t){let e=Hn.exec(t);if(!e)return null;let n=null;if(e[3]!==void 0)try{n=decodeURIComponent(e[3])}catch{return null}return{kind:Gn[e[1]],name:e[2],teamId:n}}var oe=[{uriTemplate:"onlymcp://memory/{+path}{?team}",name:"Memory file",description:"One memory file by path; ?team=<id> for a team file.",mimeType:"text/markdown"},{uriTemplate:"onlymcp://skills/{name}{?team}",name:"Skill",description:"The SKILL.md of one skill.",mimeType:"text/markdown"},{uriTemplate:"onlymcp://agents/{name}{?team}",name:"Agent",description:"The definition file of one agent.",mimeType:"text/markdown"}],re=(t,e)=>`${t}__${e}`;function be(t){let e=/^(skill|agent)__(.+)$/.exec(t);return e?{kind:e[1],name:e[2]}:null}function F(t,e,n,o){let r=0;if(n!==void 0){let a=t.findIndex(l=>e(l)===n);if(a===-1)return null;r=a+1}let i=t.slice(r,r+o),s=r+o<t.length;return{page:i,next:s&&i.length>0?e(i[i.length-1]):void 0}}function xe(t,e){return t===null||t===""?e:t.endsWith(`
|
|
13
13
|
`)?t+e:`${t}
|
|
14
|
-
${e}`}function
|
|
15
|
-
`);
|
|
16
|
-
`)&&
|
|
17
|
-
`),totalLines:
|
|
14
|
+
${e}`}function ke(t,e,n){let o=t===""?[]:t.split(`
|
|
15
|
+
`);o.length>0&&t.endsWith(`
|
|
16
|
+
`)&&o.pop();let r=o.length,i=Math.min(e+n-1,r);return{text:e>r?"":o.slice(e-1,i).join(`
|
|
17
|
+
`),totalLines:r,from:e,to:i}}var ve=(t,e)=>`No lines from ${t}: the file has ${e} ${e===1?"line":"lines"}.`;var it=["memory","folder","project","type","tag","skill","collection","agent","connection","tool"],Fn={connection:"mcp"},Wn=t=>Fn[t]??t;function ie(t){let e;return t.kind==="memory"&&typeof t.props.path=="string"?e=t.props.path:t.kind==="connection"&&typeof t.props.slug=="string"?e=t.props.slug:e=t.name??t.key,`${Wn(t.kind)} ${e}`}var Bn={links_to:{out:"links to",in:"linked from"},about:{out:"about",in:"also about it:"},has_type:{out:"has",in:"also of this type:"},tagged:{out:"has",in:"also tagged:"},contains:{out:"contains",in:"in"},in_collection:{out:"in collection",in:"in it:"},uses_skill:{out:"uses",in:"used by"},uses_tool:{out:"uses",in:"used by"},provides:{out:"provides",in:"provided by"}},Kn={links_to:0,uses_skill:1,uses_tool:1,provides:2,in_collection:2,contains:3},rt=t=>Kn[t]??4;function Vn(t,e){return Bn[t]?.[e]??`${t}${e==="in"?" (in)":""}`}var Jn={out:"\u2192",in:"\u2190"};function we(t){let e=t.split(",").map(o=>o.trim()).filter(o=>o!=="");if(e.length===0)return null;let n=e.map(o=>o==="mcp"?"connection":o);return n.every(o=>it.includes(o))?n:null}var Se=(t,e)=>`${t} ${e}${t===1?"":"s"}`;function Ce(t){let{path:e,focus:n,depth:o,kept:r}=t,i=new Map(t.nodes.map(c=>[c.id,c])),s=new Map,a=(c,h)=>{let v=s.get(c)??[];v.push(h),s.set(c,v)};for(let c of t.edges)a(c.from,{other:c.to,type:c.type,direction:"out"}),a(c.to,{other:c.from,type:c.type,direction:"in"});let l=c=>{if(c===n)return 0;let h=i.get(c);if(!h)return 1/0;if(h.depth!==void 0)return h.depth;let v=(s.get(c)??[]).map(A=>A.other===n?0:i.get(A.other)?.depth??1/0);return Math.min(1/0,...v)+1},g=new Map;for(let c of t.nodes){let h=l(c.id);if(c.id===n||!Number.isFinite(h)||h<1||h>o||r&&!r.has(c.id))continue;let v=g.get(h)??[];v.push(c.id),g.set(h,v)}let u=[],p=0;for(let c=1;c<=o;c+=1){let h=g.get(c)??[];if(h.length===0)continue;p+=h.length;let v=h.map(A=>{let j=i.get(A),O=(s.get(A)??[]).filter(w=>l(w.other)===c-1).sort((w,_)=>+(_.other===n)-+(w.other===n)||rt(w.type)-rt(_.type)||w.type.localeCompare(_.type)),z=O[0],je=z?O.filter(w=>w.other===z.other).sort((w,_)=>+(w.direction==="out")-+(_.direction==="out")):[],ln=je.length===0?"\xB7 ":`${je.map(w=>{let _=w.direction==="out"?"in":"out";return`${Jn[_]} ${Vn(w.type,_)}`}).join(" / ")} `,cn=c>1&&z&&i.has(z.other)?` (via ${ie(i.get(z.other))})`:"";return` ${ln}${ie(j)}${cn}`}).sort();u.push(`depth ${c}:`),u.push(...v.slice(0,40)),v.length>40&&u.push(` (+${v.length-40} more)`)}if(p===0)return r?`Nothing around ${e} within ${Se(o,"hop")} matches the filter.`:`${e} is connected to nothing yet.`;let m=t.truncated?" (cut at the graph limit)":"";return[`${e}: ${Se(p,"node")} within ${Se(o,"hop")}${m}`,...u].join(`
|
|
18
|
+
`)}function Ae(t){let e=[...new Set(t.filter(o=>o.type==="links_to"||o.type==="uses_skill"||o.type==="uses_tool").map(o=>`${o.direction==="in"?"\u2190 ":""}${ie(o.node)}`))].sort((o,r)=>Number(o.startsWith("\u2190"))-Number(r.startsWith("\u2190"))||o.localeCompare(r));if(e.length===0)return null;let n=e.length>8?` (+${e.length-8} more)`:"";return` \u21B3 ${e.slice(0,8).join(", ")}${n}`}function Te(t,e){let n=new URL(t);if(n.protocol!=="http:"&&n.protocol!=="https:")throw new TypeError(`serverInfo: "${t}" is not an http(s) origin`);let o=n.origin;return{name:"onlymcp",title:"OnlyMCP",version:e,websiteUrl:o,icons:[{src:`${o}/brand/connector-512.png`,mimeType:"image/png"},{src:`${o}/brand/favicon.svg`,mimeType:"image/svg+xml"}]}}var S=t=>({title:t,annotations:{title:t,readOnlyHint:!0,openWorldHint:!1}}),k=(t,e)=>({title:t,annotations:{title:t,readOnlyHint:!1,destructiveHint:e.destructive,idempotentHint:e.idempotent,openWorldHint:e.openWorld??!1}}),$e={list_memory:S("List memory files"),memory_read:S("Read a memory file"),memory_write:k("Write a memory file",{destructive:!0,idempotent:!0}),memory_append:k("Append to a memory file",{destructive:!1,idempotent:!1}),memory_delete:k("Delete a memory file",{destructive:!0,idempotent:!1}),memory_search:S("Search memory"),memory_tree:S("Show the memory tree"),memory_move:k("Move a memory file",{destructive:!1,idempotent:!1}),memory_links:S("Show memory links"),memory_graph:S("Walk the memory graph"),list_skills:S("List skills"),get_skill:S("Load a skill"),skill_write:k("Write a skill",{destructive:!0,idempotent:!0}),skill_delete:k("Delete a skill",{destructive:!0,idempotent:!1}),list_skill_files:S("List skill files"),get_skill_file:S("Read a skill file"),skill_file_write:k("Write a skill file",{destructive:!0,idempotent:!0}),skill_file_delete:k("Delete a skill file",{destructive:!0,idempotent:!1}),list_agents:S("List agents"),get_agent_definition:S("Load an agent definition"),agent_write:k("Write an agent",{destructive:!0,idempotent:!0}),agent_delete:k("Delete an agent",{destructive:!0,idempotent:!1}),list_connections:S("List connections"),connection_create:k("Add a connection",{destructive:!1,idempotent:!1,openWorld:!0}),connection_update:k("Update a connection",{destructive:!1,idempotent:!0}),connection_delete:k("Delete a connection",{destructive:!0,idempotent:!1}),connection_tools:S("List a connection's tools"),connection_tool_toggle:k("Switch a connection tool on or off",{destructive:!1,idempotent:!0}),connection_tool_schema:S("Show a connection tool's schema"),connection_call:k("Call a connection tool",{destructive:!0,idempotent:!1,openWorld:!0}),list_teams:S("List teams"),team_share:k("Share with a team",{destructive:!1,idempotent:!0}),team_return:k("Return from a team",{destructive:!1,idempotent:!0})};import{z as at}from"zod";var Qn=at.object({name:at.string().min(1).max(64)}),Ie=t=>t.replace(/[\r\n]+/g," ").trim();function W(t){let e=t.model?`model: ${Ie(t.model)}
|
|
18
19
|
`:"";return`---
|
|
19
20
|
name: ${t.name}
|
|
20
|
-
description: ${
|
|
21
|
-
${e}tools: ${(t.tools??[]).map(
|
|
21
|
+
description: ${Ie(t.description??"")}
|
|
22
|
+
${e}tools: ${(t.tools??[]).map(Ie).join(", ")}
|
|
22
23
|
---
|
|
23
|
-
${t.body}`}function
|
|
24
|
-
name: ${
|
|
25
|
-
description: ${
|
|
26
|
-
${
|
|
27
|
-
x-onlymcp-name: ${
|
|
24
|
+
${t.body}`}function lt(t,e){return{name:"get_agent_definition",description:"Delivers an agent's system prompt from the OnlyMCP cloud.",inputSchema:Qn,async handler(n){let o=`agent:${n.name}`,r=await e.get(o);if(r!==null)return{content:[{type:"text",text:r}]};try{let i=await t.getAgent(n.name,{use:!0}),s=W(i);return await e.set(o,s),{content:[{type:"text",text:s}]}}catch(i){return{content:[{type:"text",text:i instanceof d?i.code:"errors.UNKNOWN"}],isError:!0}}}}}var P=(t,e)=>Object.assign(new Error(e),{code:t}),_e=t=>Buffer.from(t,"utf8").toString("base64url");function Ne(t){return/^[A-Za-z0-9_-]+$/.test(t)?Buffer.from(t,"base64url").toString("utf8"):null}var B=()=>P(-32602,"Invalid cursor."),M=(t,e)=>t<e?-1:t>e?1:0,ct={memory:0,skill:1,agent:2};function eo(t,e){return ct[t.kind]-ct[e.kind]||M(t.name,e.name)||(t.teamId===e.teamId?0:t.teamId===null?-1:e.teamId===null?1:M(t.teamId,e.teamId))||M(e.updatedAt,t.updatedAt)}async function dt(t,e,n=200){let o=e===void 0?void 0:Ne(e);if(o===null)throw B();let[{files:r},{skills:i},{agents:s}]=await Promise.all([t.listMemory(),t.listSkills(),t.listAgents()]),a=[...r.filter(p=>p.archivedAt===null).map(p=>({kind:"memory",name:p.path,teamId:p.teamId,description:"",updatedAt:p.updatedAt})),...i.filter(p=>p.archivedAt===null).map(p=>({kind:"skill",name:p.name,teamId:p.teamId,description:p.description,updatedAt:p.updatedAt})),...s.filter(p=>p.archivedAt===null).map(p=>({kind:"agent",name:p.name,teamId:p.teamId,description:p.description,updatedAt:p.updatedAt}))].sort(eo),l=new Set,g=a.filter(p=>{let m=H(p);return l.has(m)?!1:(l.add(m),!0)}),u=F(g,p=>H(p),o,n);if(!u)throw B();return{resources:u.page.map(p=>({uri:H(p),name:p.name,...p.description?{description:p.description}:{},mimeType:"text/markdown"})),...u.next===void 0?{}:{nextCursor:_e(u.next)}}}function Ee(t){return P(-32603,t instanceof d?t.code:"errors.UNKNOWN")}async function pt(t,e){let n=ye(e);if(!n)throw P(-32002,`Unknown resource: ${e}`);let o=n.teamId??void 0;try{let r=n.kind==="memory"?(await t.readMemory(n.name,o)).content:n.kind==="skill"?(await t.getSkill(n.name,o)).body:W(await t.getAgent(n.name,{team:o}));return{contents:[{uri:e,mimeType:"text/markdown",text:r}]}}catch(r){throw r instanceof d&&r.status===404?P(-32002,`Unknown resource: ${e}`):Ee(r)}}function mt(t){let e=new Map;for(let n of t)n.archivedAt===null&&e.set(n.name,[...e.get(n.name)??[],n]);return[...e.values()].map(n=>n.find(o=>o.isOwn)??[...n].sort((o,r)=>M(r.updatedAt,o.updatedAt))[0]).sort((n,o)=>M(n.name,o.name))}async function ut(t,e,n=200){let o=e===void 0?void 0:Ne(e);if(o===null)throw B();let[{skills:r},{agents:i}]=await Promise.all([t.listSkills(),t.listAgents()]),s=[...mt(r).map(l=>({name:re("skill",l.name),description:l.description})),...mt(i).map(l=>({name:re("agent",l.name),description:l.description}))],a=F(s,l=>l.name,o,n);if(!a)throw B();return{prompts:a.page.map(l=>({name:l.name,...l.description?{description:l.description}:{}})),...a.next===void 0?{}:{nextCursor:_e(a.next)}}}async function ft(t,e){let n=be(e);if(!n)throw P(-32602,`Unknown prompt: ${e}`);let o=(r,i)=>({...r?{description:r}:{},messages:[{role:"user",content:{type:"text",text:i}}]});try{if(n.kind==="skill"){let i=await t.getSkill(n.name);return o(i.description,i.body)}let r=await t.getAgent(n.name,{use:!0});return o(r.description,W(r))}catch(r){throw r instanceof d&&r.status===404?P(-32602,`Unknown prompt: ${e}`):Ee(r)}}import{access as ro,mkdir as Re,readFile as io,rm as ht,writeFile as se}from"node:fs/promises";import{dirname as so,join as K}from"node:path";import{readFile as to}from"node:fs/promises";var Pe=()=>!1;function no(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function oo(t){let e=t.split(/\r?\n/).map(n=>n.trim()).filter(n=>n!==""&&!n.startsWith("#")).map(n=>new RegExp(`^${n.split("*").map(no).join(".*")}$`));return n=>e.some(o=>o.test(n))}async function gt(t=We()){try{return oo(await to(t,"utf8"))}catch(e){if(e.code==="ENOENT")return Pe;throw e}}var ao=/^[a-z0-9]+(-[a-z0-9]+)*$/,lo=/^[a-z0-9]+(-[a-z0-9]+)*(:[a-z0-9]+(-[a-z0-9]+)*)?$/,Le="x-onlymcp-stub";function ae(t){return t.replace(/:/g,"-")}function le(t){return(t??"").replace(/[\r\n]+/g," ").trim()}async function Oe(t,e){let n;try{n=await io(t,"utf8")}catch{return!0}let o=ne(n);if(o===null||G(o,Le)!=="true")return!1;let r=G(o,"x-onlymcp-name");return r===void 0||r===e}async function yt(t,e){return await ro(t).then(()=>!0,()=>!1)&&await Oe(t,e)}async function bt(t,e,n={}){let o=n.ignore??Pe,[{skills:r},{agents:i}]=await Promise.all([t.listSkills(),t.listAgents()]),s=0,a=0,l=[],g=[],u=0;for(let m of r){if(!lo.test(m.name))continue;let c=K(e,"skills",ae(m.name)),h=K(c,"SKILL.md");if(o(m.name)||o(ae(m.name))){g.push(m.name),await yt(h,m.name)&&(await ht(c,{recursive:!0,force:!0}),u+=1);continue}if(!await Oe(h,m.name)){l.push(`skills/${ae(m.name)}`);continue}await Re(c,{recursive:!0}),await se(h,`---
|
|
25
|
+
name: ${ae(m.name)}
|
|
26
|
+
description: ${le(m.description)||"Synchronisiert ueber OnlyMCP. Inhalt wird bei Bedarf geladen."}
|
|
27
|
+
${Le}: true
|
|
28
|
+
x-onlymcp-name: ${m.name}
|
|
28
29
|
---
|
|
29
30
|
|
|
30
|
-
Call \`get_skill({ name: "${
|
|
31
|
-
`,"utf8"),
|
|
32
|
-
name: ${
|
|
33
|
-
description: ${
|
|
34
|
-
${
|
|
35
|
-
`:""}tools: ${
|
|
36
|
-
${
|
|
37
|
-
x-onlymcp-name: ${
|
|
31
|
+
Call \`get_skill({ name: "${m.name}" })\` on the OnlyMCP server and follow whatever comes back.
|
|
32
|
+
`,"utf8"),a+=1;try{let v=await t.getSkill(m.name);for(let A of v.files??[]){if(!E(A.path))continue;let j=await t.getSkillFile(m.name,A.path),O=K(c,...A.path.split("/"));await Re(so(O),{recursive:!0}),j.encoding==="base64"?await se(O,Buffer.from(j.content,"base64")):await se(O,j.content,"utf8"),s+=1}}catch{}}await Re(K(e,"agents"),{recursive:!0});let p=0;for(let m of i){if(!ao.test(m.name))continue;let c=K(e,"agents",`${m.name}.md`);if(o(m.name)){g.push(m.name),await yt(c,m.name)&&(await ht(c),u+=1);continue}if(!await Oe(c,m.name)){l.push(`agents/${m.name}.md`);continue}let h=le(m.description),v=m.model?le(m.model):"",A=m.tools.map(le).join(", ");await se(c,`---
|
|
33
|
+
name: ${m.name}
|
|
34
|
+
description: ${h}
|
|
35
|
+
${v?`model: ${v}
|
|
36
|
+
`:""}tools: ${A}
|
|
37
|
+
${Le}: true
|
|
38
|
+
x-onlymcp-name: ${m.name}
|
|
38
39
|
---
|
|
39
40
|
|
|
40
|
-
Call \`get_agent_definition({ name: "${
|
|
41
|
-
`,"utf8"),p+=1}return{skills:
|
|
42
|
-
`)}]}}catch(e){return{content:[{type:"text",text:e instanceof
|
|
43
|
-
`)}]}}catch(e){return{content:[{type:"text",text:e instanceof
|
|
44
|
-
${n.code} ${JSON.stringify(n.params)}`}],isError:!0}}return{content:[{type:"text",text:n instanceof
|
|
45
|
-
${
|
|
46
|
-
|
|
47
|
-
`))}catch(n){return
|
|
48
|
-
`))}catch(n){return
|
|
41
|
+
Call \`get_agent_definition({ name: "${m.name}" })\` on the OnlyMCP server and follow whatever comes back.
|
|
42
|
+
`,"utf8"),p+=1}return{skills:a,agents:p,files:s,kept:l,ignored:g,removed:u}}import{z as Wo}from"zod";import{z as Me}from"zod";var co=Me.object({name:Me.string().min(1).max(64),path:Me.string().min(1).max(200)});function xt(t){return{name:"get_skill_file",description:"Delivers a single companion file of a skill from the OnlyMCP cloud, e.g. references/palette.md. Usually not needed: `npx onlymcp sync` places these files next to the SKILL.md.",inputSchema:co,async handler(e){try{let n=await t.getSkillFile(e.name,e.path);return n.encoding==="base64"?{content:[{type:"text",text:`errors.BINARY_FILE ${n.path} (${n.size} bytes) - fetch it to disk with \`npx onlymcp sync\`.`}],isError:!0}:{content:[{type:"text",text:n.content}]}}catch(n){return{content:[{type:"text",text:n instanceof d?n.code:"errors.UNKNOWN"}],isError:!0}}}}}import{z as kt}from"zod";var po=kt.object({name:kt.string().min(1).max(64)});function vt(t,e){return{name:"get_skill",description:"Delivers a skill's full content from the OnlyMCP cloud. Called from the stub files.",inputSchema:po,async handler(n){let o=`skill:${n.name}`,r=await e.get(o);if(r!==null)return{content:[{type:"text",text:r}]};try{let i=await t.getSkill(n.name);return await e.set(o,i.body),{content:[{type:"text",text:i.body}]}}catch(i){return{content:[{type:"text",text:i instanceof d?i.code:"errors.UNKNOWN"}],isError:!0}}}}}import{z as mo}from"zod";var St=mo.object({}),R=t=>t.scope==="team"?` (team: ${t.teamName??"unknown"})`:"";function wt(t){return{name:"list_skills",description:"List every skill name available to this user. Use when a skill you need is not named in the server instructions.",inputSchema:St,async handler(){try{let{skills:e}=await t.listSkills();return{content:[{type:"text",text:e.map(n=>`${n.name}${R(n)}`).join(`
|
|
43
|
+
`)}]}}catch(e){return{content:[{type:"text",text:e instanceof d?e.code:"errors.UNKNOWN"}],isError:!0}}}}}function Ct(t){return{name:"list_agents",description:"List every agent available to this user, with its description. Use when this client has no agent files of its own.",inputSchema:St,async handler(){try{let{agents:e}=await t.listAgents();return{content:[{type:"text",text:e.map(o=>`${o.name}${R(o)}: ${o.description}`).join(`
|
|
44
|
+
`)}]}}catch(e){return{content:[{type:"text",text:e instanceof d?e.code:"errors.UNKNOWN"}],isError:!0}}}}}import{hostname as uo}from"node:os";import{z as ce}from"zod";var fo=ce.object({path:ce.string().min(3).max(256),content:ce.string().min(1).max(1e6),ifMatch:ce.string().max(64).optional()}),At=t=>({content:[{type:"text",text:t instanceof d?t.code:"errors.UNKNOWN"}],isError:!0});function Tt(t){return{name:"memory_append",description:"Appends text to a memory file, after a newline when the file does not end with one. A missing file is created.",inputSchema:fo,async handler(e){if(!x(e.path))return{content:[{type:"text",text:"errors.INVALID_PATH"}],isError:!0};for(let n=0;;n+=1){let o;try{o=await t.readMemory(e.path)}catch(r){if(!(r instanceof d&&r.code==="errors.MEMORY_NOT_FOUND"))return At(r);o=null}try{let r=await t.writeMemory(e.path,o===null?e.content:xe(o.content,e.content),uo(),o===null?void 0:e.ifMatch??o.updatedAt),i=e.content.length,s=r.routedTo?` (created in team ${r.routedTo.teamName})`:"";return{content:[{type:"text",text:`Appended ${i} ${i===1?"character":"characters"} to ${e.path}.${s}`}]}}catch(r){if(r instanceof d&&r.code==="errors.MEMORY_CHANGED"&&e.ifMatch===void 0&&n===0)continue;return At(r)}}}}}import{z as U}from"zod";var go=U.object({path:U.string().min(3).max(256),from:U.string().optional(),lines:U.string().optional()}),$t=2e3;function It(t){let e=new Map;return{name:"memory_read",description:"Reads a memory file live from the OnlyMCP cloud. No disk cache. from (first line, counted from 1) and lines (how many, 1 to 2000) return a range and the total number of lines.",inputSchema:go,async handler(n){if(!x(n.path))return{content:[{type:"text",text:"errors.INVALID_PATH"}],isError:!0};let o=n.from!==void 0||n.lines!==void 0,r=U.coerce.number().int().min(1).safeParse(n.from??"1"),i=U.coerce.number().int().min(1).max($t).safeParse(n.lines??String($t));if(o&&(!r.success||!i.success))return{content:[{type:"text",text:"errors.INVALID_ARGUMENTS"}],isError:!0};try{let s=e.get(n.path);s||(s=t.readMemory(n.path).then(u=>({content:u.content,updatedAt:u.updatedAt})),e.set(n.path,s),s.finally(()=>e.delete(n.path)));let a=await s;if(!o||!r.success||!i.success)return{content:[{type:"text",text:a.content}],_meta:{updatedAt:a.updatedAt}};let l=ke(a.content,r.data,i.data);return{content:[{type:"text",text:r.data>l.totalLines?ve(r.data,l.totalLines):l.text}],_meta:{updatedAt:a.updatedAt,totalLines:l.totalLines,from:l.from,to:l.to}}}catch(s){return{content:[{type:"text",text:s instanceof d?s.code:"errors.UNKNOWN"}],isError:!0}}}}}import{hostname as ho}from"node:os";import{z as de}from"zod";var yo=de.object({path:de.string().min(3).max(256),content:de.string().max(1e6),ifMatch:de.string().max(64).optional()});function _t(t){return{name:"memory_write",description:"Writes a memory file live into the OnlyMCP cloud (write-through).",inputSchema:yo,async handler(e){if(!x(e.path))return{content:[{type:"text",text:"errors.INVALID_PATH"}],isError:!0};try{let n=await t.writeMemory(e.path,e.content,ho(),e.ifMatch),o=n.warning?`${n.path} ${n.updatedAt} ${n.warning.code} ${JSON.stringify(n.warning.params)}`:`${n.path} ${n.updatedAt}`;return n.routedTo&&(o+=` (created in team ${n.routedTo.teamName})`),{content:[{type:"text",text:o}]}}catch(n){if(n instanceof d&&n.code==="errors.MEMORY_CHANGED"){let{updatedAt:r,by:i}=n.params;return{content:[{type:"text",text:`${`The file changed since you read it (at ${r??"an unknown time"}, by ${i??"a device"}). Read it again, then write.`}
|
|
45
|
+
${n.code} ${JSON.stringify(n.params)}`}],isError:!0}}return{content:[{type:"text",text:n instanceof d?n.code:"errors.UNKNOWN"}],isError:!0}}}}}import{z as b}from"zod";var T=t=>({content:[{type:"text",text:t}]}),C=t=>({content:[{type:"text",text:t}],isError:!0});function V(t){return t instanceof d?t.code:"errors.UNKNOWN"}var pe=b.string().trim().min(1).max(128).optional(),bo=b.object({query:b.string().min(1).max(200),types:b.string().max(64).optional(),limit:b.number().int().min(1).max(50).optional(),type:pe.describe("Only memory files of this metadata.type, e.g. solution, project, feedback."),project:pe.describe("Only memory files about this project."),tag:pe.describe("Only memory files carrying this tag."),expand:b.enum(["links","none"]).optional().describe("links: name the direct links of the first five hits.")});async function xo(t,e){let n=new Map;for(let o of e.slice(0,5))try{let r=Ae((await t.graphNodeByRid(o.kind,o.id)).neighbours);r&&n.set(`${o.kind}:${o.id}`,r)}catch{}return n}function Et(t){return{name:"memory_search",description:"Full-text search across memory, skills and agents. Delivers the best hits with a short snippet each; between equally good matches the more recently changed one ranks first. type, project and tag narrow it to memory files whose frontmatter says so. expand=links names, under each of the first five, what it links to and what links to it (\u2190).",inputSchema:bo,async handler(e){try{let{hits:n}=await t.searchContent(e.query,{types:e.types?.split(",").map(i=>i.trim()).filter(i=>i!==""),limit:e.limit,...e.type===void 0?{}:{type:e.type},...e.project===void 0?{}:{project:e.project},...e.tag===void 0?{}:{tag:e.tag}});if(n.length===0)return T(`Nothing found for ${e.query}`);let o=new Map;if(n.some(i=>i.teamId!==null))try{for(let i of(await t.listTeams()).teams)o.set(i.id,i.name)}catch{}let r=e.expand==="links"?await xo(t,n):new Map;return T(n.map(i=>{let s=`${i.kind} ${i.path??i.name}${R({scope:i.scope,teamName:i.teamId===null?null:o.get(i.teamId)??null})}
|
|
46
|
+
${i.snippet}`,a=r.get(`${i.kind}:${i.id}`);return a?`${s}
|
|
47
|
+
${a}`:s}).join(`
|
|
48
|
+
`))}catch(n){return C(V(n))}}}}var ko=b.object({scope:b.string().max(96).optional(),folder:b.string().max(256).optional().describe("Only this folder and what is under it, e.g. solutions.")});function Pt(t){return{name:"memory_tree",description:"This account's folder structure: every folder, empty ones included, and the files in it, each with its frontmatter type in brackets ([solution]). folder narrows it to one folder and what is under it.",inputSchema:ko,async handler(e){try{let n=(e.folder??"").trim().replace(/^\/+|\/+$/g,"");if(n!==""&&!x(`${n}/x.md`))return C("errors.INVALID_PATH");let o=n===""?null:`${n}/`,{nodes:r}=await t.memoryTree(e.scope??"all"),i=o===null?r:r.filter(s=>s.path.startsWith(o)||s.kind==="folder"&&s.path===n);return i.length===0?T(o===null?"(empty)":`No folder ${n}`):T(i.map(s=>{let a=s.path.split("/").length-1,l=s.kind==="folder"?`${s.name}/`:s.name,g=s.kind==="file"&&s.type?` [${s.type}]`:"";return`${" ".repeat(a)}${l}${g}${R(s)}`}).join(`
|
|
49
|
+
`))}catch(n){return C(V(n))}}}}var vo=b.object({from:b.string().min(3).max(256),to:b.string().min(3).max(256),updateLinks:b.boolean().optional()});function Nt(t){return`${t} ${t===1?"file":"files"}`}function Rt(t){return{name:"memory_move",description:"Moves or renames a memory file. Every [[link]] that would no longer find it follows along, by name or by path, unless turned off.",inputSchema:vo,async handler(e){if(!x(e.from)||!x(e.to))return C("errors.INVALID_PATH");let n=e.updateLinks??!0;try{let o=await t.moveMemory(e.from,e.to,n);return T(`${o.from} moved to ${o.to}`+(n?`, links updated in ${Nt(o.rewritten)}, ${Nt(o.skipped)} left unchanged`:""))}catch(o){return C(V(o))}}}}var So=b.object({path:b.string().min(3).max(256)});function Lt(t){return{name:"memory_links",description:"A memory file's [[links]], split between the ones that point somewhere and the ones that point nowhere.",inputSchema:So,async handler(e){if(!x(e.path))return C("errors.INVALID_PATH");try{let n=await t.readMemory(e.path),{resolved:o,unresolved:r}=n.links;return o.length===0&&r.length===0?T(`${e.path} does not link to anything.`):T([o.length>0?`Resolved: ${o.join(", ")}`:"",r.length>0?`Open (no file with this name yet): ${r.join(", ")}`:""].filter(i=>i!=="").join(`
|
|
50
|
+
`))}catch(n){return C(V(n))}}}}var wo=b.object({path:b.string().min(3).max(256).describe("Path of the memory file to start from."),depth:b.number().int().min(1).max(3).optional().describe("Hops to walk, 1 to 3. Default 1."),types:b.string().max(128).optional().describe("Comma-separated node kinds to list: memory, skill, agent, mcp, tool, folder, type, project, tag, collection."),folder:b.string().max(256).optional().describe("Only memory files and folders under this folder."),project:pe.describe("Only nodes about this project (and the project itself).")});function Ot(t){return{name:"memory_graph",description:"The graph around one memory file, up to three hops: the files, skills, agents and servers it links to or is linked from, its folder, type, project and tags, and from depth 2 on what those lead to. 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:wo,async handler(e){if(!x(e.path))return C("errors.INVALID_PATH");let n=e.depth??1,o=e.types===void 0||e.types.trim()===""?void 0:we(e.types);if(o===null)return C(`Invalid types: ${e.types}`);let r=(e.folder??"").trim().replace(/^\/+|\/+$/g,"");if(r!==""&&!x(`${r}/x.md`))return C("errors.INVALID_PATH");try{let i=await t.readMemory(e.path);if(!i.id)return C("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(u){if(u instanceof d&&u.code==="errors.NODE_NOT_FOUND")return T(`${i.path} is not in the graph yet (it is added on its next save).`);throw u}let a=await t.graphAround(s,n),l={...o?{types:o}:{},...r!==""?{folder:r}:{},...e.project!==void 0?{project:e.project}:{}},g=Object.keys(l).length>0?new Set((await t.graphAround(s,n,l)).nodes.map(u=>u.id)):null;return T(Ce({path:i.path,focus:s,depth:n,nodes:a.nodes,edges:a.edges,truncated:a.truncated,kept:g}))}catch(i){return C(V(i))}}}}import{z as f}from"zod";var Co=t=>({content:[{type:"text",text:t}]}),Mt=t=>({content:[{type:"text",text:t}],isError:!0});async function D(t){try{return Co(await t())}catch(e){if(e instanceof d){let n=Object.keys(e.params).length?` ${JSON.stringify(e.params)}`:"";return Mt(`${e.code}${n}`)}return Mt("errors.UNKNOWN")}}var J=f.string().min(1).max(32).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/,"errors.INVALID_SLUG");async function me(t,e){let{connections:n}=await t.listConnections(),o=n.filter(r=>r.slug===e);return o.find(r=>r.scope==="personal")??o[0]??null}function Ue(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})
|
|
49
51
|
${t.url}${t.statusError?`
|
|
50
|
-
last error: ${t.statusError}`:""}`}var
|
|
51
|
-
`)})}}var
|
|
52
|
-
${
|
|
52
|
+
last error: ${t.statusError}`:""}`}var Ao=f.object({});function Ut(t){return{name:"list_connections",description:"List the MCP servers connected through this OnlyMCP account, with the tool-name prefix each one uses.",inputSchema:Ao,handler:()=>D(async()=>{let{connections:e}=await t.listConnections();return e.length===0?"No MCP servers are connected yet. Add one with connection_create.":e.map(Ue).join(`
|
|
53
|
+
`)})}}var To=f.object({name:f.string().min(1).max(80),slug:J,url:f.string().url().max(2e3),transport:f.enum(["http","sse"]).default("http"),authType:f.enum(["none","bearer","header"]).default("none"),authHeaderName:f.string().max(80).optional(),secret:f.string().max(4e3).optional(),teamId:f.string().max(64).optional()});function Dt(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:To,handler:e=>D(async()=>{let{connection:n}=await t.createConnection(e);return`Connected.
|
|
54
|
+
${Ue(n)}
|
|
53
55
|
|
|
54
|
-
Its tools are now available as "${n.slug}__<tool>".`})}}var
|
|
55
|
-
${
|
|
56
|
-
`)})}}var
|
|
57
|
-
`)})}}var
|
|
58
|
-
`)})}}var
|
|
59
|
-
errors.TEAM_AMBIGUOUS ${JSON.stringify({team:e,ids:s})}`)}return
|
|
60
|
-
errors.NOT_A_MEMBER ${JSON.stringify({team:e})}`)}var
|
|
61
|
-
`))})}}function
|
|
56
|
+
Its tools are now available as "${n.slug}__<tool>".`})}}var $o=f.object({slug:J,name:f.string().min(1).max(80).optional(),url:f.string().url().max(2e3).optional(),transport:f.enum(["http","sse"]).optional(),authType:f.enum(["none","bearer","header"]).optional(),authHeaderName:f.string().max(80).optional(),secret:f.string().max(4e3).optional(),enabled:f.boolean().optional()});function jt(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:$o,handler:e=>D(async()=>{let n=await me(t,e.slug);if(!n)return`Connection not found: ${e.slug}`;let{slug:o,...r}=e,{connection:i}=await t.updateConnection(n.id,r);return`Updated.
|
|
57
|
+
${Ue(i)}`})}}var Io=f.object({slug:J});function zt(t){return{name:"connection_delete",description:"Disconnect a remote MCP server and forget its stored credential. Its tools disappear from the gateway.",inputSchema:Io,handler:e=>D(async()=>{let n=await me(t,e.slug);return n?(await t.deleteConnection(n.id),`Disconnected ${e.slug}.`):`Connection not found: ${e.slug}`})}}var _o=f.object({slug:J});function Gt(t){return{name:"connection_tools",description:"List what one connected server offers, and whether each tool is switched on for the gateway.",inputSchema:_o,handler:e=>D(async()=>{let n=await me(t,e.slug);if(!n)return`Connection not found: ${e.slug}`;let{capabilities:o}=await t.listCapabilities(n.id);return o.length===0?`${e.slug} has nothing on record yet. Its status is "${n.status}".`:o.map(r=>`${r.enabled?"[on] ":"[off]"} ${r.kind} ${r.name}${r.exposedAs?` -> ${r.exposedAs}`:""}${r.description?` \u2014 ${r.description}`:""}`).join(`
|
|
58
|
+
`)})}}var No=f.object({slug:J,tool:f.string().min(1).max(200),enabled:f.boolean()});function Ht(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:No,handler:e=>D(async()=>{let n=await me(t,e.slug);if(!n)return`Connection not found: ${e.slug}`;let{capabilities:o}=await t.listCapabilities(n.id),r=o.find(i=>i.kind==="tool"&&i.name===e.tool);return r?(await t.toggleCapability(n.id,r.id,e.enabled),`${e.slug}__${r.name} is now ${e.enabled?"on":"off"}.`):`${e.slug} offers no tool called ${e.tool}.`})}}import{z as y}from"zod";var Eo=t=>({content:[{type:"text",text:t}]}),q=t=>({content:[{type:"text",text:t}],isError:!0});async function $(t){try{return Eo(await t())}catch(e){if(e instanceof d){let n=Object.keys(e.params).length?` ${JSON.stringify(e.params)}`:"";return q(`${e.code}${n}`)}return q("errors.UNKNOWN")}}var L=y.string().min(1).max(64).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/,"errors.INVALID_NAME"),Po=y.object({name:L,body:y.string().max(2e5)});function Ft(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:Po,handler:e=>$(async()=>{let n=await t.putSkill(e.name,e.body);return`${n.name} ${n.updatedAt}`})}}var Ro=y.object({name:L});function Wt(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:Ro,handler:e=>$(async()=>(await t.deleteSkill(e.name),`Deleted skill ${e.name}`))}}var Lo=y.object({skill:L});function Bt(t){return{name:"list_skill_files",description:"List the companion files of one skill, with their size in bytes.",inputSchema:Lo,handler:e=>$(async()=>{let{files:n}=await t.getSkill(e.skill);return n.length===0?`${e.skill} has no companion files.`:n.map(o=>`${o.path} (${o.size} bytes, ${o.encoding})`).join(`
|
|
59
|
+
`)})}}var Oo=y.object({skill:L,path:y.string().min(1).max(256),content:y.string().max(3e6),encoding:y.enum(["utf8","base64"]).default("utf8")});function Kt(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:Oo,handler:e=>E(e.path)?$(async()=>{let n=await t.putSkillFile(e.skill,e.path,e.content,e.encoding);return`${e.skill}/${n.path} ${n.size} bytes`}):Promise.resolve(q("errors.INVALID_PATH"))}}var Mo=y.object({skill:L,path:y.string().min(1).max(256)});function Vt(t){return{name:"skill_file_delete",description:"Delete one companion file of a skill. The skill itself stays.",inputSchema:Mo,handler:e=>E(e.path)?$(async()=>(await t.deleteSkillFile(e.skill,e.path),`Deleted ${e.skill}/${e.path}`)):Promise.resolve(q("errors.INVALID_PATH"))}}var Uo=y.object({name:L,description:y.string().min(1).max(1e3),body:y.string().max(2e5),model:y.string().max(64).optional(),tools:y.array(y.string().max(128)).max(200).optional()});function Jt(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:Uo,handler:e=>$(async()=>{let n=await t.getAgent(e.name).catch(()=>null),o=await t.putAgent(e.name,{description:e.description,body:e.body,model:e.model??n?.model??void 0,tools:e.tools??n?.tools??[]});return`${o.name} ${o.updatedAt}`})}}var Do=y.object({name:L});function qt(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:Do,handler:e=>$(async()=>(await t.deleteAgent(e.name),`Deleted agent ${e.name}`))}}var jo=y.object({});function Yt(t){return{name:"list_memory",description:"List the paths of every memory file in this account, private and team, sorted by path.",inputSchema:jo,handler:()=>$(async()=>{let{files:e}=await t.listMemory();return e.length===0?"(none)":e.map(n=>n.path+R(n)).sort().join(`
|
|
60
|
+
`)})}}var zo=y.object({path:y.string().min(3).max(256)});function Xt(t){return{name:"memory_delete",description:"Delete one memory file. Moves it to the trash; it can be restored in the dashboard for the trash period (default 7 days).",inputSchema:zo,handler:e=>x(e.path)?$(async()=>(await t.deleteMemory(e.path),`Deleted ${e.path}`)):Promise.resolve(q("errors.INVALID_PATH"))}}import{z as I}from"zod";var ue=t=>({content:[{type:"text",text:t}]}),Y=t=>({content:[{type:"text",text:t}],isError:!0});async function De(t){try{return await t()}catch(e){if(e instanceof d){let n=Object.keys(e.params).length?` ${JSON.stringify(e.params)}`:"";return Y(`${e.code}${n}`)}return Y("errors.UNKNOWN")}}var Go=I.object({}),Zt=I.enum(["memory","skill","agent"]),Ho=I.object({kind:Zt,name:I.string().min(1).max(300),team:I.string().min(1).max(200)}),Fo=I.object({kind:Zt,team:I.string().min(1).max(200),name:I.string().min(1).max(300).optional(),id:I.string().uuid().optional()});async function Qt(t,e){let n=e.trim(),{teams:o}=await t.listTeams(),r=o.find(s=>s.id===n);if(r)return r;let i=o.filter(s=>s.name===n);if(i.length===1)return i[0];if(i.length>1){let s=i.map(a=>a.id).sort();return Y(`Several of your teams are named "${e}": ${s.join(", ")}. Pass the id as team.
|
|
61
|
+
errors.TEAM_AMBIGUOUS ${JSON.stringify({team:e,ids:s})}`)}return Y(`You are not in that team.
|
|
62
|
+
errors.NOT_A_MEMBER ${JSON.stringify({team:e})}`)}var en=t=>"content"in t;function tn(t){return{name:"list_teams",description:"List the teams this account is in, one per line: the team id, its name and your role in it.",inputSchema:Go,handler:e=>De(async()=>{let{teams:n}=await t.listTeams();if(n.length===0)return ue("(none)");let o=(r,i)=>r<i?-1:r>i?1:0;return ue([...n].sort((r,i)=>o(r.name,i.name)||o(r.id,i.id)).map(r=>`${r.id} ${r.name} ${r.role}`).join(`
|
|
63
|
+
`))})}}function nn(t){return{name:"team_share",description:"Move one of your own memory files, skills or agents into a team, so its members can use it. You need the right to create that kind of content in the team, the team must not hold an item of that name already, and a frozen team takes nothing new.",inputSchema:Ho,handler:e=>De(async()=>{let n=await Qt(t,e.team);return en(n)?n:(await t.shareWithTeam(n.id,{kind:e.kind,name:e.name}),ue(`Shared ${e.kind} ${e.name} with the team ${n.name}.`))})}}function on(t){return{name:"team_return",description:"Take an item out of a team and back under its owner. Name one of your own items, or pass the id of any item of the team if you may delete that kind of content there. The item keeps its owner, and the return is never refused on a quota.",inputSchema:Fo,handler:e=>e.name===void 0==(e.id===void 0)?Promise.resolve(Y("Invalid arguments: pass name or id, not both.")):De(async()=>{let n=await Qt(t,e.team);return en(n)?n:(await t.returnFromTeam(n.id,e.name!==void 0?{kind:e.kind,name:e.name}:{kind:e.kind,id:e.id}),ue(`Returned ${e.kind} ${e.name??e.id} from the team ${n.name}.`))})}}function rn(t,e){return[It(t),_t(t),Tt(t),Yt(t),Xt(t),Et(t),Pt(t),Rt(t),Lt(t),Ot(t),wt(t),vt(t,e),Ft(t),Wt(t),Bt(t),xt(t),Kt(t),Vt(t),Ct(t),lt(t,e),Jt(t),qt(t),Ut(t),Dt(t),jt(t),zt(t),Gt(t),Ht(t),tn(t),nn(t),on(t)]}function sn(t){return t.map(e=>{let n=$e[e.name];if(!n)throw new Error(`No title and annotations in the registry table for the tool ${e.name}`);return{name:e.name,title:n.title,description:e.description,inputSchema:Wo.toJSONSchema(e.inputSchema),annotations:n.annotations}})}async function an(){let t=et(),e=new Q(t,()=>tt.read()),n=new te,o=rn(e,n),r=await(async()=>{try{let[{skills:s},{agents:a},l]=await Promise.all([e.listSkills(),e.listAgents(),e.getMe().catch(()=>({brainvaultMode:!0}))]);return he(s.map(g=>g.name),a.map(g=>g.name),{brainvault:l.brainvaultMode!==!1})}catch{return he([],[])}})(),i=new Bo(Te(t,Z),{capabilities:{tools:{},resources:{},prompts:{}},instructions:r});i.setRequestHandler(Zo,async()=>({tools:sn(o)})),i.setRequestHandler(Xo,async s=>dt(e,s.params?.cursor)),i.setRequestHandler(Yo,async()=>({resourceTemplates:[...oe]})),i.setRequestHandler(Qo,async s=>pt(e,s.params.uri)),i.setRequestHandler(qo,async s=>ut(e,s.params?.cursor)),i.setRequestHandler(Jo,async s=>ft(e,s.params.name)),i.setRequestHandler(Vo,async s=>{let a=o.find(g=>g.name===s.params.name);if(!a)return{content:[{type:"text",text:"errors.UNKNOWN_TOOL"}],isError:!0};let l=a.inputSchema.safeParse(s.params.arguments??{});return l.success?a.handler(l.data):{content:[{type:"text",text:"errors.INVALID_ARGUMENTS"}],isError:!0}}),gt().then(s=>{for(let a of Be())bt(e,a,{ignore:s}).catch(()=>{})}).catch(()=>{}),await i.connect(new Ko)}await an();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "onlymcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
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",
|