Skip to main content
Glama
schemas.ts12.4 kB
import { ParaCategorySchema } from '@inchankang/zettel-memory-common'; import { z } from 'zod'; export const SearchMemoryInputSchema = z .object({ query: z .string({ required_error: '검색어는 필수 입력값입니다.', invalid_type_error: '검색어는 문자열이어야 합니다.', }) .min(1, '검색어는 최소 1자 이상이어야 합니다.'), category: ParaCategorySchema.optional(), tags: z .array(z.string().min(1, '태그는 최소 1자 이상이어야 합니다.')) .default([]) .optional(), limit: z .number({ invalid_type_error: 'limit는 숫자여야 합니다.' }) .int('limit는 정수여야 합니다.') .min(1, 'limit는 최소 1 이상이어야 합니다.') .max(100, 'limit는 최대 100까지 허용됩니다.') .default(10) .optional(), offset: z .number({ invalid_type_error: 'offset은 숫자여야 합니다.' }) .int('offset은 정수여야 합니다.') .min(0, 'offset은 음수가 될 수 없습니다.') .default(0) .optional(), }) .strict(); export type SearchMemoryInput = z.infer<typeof SearchMemoryInputSchema>; export const CreateNoteInputSchema = z .object({ title: z .string({ required_error: '제목은 필수 입력값입니다.', invalid_type_error: '제목은 문자열이어야 합니다.', }) .min(1, '제목은 최소 1자 이상이어야 합니다.'), content: z .string({ required_error: '내용은 필수 입력값입니다.', invalid_type_error: '내용은 문자열이어야 합니다.', }) .min(1, '내용은 최소 1자 이상이어야 합니다.'), category: ParaCategorySchema.optional(), // v2: Made optional for Zettelkasten notes tags: z .array(z.string().min(1, '태그는 최소 1자 이상이어야 합니다.')) .default([]), project: z .string({ invalid_type_error: 'project는 문자열이어야 합니다.' }) .min(1, 'project는 최소 1자 이상이어야 합니다.') .optional(), links: z .array(z.string().min(1, '링크 ID는 최소 1자 이상이어야 합니다.')) .default([]) .optional(), }) .strict(); export type CreateNoteInput = z.infer<typeof CreateNoteInputSchema>; // read_note - Read a single note by UID export const ReadNoteInputSchema = z .object({ uid: z .string({ required_error: 'UID는 필수 입력값입니다.', invalid_type_error: 'UID는 문자열이어야 합니다.', }) .min(1, 'UID는 최소 1자 이상이어야 합니다.'), includeMetadata: z .boolean() .default(false) .optional() .describe('메타데이터(파일 크기, 단어 수 등) 포함 여부'), includeLinks: z .boolean() .default(false) .optional() .describe('링크 분석(백링크, 깨진 링크 등) 포함 여부'), }) .strict(); export type ReadNoteInput = z.infer<typeof ReadNoteInputSchema>; // update_note - Update existing note export const UpdateNoteInputSchema = z .object({ uid: z .string({ required_error: 'UID는 필수 입력값입니다.', }) .min(1, 'UID는 최소 1자 이상이어야 합니다.'), title: z.string().min(1, '제목은 최소 1자 이상이어야 합니다.').optional(), content: z.string().optional(), category: ParaCategorySchema.optional(), tags: z.array(z.string().min(1)).optional(), project: z.string().min(1).optional().nullable(), links: z.array(z.string().min(1)).optional(), }) .strict() .refine( data => { const { uid, ...updateFields } = data; return Object.keys(updateFields).length > 0; }, { message: '최소 하나의 업데이트 필드가 필요합니다.' } ); export type UpdateNoteInput = z.infer<typeof UpdateNoteInputSchema>; // delete_note - Delete a note export const DeleteNoteInputSchema = z .object({ uid: z .string({ required_error: 'UID는 필수 입력값입니다.', }) .min(1, 'UID는 최소 1자 이상이어야 합니다.'), confirm: z .boolean({ required_error: '삭제 확인은 필수입니다.', }) .refine(val => val === true, { message: '삭제를 확인하려면 confirm을 true로 설정해야 합니다.', }), }) .strict(); export type DeleteNoteInput = z.infer<typeof DeleteNoteInputSchema>; // list_notes - List notes with filters export const ListNotesInputSchema = z .object({ category: ParaCategorySchema.optional(), tags: z.array(z.string().min(1)).optional(), project: z.string().min(1).optional(), limit: z .number() .int('limit는 정수여야 합니다.') .min(1, 'limit는 최소 1 이상이어야 합니다.') .max(1000, 'limit는 최대 1000까지 허용됩니다.') .default(100) .optional(), offset: z .number() .int('offset은 정수여야 합니다.') .min(0, 'offset은 음수가 될 수 없습니다.') .default(0) .optional(), sortBy: z .enum(['created', 'updated', 'title']) .default('updated') .optional(), sortOrder: z.enum(['asc', 'desc']).default('desc').optional(), }) .strict(); export type ListNotesInput = z.infer<typeof ListNotesInputSchema>; // get_vault_stats - Get vault statistics export const GetVaultStatsInputSchema = z .object({ includeCategories: z .boolean() .default(true) .optional() .describe('카테고리별 통계 포함 여부'), includeTagStats: z .boolean() .default(true) .optional() .describe('태그 통계 포함 여부'), includeLinkStats: z .boolean() .default(true) .optional() .describe('링크 통계 포함 여부'), }) .strict(); export type GetVaultStatsInput = z.infer<typeof GetVaultStatsInputSchema>; // get_backlinks - Find notes linking to a specific note export const GetBacklinksInputSchema = z .object({ uid: z .string({ required_error: 'UID는 필수 입력값입니다.', }) .min(1, 'UID는 최소 1자 이상이어야 합니다.'), limit: z.number().int().min(1).max(100).default(20).optional(), }) .strict(); export type GetBacklinksInput = z.infer<typeof GetBacklinksInputSchema>; // get_metrics - Get system metrics export const GetMetricsInputSchema = z .object({ format: z .enum(['json', 'prometheus']) .default('json') .optional() .describe('출력 형식'), reset: z.boolean().default(false).optional().describe('메트릭 초기화 여부'), }) .strict(); export type GetMetricsInput = z.infer<typeof GetMetricsInputSchema>; // find_orphan_notes - Find notes with no incoming or outgoing links export const FindOrphanNotesInputSchema = z .object({ limit: z .number() .int('limit는 정수여야 합니다.') .min(1, 'limit는 최소 1 이상이어야 합니다.') .max(1000, 'limit는 최대 1000까지 허용됩니다.') .default(100) .optional() .describe('반환할 최대 고아 노트 수'), category: ParaCategorySchema.optional().describe('특정 카테고리로 필터링'), sortBy: z .enum(['created', 'updated', 'title']) .default('updated') .optional() .describe('정렬 기준'), sortOrder: z.enum(['asc', 'desc']).default('desc').optional(), }) .strict(); export type FindOrphanNotesInput = z.infer<typeof FindOrphanNotesInputSchema>; // find_stale_notes - Find notes not updated for a specified period export const FindStaleNotesInputSchema = z .object({ staleDays: z .number({ required_error: 'staleDays는 필수 입력값입니다.', invalid_type_error: 'staleDays는 숫자여야 합니다.', }) .int('staleDays는 정수여야 합니다.') .min(1, 'staleDays는 최소 1 이상이어야 합니다.') .max(3650, 'staleDays는 최대 3650(10년)까지 허용됩니다.') .describe('이 일수 이상 업데이트되지 않은 노트를 찾습니다'), category: ParaCategorySchema.optional().describe('특정 카테고리로 필터링'), excludeArchives: z .boolean() .default(true) .optional() .describe('Archives 카테고리 제외 여부'), limit: z .number() .int() .min(1) .max(1000) .default(100) .optional() .describe('반환할 최대 노트 수'), sortBy: z .enum(['created', 'updated', 'title']) .default('updated') .optional(), sortOrder: z.enum(['asc', 'desc']).default('asc').optional(), }) .strict(); export type FindStaleNotesInput = z.infer<typeof FindStaleNotesInputSchema>; // get_organization_health - Get vault organization health metrics export const GetOrganizationHealthInputSchema = z .object({ includeDetails: z .boolean() .default(true) .optional() .describe('상세 분석 포함 여부'), includeRecommendations: z .boolean() .default(true) .optional() .describe('개선 권장사항 포함 여부'), }) .strict(); export type GetOrganizationHealthInput = z.infer< typeof GetOrganizationHealthInputSchema >; // archive_notes - Archive multiple notes at once export const ArchiveNotesInputSchema = z .object({ uids: z .array(z.string().min(1, 'UID는 최소 1자 이상이어야 합니다.')) .min(1, '최소 하나의 UID가 필요합니다.') .max(100, '한 번에 최대 100개까지 아카이브할 수 있습니다.') .describe('아카이브할 노트 UID 목록'), dryRun: z .boolean() .default(false) .optional() .describe('true일 경우 실제 변경 없이 결과만 미리보기'), confirm: z .boolean() .default(false) .optional() .describe('dryRun이 false일 때 실행 확인 (필수)'), reason: z .string() .max(500, '이유는 최대 500자까지 허용됩니다.') .optional() .describe('아카이브 이유 (메타데이터에 기록)'), }) .strict() .refine( data => { // dryRun이 아닐 경우 confirm이 true여야 함 if (!data.dryRun && !data.confirm) { return false; } return true; }, { message: '실제 아카이브를 수행하려면 confirm=true를 설정하거나 dryRun=true로 미리보기하세요.', } ); export type ArchiveNotesInput = z.infer<typeof ArchiveNotesInputSchema>; // suggest_links - Suggest potential links for a note export const SuggestLinksInputSchema = z .object({ uid: z .string({ required_error: 'UID는 필수 입력값입니다.', }) .min(1, 'UID는 최소 1자 이상이어야 합니다.') .describe('링크를 제안받을 노트의 UID'), limit: z .number() .int() .min(1) .max(50) .default(10) .optional() .describe('반환할 최대 제안 수'), minScore: z .number() .min(0) .max(1) .default(0.3) .optional() .describe('최소 관련성 점수 (0-1)'), excludeExisting: z .boolean() .default(true) .optional() .describe('이미 연결된 노트 제외'), }) .strict(); export type SuggestLinksInput = z.infer<typeof SuggestLinksInputSchema>; // organize_notes - Organize notes using Ollama export const OrganizeNotesInputSchema = z .object({ dryRun: z .boolean() .default(true) .optional() .describe('true일 경우 실제 변경 없이 제안 사항만 반환'), limit: z .number() .int() .min(1) .max(50) .default(10) .optional() .describe('분석할 최대 노트 수'), }) .strict(); export type OrganizeNotesInput = z.infer<typeof OrganizeNotesInputSchema>; export const ToolNameSchema = z.enum([ 'search_memory', 'create_note', 'read_note', 'update_note', 'delete_note', 'list_notes', 'get_vault_stats', 'get_backlinks', 'get_metrics', // Organization tools 'find_orphan_notes', 'find_stale_notes', 'get_organization_health', 'archive_notes', 'suggest_links', 'organize_notes', ]); export type ToolName = z.infer<typeof ToolNameSchema>;

Latest Blog Posts

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/inchan/memory-mcp'

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