Skip to main content
Glama

Matomo MCP Server

by thichcode
index.ts15.4 kB
import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, Tool, } from '@modelcontextprotocol/sdk/types.js'; import { MatomoApiService } from './services/matomo-api.js'; import { MatomoConfig } from './types/matomo.js'; import dotenv from 'dotenv'; dotenv.config(); class MatomoMCPServer { private server: Server; private matomoService: MatomoApiService | null = null; constructor() { this.server = new Server( { name: 'matomo-mcp', version: '1.0.0', }, { capabilities: { tools: {}, }, } ); this.setupToolHandlers(); } private setupToolHandlers() { // Initialize Matomo connection this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'matomo_connect', description: 'Kết nối đến Matomo instance với URL và token xác thực', inputSchema: { type: 'object', properties: { baseUrl: { type: 'string', description: 'URL của Matomo instance (ví dụ: https://analytics.example.com)', }, tokenAuth: { type: 'string', description: 'Token xác thực Matomo API', }, }, required: ['baseUrl', 'tokenAuth'], }, }, { name: 'matomo_get_sites', description: 'Lấy danh sách tất cả các sites trong Matomo', inputSchema: { type: 'object', properties: {}, }, }, { name: 'matomo_get_site', description: 'Lấy thông tin chi tiết của một site', inputSchema: { type: 'object', properties: { siteId: { type: 'number', description: 'ID của site cần lấy thông tin', }, }, required: ['siteId'], }, }, { name: 'matomo_add_site', description: 'Thêm một site mới vào Matomo', inputSchema: { type: 'object', properties: { name: { type: 'string', description: 'Tên của site', }, urls: { type: 'array', items: { type: 'string' }, description: 'Danh sách URLs của site', }, timezone: { type: 'string', description: 'Múi giờ của site (mặc định: UTC)', default: 'UTC', }, }, required: ['name', 'urls'], }, }, { name: 'matomo_get_users', description: 'Lấy danh sách tất cả users trong Matomo', inputSchema: { type: 'object', properties: {}, }, }, { name: 'matomo_add_user', description: 'Thêm một user mới vào Matomo', inputSchema: { type: 'object', properties: { userLogin: { type: 'string', description: 'Tên đăng nhập của user', }, email: { type: 'string', description: 'Email của user', }, password: { type: 'string', description: 'Mật khẩu của user', }, alias: { type: 'string', description: 'Bí danh của user (tùy chọn)', }, }, required: ['userLogin', 'email', 'password'], }, }, { name: 'matomo_get_goals', description: 'Lấy danh sách goals của một site', inputSchema: { type: 'object', properties: { siteId: { type: 'number', description: 'ID của site', }, }, required: ['siteId'], }, }, { name: 'matomo_add_goal', description: 'Thêm một goal mới cho site', inputSchema: { type: 'object', properties: { siteId: { type: 'number', description: 'ID của site', }, name: { type: 'string', description: 'Tên của goal', }, description: { type: 'string', description: 'Mô tả của goal', }, matchAttribute: { type: 'string', description: 'Thuộc tính khớp (url, title, event, etc.)', }, pattern: { type: 'string', description: 'Mẫu khớp', }, patternType: { type: 'string', description: 'Loại mẫu (exact, contains, regex, etc.)', }, }, required: ['siteId', 'name', 'description', 'matchAttribute', 'pattern', 'patternType'], }, }, { name: 'matomo_get_visits_summary', description: 'Lấy tổng quan lượt truy cập của site', inputSchema: { type: 'object', properties: { siteId: { type: 'number', description: 'ID của site', }, date: { type: 'string', description: 'Ngày cần lấy dữ liệu (YYYY-MM-DD)', }, period: { type: 'string', description: 'Chu kỳ (day, week, month, year)', default: 'day', }, }, required: ['siteId', 'date'], }, }, { name: 'matomo_get_top_pages', description: 'Lấy danh sách trang được truy cập nhiều nhất', inputSchema: { type: 'object', properties: { siteId: { type: 'number', description: 'ID của site', }, date: { type: 'string', description: 'Ngày cần lấy dữ liệu (YYYY-MM-DD)', }, period: { type: 'string', description: 'Chu kỳ (day, week, month, year)', default: 'day', }, limit: { type: 'number', description: 'Số lượng kết quả tối đa', default: 10, }, }, required: ['siteId', 'date'], }, }, { name: 'matomo_get_system_info', description: 'Lấy thông tin hệ thống Matomo', inputSchema: { type: 'object', properties: {}, }, }, ] as Tool[], }; }); this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { switch (name) { case 'matomo_connect': return await this.handleConnect(args as { baseUrl: string; tokenAuth: string }); case 'matomo_get_sites': return await this.handleGetSites(); case 'matomo_get_site': return await this.handleGetSite(args as { siteId: number }); case 'matomo_add_site': return await this.handleAddSite(args as { name: string; urls: string[]; timezone?: string }); case 'matomo_get_users': return await this.handleGetUsers(); case 'matomo_add_user': return await this.handleAddUser(args as { userLogin: string; email: string; password: string; alias?: string }); case 'matomo_get_goals': return await this.handleGetGoals(args as { siteId: number }); case 'matomo_add_goal': return await this.handleAddGoal(args as { siteId: number; name: string; description: string; matchAttribute: string; pattern: string; patternType: string; }); case 'matomo_get_visits_summary': return await this.handleGetVisitsSummary(args as { siteId: number; date: string; period?: string }); case 'matomo_get_top_pages': return await this.handleGetTopPages(args as { siteId: number; date: string; period?: string; limit?: number }); case 'matomo_get_system_info': return await this.handleGetSystemInfo(); default: throw new Error(`Tool không được hỗ trợ: ${name}`); } } catch (error) { return { content: [ { type: 'text', text: `Lỗi: ${error instanceof Error ? error.message : 'Lỗi không xác định'}`, }, ], }; } }); } private async handleConnect(args: { baseUrl: string; tokenAuth: string }) { const config: MatomoConfig = { baseUrl: args.baseUrl, tokenAuth: args.tokenAuth, }; this.matomoService = new MatomoApiService(config); // Test connection await this.matomoService.getSites(); return { content: [ { type: 'text', text: `Đã kết nối thành công đến Matomo tại ${args.baseUrl}`, }, ], }; } private async handleGetSites() { if (!this.matomoService) { throw new Error('Chưa kết nối đến Matomo. Vui lòng sử dụng matomo_connect trước.'); } const sites = await this.matomoService.getSites(); return { content: [ { type: 'text', text: `Danh sách sites:\n${JSON.stringify(sites, null, 2)}`, }, ], }; } private async handleGetSite(args: { siteId: number }) { if (!this.matomoService) { throw new Error('Chưa kết nối đến Matomo. Vui lòng sử dụng matomo_connect trước.'); } const site = await this.matomoService.getSite(args.siteId); return { content: [ { type: 'text', text: `Thông tin site:\n${JSON.stringify(site, null, 2)}`, }, ], }; } private async handleAddSite(args: { name: string; urls: string[]; timezone?: string }) { if (!this.matomoService) { throw new Error('Chưa kết nối đến Matomo. Vui lòng sử dụng matomo_connect trước.'); } const siteId = await this.matomoService.addSite(args.name, args.urls, args.timezone); return { content: [ { type: 'text', text: `Đã thêm site thành công với ID: ${siteId}`, }, ], }; } private async handleGetUsers() { if (!this.matomoService) { throw new Error('Chưa kết nối đến Matomo. Vui lòng sử dụng matomo_connect trước.'); } const users = await this.matomoService.getUsers(); return { content: [ { type: 'text', text: `Danh sách users:\n${JSON.stringify(users, null, 2)}`, }, ], }; } private async handleAddUser(args: { userLogin: string; email: string; password: string; alias?: string }) { if (!this.matomoService) { throw new Error('Chưa kết nối đến Matomo. Vui lòng sử dụng matomo_connect trước.'); } await this.matomoService.addUser(args.userLogin, args.email, args.password, args.alias); return { content: [ { type: 'text', text: `Đã thêm user thành công: ${args.userLogin}`, }, ], }; } private async handleGetGoals(args: { siteId: number }) { if (!this.matomoService) { throw new Error('Chưa kết nối đến Matomo. Vui lòng sử dụng matomo_connect trước.'); } const goals = await this.matomoService.getGoals(args.siteId); return { content: [ { type: 'text', text: `Danh sách goals:\n${JSON.stringify(goals, null, 2)}`, }, ], }; } private async handleAddGoal(args: { siteId: number; name: string; description: string; matchAttribute: string; pattern: string; patternType: string; }) { if (!this.matomoService) { throw new Error('Chưa kết nối đến Matomo. Vui lòng sử dụng matomo_connect trước.'); } const goalId = await this.matomoService.addGoal( args.siteId, args.name, args.description, args.matchAttribute, args.pattern, args.patternType ); return { content: [ { type: 'text', text: `Đã thêm goal thành công với ID: ${goalId}`, }, ], }; } private async handleGetVisitsSummary(args: { siteId: number; date: string; period?: string }) { if (!this.matomoService) { throw new Error('Chưa kết nối đến Matomo. Vui lòng sử dụng matomo_connect trước.'); } const summary = await this.matomoService.getVisitsSummary(args.siteId, args.date, args.period); return { content: [ { type: 'text', text: `Tổng quan lượt truy cập:\n${JSON.stringify(summary, null, 2)}`, }, ], }; } private async handleGetTopPages(args: { siteId: number; date: string; period?: string; limit?: number }) { if (!this.matomoService) { throw new Error('Chưa kết nối đến Matomo. Vui lòng sử dụng matomo_connect trước.'); } const pages = await this.matomoService.getTopPages(args.siteId, args.date, args.period, args.limit); return { content: [ { type: 'text', text: `Top pages:\n${JSON.stringify(pages, null, 2)}`, }, ], }; } private async handleGetSystemInfo() { if (!this.matomoService) { throw new Error('Chưa kết nối đến Matomo. Vui lòng sử dụng matomo_connect trước.'); } const info = await this.matomoService.getSystemInfo(); return { content: [ { type: 'text', text: `Thông tin hệ thống:\n${JSON.stringify(info, null, 2)}`, }, ], }; } async run() { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error('Matomo MCP Server đang chạy...'); } } const server = new MatomoMCPServer(); server.run().catch(console.error);

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/thichcode/matomo_mcp'

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