Skip to main content
Glama

Karakeep MCP server

by karakeep-app
index.ts3.05 kB
import { initTRPC, TRPCError } from "@trpc/server"; import superjson from "superjson"; import { ZodError } from "zod"; import type { db } from "@karakeep/db"; import serverConfig from "@karakeep/shared/config"; import { createRateLimitMiddleware } from "./rateLimit"; import { apiErrorsTotalCounter, apiRequestDurationSummary, apiRequestsTotalCounter, } from "./stats"; interface User { id: string; name?: string | null | undefined; email?: string | null | undefined; role: "admin" | "user" | null; } export interface Context { user: User | null; db: typeof db; req: { ip: string | null; }; } export interface AuthedContext { user: User; db: typeof db; req: { ip: string | null; }; } // Avoid exporting the entire t-object // since it's not very descriptive. // For instance, the use of a t variable // is common in i18n libraries. const t = initTRPC.context<Context>().create({ transformer: superjson, errorFormatter(opts) { const { shape, error } = opts; apiErrorsTotalCounter.inc({ type: opts.type, path: opts.path, code: error.code, }); return { ...shape, data: { ...shape.data, zodError: error.code === "BAD_REQUEST" && error.cause instanceof ZodError ? error.cause.flatten() : null, }, }; }, }); export const createCallerFactory = t.createCallerFactory; // Base router and procedure helpers export const router = t.router; export const procedure = t.procedure .use(function isDemoMode(opts) { if (serverConfig.demoMode && opts.type == "mutation") { throw new TRPCError({ message: "Mutations are not allowed in demo mode", code: "FORBIDDEN", }); } return opts.next(); }) .use(async (opts) => { const end = apiRequestDurationSummary.startTimer({ path: opts.path, type: opts.type, }); const res = await opts.next(); apiRequestsTotalCounter.inc({ type: opts.type, path: opts.path, is_error: res.ok ? 0 : 1, }); end(); return res; }); // Default public procedure rate limiting export const publicProcedure = procedure.use( createRateLimitMiddleware({ name: "globalPublic", windowMs: 60 * 1000, maxRequests: 1000, }), ); export const authedProcedure = procedure // Default authed procedure rate limiting .use( createRateLimitMiddleware({ name: "globalAuthed", windowMs: 60 * 1000, maxRequests: 3000, }), ) .use(function isAuthed(opts) { const user = opts.ctx.user; if (!user?.id) { throw new TRPCError({ code: "UNAUTHORIZED" }); } return opts.next({ ctx: { user, }, }); }); export const adminProcedure = authedProcedure.use(function isAdmin(opts) { const user = opts.ctx.user; if (user.role != "admin") { throw new TRPCError({ code: "FORBIDDEN" }); } return opts.next(opts); }); // Export the rate limiting utilities for use in routers export { createRateLimitMiddleware };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/karakeep-app/karakeep'

If you have feedback or need assistance with the MCP directory API, please join our Discord server