mcp-gdrive-enhanced-markov
Version:
MCP server for Google Drive and Sheets with write capabilities, AI-powered PDF analysis, SQLite document indexing, and advanced directory exploration tools
327 lines (326 loc) • 14.8 kB
JavaScript
import { z } from 'zod';
// Base schema that all documents share
export const BaseDocumentSchema = z.object({
doc_type: z.enum(['contract', 'invoice', 'proposal', 'project_plan', 'report', 'unknown']),
synopsis: z.string().max(500).describe('1-2 sentence summary of the document'),
confidence_score: z.number().min(0).max(1).describe('How confident the AI is about the classification')
});
// Contract party schema
export const ContractPartySchema = z.object({
name: z.string(),
role: z.enum(['buyer', 'seller', 'vendor', 'client', 'other'])
});
// Contract schema
export const ContractSchema = BaseDocumentSchema.extend({
doc_type: z.literal('contract'),
contract_data: z.object({
contract_number: z.string().nullable(),
contract_type: z.string().nullable().describe('Service Agreement, NDA, Purchase Order, etc.'),
parties: z.array(ContractPartySchema).min(1),
effective_date: z.string().nullable().describe('ISO date format YYYY-MM-DD'),
expiration_date: z.string().nullable().describe('ISO date format YYYY-MM-DD'),
auto_renewal: z.boolean().nullable(),
notice_period_days: z.number().nullable(),
total_value: z.number().nullable(),
currency: z.string().length(3).nullable().describe('ISO 4217 currency code'),
payment_terms: z.string().nullable().describe('Net 30, Net 60, etc.'),
governing_law: z.string().nullable().describe('Jurisdiction/country'),
key_clauses: z.array(z.string()).describe('Important terms and conditions')
})
});
// Invoice line item schema
export const InvoiceItemSchema = z.object({
description: z.string(),
quantity: z.number(),
unit_price: z.number(),
amount: z.number()
});
// Invoice schema
export const InvoiceSchema = BaseDocumentSchema.extend({
doc_type: z.literal('invoice'),
invoice_data: z.object({
invoice_number: z.string().nullable(),
invoice_date: z.string().nullable().describe('ISO date format YYYY-MM-DD'),
due_date: z.string().nullable().describe('ISO date format YYYY-MM-DD'),
supplier: z.object({
name: z.string().nullable(),
address: z.string().nullable()
}),
customer: z.object({
name: z.string().nullable(),
address: z.string().nullable()
}),
line_items: z.array(InvoiceItemSchema),
subtotal: z.number().nullable(),
tax_amount: z.number().nullable(),
total_amount: z.number().nullable(),
currency: z.string().length(3).nullable().describe('ISO 4217 currency code'),
payment_status: z.enum(['paid', 'unpaid', 'partial', 'overdue']).nullable(),
payment_method: z.string().nullable()
})
});
// Proposal deliverable schema
export const ProposalDeliverableSchema = z.object({
description: z.string(),
timeline: z.string().nullable(),
value: z.number().nullable()
});
// Proposal schema
export const ProposalSchema = BaseDocumentSchema.extend({
doc_type: z.literal('proposal'),
proposal_data: z.object({
proposal_number: z.string().nullable(),
client_name: z.string().nullable(),
project_name: z.string().nullable(),
proposal_date: z.string().nullable().describe('ISO date format YYYY-MM-DD'),
valid_until: z.string().nullable().describe('ISO date format YYYY-MM-DD'),
total_value: z.number().nullable(),
currency: z.string().length(3).nullable().describe('ISO 4217 currency code'),
timeline_days: z.number().nullable(),
status: z.string().nullable().describe('Draft, Submitted, Accepted, Rejected, etc.'),
deliverables: z.array(ProposalDeliverableSchema),
executive_summary: z.string().nullable()
})
});
// Project plan schema
export const ProjectPlanSchema = BaseDocumentSchema.extend({
doc_type: z.literal('project_plan'),
project_data: z.object({
project_name: z.string().nullable(),
project_code: z.string().nullable(),
client: z.string().nullable(),
start_date: z.string().nullable().describe('ISO date format YYYY-MM-DD'),
end_date: z.string().nullable().describe('ISO date format YYYY-MM-DD'),
budget: z.number().nullable(),
currency: z.string().length(3).nullable().describe('ISO 4217 currency code'),
project_manager: z.string().nullable(),
team_members: z.array(z.string()),
milestones: z.array(z.object({
name: z.string(),
date: z.string().nullable(),
description: z.string().nullable()
})),
status: z.string().nullable().describe('Planning, In Progress, On Hold, Completed, etc.')
})
});
// Report schema
export const ReportSchema = BaseDocumentSchema.extend({
doc_type: z.literal('report'),
report_data: z.object({
report_title: z.string().nullable(),
report_type: z.string().nullable().describe('Financial, Technical, Progress, etc.'),
report_date: z.string().nullable().describe('ISO date format YYYY-MM-DD'),
author: z.string().nullable(),
department: z.string().nullable(),
period_start: z.string().nullable().describe('ISO date format YYYY-MM-DD'),
period_end: z.string().nullable().describe('ISO date format YYYY-MM-DD'),
key_findings: z.array(z.string()),
recommendations: z.array(z.string()),
metrics: z.record(z.string(), z.union([z.string(), z.number()])).nullable()
})
});
// Unknown document schema (fallback)
export const UnknownDocumentSchema = BaseDocumentSchema.extend({
doc_type: z.literal('unknown'),
extracted_data: z.record(z.string(), z.any()).describe('Any fields the AI could extract')
});
// Union type for all document types
export const DocumentAnalysisSchema = z.discriminatedUnion('doc_type', [
ContractSchema,
InvoiceSchema,
ProposalSchema,
ProjectPlanSchema,
ReportSchema,
UnknownDocumentSchema
]);
// Helper to convert Zod schema to JSON Schema for OpenRouter
export function zodToJsonSchema(schema) {
// This is a simplified version - in production you'd use a library like zod-to-json-schema
return {
type: 'object',
properties: {
doc_type: {
type: 'string',
enum: ['contract', 'invoice', 'proposal', 'project_plan', 'report', 'unknown']
},
synopsis: {
type: 'string',
maxLength: 500
},
confidence_score: {
type: 'number',
minimum: 0,
maximum: 1
},
// The specific data field depends on doc_type
contract_data: {
type: 'object',
properties: {
contract_number: { type: ['string', 'null'] },
contract_type: { type: ['string', 'null'] },
parties: {
type: 'array',
items: {
type: 'object',
properties: {
name: { type: 'string' },
role: { type: 'string', enum: ['buyer', 'seller', 'vendor', 'client', 'other'] }
},
required: ['name', 'role']
}
},
effective_date: { type: ['string', 'null'], format: 'date' },
expiration_date: { type: ['string', 'null'], format: 'date' },
auto_renewal: { type: ['boolean', 'null'] },
notice_period_days: { type: ['number', 'null'] },
total_value: { type: ['number', 'null'] },
currency: { type: ['string', 'null'], pattern: '^[A-Z]{3}$' },
payment_terms: { type: ['string', 'null'] },
governing_law: { type: ['string', 'null'] },
key_clauses: { type: 'array', items: { type: 'string' } }
}
},
invoice_data: {
type: 'object',
properties: {
invoice_number: { type: ['string', 'null'] },
invoice_date: { type: ['string', 'null'], format: 'date' },
due_date: { type: ['string', 'null'], format: 'date' },
supplier: {
type: 'object',
properties: {
name: { type: ['string', 'null'] },
address: { type: ['string', 'null'] }
}
},
customer: {
type: 'object',
properties: {
name: { type: ['string', 'null'] },
address: { type: ['string', 'null'] }
}
},
line_items: {
type: 'array',
items: {
type: 'object',
properties: {
description: { type: 'string' },
quantity: { type: 'number' },
unit_price: { type: 'number' },
amount: { type: 'number' }
},
required: ['description', 'quantity', 'unit_price', 'amount']
}
},
subtotal: { type: ['number', 'null'] },
tax_amount: { type: ['number', 'null'] },
total_amount: { type: ['number', 'null'] },
currency: { type: ['string', 'null'], pattern: '^[A-Z]{3}$' },
payment_status: { type: ['string', 'null'], enum: ['paid', 'unpaid', 'partial', 'overdue'] },
payment_method: { type: ['string', 'null'] }
}
},
proposal_data: {
type: 'object',
properties: {
proposal_number: { type: ['string', 'null'] },
client_name: { type: ['string', 'null'] },
project_name: { type: ['string', 'null'] },
proposal_date: { type: ['string', 'null'], format: 'date' },
valid_until: { type: ['string', 'null'], format: 'date' },
total_value: { type: ['number', 'null'] },
currency: { type: ['string', 'null'], pattern: '^[A-Z]{3}$' },
timeline_days: { type: ['number', 'null'] },
status: { type: ['string', 'null'] },
deliverables: {
type: 'array',
items: {
type: 'object',
properties: {
description: { type: 'string' },
timeline: { type: ['string', 'null'] },
value: { type: ['number', 'null'] }
},
required: ['description']
}
},
executive_summary: { type: ['string', 'null'] }
}
},
project_data: {
type: 'object',
properties: {
project_name: { type: ['string', 'null'] },
project_code: { type: ['string', 'null'] },
client: { type: ['string', 'null'] },
start_date: { type: ['string', 'null'], format: 'date' },
end_date: { type: ['string', 'null'], format: 'date' },
budget: { type: ['number', 'null'] },
currency: { type: ['string', 'null'], pattern: '^[A-Z]{3}$' },
project_manager: { type: ['string', 'null'] },
team_members: { type: 'array', items: { type: 'string' } },
milestones: {
type: 'array',
items: {
type: 'object',
properties: {
name: { type: 'string' },
date: { type: ['string', 'null'] },
description: { type: ['string', 'null'] }
},
required: ['name']
}
},
status: { type: ['string', 'null'] }
}
},
report_data: {
type: 'object',
properties: {
report_title: { type: ['string', 'null'] },
report_type: { type: ['string', 'null'] },
report_date: { type: ['string', 'null'], format: 'date' },
author: { type: ['string', 'null'] },
department: { type: ['string', 'null'] },
period_start: { type: ['string', 'null'], format: 'date' },
period_end: { type: ['string', 'null'], format: 'date' },
key_findings: { type: 'array', items: { type: 'string' } },
recommendations: { type: 'array', items: { type: 'string' } },
metrics: { type: ['object', 'null'] }
}
},
extracted_data: {
type: 'object',
additionalProperties: true
}
},
required: ['doc_type', 'synopsis', 'confidence_score'],
allOf: [
{
if: { properties: { doc_type: { const: 'contract' } } },
then: { required: ['contract_data'] }
},
{
if: { properties: { doc_type: { const: 'invoice' } } },
then: { required: ['invoice_data'] }
},
{
if: { properties: { doc_type: { const: 'proposal' } } },
then: { required: ['proposal_data'] }
},
{
if: { properties: { doc_type: { const: 'project_plan' } } },
then: { required: ['project_data'] }
},
{
if: { properties: { doc_type: { const: 'report' } } },
then: { required: ['report_data'] }
},
{
if: { properties: { doc_type: { const: 'unknown' } } },
then: { required: ['extracted_data'] }
}
]
};
}