feat(mcp): upgrade to mcp v2

This commit is contained in:
Mohamed Bassem
2026-08-30 15:53:33 +01:00
parent ca72503ca1
commit 39df6c6ea7
26 changed files with 326 additions and 531 deletions
+1 -1
View File
@@ -39,7 +39,7 @@
"superjson": "^2.2.1",
"tailwind-merge": "^2.2.1",
"tailwindcss-animate": "^1.0.7",
"zod": "^4.0.0"
"zod": "^4.2.0"
},
"devDependencies": {
"@crxjs/vite-plugin": "2.2.0",
+3 -3
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@karakeep/mcp",
"version": "0.33.0",
"version": "0.33.1",
"description": "MCP server for Karakeep",
"license": "GNU Affero General Public License version 3",
"type": "module",
@@ -41,8 +41,8 @@
},
"dependencies": {
"@karakeep/sdk": "workspace:*",
"@modelcontextprotocol/sdk": "^1.29.0",
"@modelcontextprotocol/server": "^2.0.0",
"turndown": "^7.2.0",
"zod": "^4.0.0"
"zod": "^4.2.0"
}
}
+2 -2
View File
@@ -1,4 +1,4 @@
import type { CallToolResult } from "@modelcontextprotocol/sdk/types";
import type { CallToolResult } from "@modelcontextprotocol/server";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const { mockClient, mockTool } = vi.hoisted(() => ({
@@ -10,7 +10,7 @@ const { mockClient, mockTool } = vi.hoisted(() => ({
vi.mock("./shared", () => ({
karakeepClient: mockClient,
mcpServer: { tool: mockTool },
registerTool: mockTool,
}));
import { getAssetHandler } from "./assets";
+8 -5
View File
@@ -1,7 +1,7 @@
import type { CallToolResult } from "@modelcontextprotocol/sdk/types";
import type { CallToolResult } from "@modelcontextprotocol/server";
import { z } from "zod";
import { karakeepClient, mcpServer } from "./shared";
import { karakeepClient, registerTool } from "./shared";
import { toMcpToolError } from "./utils";
export const getAssetInputSchema = {
@@ -36,9 +36,12 @@ Expires at: ${res.data.expiresAt}`,
};
}
mcpServer.tool(
registerTool(
"get-asset",
"Get a temporary signed URL for downloading an asset by its asset ID.",
getAssetInputSchema,
{
description:
"Get a temporary signed URL for downloading an asset by its asset ID.",
inputSchema: z.object(getAssetInputSchema),
},
getAssetHandler,
);
+2 -2
View File
@@ -1,4 +1,4 @@
import type { CallToolResult } from "@modelcontextprotocol/sdk/types";
import type { CallToolResult } from "@modelcontextprotocol/server";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const { mockClient, mockTool, mockTurndown } = vi.hoisted(() => ({
@@ -15,7 +15,7 @@ const { mockClient, mockTool, mockTurndown } = vi.hoisted(() => ({
vi.mock("./shared", () => ({
karakeepClient: mockClient,
mcpServer: { tool: mockTool },
registerTool: mockTool,
turndownService: mockTurndown,
}));
+86 -70
View File
@@ -1,7 +1,7 @@
import { CallToolResult } from "@modelcontextprotocol/sdk/types";
import { CallToolResult } from "@modelcontextprotocol/server";
import { z } from "zod";
import { karakeepClient, mcpServer, turndownService } from "./shared";
import { karakeepClient, registerTool, turndownService } from "./shared";
import { compactBookmark, compactList, toMcpToolError } from "./utils";
// Tools
@@ -89,18 +89,22 @@ Next cursor: ${res.data.nextCursor ? `'${res.data.nextCursor}'` : "no more pages
};
}
mcpServer.tool(
registerTool(
"search-bookmarks",
`Search for bookmarks matching a specific query using full-text, semantic, or hybrid search.`,
searchBookmarksInputSchema,
{
description: `Search for bookmarks matching a specific query using full-text, semantic, or hybrid search.`,
inputSchema: z.object(searchBookmarksInputSchema),
},
searchBookmarksHandler,
);
mcpServer.tool(
registerTool(
"get-bookmark",
`Get a bookmark by id.`,
{
bookmarkId: z.string().describe(`The bookmarkId to get.`),
description: `Get a bookmark by id.`,
inputSchema: z.object({
bookmarkId: z.string().describe(`The bookmarkId to get.`),
}),
},
async ({ bookmarkId }): Promise<CallToolResult> => {
const res = await karakeepClient.GET(`/bookmarks/{bookmarkId}`, {
@@ -158,25 +162,31 @@ export async function getBookmarkListsHandler({
};
}
mcpServer.tool(
registerTool(
"get-bookmark-lists",
`List every list that contains a bookmark.`,
getBookmarkListsInputSchema,
{ readOnlyHint: true },
{
description: `List every list that contains a bookmark.`,
inputSchema: z.object(getBookmarkListsInputSchema),
annotations: { readOnlyHint: true },
},
getBookmarkListsHandler,
);
mcpServer.tool(
registerTool(
"create-bookmark",
`Create a link bookmark or a text bookmark`,
{
type: z.enum(["link", "text"]).describe(`The type of bookmark to create.`),
title: z.string().optional().describe(`The title of the bookmark`),
content: z
.string()
.describe(
"If type is text, the text to be bookmarked. If the type is link, then it's the URL to be bookmarked.",
),
description: `Create a link bookmark or a text bookmark`,
inputSchema: z.object({
type: z
.enum(["link", "text"])
.describe(`The type of bookmark to create.`),
title: z.string().optional().describe(`The title of the bookmark`),
content: z
.string()
.describe(
"If type is text, the text to be bookmarked. If the type is link, then it's the URL to be bookmarked.",
),
}),
},
async ({ title, type, content }): Promise<CallToolResult> => {
const res = await karakeepClient.POST(`/bookmarks`, {
@@ -207,51 +217,53 @@ mcpServer.tool(
},
);
mcpServer.tool(
registerTool(
"update-bookmark",
`Update fields on an existing bookmark. Only the fields you pass are modified; omitted fields stay unchanged. Returns the updated bookmark.`,
{
bookmarkId: z.string().describe(`The bookmarkId to update.`),
title: z
.string()
.nullable()
.optional()
.describe(`The bookmark's user-set title. Pass null to clear it.`),
note: z.string().optional().describe(`A free-form note on the bookmark.`),
summary: z
.string()
.nullable()
.optional()
.describe(`The bookmark's summary. Pass null to clear it.`),
archived: z
.boolean()
.optional()
.describe(`Whether the bookmark is archived.`),
favourited: z
.boolean()
.optional()
.describe(`Whether the bookmark is favourited.`),
url: z.string().url().optional().describe(`New URL for a link bookmark.`),
description: z
.string()
.nullable()
.optional()
.describe(`Link description. Pass null to clear it.`),
author: z
.string()
.nullable()
.optional()
.describe(`Link author. Pass null to clear it.`),
publisher: z
.string()
.nullable()
.optional()
.describe(`Link publisher. Pass null to clear it.`),
createdAt: z
.string()
.datetime()
.optional()
.describe(`Override the bookmark's createdAt timestamp (ISO 8601).`),
description: `Update fields on an existing bookmark. Only the fields you pass are modified; omitted fields stay unchanged. Returns the updated bookmark.`,
inputSchema: z.object({
bookmarkId: z.string().describe(`The bookmarkId to update.`),
title: z
.string()
.nullable()
.optional()
.describe(`The bookmark's user-set title. Pass null to clear it.`),
note: z.string().optional().describe(`A free-form note on the bookmark.`),
summary: z
.string()
.nullable()
.optional()
.describe(`The bookmark's summary. Pass null to clear it.`),
archived: z
.boolean()
.optional()
.describe(`Whether the bookmark is archived.`),
favourited: z
.boolean()
.optional()
.describe(`Whether the bookmark is favourited.`),
url: z.string().url().optional().describe(`New URL for a link bookmark.`),
description: z
.string()
.nullable()
.optional()
.describe(`Link description. Pass null to clear it.`),
author: z
.string()
.nullable()
.optional()
.describe(`Link author. Pass null to clear it.`),
publisher: z
.string()
.nullable()
.optional()
.describe(`Link publisher. Pass null to clear it.`),
createdAt: z
.string()
.datetime()
.optional()
.describe(`Override the bookmark's createdAt timestamp (ISO 8601).`),
}),
},
async ({ bookmarkId, ...fields }): Promise<CallToolResult> => {
const patchRes = await karakeepClient.PATCH(`/bookmarks/{bookmarkId}`, {
@@ -326,10 +338,12 @@ export async function getBookmarkContentHandler({
};
}
mcpServer.tool(
registerTool(
"get-bookmark-content",
`Get the content of the bookmark in markdown`,
getBookmarkContentInputSchema,
{
description: `Get the content of the bookmark in markdown`,
inputSchema: z.object(getBookmarkContentInputSchema),
},
getBookmarkContentHandler,
);
@@ -369,9 +383,11 @@ export async function deleteBookmarkHandler({
};
}
mcpServer.tool(
registerTool(
"delete-bookmark",
`Delete a bookmark by id. This is destructive — the bookmark, its highlights, and its assets are removed.`,
deleteBookmarkInputSchema,
{
description: `Delete a bookmark by id. This is destructive — the bookmark, its highlights, and its assets are removed.`,
inputSchema: z.object(deleteBookmarkInputSchema),
},
deleteBookmarkHandler,
);
+2 -2
View File
@@ -1,4 +1,4 @@
import type { CallToolResult } from "@modelcontextprotocol/sdk/types";
import type { CallToolResult } from "@modelcontextprotocol/server";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const { mockClient, mockTool } = vi.hoisted(() => ({
@@ -13,7 +13,7 @@ const { mockClient, mockTool } = vi.hoisted(() => ({
vi.mock("./shared", () => ({
karakeepClient: mockClient,
mcpServer: { tool: mockTool },
registerTool: mockTool,
}));
import {
+42 -26
View File
@@ -1,7 +1,7 @@
import type { CallToolResult } from "@modelcontextprotocol/sdk/types";
import type { CallToolResult } from "@modelcontextprotocol/server";
import { z } from "zod";
import { karakeepClient, mcpServer } from "./shared";
import { karakeepClient, registerTool } from "./shared";
import { compactHighlight, pickDefined, toMcpToolError } from "./utils";
const highlightColorSchema = z.enum(["yellow", "red", "green", "blue"]);
@@ -45,11 +45,13 @@ export async function listHighlightsHandler(
};
}
mcpServer.tool(
registerTool(
"list-highlights",
`List highlights across all bookmarks, newest first.`,
listHighlightsInputSchema,
{ readOnlyHint: true },
{
description: `List highlights across all bookmarks, newest first.`,
inputSchema: z.object(listHighlightsInputSchema),
annotations: { readOnlyHint: true },
},
listHighlightsHandler,
);
@@ -84,11 +86,13 @@ export async function getBookmarkHighlightsHandler({
};
}
mcpServer.tool(
registerTool(
"get-bookmark-highlights",
`List every highlight on a bookmark.`,
getBookmarkHighlightsInputSchema,
{ readOnlyHint: true },
{
description: `List every highlight on a bookmark.`,
inputSchema: z.object(getBookmarkHighlightsInputSchema),
annotations: { readOnlyHint: true },
},
getBookmarkHighlightsHandler,
);
@@ -115,11 +119,13 @@ export async function getHighlightHandler({
};
}
mcpServer.tool(
registerTool(
"get-highlight",
`Retrieve a single highlight by id.`,
getHighlightInputSchema,
{ readOnlyHint: true },
{
description: `Retrieve a single highlight by id.`,
inputSchema: z.object(getHighlightInputSchema),
annotations: { readOnlyHint: true },
},
getHighlightHandler,
);
@@ -172,11 +178,13 @@ export async function createHighlightHandler(
};
}
mcpServer.tool(
registerTool(
"create-highlight",
`Create a text highlight on a bookmark using character offsets from the bookmark's readable content.`,
createHighlightInputSchema,
{ readOnlyHint: false, destructiveHint: false },
{
description: `Create a text highlight on a bookmark using character offsets from the bookmark's readable content.`,
inputSchema: z.object(createHighlightInputSchema),
annotations: { readOnlyHint: false, destructiveHint: false },
},
createHighlightHandler,
);
@@ -216,11 +224,13 @@ export async function updateHighlightHandler(
};
}
mcpServer.tool(
registerTool(
"update-highlight",
`Update a highlight's color or note.`,
updateHighlightInputSchema,
{ readOnlyHint: false, destructiveHint: false },
{
description: `Update a highlight's color or note.`,
inputSchema: z.object(updateHighlightInputSchema),
annotations: { readOnlyHint: false, destructiveHint: false },
},
updateHighlightHandler,
);
@@ -249,10 +259,16 @@ export async function deleteHighlightHandler({
};
}
mcpServer.tool(
registerTool(
"delete-highlight",
`Delete a highlight by id.`,
deleteHighlightInputSchema,
{ readOnlyHint: false, destructiveHint: true, idempotentHint: false },
{
description: `Delete a highlight by id.`,
inputSchema: z.object(deleteHighlightInputSchema),
annotations: {
readOnlyHint: false,
destructiveHint: true,
idempotentHint: false,
},
},
deleteHighlightHandler,
);
+3 -10
View File
@@ -1,7 +1,6 @@
#!/usr/bin/env node
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { mcpServer } from "./shared";
import { serveStdio } from "@modelcontextprotocol/server/stdio";
import { createMcpServer } from "./shared";
import "./assets.ts";
import "./bookmarks.ts";
@@ -9,10 +8,4 @@ import "./highlights.ts";
import "./lists.ts";
import "./tags.ts";
async function run() {
// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
await mcpServer.connect(transport);
}
run();
serveStdio(createMcpServer);
+2 -2
View File
@@ -1,4 +1,4 @@
import type { CallToolResult } from "@modelcontextprotocol/sdk/types";
import type { CallToolResult } from "@modelcontextprotocol/server";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const { mockClient, mockTool } = vi.hoisted(() => ({
@@ -14,7 +14,7 @@ const { mockClient, mockTool } = vi.hoisted(() => ({
vi.mock("./shared", () => ({
karakeepClient: mockClient,
mcpServer: { tool: mockTool },
registerTool: mockTool,
}));
import {
+47 -33
View File
@@ -1,4 +1,4 @@
import { CallToolResult } from "@modelcontextprotocol/sdk/types";
import { CallToolResult } from "@modelcontextprotocol/server";
import { z } from "zod";
import {
@@ -6,7 +6,7 @@ import {
zEditBookmarkListSchemaWithValidation,
} from "@karakeep/shared/types/lists";
import { karakeepClient, mcpServer } from "./shared";
import { karakeepClient, registerTool } from "./shared";
import {
compactBookmark,
compactList,
@@ -14,9 +14,9 @@ import {
toMcpToolError,
} from "./utils";
mcpServer.tool(
registerTool(
"get-lists",
`Retrieves a list of lists.`,
{ description: `Retrieves a list of lists.` },
async (): Promise<CallToolResult> => {
const res = await karakeepClient.GET("/lists", {
params: {},
@@ -60,10 +60,12 @@ export async function getListHandler({
};
}
mcpServer.tool(
registerTool(
"get-list",
`Retrieve a single list by its id.`,
getListInputSchema,
{
description: `Retrieve a single list by its id.`,
inputSchema: z.object(getListInputSchema),
},
getListHandler,
);
@@ -135,10 +137,12 @@ ${compactList(res.data)}`,
};
}
mcpServer.tool(
registerTool(
"update-list",
`Update a list. Only the fields you pass are changed. Length caps and smart-list query rules come from the shared list schema.`,
updateListInputSchema,
{
description: `Update a list. Only the fields you pass are changed. Length caps and smart-list query rules come from the shared list schema.`,
inputSchema: z.object(updateListInputSchema),
},
updateListHandler,
);
@@ -175,19 +179,23 @@ export async function deleteListHandler({
};
}
mcpServer.tool(
registerTool(
"delete-list",
`Delete a list by id. Bookmarks inside the list are not deleted. Child lists are also not deleted. Any child lists become root-level lists (their parentId is set to null). If that isn't the tree change you want, move or re-parent the children before calling this.`,
deleteListInputSchema,
{
description: `Delete a list by id. Bookmarks inside the list are not deleted. Child lists are also not deleted. Any child lists become root-level lists (their parentId is set to null). If that isn't the tree change you want, move or re-parent the children before calling this.`,
inputSchema: z.object(deleteListInputSchema),
},
deleteListHandler,
);
mcpServer.tool(
registerTool(
"add-bookmark-to-list",
`Add a bookmark to a list.`,
{
listId: z.string().describe(`The listId to add the bookmark to.`),
bookmarkId: z.string().describe(`The bookmarkId to add.`),
description: `Add a bookmark to a list.`,
inputSchema: z.object({
listId: z.string().describe(`The listId to add the bookmark to.`),
bookmarkId: z.string().describe(`The bookmarkId to add.`),
}),
},
async ({ listId, bookmarkId }): Promise<CallToolResult> => {
const res = await karakeepClient.PUT(
@@ -215,12 +223,14 @@ mcpServer.tool(
},
);
mcpServer.tool(
registerTool(
"remove-bookmark-from-list",
`Remove a bookmark from a list.`,
{
listId: z.string().describe(`The listId to remove the bookmark from.`),
bookmarkId: z.string().describe(`The bookmarkId to remove.`),
description: `Remove a bookmark from a list.`,
inputSchema: z.object({
listId: z.string().describe(`The listId to remove the bookmark from.`),
bookmarkId: z.string().describe(`The bookmarkId to remove.`),
}),
},
async ({ listId, bookmarkId }): Promise<CallToolResult> => {
const res = await karakeepClient.DELETE(
@@ -305,24 +315,28 @@ export async function getListBookmarksHandler(
};
}
mcpServer.tool(
registerTool(
"get-list-bookmarks",
`List bookmarks in a list by its stable id. Smart lists are evaluated using their saved query.`,
getListBookmarksInputSchema,
{ readOnlyHint: true },
{
description: `List bookmarks in a list by its stable id. Smart lists are evaluated using their saved query.`,
inputSchema: z.object(getListBookmarksInputSchema),
annotations: { readOnlyHint: true },
},
getListBookmarksHandler,
);
mcpServer.tool(
registerTool(
"create-list",
`Create a list.`,
{
name: z.string().describe(`The name of the list.`),
icon: z.string().describe(`The emoji icon of the list.`),
parentId: z
.string()
.optional()
.describe(`The parent list id of this list.`),
description: `Create a list.`,
inputSchema: z.object({
name: z.string().describe(`The name of the list.`),
icon: z.string().describe(`The emoji icon of the list.`),
parentId: z
.string()
.optional()
.describe(`The parent list id of this list.`),
}),
},
async ({ name, icon, parentId }): Promise<CallToolResult> => {
const res = await karakeepClient.POST("/lists", {
+44 -5
View File
@@ -1,4 +1,10 @@
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { McpServer } from "@modelcontextprotocol/server";
import type {
Icon,
StandardSchemaWithJSON,
ToolAnnotations,
ToolCallback,
} from "@modelcontextprotocol/server";
import TurndownService from "turndown";
import { createKarakeepClient } from "@karakeep/sdk";
@@ -28,9 +34,42 @@ export const karakeepClient = createKarakeepClient({
},
});
export const mcpServer = new McpServer({
name: "Karakeep",
version: packageJson.version,
});
type ToolRegistration = (server: McpServer) => void;
const toolRegistrations: ToolRegistration[] = [];
export function registerTool<
OutputArgs extends StandardSchemaWithJSON,
InputArgs extends StandardSchemaWithJSON | undefined = undefined,
>(
name: string,
config: {
title?: string;
description?: string;
inputSchema?: InputArgs;
outputSchema?: OutputArgs;
annotations?: ToolAnnotations;
icons?: Icon[];
_meta?: Record<string, unknown>;
},
callback: ToolCallback<InputArgs>,
) {
toolRegistrations.push((server) => {
server.registerTool(name, config, callback);
});
}
export function createMcpServer() {
const server = new McpServer({
name: "Karakeep",
version: packageJson.version,
});
for (const register of toolRegistrations) {
register(server);
}
return server;
}
export const turndownService = new TurndownService();
+2 -2
View File
@@ -1,4 +1,4 @@
import type { CallToolResult } from "@modelcontextprotocol/sdk/types";
import type { CallToolResult } from "@modelcontextprotocol/server";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const { mockClient, mockTool } = vi.hoisted(() => ({
@@ -14,7 +14,7 @@ const { mockClient, mockTool } = vi.hoisted(() => ({
vi.mock("./shared", () => ({
karakeepClient: mockClient,
mcpServer: { tool: mockTool },
registerTool: mockTool,
}));
import {
+39 -25
View File
@@ -1,7 +1,7 @@
import { CallToolResult } from "@modelcontextprotocol/sdk/types";
import { CallToolResult } from "@modelcontextprotocol/server";
import { z } from "zod";
import { karakeepClient, mcpServer } from "./shared";
import { karakeepClient, registerTool } from "./shared";
import {
compactBookmark,
compactTag,
@@ -9,12 +9,14 @@ import {
toMcpToolError,
} from "./utils";
mcpServer.tool(
registerTool(
"attach-tag-to-bookmark",
`Attach a tag to a bookmark.`,
{
bookmarkId: z.string().describe(`The bookmarkId to attach the tag to.`),
tagsToAttach: z.array(z.string()).describe(`The tag names to attach.`),
description: `Attach a tag to a bookmark.`,
inputSchema: z.object({
bookmarkId: z.string().describe(`The bookmarkId to attach the tag to.`),
tagsToAttach: z.array(z.string()).describe(`The tag names to attach.`),
}),
},
async ({ bookmarkId, tagsToAttach }): Promise<CallToolResult> => {
const res = await karakeepClient.POST(`/bookmarks/{bookmarkId}/tags`, {
@@ -41,12 +43,14 @@ mcpServer.tool(
},
);
mcpServer.tool(
registerTool(
"detach-tag-from-bookmark",
`Detach a tag from a bookmark.`,
{
bookmarkId: z.string().describe(`The bookmarkId to detach the tag from.`),
tagsToDetach: z.array(z.string()).describe(`The tag names to detach.`),
description: `Detach a tag from a bookmark.`,
inputSchema: z.object({
bookmarkId: z.string().describe(`The bookmarkId to detach the tag from.`),
tagsToDetach: z.array(z.string()).describe(`The tag names to detach.`),
}),
},
async ({ bookmarkId, tagsToDetach }): Promise<CallToolResult> => {
const res = await karakeepClient.DELETE(`/bookmarks/{bookmarkId}/tags`, {
@@ -126,10 +130,12 @@ export async function getTagsHandler(
};
}
mcpServer.tool(
registerTool(
"get-tags",
`List tags with their bookmark counts. Supports filtering and pagination.`,
getTagsInputSchema,
{
description: `List tags with their bookmark counts. Supports filtering and pagination.`,
inputSchema: z.object(getTagsInputSchema),
},
getTagsHandler,
);
@@ -153,10 +159,12 @@ export async function getTagHandler({
};
}
mcpServer.tool(
registerTool(
"get-tag",
`Retrieve a single tag by id, including its bookmark counts.`,
getTagInputSchema,
{
description: `Retrieve a single tag by id, including its bookmark counts.`,
inputSchema: z.object(getTagInputSchema),
},
getTagHandler,
);
@@ -191,10 +199,12 @@ export async function updateTagHandler(
};
}
mcpServer.tool(
registerTool(
"update-tag",
`Rename a tag. The new name is normalized by the server.`,
updateTagInputSchema,
{
description: `Rename a tag. The new name is normalized by the server.`,
inputSchema: z.object(updateTagInputSchema),
},
updateTagHandler,
);
@@ -231,10 +241,12 @@ export async function deleteTagHandler({
};
}
mcpServer.tool(
registerTool(
"delete-tag",
`Delete a tag by id. Bookmarks that had this tag are not deleted; the tag is just removed from them.`,
deleteTagInputSchema,
{
description: `Delete a tag by id. Bookmarks that had this tag are not deleted; the tag is just removed from them.`,
inputSchema: z.object(deleteTagInputSchema),
},
deleteTagHandler,
);
@@ -299,9 +311,11 @@ export async function getTagBookmarksHandler(
};
}
mcpServer.tool(
registerTool(
"get-tag-bookmarks",
`List bookmarks that have a given tag, with pagination.`,
getTagBookmarksInputSchema,
{
description: `List bookmarks that have a given tag, with pagination.`,
inputSchema: z.object(getTagBookmarksInputSchema),
},
getTagBookmarksHandler,
);
+1 -2
View File
@@ -1,5 +1,4 @@
import { CallToolResult } from "@modelcontextprotocol/sdk/types";
import { CallToolResult } from "@modelcontextprotocol/server";
import { KarakeepAPISchemas } from "@karakeep/sdk";
import { turndownService } from "./shared";
+1 -1
View File
@@ -88,7 +88,7 @@
"sonner-native": "^0.22.2",
"superjson": "^2.2.1",
"tailwind-merge": "^2.2.1",
"zod": "^4.0.0",
"zod": "^4.2.0",
"zustand": "^5.0.5"
},
"devDependencies": {
+1 -1
View File
@@ -110,7 +110,7 @@
"streamdown": "^2.5.0",
"superjson": "^2.2.1",
"tailwind-merge": "^2.2.1",
"zod": "^4.0.0",
"zod": "^4.2.0",
"zustand": "^5.0.5"
},
"devDependencies": {
+1 -1
View File
@@ -59,7 +59,7 @@
"tesseract.js": "^7.0.0",
"tsx": "^4.8.1",
"typescript": "^5.9",
"zod": "^4.0.0"
"zod": "^4.2.0"
},
"devDependencies": {
"@types/archiver": "^7.0.0",
+1 -1
View File
@@ -27,7 +27,7 @@
"hono": "^4.12.32",
"prom-client": "^15.1.3",
"rss": "^1.2.2",
"zod": "^4.0.0"
"zod": "^4.2.0"
},
"devDependencies": {
"@karakeep/tsconfig": "workspace:^0.1.0",
+1 -1
View File
@@ -19,7 +19,7 @@
"p-limit": "^7.2.0",
"superjson": "^2.2.1",
"tinybench": "^6.0.0",
"zod": "^4.0.0"
"zod": "^4.2.0"
},
"devDependencies": {
"@karakeep/tsconfig": "workspace:^0.1.0",
+1 -1
View File
@@ -21,7 +21,7 @@
"@karakeep/trpc": "workspace:^0.1.0",
"@trpc/client": "^11.9.0",
"superjson": "^2.2.1",
"zod": "^4.0.0"
"zod": "^4.2.0"
},
"devDependencies": {
"@karakeep/tsconfig": "workspace:^0.1.0",
+1 -1
View File
@@ -7,7 +7,7 @@
"dependencies": {
"@asteasolutions/zod-to-openapi": "^8.5.0",
"@karakeep/shared": "workspace:^0.1.0",
"zod": "^4.0.0"
"zod": "^4.2.0"
},
"devDependencies": {
"@karakeep/tsconfig": "workspace:^0.1.0",
+1 -1
View File
@@ -16,7 +16,7 @@
"typescript-parsec": "^0.3.4",
"undici": "^6.28.0",
"winston": "^3.11.0",
"zod": "^4.0.0"
"zod": "^4.2.0"
},
"devDependencies": {
"@karakeep/tsconfig": "workspace:^0.1.0",
+1 -1
View File
@@ -26,7 +26,7 @@
"superjson": "^2.2.1",
"tiny-invariant": "^1.3.3",
"turndown": "^7.2.0",
"zod": "^4.0.0"
"zod": "^4.2.0"
},
"devDependencies": {
"@karakeep/tsconfig": "workspace:^0.1.0",
+32 -331
View File
@@ -123,7 +123,7 @@ importers:
specifier: ^1.0.7
version: 1.0.7(tailwindcss@3.4.1)
zod:
specifier: ^4.0.0
specifier: ^4.2.0
version: 4.3.6
devDependencies:
'@crxjs/vite-plugin':
@@ -286,14 +286,14 @@ importers:
'@karakeep/sdk':
specifier: workspace:*
version: link:../../packages/sdk
'@modelcontextprotocol/sdk':
specifier: ^1.29.0
version: 1.29.0(zod@4.3.6)
'@modelcontextprotocol/server':
specifier: ^2.0.0
version: 2.0.0
turndown:
specifier: ^7.2.0
version: 7.2.0
zod:
specifier: ^4.0.0
specifier: ^4.2.0
version: 4.3.6
devDependencies:
'@karakeep/shared':
@@ -531,7 +531,7 @@ importers:
specifier: ^2.2.1
version: 2.2.1
zod:
specifier: ^4.0.0
specifier: ^4.2.0
version: 4.3.6
zustand:
specifier: ^5.0.5
@@ -838,7 +838,7 @@ importers:
specifier: ^2.2.1
version: 2.2.1
zod:
specifier: ^4.0.0
specifier: ^4.2.0
version: 4.3.6
zustand:
specifier: ^5.0.5
@@ -1061,7 +1061,7 @@ importers:
specifier: ^5.9
version: 5.9.3
zod:
specifier: ^4.0.0
specifier: ^4.2.0
version: 4.3.6
devDependencies:
'@types/archiver':
@@ -1177,7 +1177,7 @@ importers:
specifier: ^1.2.2
version: 1.2.2
zod:
specifier: ^4.0.0
specifier: ^4.2.0
version: 4.3.6
devDependencies:
'@karakeep/tsconfig':
@@ -1220,7 +1220,7 @@ importers:
specifier: ^6.0.0
version: 6.0.0
zod:
specifier: ^4.0.0
specifier: ^4.2.0
version: 4.3.6
devDependencies:
'@karakeep/tsconfig':
@@ -1294,7 +1294,7 @@ importers:
specifier: ^2.2.1
version: 2.2.1
zod:
specifier: ^4.0.0
specifier: ^4.2.0
version: 4.3.6
devDependencies:
'@karakeep/tsconfig':
@@ -1322,7 +1322,7 @@ importers:
specifier: workspace:^0.1.0
version: link:../shared
zod:
specifier: ^4.0.0
specifier: ^4.2.0
version: 4.3.6
devDependencies:
'@karakeep/tsconfig':
@@ -1427,7 +1427,7 @@ importers:
specifier: ^3.11.0
version: 3.17.0
zod:
specifier: ^4.0.0
specifier: ^4.2.0
version: 4.3.6
devDependencies:
'@karakeep/tsconfig':
@@ -1598,7 +1598,7 @@ importers:
specifier: ^7.2.0
version: 7.2.0
zod:
specifier: ^4.0.0
specifier: ^4.2.0
version: 4.3.6
devDependencies:
'@karakeep/tsconfig':
@@ -1686,7 +1686,7 @@ importers:
specifier: ^5.3.0
version: 5.4.1
zod:
specifier: ^4.0.0
specifier: ^4.2.0
version: 4.3.6
devDependencies:
'@types/node':
@@ -1699,6 +1699,8 @@ importers:
specifier: ^5.9
version: 5.9.3
tools/evals: {}
tools/seed-snapshot:
dependencies:
'@karakeep/shared':
@@ -5650,15 +5652,13 @@ packages:
'@mixmark-io/domino@2.2.0':
resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==}
'@modelcontextprotocol/sdk@1.29.0':
resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==}
engines: {node: '>=18'}
peerDependencies:
'@cfworker/json-schema': ^4.1.1
zod: ^3.25 || ^4.0
peerDependenciesMeta:
'@cfworker/json-schema':
optional: true
'@modelcontextprotocol/core@2.0.0':
resolution: {integrity: sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==}
engines: {node: '>=20'}
'@modelcontextprotocol/server@2.0.0':
resolution: {integrity: sha512-YhHWdHfpFMQfd0prsEnxKeS3Qz3ytIGmsS0sth4KDjnacIT7hxk6hXHkJ9KysxlkvTM+WZAtQbbcUhdoP4Hvtw==}
engines: {node: '>=20'}
'@mozilla/readability@0.6.0':
resolution: {integrity: sha512-juG5VWh4qAivzTAeMzvY9xs9HY5rAcr2E4I7tiSSCokRFi7XIZCAu92ZkSTsIj1OPceCifL3cpfteP3pDT9/QQ==}
@@ -8998,9 +8998,6 @@ packages:
ajv@8.13.0:
resolution: {integrity: sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==}
ajv@8.18.0:
resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==}
ajv@8.20.0:
resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==}
@@ -9392,10 +9389,6 @@ packages:
resolution: {integrity: sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
body-parser@2.2.2:
resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==}
engines: {node: '>=18'}
bonjour-service@1.4.4:
resolution: {integrity: sha512-jCZcVv7eoc4QesRscwEZtSROBen+6LpKAmBIsQYQrsAeVHLyMXWX/t6eIV5KiRZYNUBl8eVqImEEMQ8L5+c/Kw==}
@@ -9920,10 +9913,6 @@ packages:
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
engines: {node: '>= 0.6'}
content-disposition@1.0.0:
resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==}
engines: {node: '>= 0.6'}
content-type@1.0.5:
resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
engines: {node: '>= 0.6'}
@@ -9940,10 +9929,6 @@ packages:
cookie-signature@1.0.7:
resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==}
cookie-signature@1.2.2:
resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==}
engines: {node: '>=6.6.0'}
cookie@0.6.0:
resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
engines: {node: '>= 0.6'}
@@ -9985,10 +9970,6 @@ packages:
core-util-is@1.0.3:
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
cors@2.8.5:
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
engines: {node: '>= 0.10'}
cose-base@1.0.3:
resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==}
@@ -11138,18 +11119,10 @@ packages:
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
engines: {node: '>=0.8.x'}
eventsource-parser@3.0.2:
resolution: {integrity: sha512-6RxOBZ/cYgd8usLwsEl+EC09Au/9BcmCKYF2/xbml6DNczf7nv0MQb+7BA2F+li6//I+28VNlQR37XfQtcAJuA==}
engines: {node: '>=18.0.0'}
eventsource-parser@3.1.0:
resolution: {integrity: sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==}
engines: {node: '>=18.0.0'}
eventsource@3.0.7:
resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==}
engines: {node: '>=18.0.0'}
execa@1.0.0:
resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==}
engines: {node: '>=6'}
@@ -11450,20 +11423,10 @@ packages:
exponential-backoff@3.1.2:
resolution: {integrity: sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==}
express-rate-limit@8.3.2:
resolution: {integrity: sha512-77VmFeJkO0/rvimEDuUC5H30oqUC4EyOhyGccfqoLebB0oiEYfM7nwPrsDsBL1gsTpwfzX8SFy2MT3TDyRq+bg==}
engines: {node: '>= 16'}
peerDependencies:
express: '>= 4.11'
express@4.22.2:
resolution: {integrity: sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==}
engines: {node: '>= 0.10.0'}
express@5.2.1:
resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==}
engines: {node: '>= 18'}
exsolve@1.0.5:
resolution: {integrity: sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==}
@@ -11608,10 +11571,6 @@ packages:
resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==}
engines: {node: '>= 0.8'}
finalhandler@2.1.0:
resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==}
engines: {node: '>= 0.8'}
find-cache-dir@4.0.0:
resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==}
engines: {node: '>=14.16'}
@@ -11713,10 +11672,6 @@ packages:
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
engines: {node: '>= 0.6'}
fresh@2.0.0:
resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
engines: {node: '>= 0.8'}
fs-extra@10.1.0:
resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
engines: {node: '>=12'}
@@ -12060,10 +12015,6 @@ packages:
resolution: {integrity: sha512-XcuyW9qE2kJn07PkecMOBd5Vq/hMy7mmGw+idz1yblbg9N17ijJODrvPkn7/dwL3Kulj8LcRJ69DLOWf91dRUg==}
engines: {node: '>=16.9.0'}
hono@4.12.8:
resolution: {integrity: sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==}
engines: {node: '>=16.9.0'}
hookable@5.5.3:
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
@@ -12351,10 +12302,6 @@ packages:
invariant@2.2.4:
resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
ip-address@10.1.0:
resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==}
engines: {node: '>= 12'}
ip-address@9.0.5:
resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==}
engines: {node: '>= 12'}
@@ -12554,9 +12501,6 @@ packages:
is-potential-custom-element-name@1.0.1:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
is-promise@4.0.0:
resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
is-regex@1.2.1:
resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
engines: {node: '>= 0.4'}
@@ -12742,9 +12686,6 @@ packages:
jose@5.10.0:
resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==}
jose@6.2.2:
resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==}
js-levenshtein@1.1.6:
resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==}
engines: {node: '>=0.10.0'}
@@ -12841,9 +12782,6 @@ packages:
json-schema-traverse@1.0.0:
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
json-schema-typed@8.0.2:
resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==}
json-schema@0.4.0:
resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
@@ -13357,10 +13295,6 @@ packages:
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
engines: {node: '>= 0.6'}
media-typer@1.1.0:
resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
engines: {node: '>= 0.8'}
meilisearch@0.58.0:
resolution: {integrity: sha512-MXFlU+JVG2I3tDI4brS3UHxEv2fjOROP24TPP16c8dGHTulb1kxMgXvKP0x4ImvUcsVVJFi4QXP0JNDS/TaWaw==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -13383,10 +13317,6 @@ packages:
merge-descriptors@1.0.3:
resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==}
merge-descriptors@2.0.0:
resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==}
engines: {node: '>=18'}
merge-options@3.0.4:
resolution: {integrity: sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==}
engines: {node: '>=10'}
@@ -14649,9 +14579,6 @@ packages:
path-to-regexp@3.3.0:
resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==}
path-to-regexp@8.4.2:
resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==}
path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
@@ -14715,10 +14642,6 @@ packages:
resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
engines: {node: '>= 6'}
pkce-challenge@5.0.0:
resolution: {integrity: sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==}
engines: {node: '>=16.20.0'}
pkg-dir@7.0.0:
resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==}
engines: {node: '>=14.16'}
@@ -15362,6 +15285,7 @@ packages:
prom-client@15.1.3:
resolution: {integrity: sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==}
engines: {node: ^16 || ^18 || >=20}
deprecated: prom-client has been replaced by @prometheus-io/client
promise@7.3.1:
resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==}
@@ -15482,10 +15406,6 @@ packages:
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
engines: {node: '>=0.6'}
qs@6.15.1:
resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==}
engines: {node: '>=0.6'}
qs@6.15.3:
resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==}
engines: {node: '>=0.6'}
@@ -15532,14 +15452,6 @@ packages:
resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==}
engines: {node: '>= 0.8'}
raw-body@3.0.0:
resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==}
engines: {node: '>= 0.8'}
raw-body@3.0.2:
resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==}
engines: {node: '>= 0.10'}
rc@1.2.8:
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
hasBin: true
@@ -16323,10 +16235,6 @@ packages:
roughjs@4.6.6:
resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==}
router@2.2.0:
resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
engines: {node: '>= 18'}
rrweb-cssom@0.7.1:
resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==}
@@ -16521,10 +16429,6 @@ packages:
resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==}
engines: {node: '>= 0.8.0'}
send@1.2.0:
resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==}
engines: {node: '>= 18'}
serialize-error@2.1.0:
resolution: {integrity: sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==}
engines: {node: '>=0.10.0'}
@@ -16547,10 +16451,6 @@ packages:
resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==}
engines: {node: '>= 0.8.0'}
serve-static@2.2.0:
resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==}
engines: {node: '>= 18'}
server-only@0.0.1:
resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==}
@@ -17511,10 +17411,6 @@ packages:
resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==}
engines: {node: '>= 0.6'}
type-is@2.0.1:
resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==}
engines: {node: '>= 0.6'}
typedarray-to-buffer@3.1.5:
resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==}
@@ -18536,11 +18432,6 @@ packages:
zlibjs@0.3.1:
resolution: {integrity: sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w==}
zod-to-json-schema@3.25.2:
resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==}
peerDependencies:
zod: ^3.25.28 || ^4
zod@3.25.76:
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
@@ -23667,10 +23558,6 @@ snapshots:
dependencies:
hono: 4.12.32
'@hono/node-server@1.19.11(hono@4.12.8)':
dependencies:
hono: 4.12.8
'@hono/otel@1.1.1(hono@4.12.32)':
dependencies:
'@opentelemetry/api': 1.9.0
@@ -24517,27 +24404,14 @@ snapshots:
'@mixmark-io/domino@2.2.0': {}
'@modelcontextprotocol/sdk@1.29.0(zod@4.3.6)':
'@modelcontextprotocol/core@2.0.0':
dependencies:
'@hono/node-server': 1.19.11(hono@4.12.8)
ajv: 8.18.0
ajv-formats: 3.0.1(ajv@8.18.0)
content-type: 1.0.5
cors: 2.8.5
cross-spawn: 7.0.6
eventsource: 3.0.7
eventsource-parser: 3.0.2
express: 5.2.1
express-rate-limit: 8.3.2(express@5.2.1)
hono: 4.12.8
jose: 6.2.2
json-schema-typed: 8.0.2
pkce-challenge: 5.0.0
raw-body: 3.0.0
zod: 4.3.6
zod-to-json-schema: 3.25.2(zod@4.3.6)
transitivePeerDependencies:
- supports-color
'@modelcontextprotocol/server@2.0.0':
dependencies:
'@modelcontextprotocol/core': 2.0.0
zod: 4.3.6
'@mozilla/readability@0.6.0': {}
@@ -28098,10 +27972,6 @@ snapshots:
optionalDependencies:
ajv: 8.13.0
ajv-formats@3.0.1(ajv@8.18.0):
optionalDependencies:
ajv: 8.18.0
ajv-keywords@3.5.2(ajv@6.15.0):
dependencies:
ajv: 6.15.0
@@ -28139,13 +28009,6 @@ snapshots:
require-from-string: 2.0.2
uri-js: 4.4.1
ajv@8.18.0:
dependencies:
fast-deep-equal: 3.1.3
fast-uri: 3.0.6
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
ajv@8.20.0:
dependencies:
fast-deep-equal: 3.1.3
@@ -28728,20 +28591,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
body-parser@2.2.2:
dependencies:
bytes: 3.1.2
content-type: 1.0.5
debug: 4.4.3
http-errors: 2.0.0
iconv-lite: 0.7.3
on-finished: 2.4.1
qs: 6.15.1
raw-body: 3.0.2
type-is: 2.0.1
transitivePeerDependencies:
- supports-color
bonjour-service@1.4.4:
dependencies:
fast-deep-equal: 3.1.3
@@ -29352,10 +29201,6 @@ snapshots:
dependencies:
safe-buffer: 5.2.1
content-disposition@1.0.0:
dependencies:
safe-buffer: 5.2.1
content-type@1.0.5: {}
convert-source-map@1.9.0: {}
@@ -29366,8 +29211,6 @@ snapshots:
cookie-signature@1.0.7: {}
cookie-signature@1.2.2: {}
cookie@0.6.0: {}
cookie@0.7.2: {}
@@ -29404,11 +29247,6 @@ snapshots:
core-util-is@1.0.3: {}
cors@2.8.5:
dependencies:
object-assign: 4.1.1
vary: 1.1.2
cose-base@1.0.3:
dependencies:
layout-base: 1.0.2
@@ -30527,14 +30365,8 @@ snapshots:
events@3.3.0: {}
eventsource-parser@3.0.2: {}
eventsource-parser@3.1.0: {}
eventsource@3.0.7:
dependencies:
eventsource-parser: 3.0.2
execa@1.0.0:
dependencies:
cross-spawn: 6.0.6
@@ -30911,11 +30743,6 @@ snapshots:
exponential-backoff@3.1.2: {}
express-rate-limit@8.3.2(express@5.2.1):
dependencies:
express: 5.2.1
ip-address: 10.1.0
express@4.22.2:
dependencies:
accepts: 1.3.8
@@ -30952,39 +30779,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
express@5.2.1:
dependencies:
accepts: 2.0.0
body-parser: 2.2.2
content-disposition: 1.0.0
content-type: 1.0.5
cookie: 0.7.2
cookie-signature: 1.2.2
debug: 4.4.3
depd: 2.0.0
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
finalhandler: 2.1.0
fresh: 2.0.0
http-errors: 2.0.0
merge-descriptors: 2.0.0
mime-types: 3.0.1
on-finished: 2.4.1
once: 1.4.0
parseurl: 1.3.3
proxy-addr: 2.0.7
qs: 6.14.0
range-parser: 1.2.1
router: 2.2.0
send: 1.2.0
serve-static: 2.2.0
statuses: 2.0.1
type-is: 2.0.1
vary: 1.1.2
transitivePeerDependencies:
- supports-color
exsolve@1.0.5: {}
extend-shallow@2.0.1:
@@ -31149,17 +30943,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
finalhandler@2.1.0:
dependencies:
debug: 4.4.3
encodeurl: 2.0.0
escape-html: 1.0.3
on-finished: 2.4.1
parseurl: 1.3.3
statuses: 2.0.1
transitivePeerDependencies:
- supports-color
find-cache-dir@4.0.0:
dependencies:
common-path-prefix: 3.0.0
@@ -31240,8 +31023,6 @@ snapshots:
fresh@0.5.2: {}
fresh@2.0.0: {}
fs-extra@10.1.0:
dependencies:
graceful-fs: 4.2.11
@@ -31726,8 +31507,6 @@ snapshots:
hono@4.12.32: {}
hono@4.12.8: {}
hookable@5.5.3: {}
hosted-git-info@7.0.2:
@@ -31942,6 +31721,7 @@ snapshots:
iconv-lite@0.7.3:
dependencies:
safer-buffer: 2.1.2
optional: true
icss-utils@5.1.0(postcss@8.5.25):
dependencies:
@@ -32024,8 +31804,6 @@ snapshots:
dependencies:
loose-envify: 1.4.0
ip-address@10.1.0: {}
ip-address@9.0.5:
dependencies:
jsbn: 1.1.0
@@ -32174,8 +31952,6 @@ snapshots:
is-potential-custom-element-name@1.0.1: {}
is-promise@4.0.0: {}
is-regex@1.2.1:
dependencies:
call-bound: 1.0.4
@@ -32380,8 +32156,6 @@ snapshots:
jose@5.10.0: {}
jose@6.2.2: {}
js-levenshtein@1.1.6: {}
js-tiktoken@1.0.20:
@@ -32505,8 +32279,6 @@ snapshots:
json-schema-traverse@1.0.0: {}
json-schema-typed@8.0.2: {}
json-schema@0.4.0: {}
json5@2.2.3: {}
@@ -33133,8 +32905,6 @@ snapshots:
media-typer@0.3.0: {}
media-typer@1.1.0: {}
meilisearch@0.58.0: {}
memfs@4.64.0(tslib@2.8.1):
@@ -33166,8 +32936,6 @@ snapshots:
merge-descriptors@1.0.3: {}
merge-descriptors@2.0.0: {}
merge-options@3.0.4:
dependencies:
is-plain-obj: 2.1.0
@@ -34959,8 +34727,6 @@ snapshots:
path-to-regexp@3.3.0: {}
path-to-regexp@8.4.2: {}
path-type@4.0.0: {}
pathe@2.0.3: {}
@@ -34999,8 +34765,6 @@ snapshots:
pirates@4.0.7: {}
pkce-challenge@5.0.0: {}
pkg-dir@7.0.0:
dependencies:
find-up: 6.3.0
@@ -35776,10 +35540,6 @@ snapshots:
dependencies:
side-channel: 1.1.0
qs@6.15.1:
dependencies:
side-channel: 1.1.0
qs@6.15.3:
dependencies:
es-define-property: 1.0.1
@@ -35823,20 +35583,6 @@ snapshots:
iconv-lite: 0.4.24
unpipe: 1.0.0
raw-body@3.0.0:
dependencies:
bytes: 3.1.2
http-errors: 2.0.0
iconv-lite: 0.6.3
unpipe: 1.0.0
raw-body@3.0.2:
dependencies:
bytes: 3.1.2
http-errors: 2.0.1
iconv-lite: 0.7.3
unpipe: 1.0.0
rc@1.2.8:
dependencies:
deep-extend: 0.6.0
@@ -37030,16 +36776,6 @@ snapshots:
points-on-curve: 0.2.0
points-on-path: 0.2.1
router@2.2.0:
dependencies:
debug: 4.4.3
depd: 2.0.0
is-promise: 4.0.0
parseurl: 1.3.3
path-to-regexp: 8.4.2
transitivePeerDependencies:
- supports-color
rrweb-cssom@0.7.1: {}
rrweb-cssom@0.8.0: {}
@@ -37230,22 +36966,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
send@1.2.0:
dependencies:
debug: 4.4.3
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
fresh: 2.0.0
http-errors: 2.0.0
mime-types: 3.0.1
ms: 2.1.3
on-finished: 2.4.1
range-parser: 1.2.1
statuses: 2.0.1
transitivePeerDependencies:
- supports-color
serialize-error@2.1.0: {}
serialize-javascript@6.0.2:
@@ -37292,15 +37012,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
serve-static@2.2.0:
dependencies:
encodeurl: 2.0.0
escape-html: 1.0.3
parseurl: 1.3.3
send: 1.2.0
transitivePeerDependencies:
- supports-color
server-only@0.0.1: {}
set-function-length@1.2.2:
@@ -38361,12 +38072,6 @@ snapshots:
media-typer: 0.3.0
mime-types: 2.1.35
type-is@2.0.1:
dependencies:
content-type: 1.0.5
media-typer: 1.1.0
mime-types: 3.0.1
typedarray-to-buffer@3.1.5:
dependencies:
is-typedarray: 1.0.0
@@ -39556,10 +39261,6 @@ snapshots:
zlibjs@0.3.1: {}
zod-to-json-schema@3.25.2(zod@4.3.6):
dependencies:
zod: 4.3.6
zod@3.25.76: {}
zod@4.3.6: {}
+1 -1
View File
@@ -14,7 +14,7 @@
"@karakeep/sdk": "workspace:^",
"@karakeep/shared": "workspace:^",
"chalk": "^5.3.0",
"zod": "^4.0.0"
"zod": "^4.2.0"
},
"devDependencies": {
"@types/node": "^24",