@curenorway/kode-mcp 1.6.0 → 1.8.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/dist/index.js +111 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -154,6 +154,13 @@ var KodeApiClient = class {
|
|
|
154
154
|
body: JSON.stringify({ siteId, url })
|
|
155
155
|
});
|
|
156
156
|
}
|
|
157
|
+
// Library operations
|
|
158
|
+
async listLibrary(queryString) {
|
|
159
|
+
return this.request(`/api/cdn/library${queryString || ""}`);
|
|
160
|
+
}
|
|
161
|
+
async getLibrarySnippet(slugOrId) {
|
|
162
|
+
return this.request(`/api/cdn/library/${encodeURIComponent(slugOrId)}`);
|
|
163
|
+
}
|
|
157
164
|
// Validate API key
|
|
158
165
|
async validateKey() {
|
|
159
166
|
try {
|
|
@@ -832,6 +839,56 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
832
839
|
},
|
|
833
840
|
required: []
|
|
834
841
|
}
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
name: "kode_library_list",
|
|
845
|
+
description: "List all snippets in the global Kode library (Bibliotek). Returns reusable code patterns like GSAP animations, form handlers, scroll effects. Use this before writing common patterns from scratch.",
|
|
846
|
+
inputSchema: {
|
|
847
|
+
type: "object",
|
|
848
|
+
properties: {
|
|
849
|
+
category: {
|
|
850
|
+
type: "string",
|
|
851
|
+
description: "Filter by category: animations, forms, utilities, tracking, analytics, consent, integrations, other"
|
|
852
|
+
},
|
|
853
|
+
search: {
|
|
854
|
+
type: "string",
|
|
855
|
+
description: "Search by name or tags"
|
|
856
|
+
}
|
|
857
|
+
},
|
|
858
|
+
required: []
|
|
859
|
+
}
|
|
860
|
+
},
|
|
861
|
+
{
|
|
862
|
+
name: "kode_library_get",
|
|
863
|
+
description: "Get a library snippet by slug or ID. Returns full code, description, tags, example usage, and version.",
|
|
864
|
+
inputSchema: {
|
|
865
|
+
type: "object",
|
|
866
|
+
properties: {
|
|
867
|
+
slug: {
|
|
868
|
+
type: "string",
|
|
869
|
+
description: "Snippet slug or ID"
|
|
870
|
+
}
|
|
871
|
+
},
|
|
872
|
+
required: ["slug"]
|
|
873
|
+
}
|
|
874
|
+
},
|
|
875
|
+
{
|
|
876
|
+
name: "kode_library_use",
|
|
877
|
+
description: "Copy a library snippet into the current project as a new script file. The snippet code is written to .cure-kode-scripts/{slug}.{ext}. Use kode_push afterwards to upload to CDN.",
|
|
878
|
+
inputSchema: {
|
|
879
|
+
type: "object",
|
|
880
|
+
properties: {
|
|
881
|
+
snippetSlug: {
|
|
882
|
+
type: "string",
|
|
883
|
+
description: "Library snippet slug to copy"
|
|
884
|
+
},
|
|
885
|
+
newName: {
|
|
886
|
+
type: "string",
|
|
887
|
+
description: "Optional new filename (without extension). Defaults to the snippet slug."
|
|
888
|
+
}
|
|
889
|
+
},
|
|
890
|
+
required: ["snippetSlug"]
|
|
891
|
+
}
|
|
835
892
|
}
|
|
836
893
|
]
|
|
837
894
|
};
|
|
@@ -2540,12 +2597,16 @@ Use kode_list_pages_context to see cached pages, or kode_refresh_page to cache a
|
|
|
2540
2597
|
try {
|
|
2541
2598
|
const scripts = await client.listScripts(siteId);
|
|
2542
2599
|
const pages = await client.listPages(siteId);
|
|
2600
|
+
const deployStatus = await client.getDeploymentStatus(siteId).catch(() => null);
|
|
2601
|
+
const productionEnabled = deployStatus?.productionEnabled ?? false;
|
|
2543
2602
|
let text = `Documentation synced:
|
|
2544
2603
|
|
|
2545
2604
|
`;
|
|
2546
2605
|
text += `Scripts: ${scripts.length}
|
|
2547
2606
|
`;
|
|
2548
2607
|
text += `Pages: ${pages.length}
|
|
2608
|
+
`;
|
|
2609
|
+
text += `Production: ${productionEnabled ? "Enabled" : "Disabled (staging only)"}
|
|
2549
2610
|
|
|
2550
2611
|
`;
|
|
2551
2612
|
if (scripts.length > 0) {
|
|
@@ -2584,13 +2645,16 @@ Use kode_list_pages_context to see cached pages, or kode_refresh_page to cache a
|
|
|
2584
2645
|
`;
|
|
2585
2646
|
kodeMd += `> **This file is auto-generated.** Do not edit manually.
|
|
2586
2647
|
|
|
2648
|
+
`;
|
|
2649
|
+
kodeMd += `**Produksjon:** ${productionEnabled ? "\u2713 Aktivert \u2014 deploy til staging og produksjon" : "\u25CB Deaktivert \u2014 kun staging. Ikke hent fra produksjons-URL."}
|
|
2650
|
+
|
|
2587
2651
|
---
|
|
2588
2652
|
|
|
2589
2653
|
`;
|
|
2590
2654
|
kodeMd += `## CDN URL
|
|
2591
2655
|
|
|
2592
2656
|
\`\`\`html
|
|
2593
|
-
<script
|
|
2657
|
+
<script src="https://app.cure.no/api/cdn/${siteSlug}/init.js"></script>
|
|
2594
2658
|
\`\`\`
|
|
2595
2659
|
|
|
2596
2660
|
---
|
|
@@ -2686,6 +2750,52 @@ Full documentation: [.cure-kode/KODE.md](.cure-kode/KODE.md)
|
|
|
2686
2750
|
};
|
|
2687
2751
|
}
|
|
2688
2752
|
}
|
|
2753
|
+
case "kode_library_list": {
|
|
2754
|
+
const { category, search } = args;
|
|
2755
|
+
const params = new URLSearchParams();
|
|
2756
|
+
if (category) params.set("category", category);
|
|
2757
|
+
if (search) params.set("search", search);
|
|
2758
|
+
const snippets = await client.listLibrary(params.toString() ? `?${params.toString()}` : "");
|
|
2759
|
+
return {
|
|
2760
|
+
content: [{ type: "text", text: JSON.stringify(snippets, null, 2) }]
|
|
2761
|
+
};
|
|
2762
|
+
}
|
|
2763
|
+
case "kode_library_get": {
|
|
2764
|
+
const { slug } = args;
|
|
2765
|
+
const snippet = await client.getLibrarySnippet(slug);
|
|
2766
|
+
return {
|
|
2767
|
+
content: [{ type: "text", text: JSON.stringify(snippet, null, 2) }]
|
|
2768
|
+
};
|
|
2769
|
+
}
|
|
2770
|
+
case "kode_library_use": {
|
|
2771
|
+
const { snippetSlug, newName } = args;
|
|
2772
|
+
const snippet = await client.getLibrarySnippet(snippetSlug);
|
|
2773
|
+
const fileName = newName || snippet.slug;
|
|
2774
|
+
const ext = snippet.type === "javascript" ? "js" : "css";
|
|
2775
|
+
const scriptsDir = getScriptsDir();
|
|
2776
|
+
if (!scriptsDir) {
|
|
2777
|
+
return {
|
|
2778
|
+
content: [{ type: "text", text: "Scripts directory not found. Run `kode init` first." }],
|
|
2779
|
+
isError: true
|
|
2780
|
+
};
|
|
2781
|
+
}
|
|
2782
|
+
const filePath = path2.join(scriptsDir, `${fileName}.${ext}`);
|
|
2783
|
+
if (fs2.existsSync(filePath)) {
|
|
2784
|
+
return {
|
|
2785
|
+
content: [{ type: "text", text: `File already exists: ${fileName}.${ext}. Use a different newName or delete the existing file.` }],
|
|
2786
|
+
isError: true
|
|
2787
|
+
};
|
|
2788
|
+
}
|
|
2789
|
+
if (!fs2.existsSync(scriptsDir)) {
|
|
2790
|
+
fs2.mkdirSync(scriptsDir, { recursive: true });
|
|
2791
|
+
}
|
|
2792
|
+
fs2.writeFileSync(filePath, snippet.code);
|
|
2793
|
+
return {
|
|
2794
|
+
content: [{ type: "text", text: `Copied "${snippet.name}" to ${fileName}.${ext}
|
|
2795
|
+
|
|
2796
|
+
Run \`kode push\` to upload to CDN.` }]
|
|
2797
|
+
};
|
|
2798
|
+
}
|
|
2689
2799
|
default:
|
|
2690
2800
|
return {
|
|
2691
2801
|
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|