@cachly-dev/mcp-server 0.10.182 → 0.10.183
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 +7 -3
- package/dist/src/index.js +1 -1
- package/dist/src/rangfolge-stellschrauben.js +1 -1
- package/glama.json +1 -1
- package/hooks/cachly-ambient-einblendung.mjs +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|

|
|
11
11
|
|
|
12
12
|
`@cachly-dev/mcp-server` connects [cachly](https://cachly.dev) to Claude Code, Cursor,
|
|
13
|
-
GitHub Copilot, Windsurf, Cline, Continue.dev and
|
|
13
|
+
GitHub Copilot, Windsurf, Cline, Continue.dev, Zed, Codex CLI and Gemini CLI over
|
|
14
14
|
[MCP](https://modelcontextprotocol.io). It offers 124 MCP tools. Your AI stores a
|
|
15
15
|
lesson after a fix, and finds it again when the same problem returns. Your Brain
|
|
16
16
|
(the store of your lessons) lives on EU servers.
|
|
@@ -104,6 +104,8 @@ entry points at this npm package.
|
|
|
104
104
|
|-------|---------------------|
|
|
105
105
|
| [Claude Code hooks: which event to use when](https://cachly.dev/docs/claude-code-hooks) | `SessionStart`, `UserPromptSubmit`, `PreToolUse`, `Stop` and more, sorted by when they fire. What each one can block, add and change. |
|
|
106
106
|
| [A UserPromptSubmit hook for Claude Code](https://cachly.dev/docs/claude-code-hooks/userpromptsubmit) | The stdin JSON, `additionalContext`, a working Node script and five traps to avoid. |
|
|
107
|
+
| The same hooks in [VS Code and Copilot CLI](https://cachly.dev/docs/claude-code-hooks#vscode), [Codex CLI](https://cachly.dev/docs/claude-code-hooks#codex) and [Gemini CLI](https://cachly.dev/docs/claude-code-hooks#gemini) | Which event takes context in each editor, and the exact file `setup` writes there. |
|
|
108
|
+
| Comparisons: [Supermemory](https://cachly.dev/docs/cachly-vs-supermemory), [Zep](https://cachly.dev/docs/cachly-vs-zep), [claude-mem](https://cachly.dev/docs/cachly-vs-claude-mem), [Basic Memory](https://cachly.dev/docs/cachly-vs-basic-memory), [mem0](https://cachly.dev/docs/cachly-vs-mem0), [Letta](https://cachly.dev/docs/cachly-vs-letta) | Side by side, each row with its source and a visible date, including when the other product fits better. |
|
|
107
109
|
| [EU-hosted MCP server: what leaves your machine](https://cachly.dev/docs/eu-hosted-mcp-memory-server) | Where data lands: storage in Germany, embeddings in the EU, the network edge, and a checklist. |
|
|
108
110
|
| [Lessons learned for coding agents](https://cachly.dev/docs/coding-agent-lessons-learned) | How to write a lesson your agent finds again: symptom, decisive fact first, what failed, files, a check. With examples and a `LESSONS.md`. |
|
|
109
111
|
| [JetBrains plugin guide](https://cachly.dev/docs/jetbrains) | What the plugin does, and how Claude Code, Junie and JetBrains AI Assistant use the Brain. |
|
|
@@ -309,9 +311,11 @@ Manual snippets are in [Manual Setup](#manual-setup).
|
|
|
309
311
|
| Editor / client | Auto-setup | Config file written | Global config | Notes |
|
|
310
312
|
|---|---|---|---|---|
|
|
311
313
|
| **Claude Code** | yes | `~/.claude/mcp.json` + `.mcp.json` | yes, always | Without a key: test Brain on the first tool call; browser sign-in only as fallback |
|
|
312
|
-
| **Cursor** | yes, detected via `.cursor/` | `.cursor/mcp.json` | no | Project-level; restart Cursor after setup |
|
|
314
|
+
| **Cursor** | yes, detected via `.cursor/` | `.cursor/mcp.json`, hooks in `.cursor/hooks.json` | no | Project-level; restart Cursor after setup. Lessons arrive with the first tool call of a turn |
|
|
313
315
|
| **Windsurf** | yes, detected via `.windsurf/` | `.windsurf/mcp.json` | no | Project-level; restart Windsurf after setup |
|
|
314
|
-
| **VS Code + Copilot** | yes, detected via `.vscode/` | `.vscode/mcp.json` | no | Needs the VS Code MCP support or Copilot chat |
|
|
316
|
+
| **VS Code + Copilot** | yes, detected via `.vscode/` | `.vscode/mcp.json`, hooks in `.github/hooks/cachly-ambient.json` | no | Needs the VS Code MCP support or Copilot chat. Briefing at session start, lessons before each prompt |
|
|
317
|
+
| **Codex CLI** | hooks yes, detected via `~/.codex` | hooks in `.codex/hooks.json` | no | Trust `.codex/` and confirm the hook once in `/hooks`. For the tools, `init --editor codex` prints the `codex mcp add` line |
|
|
318
|
+
| **Gemini CLI** | hooks yes, detected via `~/.gemini` | `hooks` in `.gemini/settings.json` | no | Lessons are appended to the prompt (`BeforeAgent`). For the tools, `init --editor gemini` prints the `gemini mcp add` line |
|
|
315
319
|
| **Cline** | yes, detected via VS Code | `.vscode/mcp.json` | no | Shares the config with Copilot; restart VS Code |
|
|
316
320
|
| **Continue.dev** | yes, detected via `.continue/` | `.continue/config.json` | no | Uses the `modelContextProtocolServers` key |
|
|
317
321
|
| **Zed** | yes, detected via `.zed/` | `.zed/settings.json` | no | Uses the `context_servers` key |
|
package/dist/src/index.js
CHANGED
|
@@ -123,7 +123,7 @@ description: Cachly AI Brain \u2014 persistent memory protocol (recall before ta
|
|
|
123
123
|
alwaysApply: true
|
|
124
124
|
---
|
|
125
125
|
|
|
126
|
-
`;async function St(e,t){const{writeFile:n,appendFile:s,readFile:o,mkdir:c}=await import("node:fs/promises"),{existsSync:i}=await import("node:fs"),{resolve:a,dirname:g}=await import("node:path"),d=[{path:a(e,"CLAUDE.md")},{path:a(e,"AGENTS.md")},{path:a(e,".github","copilot-instructions.md")},{path:a(e,".cursor","rules","cachly.mdc"),prefix:Un},{path:a(e,".windsurfrules")},{path:a(e,".clinerules")}],l=`
|
|
126
|
+
`;async function St(e,t){const{writeFile:n,appendFile:s,readFile:o,mkdir:c}=await import("node:fs/promises"),{existsSync:i}=await import("node:fs"),{resolve:a,dirname:g}=await import("node:path"),d=[{path:a(e,"CLAUDE.md")},{path:a(e,"AGENTS.md")},{path:a(e,".github","copilot-instructions.md")},{path:a(e,".cursor","rules","cachly.mdc"),prefix:Un},{path:a(e,".windsurfrules")},{path:a(e,".clinerules")},...i(a(e,".idea"))?[{path:a(e,".aiassistant","rules","cachly.md")}]:[]],l=`
|
|
127
127
|
`+Ct(t)+`
|
|
128
128
|
`,p={};for(const{path:y,prefix:w}of d){if(await c(g(y),{recursive:!0}),i(y)){const b=await o(y,"utf-8");if(b.includes(Ee)){const u=b.replace(new RegExp(`${Ee}[\\s\\S]*?${wt}`),Ct(t));await n(y,u,"utf-8"),p[y]="updated";continue}await s(y,l,"utf-8"),p[y]="appended";continue}await n(y,(w??"")+l.trimStart(),"utf-8"),p[y]="written"}return p}if(process.argv[2]==="digest"){const e=process.env.CACHLY_JWT??"",t=process.env.CACHLY_BRAIN_INSTANCE_ID??"";(!e||!t)&&(console.log(`
|
|
129
129
|
\u26A0\uFE0F CACHLY_JWT and CACHLY_BRAIN_INSTANCE_ID must be set.`),console.log(` Run: npx @cachly-dev/mcp-server@latest autopilot
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const E=75,o=.5,t=.7,L="qwen3-embedding:0.6b",_=1,N=.8,I=.9,e=1,n=.35,c=.35,p=.05,r=1,s=1,x=25,G=
|
|
1
|
+
const E=75,o=.5,t=.7,L="qwen3-embedding:0.6b",_=1,N=.8,I=.9,e=1,n=.35,c=.35,p=.05,r=1,s=1,x=25,G=15,T=2500,S=1500,C=.5,H=.5;export{p as ABLEHN_ABSTAND,c as CKG_BELEG_SCHWELLE,C as EINBLENDUNG_DECKUNG,H as EINBLENDUNG_ZEUGE,o as EINGANG_SCHWELLE,t as EINGANG_SORTIER_GEWICHT,s as LESER_GEWICHT,S as LESER_MAX_ZEICHEN,x as LESER_TIEFE,G as LESER_TIEFE_EINBLENDUNG,T as LESER_ZEITLIMIT_MS,I as NAHDUPLIKAT_SCHWELLE,r as SELTENHEIT_LAENGE_B,n as SINN_BELEG_SCHWELLE,E as SINN_TOPF,e as WORT_BELEG_SCHWELLE,_ as ZWEIT_GEWICHT,N as ZWEIT_MINDESTDECKUNG,L as ZWEIT_MODELL};
|
package/glama.json
CHANGED
|
@@ -15,7 +15,7 @@ ${e}
|
|
|
15
15
|
</${se}>`:""}var Cn=/(?:^|__)(learn_from_attempts|remember_context|session_end|session_handoff|team_learn|global_learn|auto_learn_session)$/,In=/^\s*(✋|⛔|Error\b|Fehler\b|Update abgewiesen|Rejected)/i,at=/\bBeleg:\s*`?([0-9a-f]{8})`?/gi,Nn=[/\b(lektion(en)?|lesson|brain|gedaechtnis|gedächtnis|memory|cachly)\b[^.\n]{0,80}\b(gespeichert|abgelegt|eingetragen|festgehalten|hinterlegt|geschrieben|stored|saved|recorded|persisted)\b/i,/\b(gespeichert|abgelegt|eingetragen|festgehalten|hinterlegt|geschrieben|stored|saved|recorded|persisted|learned)\b[^.\n]{0,40}\b(im|ins|in the|to the|to|into)\s+(brain|gedaechtnis|gedächtnis|memory)\b/i,/\b(als|as an?)\s+(?!(?:die|der|das|den|dem|the)\b)(?:[\wäöüß-]+\s+){0,2}(lektion|lesson)\b/i];var zn=/\?\s*$|\b(soll ich|kann ich|darf ich|moechtest|möchtest|willst|wenn du|falls du|shall i|should i|would you|want me to|if you)\b/i,ut="(?:die ki|das modell|der agent|der assistent|the (?:ai|model|agent|assistant)|claude)",ct="(?:wenn|ob|falls|dass|behauptet|if|whether|claims?|says?)",Tn=new RegExp(`\\b${ut}\\b[^.\\n]*?\\b${ct}\\b|\\b${ct}\\b[^.\\n]*?\\b${ut}\\b`,"i"),Rn=/„[^“”"\n]*[“”"]|“[^”\n]*”|"[^"\n]*"|»[^«\n]*«|«[^»\n]*»|‚[^‘’\n]*[‘’]|(?<![\p{L}\p{N}])'[^'\n]*'(?![\p{L}\p{N}])/gu,Pn=/\b(sei|seien)\b|\b(sagt|sagte|meint|meinte|schreibt|schrieb|behauptet)\s+(er|sie|es|man)\b|\blaut\b|\baccording to\b|\b(he|she|they)\s+(says?|said|claims?|claimed|wrote)\b/i;function On(t){return t.replace(Rn," ")}function jn(t){return t.split(/\n+/).filter(e=>!e.trim().startsWith("|")).map(On).flatMap(e=>e.split(/(?<=[.!?])\s+/)).some(e=>!zn.test(e)&&!Tn.test(e)&&!Pn.test(e)&&Nn.some(n=>n.test(e)))}function oe(t){let e=t.message?.content;return typeof e=="string"?[{type:"text",text:e}]:Array.isArray(e)?e:[]}function Mn(t){return typeof t.content=="string"?t.content:Array.isArray(t.content)?t.content.map(e=>typeof e?.text=="string"?e.text:"").join(`
|
|
16
16
|
`):""}function Hn(t){if(t.type!=="user"||t.isMeta||t.origin?.kind&&t.origin.kind!=="human")return!1;let e=oe(t).filter(n=>n.type==="text").map(n=>n.text??"").join("");return e?!/^\s*<(task-notification|local-command|command-name|system-reminder)/.test(e):!1}function Wn(t){let e=[];for(let l of t)if(l.trim())try{let d=JSON.parse(l);d&&!d.isSidechain&&(d.type==="user"||d.type==="assistant")&&e.push(d)}catch{}let n=0;for(let l=e.length-1;l>=0;l--)if(Hn(e[l])){n=l+1;break}let r=e.slice(n),o=new Set,s="";for(let l of r)if(l.type==="assistant")for(let d of oe(l))d.type==="text"&&d.text&&(s+=`${d.text}
|
|
17
17
|
`),d.type==="tool_use"&&d.id&&Cn.test(d.name??"")&&o.add(d.id);let c=0,a="";for(let l of r)if(l.type==="user")for(let d of oe(l)){if(d.type!=="tool_result")continue;let f=Mn(d);a+=`${f}
|
|
18
|
-
`,d.tool_use_id&&o.has(d.tool_use_id)&&!d.is_error&&!In.test(f)&&c++}let g=new Set([...a.matchAll(at)].map(l=>l[1].toLowerCase())),u=[...s.matchAll(at)].map(l=>l[1].toLowerCase()),i=[...new Set(u.filter(l=>!g.has(l)))];return{behauptet:jn(s),schreibaufrufe:o.size,erfolgreich:c,erfundeneBelege:i}}function ie(t,e){if(e)return"";let n=Wn(t),r=[];return n.erfundeneBelege.length&&r.push(`Die Antwort nennt Beleg ${n.erfundeneBelege.join(", ")}, den kein cachly-Werkzeug in diesem Zug ausgegeben hat.`),n.behauptet&&n.erfolgreich===0&&r.push(n.schreibaufrufe>0?"Die Antwort meldet eine Speicherung im Brain, aber der Schreibaufruf wurde abgewiesen oder schlug fehl.":"Die Antwort meldet eine Speicherung im Brain, aber in diesem Zug lief kein Schreibaufruf (learn_from_attempts, remember_context, session_end)."),r.length?JSON.stringify({decision:"block",reason:`cachly Schreibbeleg: ${r.join(" ")} Speichere jetzt wirklich oder korrigiere die Aussage gegenueber dem Nutzer. Bezieht sich die Aussage auf eine fruehere Speicherung, sag das ausdruecklich.`}):""}var Fn=75,Kn=["topic","outcome","what_worked","what_failed","severity","confidence","recall_count","ts","endorsements"],lt=new Set("the a an and or but for to of in on at is are be do does did we you i it this that with without how what why when where can could would should please just get set use using make made need bitte und oder der die das ein eine f\xFCr mit ohne wie was warum kann soll noch mal auch von den dem ist weil wenn dann doch aber alle jede jeder jedes immer wieder wird werden wurde muss beim sehr nicht".split(/\s+/)),$n=["ierungen","ierung","ieren","iert","ungen","ung","heit","keit","lich","isch","ing","ed","en","er","es","e","n","s"];function Gn(t){for(let e of $n)if(t.length-e.length>=4&&t.endsWith(e))return t.slice(0,-e.length);return t}function ae(t){return[...new Set(String(t).toLowerCase().split(/[^a-z0-9]+/).filter(e=>e.length>3&&!lt.has(e)).map(Gn).filter(e=>!lt.has(e)))]}function Yn(t,e){let n=0;for(let r of t)e.includes(r)&&n++;return n}var F=class{constructor(e,{topf:n=Fn}={}){this.lektionen=e;this.topf=n,this.texte=e.map(o=>Re(o)),this.wortmengen=this.texte.map(o=>new Set([...W(o)].map(Te))),this.heuhaufen=this.texte.map(o=>o.toLowerCase()),this.statistik=new T(this.texte);let r=e.map((o,s)=>{let c=`cachly:lesson:best:${String(o.topic??s)}`;this.platzVonSchluessel.set(c,s);let a={};for(let g of Kn)o[g]!==void 0&&(a[g]=o[g]);return{key:c,content:JSON.stringify(a)}});this.wortbestand=rt(r)}lektionen;texte;wortmengen;heuhaufen;statistik;wortbestand;platzVonSchluessel=new Map;topf;get groesse(){return this.lektionen.length}sortiere(e){if(!this.wortbestand)return[];let n=st(this.wortbestand,e,this.topf),r=[],o=[];for(let u of n){let i=this.platzVonSchluessel.get(u.key);i!==void 0&&(r.push(i),o.push(u.score))}if(r.length===0)return[];let s=W(e),c=ae(e),a=Q(o),g=Q(r.map(u=>this.statistik.besterZeuge(s,this.wortmengen[u])));return r.map((u,i)=>({lektion:this.lektionen[u],punkte:a[i]+.5*this.statistik.deckung(s,this.wortmengen[u])+.5*g[i],belege:Yn(c,this.heuhaufen[u])})).sort((u,i)=>i.punkte-u.punkte||Number(i.lektion.recall_count??0)-Number(u.lektion.recall_count??0))}};var qn={apiUrl:process.env.CACHLY_API_URL??"https://api.cachly.dev",jwt:process.env.CACHLY_JWT??"",model:process.env.CACHLY_EMBED_MODEL??""};var Vs=Number(process.env.CACHLY_EMBED_TIMEOUT_MS??8e3),Xs=Number(process.env.CACHLY_EMBED_TIMEOUT_MAX_MS??45e3);function Zn(){return process.env.CACHLY_JWT?"cachly":process.env.OLLAMA_BASE_URL?"ollama":"none"}var Qs=!!process.env.CACHLY_EMBED_PROVIDER,eo=(process.env.CACHLY_EMBED_PROVIDER??Zn()).toLowerCase();import{readFileSync as Jn,writeFileSync as Vn,renameSync as Xn,mkdirSync as Qn,rmSync as er}from"node:fs";import{dirname as tr}from"node:path";var K=3,ue=10*6e4,dt={fehlschlaege:0,offenBis:0};function ce(){return["0","off","aus","false"].includes(String(process.env.CACHLY_LESER_SICHERUNG??"").toLowerCase())}function nr(t){return t===503?"abgeschaltet":t>=500?"fehlschlag":"neutral"}function rr(t){return t?.name==="SyntaxError"?"neutral":"fehlschlag"}function gt(t){let e=t??{},n=r=>typeof r=="number"&&Number.isFinite(r)&&r>0?r:0;return{fehlschlaege:Math.floor(n(e.fehlschlaege)),offenBis:n(e.offenBis)}}var R=class{constructor(e,n=()=>Date.now()){this.speicher=e;this.jetzt=n}speicher;jetzt;offen(){if(ce())return!1;let e=this.speicher.lies();if(e.fehlschlaege<K)return!1;let n=this.jetzt();return n<e.offenBis&&e.offenBis-n<=ue}darfFragen(){if(ce())return!0;if(this.offen())return!1;let e=this.speicher.lies();return e.fehlschlaege>=K&&this.speicher.schreib({fehlschlaege:e.fehlschlaege,offenBis:this.jetzt()+ue}),!0}melde(e){if(e==="neutral"||ce())return;let n=this.speicher.lies();if(e==="erfolg"){(n.fehlschlaege!==0||n.offenBis!==0)&&this.speicher.schreib({...dt});return}let r=e==="abgeschaltet"?Math.max(n.fehlschlaege+1,K):n.fehlschlaege+1;this.speicher.schreib({fehlschlaege:r,offenBis:r>=K?this.jetzt()+ue:0})}},le={art:"ohne"};async function ge(t,e){if(!e.darfFragen())return{art:"uebersprungen"};let n=t.fetchFn??fetch;try{let r=await n(t.url,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t.jwt}`,...t.zusatzKopf??{}},body:JSON.stringify({query:t.frage,texts:t.texte,instance_id:t.instanceId}),signal:AbortSignal.timeout(t.zeitlimitMs)});if(!r.ok)return e.melde(nr(r.status)),le;let o=await r.json(),s=Array.isArray(o?.scores)?o.scores:null;return!s||s.length!==t.texte.length||!s.every(c=>typeof c=="number"&&Number.isFinite(c))?le:(e.melde("erfolg"),{art:"punkte",scores:s,provider:typeof o.provider=="string"?o.provider:"?",ms:Number(o.ms)||0})}catch(r){return e.melde(rr(r)),le}}function ft(t){return{lies:()=>{try{return gt(JSON.parse(Jn(t,"utf8")))}catch{return{...dt}}},schreib:e=>{let n=`${t}.${process.pid}.tmp`;try{Qn(tr(t),{recursive:!0}),Vn(n,JSON.stringify(gt(e)),{mode:384}),Xn(n,t)}catch{try{er(n,{force:!0})}catch{}}}}}function ht(t,e,n=1){let r=c=>{let a=Math.min(...c),g=Math.max(...c);return g>a?c.map(u=>(u-a)/(g-a)):c.map(()=>0)},o=r(t),s=r(e);return t.map((c,a)=>({i:a,p:o[a]+n*s[a]})).sort((c,a)=>a.p-c.p||c.i-a.i).map(c=>c.i)}var pr=600*1e3,Et=8e3,hr=60*1e3,mt=120,_t=
|
|
18
|
+
`,d.tool_use_id&&o.has(d.tool_use_id)&&!d.is_error&&!In.test(f)&&c++}let g=new Set([...a.matchAll(at)].map(l=>l[1].toLowerCase())),u=[...s.matchAll(at)].map(l=>l[1].toLowerCase()),i=[...new Set(u.filter(l=>!g.has(l)))];return{behauptet:jn(s),schreibaufrufe:o.size,erfolgreich:c,erfundeneBelege:i}}function ie(t,e){if(e)return"";let n=Wn(t),r=[];return n.erfundeneBelege.length&&r.push(`Die Antwort nennt Beleg ${n.erfundeneBelege.join(", ")}, den kein cachly-Werkzeug in diesem Zug ausgegeben hat.`),n.behauptet&&n.erfolgreich===0&&r.push(n.schreibaufrufe>0?"Die Antwort meldet eine Speicherung im Brain, aber der Schreibaufruf wurde abgewiesen oder schlug fehl.":"Die Antwort meldet eine Speicherung im Brain, aber in diesem Zug lief kein Schreibaufruf (learn_from_attempts, remember_context, session_end)."),r.length?JSON.stringify({decision:"block",reason:`cachly Schreibbeleg: ${r.join(" ")} Speichere jetzt wirklich oder korrigiere die Aussage gegenueber dem Nutzer. Bezieht sich die Aussage auf eine fruehere Speicherung, sag das ausdruecklich.`}):""}var Fn=75,Kn=["topic","outcome","what_worked","what_failed","severity","confidence","recall_count","ts","endorsements"],lt=new Set("the a an and or but for to of in on at is are be do does did we you i it this that with without how what why when where can could would should please just get set use using make made need bitte und oder der die das ein eine f\xFCr mit ohne wie was warum kann soll noch mal auch von den dem ist weil wenn dann doch aber alle jede jeder jedes immer wieder wird werden wurde muss beim sehr nicht".split(/\s+/)),$n=["ierungen","ierung","ieren","iert","ungen","ung","heit","keit","lich","isch","ing","ed","en","er","es","e","n","s"];function Gn(t){for(let e of $n)if(t.length-e.length>=4&&t.endsWith(e))return t.slice(0,-e.length);return t}function ae(t){return[...new Set(String(t).toLowerCase().split(/[^a-z0-9]+/).filter(e=>e.length>3&&!lt.has(e)).map(Gn).filter(e=>!lt.has(e)))]}function Yn(t,e){let n=0;for(let r of t)e.includes(r)&&n++;return n}var F=class{constructor(e,{topf:n=Fn}={}){this.lektionen=e;this.topf=n,this.texte=e.map(o=>Re(o)),this.wortmengen=this.texte.map(o=>new Set([...W(o)].map(Te))),this.heuhaufen=this.texte.map(o=>o.toLowerCase()),this.statistik=new T(this.texte);let r=e.map((o,s)=>{let c=`cachly:lesson:best:${String(o.topic??s)}`;this.platzVonSchluessel.set(c,s);let a={};for(let g of Kn)o[g]!==void 0&&(a[g]=o[g]);return{key:c,content:JSON.stringify(a)}});this.wortbestand=rt(r)}lektionen;texte;wortmengen;heuhaufen;statistik;wortbestand;platzVonSchluessel=new Map;topf;get groesse(){return this.lektionen.length}sortiere(e){if(!this.wortbestand)return[];let n=st(this.wortbestand,e,this.topf),r=[],o=[];for(let u of n){let i=this.platzVonSchluessel.get(u.key);i!==void 0&&(r.push(i),o.push(u.score))}if(r.length===0)return[];let s=W(e),c=ae(e),a=Q(o),g=Q(r.map(u=>this.statistik.besterZeuge(s,this.wortmengen[u])));return r.map((u,i)=>({lektion:this.lektionen[u],punkte:a[i]+.5*this.statistik.deckung(s,this.wortmengen[u])+.5*g[i],belege:Yn(c,this.heuhaufen[u])})).sort((u,i)=>i.punkte-u.punkte||Number(i.lektion.recall_count??0)-Number(u.lektion.recall_count??0))}};var qn={apiUrl:process.env.CACHLY_API_URL??"https://api.cachly.dev",jwt:process.env.CACHLY_JWT??"",model:process.env.CACHLY_EMBED_MODEL??""};var Vs=Number(process.env.CACHLY_EMBED_TIMEOUT_MS??8e3),Xs=Number(process.env.CACHLY_EMBED_TIMEOUT_MAX_MS??45e3);function Zn(){return process.env.CACHLY_JWT?"cachly":process.env.OLLAMA_BASE_URL?"ollama":"none"}var Qs=!!process.env.CACHLY_EMBED_PROVIDER,eo=(process.env.CACHLY_EMBED_PROVIDER??Zn()).toLowerCase();import{readFileSync as Jn,writeFileSync as Vn,renameSync as Xn,mkdirSync as Qn,rmSync as er}from"node:fs";import{dirname as tr}from"node:path";var K=3,ue=10*6e4,dt={fehlschlaege:0,offenBis:0};function ce(){return["0","off","aus","false"].includes(String(process.env.CACHLY_LESER_SICHERUNG??"").toLowerCase())}function nr(t){return t===503?"abgeschaltet":t>=500?"fehlschlag":"neutral"}function rr(t){return t?.name==="SyntaxError"?"neutral":"fehlschlag"}function gt(t){let e=t??{},n=r=>typeof r=="number"&&Number.isFinite(r)&&r>0?r:0;return{fehlschlaege:Math.floor(n(e.fehlschlaege)),offenBis:n(e.offenBis)}}var R=class{constructor(e,n=()=>Date.now()){this.speicher=e;this.jetzt=n}speicher;jetzt;offen(){if(ce())return!1;let e=this.speicher.lies();if(e.fehlschlaege<K)return!1;let n=this.jetzt();return n<e.offenBis&&e.offenBis-n<=ue}darfFragen(){if(ce())return!0;if(this.offen())return!1;let e=this.speicher.lies();return e.fehlschlaege>=K&&this.speicher.schreib({fehlschlaege:e.fehlschlaege,offenBis:this.jetzt()+ue}),!0}melde(e){if(e==="neutral"||ce())return;let n=this.speicher.lies();if(e==="erfolg"){(n.fehlschlaege!==0||n.offenBis!==0)&&this.speicher.schreib({...dt});return}let r=e==="abgeschaltet"?Math.max(n.fehlschlaege+1,K):n.fehlschlaege+1;this.speicher.schreib({fehlschlaege:r,offenBis:r>=K?this.jetzt()+ue:0})}},le={art:"ohne"};async function ge(t,e){if(!e.darfFragen())return{art:"uebersprungen"};let n=t.fetchFn??fetch;try{let r=await n(t.url,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t.jwt}`,...t.zusatzKopf??{}},body:JSON.stringify({query:t.frage,texts:t.texte,instance_id:t.instanceId}),signal:AbortSignal.timeout(t.zeitlimitMs)});if(!r.ok)return e.melde(nr(r.status)),le;let o=await r.json(),s=Array.isArray(o?.scores)?o.scores:null;return!s||s.length!==t.texte.length||!s.every(c=>typeof c=="number"&&Number.isFinite(c))?le:(e.melde("erfolg"),{art:"punkte",scores:s,provider:typeof o.provider=="string"?o.provider:"?",ms:Number(o.ms)||0})}catch(r){return e.melde(rr(r)),le}}function ft(t){return{lies:()=>{try{return gt(JSON.parse(Jn(t,"utf8")))}catch{return{...dt}}},schreib:e=>{let n=`${t}.${process.pid}.tmp`;try{Qn(tr(t),{recursive:!0}),Vn(n,JSON.stringify(gt(e)),{mode:384}),Xn(n,t)}catch{try{er(n,{force:!0})}catch{}}}}}function ht(t,e,n=1){let r=c=>{let a=Math.min(...c),g=Math.max(...c);return g>a?c.map(u=>(u-a)/(g-a)):c.map(()=>0)},o=r(t),s=r(e);return t.map((c,a)=>({i:a,p:o[a]+n*s[a]})).sort((c,a)=>a.p-c.p||c.i-a.i).map(c=>c.i)}var pr=600*1e3,Et=8e3,hr=60*1e3,mt=120,_t=15,mr=1500,St=2500,br=$(G(),"cachly-ambient-netlog.jsonl");function de(t){return dr("sha1").update(t).digest("hex").slice(0,12)}function yr(t){return $(G(),`cachly-ambient-bestand-${de(t)}.json`)}function kr(t){return $(G(),`cachly-leser-sicherung-${de(t)}.json`)}function wr(t){return $(G(),`cachly-ambient-auffrischen-${de(t)}.lock`)}async function bt(t,{fetchFn:e=fetch,zeitlimitMs:n=Et}={}){try{let r=await e(`${t.apiUrl}/api/v1/instances/${t.instanceId}/export`,{headers:{Authorization:`Bearer ${t.jwt}`},signal:AbortSignal.timeout(n)});if(!r.ok)return null;let o=await r.json();return Array.isArray(o?.lessons)?o.lessons.map(s=>typeof s=="string"?Er(s):s).filter(s=>!!s&&typeof s=="object"):null}catch{return null}}function Er(t){try{return JSON.parse(t)}catch{return null}}function yt(t,e){try{ur(gr(t),{recursive:!0}),wt(t,JSON.stringify({at:Date.now(),lessons:e}),{mode:384})}catch{}}function kt(t){try{let e=JSON.parse(ir(t,"utf8"));if(Array.isArray(e?.lessons))return{at:Number(e.at)||0,lessons:e.lessons}}catch{}return null}function _r(t,e){let n=wr(t.instanceId);try{if(ar(n)&&Date.now()-cr(n).mtimeMs<hr)return;wt(n,String(Date.now()),{mode:384})}catch{return}try{fr(process.execPath,e,{detached:!0,stdio:"ignore",env:{...process.env,CACHLY_API_URL:t.apiUrl,CACHLY_JWT:t.jwt,CACHLY_BRAIN_INSTANCE_ID:t.instanceId}}).unref()}catch{}}async function P(t,{force:e=!1,nebenlauf:n,abrufMs:r=Et,fetchFn:o}={}){if(!t.jwt||!t.instanceId)return{lessons:[],quelle:"nicht-eingerichtet"};let s=yr(t.instanceId);if(e){let g=await bt(t,{fetchFn:o,zeitlimitMs:r});if(g)return yt(s,g),{lessons:g,quelle:"server"};let u=kt(s);return u?{lessons:u.lessons,quelle:"platte-alt"}:{lessons:[],quelle:"server-nicht-erreichbar"}}let c=kt(s);if(c){let g=Date.now()-c.at<pr;return!g&&n&&_r(t,n),{lessons:c.lessons,quelle:g?"platte":"platte-alt"}}let a=await bt(t,{fetchFn:o,zeitlimitMs:r});return a?(yt(s,a),{lessons:a,quelle:"server"}):{lessons:[],quelle:"server-nicht-erreichbar"}}function O(t){return Math.ceil(String(t).length/4)}function fe(t){let e=t.severity?`[${t.severity}] `:"",n=String(t.what_worked??"").replace(/\s+/g," ").trim(),r=n.length>mt?`${n.slice(0,mt)}\u2026`:n;return`- ${e}${t.topic}: ${r}`}var Sr={lessons:[],tokens:0,topScore:0,belege:0};function vr(t,e,n){let r=[],o=0;for(let{lektion:s}of t.slice(0,e)){let c=O(fe(s));if(o+c>n)break;r.push(s),o+=c}return{lessons:r,tokens:o,topScore:Math.round(t[0].punkte*100)/100,belege:t[0].belege}}function xr(t){return Pe(t,mr)}async function Ar(t,e,n,{zeitlimitMs:r=St,fetchFn:o}={}){if(!t?.jwt||!t?.instanceId||n.length===0)return{art:"ohne"};if(["0","off","aus","false"].includes(String(process.env.CACHLY_LESER||"").toLowerCase()))return{art:"ohne"};let s=new R(ft(kr(t.instanceId)));return ge({url:`${t.apiUrl}/api/v1/rerank`,jwt:t.jwt,frage:e,texte:n,instanceId:t.instanceId,zeitlimitMs:r,fetchFn:o},s)}async function Lr(t,e,n,{minBelege:r=2,topK:o=3,tokenBudget:s=600,tiefe:c=_t,zeitlimitMs:a=St,fetchFn:g}={}){let u={...Sr,leser:"aus",leserMs:0};if(!Array.isArray(e)||e.length===0||ae(t).length===0)return u;let i=new F(e).sortiere(t).filter(f=>f.belege>=r);if(i.length===0)return u;let l="aus",d=0;if(i.length>1&&c>0){let f=i.slice(0,c),y=i.slice(c),_=await Ar(n,t,f.map(N=>xr(N.lektion)),{zeitlimitMs:a,fetchFn:g});_.art==="punkte"?(i=[...ht(f.map(v=>v.punkte),_.scores,1).map(v=>f[v]),...y],l=_.provider,d=_.ms):_.art==="uebersprungen"&&(l="uebersprungen")}return{...vr(i,o,s),leser:l,leserMs:d}}function Cr(t){if(!t.lessons.length)return"";let e=t.lessons.map(fe).join(`
|
|
19
19
|
`);return`\u{1F9E0} Cachly Brain \u2014 relevant lessons for this task (auto-recall, ${t.lessons.length}):
|
|
20
20
|
${D(e)}
|
|
21
21
|
(ambient-recall \xB7 ~${t.tokens} tokens \xB7 match score ${t.topScore})`}var Ir=5;function vt(t){if(!t.length)return"";let e=t.filter(o=>{let s=String(o.topic??"");return!(/^auto:/.test(s)||/^[a-z]+:?$/.test(s))}),r=[...e.length?e:t].sort((o,s)=>(Number(s.recall_count)||0)-(Number(o.recall_count)||0)).slice(0,Ir).map(fe).join(`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cachly-dev/mcp-server",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.183",
|
|
4
4
|
"mcpName": "io.github.cachly-dev/mcp-server",
|
|
5
5
|
"description": "Solve it once. From then on, your AI knows. Experience for coding agents, EU-hosted: 124 MCP tools for Claude Code, Cursor, Copilot & Windsurf. Learns from every bug fix, commit and CI run.",
|
|
6
6
|
"type": "module",
|
package/server.json
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
"url": "https://github.com/cachly-dev/cachly-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.10.
|
|
9
|
+
"version": "0.10.183",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"name": "@cachly-dev/mcp-server",
|
|
14
14
|
"identifier": "@cachly-dev/mcp-server",
|
|
15
|
-
"version": "0.10.
|
|
15
|
+
"version": "0.10.183",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
}
|