From cf97bace33fdd14f29ce947d55d17cba8fa85c11 Mon Sep 17 00:00:00 2001 From: Mohamed Bassem Date: Sun, 13 Apr 2025 01:27:45 +0000 Subject: feat: Add an MCP server for karakeep --- packages/open-api/hoarder-openapi-spec.json | 638 ++++++++++++++++++++++++++++ packages/open-api/lib/bookmarks.ts | 89 ++++ packages/open-api/lib/errors.ts | 6 + packages/open-api/lib/highlights.ts | 41 ++ packages/open-api/lib/lists.ts | 73 ++++ packages/open-api/lib/tags.ts | 33 ++ packages/open-api/package.json | 2 +- 7 files changed, 881 insertions(+), 1 deletion(-) create mode 100644 packages/open-api/lib/errors.ts (limited to 'packages/open-api') diff --git a/packages/open-api/hoarder-openapi-spec.json b/packages/open-api/hoarder-openapi-spec.json index a1d48ba2..c7f91949 100644 --- a/packages/open-api/hoarder-openapi-spec.json +++ b/packages/open-api/hoarder-openapi-spec.json @@ -712,6 +712,28 @@ } } } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } @@ -795,6 +817,28 @@ } } } + }, + "404": { + "description": "Bookmark not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } }, @@ -817,6 +861,28 @@ "responses": { "204": { "description": "No content - the bookmark was deleted" + }, + "404": { + "description": "Bookmark not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } }, @@ -955,6 +1021,28 @@ } } } + }, + "404": { + "description": "Bookmark not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } @@ -1033,6 +1121,28 @@ } } } + }, + "404": { + "description": "Bookmark not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } @@ -1104,6 +1214,28 @@ } } } + }, + "404": { + "description": "Bookmark not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } }, @@ -1173,6 +1305,28 @@ } } } + }, + "404": { + "description": "Bookmark not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } @@ -1215,6 +1369,28 @@ } } } + }, + "404": { + "description": "Bookmark not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } @@ -1300,6 +1476,28 @@ } } } + }, + "404": { + "description": "Bookmark not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } @@ -1345,6 +1543,28 @@ "responses": { "204": { "description": "No content - asset was replaced successfully" + }, + "404": { + "description": "Bookmark not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } }, @@ -1370,6 +1590,28 @@ "responses": { "204": { "description": "No content - asset was detached successfully" + }, + "404": { + "description": "Bookmark not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } @@ -1476,6 +1718,28 @@ } } } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } @@ -1507,6 +1771,28 @@ } } } + }, + "404": { + "description": "List not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } }, @@ -1529,6 +1815,28 @@ "responses": { "204": { "description": "No content - the bookmark was deleted" + }, + "404": { + "description": "List not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } }, @@ -1592,6 +1900,28 @@ } } } + }, + "404": { + "description": "List not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } @@ -1639,6 +1969,28 @@ } } } + }, + "404": { + "description": "List not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } @@ -1666,6 +2018,50 @@ "responses": { "204": { "description": "No content - the bookmark was added" + }, + "400": { + "description": "Bookmark already in list", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } + }, + "404": { + "description": "List or bookmark not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } }, @@ -1691,6 +2087,50 @@ "responses": { "204": { "description": "No content - the bookmark was added" + }, + "400": { + "description": "Bookmark already not in list", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } + }, + "404": { + "description": "List or bookmark not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } @@ -1759,6 +2199,28 @@ } } } + }, + "404": { + "description": "Tag not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } }, @@ -1781,6 +2243,28 @@ "responses": { "204": { "description": "No content - the bookmark was deleted" + }, + "404": { + "description": "Tag not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } }, @@ -1825,6 +2309,28 @@ } } } + }, + "404": { + "description": "Tag not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } @@ -1872,6 +2378,28 @@ } } } + }, + "404": { + "description": "Tag not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } @@ -1986,6 +2514,50 @@ } } } + }, + "400": { + "description": "Bad highlight request", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } + }, + "404": { + "description": "Bookmark not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } @@ -2017,6 +2589,28 @@ } } } + }, + "404": { + "description": "Highlight not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } }, @@ -2046,6 +2640,28 @@ } } } + }, + "404": { + "description": "Highlight not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } }, @@ -2096,6 +2712,28 @@ } } } + }, + "404": { + "description": "Highlight not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + } } } } diff --git a/packages/open-api/lib/bookmarks.ts b/packages/open-api/lib/bookmarks.ts index b45d6350..51c67369 100644 --- a/packages/open-api/lib/bookmarks.ts +++ b/packages/open-api/lib/bookmarks.ts @@ -13,6 +13,7 @@ import { } from "@karakeep/shared/types/bookmarks"; import { BearerAuth } from "./common"; +import { ErrorSchema } from "./errors"; import { HighlightSchema } from "./highlights"; import { BookmarkSchema, @@ -125,6 +126,14 @@ registry.registerPath({ }, }, }, + 400: { + description: "Bad request", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); registry.registerPath({ @@ -146,6 +155,14 @@ registry.registerPath({ }, }, }, + 404: { + description: "Bookmark not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -163,6 +180,14 @@ registry.registerPath({ 204: { description: "No content - the bookmark was deleted", }, + 404: { + description: "Bookmark not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -194,6 +219,14 @@ registry.registerPath({ }, }, }, + 404: { + description: "Bookmark not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -217,6 +250,14 @@ registry.registerPath({ }, }, }, + 404: { + description: "Bookmark not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -247,6 +288,14 @@ registry.registerPath({ }, }, }, + 404: { + description: "Bookmark not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -277,6 +326,14 @@ registry.registerPath({ }, }, }, + 404: { + description: "Bookmark not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -299,6 +356,14 @@ registry.registerPath({ }, }, }, + 404: { + description: "Bookmark not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -329,6 +394,14 @@ registry.registerPath({ }, }, }, + 404: { + description: "Bookmark not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -359,6 +432,14 @@ registry.registerPath({ 204: { description: "No content - asset was replaced successfully", }, + 404: { + description: "Bookmark not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -379,5 +460,13 @@ registry.registerPath({ 204: { description: "No content - asset was detached successfully", }, + 404: { + description: "Bookmark not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); diff --git a/packages/open-api/lib/errors.ts b/packages/open-api/lib/errors.ts new file mode 100644 index 00000000..326e0e9a --- /dev/null +++ b/packages/open-api/lib/errors.ts @@ -0,0 +1,6 @@ +import { z } from "zod"; + +export const ErrorSchema = z.object({ + code: z.string(), + message: z.string(), +}); diff --git a/packages/open-api/lib/highlights.ts b/packages/open-api/lib/highlights.ts index 2e4ec2d1..6eb1970e 100644 --- a/packages/open-api/lib/highlights.ts +++ b/packages/open-api/lib/highlights.ts @@ -11,6 +11,7 @@ import { } from "@karakeep/shared/types/highlights"; import { BearerAuth } from "./common"; +import { ErrorSchema } from "./errors"; import { PaginationSchema } from "./pagination"; export const registry = new OpenAPIRegistry(); @@ -84,6 +85,22 @@ registry.registerPath({ }, }, }, + 400: { + description: "Bad highlight request", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, + 404: { + description: "Bookmark not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); registry.registerPath({ @@ -105,6 +122,14 @@ registry.registerPath({ }, }, }, + 404: { + description: "Highlight not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -127,6 +152,14 @@ registry.registerPath({ }, }, }, + 404: { + description: "Highlight not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -158,5 +191,13 @@ registry.registerPath({ }, }, }, + 404: { + description: "Highlight not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); diff --git a/packages/open-api/lib/lists.ts b/packages/open-api/lib/lists.ts index c66acef4..f2c0d954 100644 --- a/packages/open-api/lib/lists.ts +++ b/packages/open-api/lib/lists.ts @@ -12,6 +12,7 @@ import { import { BookmarkIdSchema } from "./bookmarks"; import { BearerAuth } from "./common"; +import { ErrorSchema } from "./errors"; import { PaginatedBookmarksSchema, PaginationSchema } from "./pagination"; export const registry = new OpenAPIRegistry(); @@ -78,6 +79,14 @@ registry.registerPath({ }, }, }, + 400: { + description: "Bad request", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); registry.registerPath({ @@ -99,6 +108,14 @@ registry.registerPath({ }, }, }, + 404: { + description: "List not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -116,6 +133,14 @@ registry.registerPath({ 204: { description: "No content - the bookmark was deleted", }, + 404: { + description: "List not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -147,6 +172,14 @@ registry.registerPath({ }, }, }, + 404: { + description: "List not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -170,6 +203,14 @@ registry.registerPath({ }, }, }, + 404: { + description: "List not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -187,6 +228,22 @@ registry.registerPath({ 204: { description: "No content - the bookmark was added", }, + 400: { + description: "Bookmark already in list", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, + 404: { + description: "List or bookmark not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -204,5 +261,21 @@ registry.registerPath({ 204: { description: "No content - the bookmark was added", }, + 400: { + description: "Bookmark already not in list", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, + 404: { + description: "List or bookmark not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); diff --git a/packages/open-api/lib/tags.ts b/packages/open-api/lib/tags.ts index e7e6561d..86353924 100644 --- a/packages/open-api/lib/tags.ts +++ b/packages/open-api/lib/tags.ts @@ -10,6 +10,7 @@ import { } from "@karakeep/shared/types/tags"; import { BearerAuth } from "./common"; +import { ErrorSchema } from "./errors"; import { PaginatedBookmarksSchema, PaginationSchema } from "./pagination"; export const registry = new OpenAPIRegistry(); @@ -69,6 +70,14 @@ registry.registerPath({ }, }, }, + 404: { + description: "Tag not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -86,6 +95,14 @@ registry.registerPath({ 204: { description: "No content - the bookmark was deleted", }, + 404: { + description: "Tag not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -117,6 +134,14 @@ registry.registerPath({ }, }, }, + 404: { + description: "Tag not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); @@ -140,5 +165,13 @@ registry.registerPath({ }, }, }, + 404: { + description: "Tag not found", + content: { + "application/json": { + schema: ErrorSchema, + }, + }, + }, }, }); diff --git a/packages/open-api/package.json b/packages/open-api/package.json index 0059f9bf..dfbb0bb6 100644 --- a/packages/open-api/package.json +++ b/packages/open-api/package.json @@ -7,7 +7,7 @@ "dependencies": { "@asteasolutions/zod-to-openapi": "^7.2.0", "@karakeep/shared": "workspace:^0.1.0", - "zod": "^3.22.4" + "zod": "^3.24.2" }, "devDependencies": { "@karakeep/eslint-config": "workspace:^0.2.0", -- cgit v1.2.3-70-g09d2