Skip to main content
Glama

Video Metadata MCP Server

server.js14.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Server = void 0; const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js"); const zod_1 = __importDefault(require("zod")); const VideoMetadataDao_1 = require("./db/VideoMetadataDao"); const VideoMetadataSchema = zod_1.default.object({ title: zod_1.default .string() .describe("Title of the video, e.g. 'LaLiga : Barcelona vs Real Madrid'."), gameType: zod_1.default.string().describe("Type of game, e.g. 'football', 'basketball'."), teams: zod_1.default .array(zod_1.default.string()) .describe("Array of team names involved in the match, e.g. ['Barcelona', 'Real Madrid']."), score: zod_1.default.string().optional().describe("Score of the match, e.g. '2-1'."), winner: zod_1.default .string() .optional() .describe("Winner of the match, e.g. 'Barcelona'."), videoUrl: zod_1.default .string() .url() .optional() .describe("URL of the video, e.g. 'https://example.com/video/123'."), description: zod_1.default.string().optional().describe("Description of the video."), tags: zod_1.default .record(zod_1.default.any()) .optional() .describe("Tags associated with the video."), matchDate: zod_1.default .string() .datetime() .optional() .describe("Date of the match, e.g. '2022-01-01T00:00:00Z'."), venue: zod_1.default.string().optional().describe("Venue of the match, e.g. 'Camp Nou'."), league: zod_1.default .string() .optional() .describe("League of the match, e.g. 'La Liga'."), season: zod_1.default.string().optional().describe("Season of the match, e.g. '2022'."), }); const SearchFiltersSchema = zod_1.default.object({ gameType: zod_1.default .string() .optional() .describe("Filter by game type, e.g. 'football', 'basketball'."), teams: zod_1.default .union([zod_1.default.string(), zod_1.default.array(zod_1.default.string())]) .optional() .describe("Filter by team name(s) e.g. 'Celtics', ['Celtics', 'Knicks']."), league: zod_1.default .string() .optional() .describe("Filter by league name, e.g. 'NBA', 'Premier League'."), season: zod_1.default .string() .optional() .describe("Filter by season, e.g. '2021', '2022'."), winner: zod_1.default .string() .optional() .describe("Filter by winner team name, e.g. 'Arsenal'."), venue: zod_1.default .string() .optional() .describe("Filter by venue name, e.g. 'Wembley Stadium'."), tags: zod_1.default .record(zod_1.default.any()) .optional() .describe("Filter by tags., e.g. { 'highlight': true, 'full_match': false }."), matchDateStart: zod_1.default .string() .datetime() .optional() .describe("Filter by match start date, e.g. '2022-01-01T00:00:00Z'."), matchDateEnd: zod_1.default .string() .datetime() .optional() .describe("Filter by match end date, e.g. '2022-12-31T23:59:59Z'."), }); const SearchQuerySchema = zod_1.default.object({ limit: zod_1.default .number() .int() .positive() .optional() .describe("Maximum number of results to return."), offset: zod_1.default .number() .int() .min(0) .optional() .describe("Number of results to skip before starting to return results."), orderBy: zod_1.default .string() .optional() .describe("Field to order results by, e.g. 'matchDate', 'title'."), orderDirection: zod_1.default .enum(["asc", "desc"]) .optional() .describe("Direction to order results, either 'asc' for ascending or 'desc' for descending."), select: zod_1.default .array(zod_1.default.string()) .optional() .describe("Fields to select in the results, e.g. ['title', 'gameType', 'teams']."), }); class Server { _server; _db; constructor(db) { if (!db) { throw new Error("DatabaseManager instance is required."); } this._db = db; this._server = new mcp_js_1.McpServer({ name: "sports-metadata-server", version: "1.0.0", }); } async initialize() { this.registerTools(); } async shutdown() { await this._server.close(); } registerTools() { this._server.tool("list_unique_game_types", "Lists all unique game types in the video library (e.g. 'football', 'basketball').", {}, async () => { const result = await VideoMetadataDao_1.videoMetadataDao.getUniqueGameTypes(this._db); return { content: [ { type: "text", text: result.join(", "), }, ], }; }); this._server.tool("list_unique_leagues", "Lists all unique leagues in the video library (e.g. 'NBA', 'Premier League').", {}, async () => { const result = await VideoMetadataDao_1.videoMetadataDao.getUniqueLeagues(this._db); return { content: [ { type: "text", text: result.join(", "), }, ], }; }); this._server.tool("list_unique_seasons", "Lists all unique seasons in the video library (e.g. '2021', '2022').", {}, async () => { const result = await VideoMetadataDao_1.videoMetadataDao.getUniqueSeasons(this._db); return { content: [ { type: "text", text: result.join(", "), }, ], }; }); this._server.tool("search_videos", "Searches for videos based on various filters, e.g. 'football', 'Barcelona vs Real Madrid'.", { term: zod_1.default .string() .describe("Search term to filter videos, e.g 'barcelona'."), gameType: zod_1.default .string() .optional() .describe("Filter by game type, e.g. 'football', 'basketball'."), teams: zod_1.default .union([zod_1.default.string(), zod_1.default.array(zod_1.default.string())]) .optional() .describe("Filter by team name(s) e.g. 'Celtics', ['Celtics', 'Knicks']."), league: zod_1.default .string() .optional() .describe("Filter by league name, e.g. 'NBA', 'Premier League'."), season: zod_1.default .string() .optional() .describe("Filter by season, e.g. '2021', '2022'."), winner: zod_1.default .string() .optional() .describe("Filter by winner team name, e.g. 'Arsenal'."), venue: zod_1.default .string() .optional() .describe("Filter by venue name, e.g. 'Wembley Stadium'."), tags: zod_1.default .record(zod_1.default.any()) .optional() .describe("Filter by tags., e.g. { 'highlight': true, 'full_match': false }."), matchDateStart: zod_1.default .string() .datetime() .optional() .describe("Filter by match start date, e.g. '2022-01-01T00:00:00Z'."), matchDateEnd: zod_1.default .string() .datetime() .optional() .describe("Filter by match end date, e.g. '2022-12-31T23:59:59Z'."), limit: zod_1.default .number() .int() .positive() .optional() .describe("Maximum number of results to return."), offset: zod_1.default .number() .int() .min(0) .optional() .describe("Number of results to skip before starting to return results."), orderBy: zod_1.default .string() .optional() .describe("Field to order results by, e.g. 'matchDate', 'title'."), orderDirection: zod_1.default .enum(["asc", "desc"]) .optional() .describe("Direction to order results, either 'asc' for ascending or 'desc' for descending."), select: zod_1.default .array(zod_1.default.string()) .optional() .describe("Fields to select in the results, e.g. ['title', 'gameType', 'teams']."), }, async (request) => { console.log("Search term:", request.term); const validatedFilters = SearchFiltersSchema.parse(request); const filter = { ...validatedFilters, dateRange: { start: validatedFilters.matchDateStart ? new Date(validatedFilters.matchDateStart) : undefined, end: validatedFilters.matchDateEnd ? new Date(validatedFilters.matchDateEnd) : undefined, }, }; const validatedQuery = SearchQuerySchema.parse(request); const queryOpts = { ...validatedQuery, }; const result = await VideoMetadataDao_1.videoMetadataDao.searchVideoMetadata(this._db, request.term, filter, queryOpts); return { content: [ { type: "text", text: JSON.stringify(result, null), }, ], }; }); this._server.tool("get_video_metadata_by_filters", "Retrieves video metadata based on the provided filters.", { gameType: zod_1.default .string() .optional() .describe("Filter by game type, e.g. 'football', 'basketball'."), teams: zod_1.default .union([zod_1.default.string(), zod_1.default.array(zod_1.default.string())]) .optional() .describe("Filter by team name(s) e.g. 'Celtics', ['Celtics', 'Knicks']."), league: zod_1.default .string() .optional() .describe("Filter by league name, e.g. 'NBA', 'Premier League'."), season: zod_1.default .string() .optional() .describe("Filter by season, e.g. '2021', '2022'."), winner: zod_1.default .string() .optional() .describe("Filter by winner team name, e.g. 'Arsenal'."), venue: zod_1.default .string() .optional() .describe("Filter by venue name, e.g. 'Wembley Stadium'."), tags: zod_1.default .record(zod_1.default.any()) .optional() .describe("Filter by tags., e.g. { 'highlight': true, 'full_match': false }."), matchDateStart: zod_1.default .string() .datetime() .optional() .describe("Filter by match start date, e.g. '2022-01-01T00:00:00Z'."), matchDateEnd: zod_1.default .string() .datetime() .optional() .describe("Filter by match end date, e.g. '2022-12-31T23:59:59Z'."), limit: zod_1.default .number() .int() .positive() .optional() .describe("Maximum number of results to return."), offset: zod_1.default .number() .int() .min(0) .optional() .describe("Number of results to skip before starting to return results."), orderBy: zod_1.default .string() .optional() .describe("Field to order results by, e.g. 'matchDate', 'title'."), orderDirection: zod_1.default .enum(["asc", "desc"]) .optional() .describe("Direction to order results, either 'asc' for ascending or 'desc' for descending."), select: zod_1.default .array(zod_1.default.string()) .optional() .describe("Fields to select in the results, e.g. ['title', 'gameType', 'teams']."), }, async (request) => { const validatedFilters = SearchFiltersSchema.parse(request); const filter = { ...validatedFilters, dateRange: { start: validatedFilters.matchDateStart ? new Date(validatedFilters.matchDateStart) : undefined, end: validatedFilters.matchDateEnd ? new Date(validatedFilters.matchDateEnd) : undefined, }, }; const validatedQuery = SearchQuerySchema.parse(request); const queryOpts = { ...validatedQuery, }; const result = await VideoMetadataDao_1.videoMetadataDao.getVideoMetadataByFilters(this._db, filter, queryOpts); return { content: [ { type: "text", text: JSON.stringify(result, null), }, ], }; }); } get server() { return this._server; } } exports.Server = Server;

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/stich-studios/metadata-mcp'

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