learning_ai_notes/backend/src/mcp/note-tool-contracts.ts
2026-03-10 09:12:09 -07:00

142 lines
4.9 KiB
TypeScript

import { z } from 'zod';
export const NOTES_MCP_NAMESPACE = 'notes';
export const NOTES_MCP_TOOL_NAMES = {
list: 'notes.notes.list',
get: 'notes.notes.get',
search: 'notes.notes.search',
createDraft: 'notes.notes.create_draft',
} as const;
export const NoteToolRoleSchema = z.enum(['viewer', 'admin', 'super_admin']);
export type NoteToolRole = z.infer<typeof NoteToolRoleSchema>;
export const ListNotesToolInputSchema = z.object({
workspaceId: z.string().min(1).max(128),
status: z.enum(['draft', 'active', 'archived']).optional(),
tag: z.string().min(1).max(64).optional(),
limit: z.coerce.number().int().min(1).max(100).default(50),
offset: z.coerce.number().int().min(0).default(0),
});
export const GetNoteToolInputSchema = z.object({
noteId: z.string().min(1).max(128),
workspaceId: z.string().min(1).max(128),
});
export const SearchNotesToolInputSchema = z.object({
workspaceId: z.string().min(1).max(128),
query: z.string().min(1).max(200),
status: z.enum(['draft', 'active', 'archived']).optional(),
tag: z.string().min(1).max(64).optional(),
limit: z.coerce.number().int().min(1).max(100).default(25),
offset: z.coerce.number().int().min(0).default(0),
});
export const CreateNoteDraftToolInputSchema = z.object({
workspaceId: z.string().min(1).max(128),
title: z.string().min(1).max(500),
body: z.string().min(1).max(50000),
tags: z.array(z.string().min(1).max(64)).default([]),
links: z.array(z.string().min(1).max(512)).default([]),
sourceType: z.string().max(128).optional(),
sourceUri: z.string().max(2000).optional(),
agentId: z.string().max(128).optional(),
dryRun: z.boolean().default(false),
idempotencyKey: z.string().max(255).optional(),
correlationId: z.string().max(255).optional(),
});
export const NoteSummarySchema = z.object({
id: z.string(),
workspaceId: z.string(),
title: z.string(),
status: z.enum(['draft', 'active', 'archived']),
updatedAt: z.string(),
tags: z.array(z.string()),
});
export const ListNotesToolOutputSchema = z.object({
items: z.array(NoteSummarySchema),
total: z.number().int().min(0),
limit: z.number().int().min(1),
offset: z.number().int().min(0),
});
export const GetNoteToolOutputSchema = z.object({
id: z.string(),
workspaceId: z.string(),
title: z.string(),
body: z.string(),
status: z.enum(['draft', 'active', 'archived']),
tags: z.array(z.string()),
links: z.array(z.string()),
sourceType: z.string().optional(),
sourceUri: z.string().optional(),
agentId: z.string().optional(),
createdAt: z.string(),
updatedAt: z.string(),
});
export const SearchNotesToolOutputSchema = z.object({
query: z.string(),
items: z.array(NoteSummarySchema.extend({
matchFields: z.array(z.enum(['title', 'body', 'tags'])).default([]),
})),
total: z.number().int().min(0),
limit: z.number().int().min(1),
offset: z.number().int().min(0),
});
export const CreateNoteDraftToolOutputSchema = z.object({
dryRun: z.boolean(),
state: z.enum(['draft', 'proposed']),
note: GetNoteToolOutputSchema,
idempotencyKey: z.string().optional(),
correlationId: z.string().optional(),
});
export const NotesMcpToolDefinitions = {
list: {
name: NOTES_MCP_TOOL_NAMES.list,
description: 'List notes in a workspace with optional status and tag filters.',
requiredRole: 'viewer' as const,
inputSchema: ListNotesToolInputSchema,
outputSchema: ListNotesToolOutputSchema,
readOnly: true,
},
get: {
name: NOTES_MCP_TOOL_NAMES.get,
description: 'Get a single note by note ID and workspace scope.',
requiredRole: 'viewer' as const,
inputSchema: GetNoteToolInputSchema,
outputSchema: GetNoteToolOutputSchema,
readOnly: true,
},
search: {
name: NOTES_MCP_TOOL_NAMES.search,
description: 'Search notes in a workspace using lexical query plus optional filters.',
requiredRole: 'viewer' as const,
inputSchema: SearchNotesToolInputSchema,
outputSchema: SearchNotesToolOutputSchema,
readOnly: true,
},
createDraft: {
name: NOTES_MCP_TOOL_NAMES.createDraft,
description: 'Create a note draft in a workspace. Supports dry-run, idempotency, and correlation metadata.',
requiredRole: 'admin' as const,
inputSchema: CreateNoteDraftToolInputSchema,
outputSchema: CreateNoteDraftToolOutputSchema,
readOnly: false,
},
};
export type ListNotesToolInput = z.infer<typeof ListNotesToolInputSchema>;
export type GetNoteToolInput = z.infer<typeof GetNoteToolInputSchema>;
export type SearchNotesToolInput = z.infer<typeof SearchNotesToolInputSchema>;
export type CreateNoteDraftToolInput = z.infer<typeof CreateNoteDraftToolInputSchema>;
export type ListNotesToolOutput = z.infer<typeof ListNotesToolOutputSchema>;
export type GetNoteToolOutput = z.infer<typeof GetNoteToolOutputSchema>;
export type SearchNotesToolOutput = z.infer<typeof SearchNotesToolOutputSchema>;
export type CreateNoteDraftToolOutput = z.infer<typeof CreateNoteDraftToolOutputSchema>;