import { z } from 'zod';
import type { DroydClient } from '../client.js';
// =============================================================================
// Zod Schema
// =============================================================================
export const searchContentSchema = z.object({
search_mode: z
.enum(['recent', 'semantic'])
.describe('Search mode: recent for time-based, semantic for AI-powered'),
query: z
.string()
.optional()
.describe('Search query (required for semantic mode)'),
content_types: z
.array(z.enum(['posts', 'news', 'developments', 'tweets', 'youtube', 'memories', 'concepts']))
.optional()
.describe('Content types to include'),
categories: z
.array(z.string())
.max(5)
.optional()
.describe('Category slugs to filter by (max 5)'),
ecosystems: z
.array(z.string())
.max(5)
.optional()
.describe('Ecosystem slugs to filter by (max 5)'),
days_back: z
.number()
.min(1)
.max(90)
.optional()
.describe('Days to look back (1-90)'),
limit: z
.number()
.min(10)
.max(100)
.optional()
.describe('Max results (10-100)'),
sort_by: z
.enum(['relevance', 'date'])
.optional()
.describe('Sort order'),
include_analysis: z
.boolean()
.optional()
.describe('Include AI analysis of results (semantic mode only)'),
minimum_relevance_score: z
.number()
.min(0)
.max(1)
.optional()
.describe('Minimum relevance score threshold (0-1)'),
});
// =============================================================================
// MCP Tool Definition
// =============================================================================
export const searchContentTool = {
name: 'droyd_search_content',
description: `Search the DROYD knowledge base for crypto content.
**Search Modes:**
- **recent** - Browse latest content by type, category, or ecosystem
- **semantic** - AI-powered search with natural language query
**Content Types:**
posts, news, developments, tweets, youtube, memories, concepts
**Categories:**
defi, nfts, gaming, ai, memecoins, stablecoins, rwas, depin, wallets, etc.
**Ecosystems:**
solana, ethereum, base, bitcoin, arbitrum, optimism, polygon, avalanche, etc.
**Examples:**
- Recent DeFi news: { "search_mode": "recent", "content_types": ["news"], "categories": ["defi"], "days_back": 7 }
- Semantic search: { "search_mode": "semantic", "query": "AI agents in crypto", "include_analysis": true }
- Ecosystem research: { "search_mode": "recent", "ecosystems": ["solana", "base"], "content_types": ["posts", "tweets"] }`,
inputSchema: {
type: 'object' as const,
properties: {
search_mode: {
type: 'string',
enum: ['recent', 'semantic'],
description: 'Search mode',
},
query: {
type: 'string',
description: 'Search query (required for semantic mode)',
},
content_types: {
type: 'array',
items: {
type: 'string',
enum: ['posts', 'news', 'developments', 'tweets', 'youtube', 'memories', 'concepts'],
},
description: 'Content types to include',
},
categories: {
type: 'array',
items: { type: 'string' },
description: 'Category slugs (max 5)',
maxItems: 5,
},
ecosystems: {
type: 'array',
items: { type: 'string' },
description: 'Ecosystem slugs (max 5)',
maxItems: 5,
},
days_back: {
type: 'number',
description: 'Days to look back (1-90)',
minimum: 1,
maximum: 90,
},
limit: {
type: 'number',
description: 'Max results (10-100)',
minimum: 10,
maximum: 100,
},
sort_by: {
type: 'string',
enum: ['relevance', 'date'],
description: 'Sort order',
},
include_analysis: {
type: 'boolean',
description: 'Include AI analysis (semantic mode only)',
},
minimum_relevance_score: {
type: 'number',
description: 'Min relevance score (0-1)',
minimum: 0,
maximum: 1,
},
},
required: ['search_mode'],
},
};
// =============================================================================
// Handler
// =============================================================================
export async function handleSearchContent(
client: DroydClient,
args: Record<string, unknown>
) {
const parsed = searchContentSchema.parse(args);
return client.searchContent(parsed);
}