|
@@ -0,0 +1,783 @@
|
|
|
|
|
+#!/usr/bin/env node
|
|
|
|
|
+/**
|
|
|
|
|
+ * Admin MCP Server
|
|
|
|
|
+ *
|
|
|
|
|
+ * MCP server for admin backend API integration.
|
|
|
|
|
+ * Provides tools for user management, role management, system configuration,
|
|
|
|
|
+ * order management, and authentication.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Transport: Streamable HTTP (recommended for remote servers)
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
|
|
+import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
|
|
|
+import express from 'express';
|
|
|
|
|
+import { z } from 'zod';
|
|
|
|
|
+import { userTools } from './tools/user-tools.js';
|
|
|
|
|
+import { roleTools } from './tools/role-tools.js';
|
|
|
|
|
+import { systemConfigTools } from './tools/system-config-tools.js';
|
|
|
|
|
+import { orderTools } from './tools/order-tools.js';
|
|
|
|
|
+import { authTools } from './tools/auth-tools.js';
|
|
|
|
|
+
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+// Server Configuration
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+const SERVER_CONFIG = {
|
|
|
|
|
+ name: 'admin-mcp-server',
|
|
|
|
|
+ version: '1.0.0',
|
|
|
|
|
+ port: parseInt(process.env.PORT || '3000', 10),
|
|
|
|
|
+ apiBaseUrl: process.env.API_BASE_URL || 'http://localhost:8080'
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+// Create MCP Server Instance
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+const server = new McpServer({
|
|
|
|
|
+ name: SERVER_CONFIG.name,
|
|
|
|
|
+ version: SERVER_CONFIG.version
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+// Helper: Register Tool with Annotations
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+interface ToolRegistration {
|
|
|
|
|
+ name: string;
|
|
|
|
|
+ schema?: z.ZodSchema;
|
|
|
|
|
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
|
+ handler: (...args: any[]) => any;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface ToolAnnotations {
|
|
|
|
|
+ readOnlyHint?: boolean;
|
|
|
|
|
+ destructiveHint?: boolean;
|
|
|
|
|
+ idempotentHint?: boolean;
|
|
|
|
|
+ openWorldHint?: boolean;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function registerToolWithAnnotations(
|
|
|
|
|
+ registration: ToolRegistration,
|
|
|
|
|
+ annotations: ToolAnnotations,
|
|
|
|
|
+ title: string,
|
|
|
|
|
+ description: string
|
|
|
|
|
+): void {
|
|
|
|
|
+ const { name, schema, handler } = registration;
|
|
|
|
|
+
|
|
|
|
|
+ // Build tool options
|
|
|
|
|
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
|
+ const toolOptions: any = {
|
|
|
|
|
+ title,
|
|
|
|
|
+ description
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // Add input schema if provided
|
|
|
|
|
+ if (schema) {
|
|
|
|
|
+ toolOptions.inputSchema = schema;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Add annotations
|
|
|
|
|
+ toolOptions.annotations = annotations;
|
|
|
|
|
+
|
|
|
|
|
+ // Register the tool
|
|
|
|
|
+ server.registerTool(name, toolOptions, handler);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+// Register Authentication Tools
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+// Login tool
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ authTools.login,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: false,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: false,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Admin Login',
|
|
|
|
|
+ `Authenticate with the admin backend using username and password.
|
|
|
|
|
+
|
|
|
|
|
+This tool establishes an authenticated session by logging in to the admin system.
|
|
|
|
|
+The authentication token is automatically stored and used for subsequent tool calls.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - username (string): Admin username
|
|
|
|
|
+ - password (string): Admin password
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Authentication result with user information.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Login to admin system" -> params with username="admin", password="password"
|
|
|
|
|
+ - Use when: "I need to access the admin API" -> first call this tool
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Authentication failed" if credentials are invalid
|
|
|
|
|
+ - Returns "Error: Cannot connect to API server" if backend is unreachable`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Logout tool
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ authTools.logout,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: false,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: true,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Admin Logout',
|
|
|
|
|
+ `Logout from the admin backend and clear the authentication token.
|
|
|
|
|
+
|
|
|
|
|
+This tool ends the current admin session by clearing the stored authentication token.
|
|
|
|
|
+Subsequent API calls will require re-authentication.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - None
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Logout confirmation message.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Logout from admin system" or "End admin session"
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Rarely fails, mainly for client-side issues`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Get current user tool
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ authTools.getCurrentUser,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: true,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: true,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Get Current Admin User',
|
|
|
|
|
+ `Retrieve information about the currently authenticated admin user.
|
|
|
|
|
+
|
|
|
|
|
+This tool returns details about the user that is currently logged in,
|
|
|
|
|
+including their roles, permissions, and profile information.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - None
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Current user information including ID, username, roles, and permissions.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Who am I logged in as?" or "Get current user info"
|
|
|
|
|
+ - Use when: "Check my admin permissions"
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Authentication failed" if not logged in`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+// Register User Management Tools
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+// List users
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ userTools.userList,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: true,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: true,
|
|
|
|
|
+ openWorldHint: true
|
|
|
|
|
+ },
|
|
|
|
|
+ 'List Users',
|
|
|
|
|
+ `List and search users in the admin system with pagination and filtering.
|
|
|
|
|
+
|
|
|
|
|
+This tool retrieves a paginated list of users from the admin system.
|
|
|
|
|
+Supports keyword search, sorting, and advanced filtering.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - page (number): Page number, starting from 1 (default: 1)
|
|
|
|
|
+ - pageSize (number): Number of items per page, 1-100 (default: 20)
|
|
|
|
|
+ - keyword (string): Optional search keyword for partial matching
|
|
|
|
|
+ - sortBy (string): Optional field to sort by (e.g., "id", "createdAt", "name")
|
|
|
|
|
+ - sortOrder (string): Sort direction: "ASC" or "DESC" (default: "DESC")
|
|
|
|
|
+ - filters (string): Optional filter conditions as JSON string
|
|
|
|
|
+ - response_format (string): Output format: "markdown" or "json" (default: "markdown")
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ For JSON format: Structured data with schema:
|
|
|
|
|
+ {
|
|
|
|
|
+ "total": number, // Total number of users
|
|
|
|
|
+ "count": number, // Number of results in this response
|
|
|
|
|
+ "current": number, // Current page number
|
|
|
|
|
+ "pageSize": number, // Page size
|
|
|
|
|
+ "users": [...], // Array of user objects
|
|
|
|
|
+ "has_more": boolean // Whether more results exist
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "List all users" -> params with page=1, pageSize=20
|
|
|
|
|
+ - Use when: "Search for user john" -> params with keyword="john"
|
|
|
|
|
+ - Use when: "List active users only" -> params with filters='{"status": 1}'
|
|
|
|
|
+ - Use when: "List users sorted by creation date" -> params with sortBy="createdAt", sortOrder="DESC"
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Permission denied" if not authorized
|
|
|
|
|
+ - Returns "Error: Cannot connect to API server" if backend is unreachable`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Get user
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ userTools.userGet,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: true,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: true,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Get User by ID',
|
|
|
|
|
+ `Retrieve detailed information about a specific user by their ID.
|
|
|
|
|
+
|
|
|
|
|
+This tool fetches complete user information including profile, roles, and company.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - id (number): User ID (required)
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Complete user information with roles and company details.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Get user with ID 123" -> params with id=123
|
|
|
|
|
+ - Use when: "Show user details for user 456"
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Resource not found" if user ID doesn't exist
|
|
|
|
|
+ - Returns "Error: Permission denied" if not authorized`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Create user
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ userTools.userCreate,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: false,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: false,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Create User',
|
|
|
|
|
+ `Create a new user in the admin system.
|
|
|
|
|
+
|
|
|
|
|
+This tool creates a new user with the provided information.
|
|
|
|
|
+A password will be generated if not provided.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - username (string): Username (required)
|
|
|
|
|
+ - password (string): Password, min 6 characters (optional)
|
|
|
|
|
+ - nickname (string): Display name (optional)
|
|
|
|
|
+ - phone (string): Phone number in Chinese format (optional)
|
|
|
|
|
+ - email (string): Email address (optional)
|
|
|
|
|
+ - realName (string): Real/legal name (optional)
|
|
|
|
|
+ - avatarFileId (number): Avatar file ID (optional)
|
|
|
|
|
+ - companyId (number): Company ID (optional)
|
|
|
|
|
+ - status (number): Status: 0 = disabled, 1 = enabled (optional)
|
|
|
|
|
+ - roleIds (array): Array of role IDs to assign (optional)
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Created user information with ID.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Create a new user john_doe" -> params with username="john_doe"
|
|
|
|
|
+ - Use when: "Add user with phone number" -> params with username="user123", phone="13800138000"
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Data already exists" if username/phone/email is duplicated
|
|
|
|
|
+ - Returns "Error: Permission denied" if not authorized`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Update user
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ userTools.userUpdate,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: false,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: true,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Update User',
|
|
|
|
|
+ `Update an existing user's information.
|
|
|
|
|
+
|
|
|
|
|
+This tool modifies user information for the specified user ID.
|
|
|
|
|
+Only the fields provided will be updated.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - id (number): User ID to update (required)
|
|
|
|
|
+ - username (string): Username (optional)
|
|
|
|
|
+ - password (string): New password, min 6 characters (optional)
|
|
|
|
|
+ - nickname (string): Display name (optional)
|
|
|
|
|
+ - phone (string): Phone number (optional)
|
|
|
|
|
+ - email (string): Email address (optional)
|
|
|
|
|
+ - realName (string): Real/legal name (optional)
|
|
|
|
|
+ - avatarFileId (number): Avatar file ID (optional)
|
|
|
|
|
+ - companyId (number): Company ID (optional)
|
|
|
|
|
+ - status (number): Status: 0 = disabled, 1 = enabled (optional)
|
|
|
|
|
+ - roleIds (array): Array of role IDs to assign (optional)
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Updated user information.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Update user 123 nickname to John" -> params with id=123, nickname="John"
|
|
|
|
|
+ - Use when: "Disable user 456" -> params with id=456, status=0
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Resource not found" if user ID doesn't exist
|
|
|
|
|
+ - Returns "Error: Permission denied" if not authorized`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Delete user
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ userTools.userDelete,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: false,
|
|
|
|
|
+ destructiveHint: true,
|
|
|
|
|
+ idempotentHint: false,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Delete User',
|
|
|
|
|
+ `Delete a user from the admin system.
|
|
|
|
|
+
|
|
|
|
|
+This tool permanently deletes the specified user.
|
|
|
|
|
+This action cannot be undone.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - id (number): User ID to delete (required)
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Deletion confirmation with deleted user ID.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Delete user 123" -> params with id=123
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Resource not found" if user ID doesn't exist
|
|
|
|
|
+ - Returns "Error: Permission denied" if not authorized
|
|
|
|
|
+ - May fail if user has dependent records`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+// Register Role Management Tools
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+// List roles
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ roleTools.roleList,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: true,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: true,
|
|
|
|
|
+ openWorldHint: true
|
|
|
|
|
+ },
|
|
|
|
|
+ 'List Roles',
|
|
|
|
|
+ `List and search roles in the admin system with pagination.
|
|
|
|
|
+
|
|
|
|
|
+This tool retrieves a paginated list of roles from the admin system.
|
|
|
|
|
+Supports keyword search and sorting.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - page (number): Page number, starting from 1 (default: 1)
|
|
|
|
|
+ - pageSize (number): Number of items per page, 1-100 (default: 20)
|
|
|
|
|
+ - keyword (string): Optional search keyword (optional)
|
|
|
|
|
+ - sortBy (string): Optional field to sort by (optional)
|
|
|
|
|
+ - sortOrder (string): Sort direction: "ASC" or "DESC" (default: "DESC")
|
|
|
|
|
+ - filters (string): Optional filter conditions as JSON string (optional)
|
|
|
|
|
+ - response_format (string): Output format: "markdown" or "json" (default: "markdown")
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Paginated list of roles with total count.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "List all roles" -> default parameters
|
|
|
|
|
+ - Use when: "Search for admin role" -> params with keyword="admin"
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Permission denied" if not authorized`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Get role
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ roleTools.roleGet,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: true,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: true,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Get Role by ID',
|
|
|
|
|
+ `Retrieve detailed information about a specific role by ID.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - id (number): Role ID (required)
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Complete role information.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Get role with ID 5" -> params with id=5
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Resource not found" if role ID doesn't exist`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Create role
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ roleTools.roleCreate,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: false,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: false,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Create Role',
|
|
|
|
|
+ `Create a new role in the admin system.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - name (string): Role name (required)
|
|
|
|
|
+ - description (string): Role description (optional)
|
|
|
|
|
+ - code (string): Role code for permission checks (optional)
|
|
|
|
|
+ - status (number): Status: 0 = disabled, 1 = enabled (optional)
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Created role information with ID.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Create role Content Manager" -> params with name="Content Manager"
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Data already exists" if role name/code is duplicated`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Update role
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ roleTools.roleUpdate,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: false,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: true,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Update Role',
|
|
|
|
|
+ `Update an existing role's information.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - id (number): Role ID to update (required)
|
|
|
|
|
+ - name (string): Role name (optional)
|
|
|
|
|
+ - description (string): Role description (optional)
|
|
|
|
|
+ - code (string): Role code (optional)
|
|
|
|
|
+ - status (number): Status (optional)
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Updated role information.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Update role 3 description" -> params with id=3, description="New description"
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Resource not found" if role ID doesn't exist`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Delete role
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ roleTools.roleDelete,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: false,
|
|
|
|
|
+ destructiveHint: true,
|
|
|
|
|
+ idempotentHint: false,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Delete Role',
|
|
|
|
|
+ `Delete a role from the admin system.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - id (number): Role ID to delete (required)
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Deletion confirmation.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Delete role 10" -> params with id=10
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Resource not found" if role ID doesn't exist
|
|
|
|
|
+ - May fail if role is assigned to users`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+// Register System Config Tools
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+// List system configs
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ systemConfigTools.systemConfigList,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: true,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: true,
|
|
|
|
|
+ openWorldHint: true
|
|
|
|
|
+ },
|
|
|
|
|
+ 'List System Configurations',
|
|
|
|
|
+ `List and search system configurations with pagination.
|
|
|
|
|
+
|
|
|
|
|
+This tool retrieves a paginated list of system configuration items.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - page (number): Page number, starting from 1 (default: 1)
|
|
|
|
|
+ - pageSize (number): Number of items per page, 1-100 (default: 20)
|
|
|
|
|
+ - keyword (string): Optional search keyword (optional)
|
|
|
|
|
+ - sortBy (string): Optional field to sort by (optional)
|
|
|
|
|
+ - sortOrder (string): Sort direction: "ASC" or "DESC" (default: "DESC")
|
|
|
|
|
+ - filters (string): Optional filter conditions as JSON string (optional)
|
|
|
|
|
+ - response_format (string): Output format: "markdown" or "json" (default: "markdown")
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Paginated list of system configurations.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "List all system configs" -> default parameters
|
|
|
|
|
+ - Use when: "Get configs in category 'payment'" -> params with filters='{"category": "payment"}'
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Permission denied" if not authorized`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Get system config
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ systemConfigTools.systemConfigGet,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: true,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: true,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Get System Configuration by ID',
|
|
|
|
|
+ `Retrieve a specific system configuration by ID.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - id (number): Configuration ID (required)
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ System configuration details.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Get config with ID 1" -> params with id=1
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Resource not found" if config ID doesn't exist`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Create system config
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ systemConfigTools.systemConfigCreate,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: false,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: false,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Create System Configuration',
|
|
|
|
|
+ `Create a new system configuration item.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - configKey (string): Configuration key (required)
|
|
|
|
|
+ - configValue (string): Configuration value (required)
|
|
|
|
|
+ - description (string): Configuration description (optional)
|
|
|
|
|
+ - category (string): Configuration category (optional)
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Created configuration with ID.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Create config for max upload size" -> params with configKey="maxUploadSize", configValue="10485760"
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Data already exists" if config key is duplicated`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Update system config
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ systemConfigTools.systemConfigUpdate,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: false,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: true,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Update System Configuration',
|
|
|
|
|
+ `Update an existing system configuration.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - id (number): Configuration ID to update (required)
|
|
|
|
|
+ - configKey (string): Configuration key (optional)
|
|
|
|
|
+ - configValue (string): Configuration value (optional)
|
|
|
|
|
+ - description (string): Configuration description (optional)
|
|
|
|
|
+ - category (string): Configuration category (optional)
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Updated configuration details.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Update config 5 value to 100" -> params with id=5, configValue="100"
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Resource not found" if config ID doesn't exist`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Delete system config
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ systemConfigTools.systemConfigDelete,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: false,
|
|
|
|
|
+ destructiveHint: true,
|
|
|
|
|
+ idempotentHint: false,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Delete System Configuration',
|
|
|
|
|
+ `Delete a system configuration item.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - id (number): Configuration ID to delete (required)
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Deletion confirmation.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Delete config 10" -> params with id=10
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Resource not found" if config ID doesn't exist`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+// Register Order Management Tools
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+// List orders
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ orderTools.orderList,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: true,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: true,
|
|
|
|
|
+ openWorldHint: true
|
|
|
|
|
+ },
|
|
|
|
|
+ 'List Orders',
|
|
|
|
|
+ `List and search orders in the admin system with pagination and filtering.
|
|
|
|
|
+
|
|
|
|
|
+This tool retrieves a paginated list of orders from the system.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - page (number): Page number, starting from 1 (default: 1)
|
|
|
|
|
+ - pageSize (number): Number of items per page, 1-100 (default: 20)
|
|
|
|
|
+ - keyword (string): Optional search keyword (optional)
|
|
|
|
|
+ - sortBy (string): Optional field to sort by (optional)
|
|
|
|
|
+ - sortOrder (string): Sort direction: "ASC" or "DESC" (default: "DESC")
|
|
|
|
|
+ - filters (string): Optional filter conditions as JSON string (optional)
|
|
|
|
|
+ - response_format (string): Output format: "markdown" or "json" (default: "markdown")
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Paginated list of orders with total count.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "List all orders" -> default parameters
|
|
|
|
|
+ - Use when: "Get pending orders" -> params with filters='{"status": "pending"}'
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Permission denied" if not authorized`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// Get order
|
|
|
|
|
+registerToolWithAnnotations(
|
|
|
|
|
+ orderTools.orderGet,
|
|
|
|
|
+ {
|
|
|
|
|
+ readOnlyHint: true,
|
|
|
|
|
+ destructiveHint: false,
|
|
|
|
|
+ idempotentHint: true,
|
|
|
|
|
+ openWorldHint: false
|
|
|
|
|
+ },
|
|
|
|
|
+ 'Get Order by ID',
|
|
|
|
|
+ `Retrieve detailed information about a specific order by ID.
|
|
|
|
|
+
|
|
|
|
|
+Args:
|
|
|
|
|
+ - id (number): Order ID (required)
|
|
|
|
|
+
|
|
|
|
|
+Returns:
|
|
|
|
|
+ Complete order information with delivery address.
|
|
|
|
|
+
|
|
|
|
|
+Examples:
|
|
|
|
|
+ - Use when: "Get order with ID 12345" -> params with id=12345
|
|
|
|
|
+
|
|
|
|
|
+Error Handling:
|
|
|
|
|
+ - Returns "Error: Resource not found" if order ID doesn't exist`
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+// Start HTTP Server with Streamable Transport
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+async function runHTTP() {
|
|
|
|
|
+ // Create Express app
|
|
|
|
|
+ const app = express();
|
|
|
|
|
+ app.use(express.json());
|
|
|
|
|
+
|
|
|
|
|
+ // Health check endpoint
|
|
|
|
|
+ app.get('/health', (_req, res) => {
|
|
|
|
|
+ res.json({
|
|
|
|
|
+ status: 'healthy',
|
|
|
|
|
+ server: SERVER_CONFIG.name,
|
|
|
|
|
+ version: SERVER_CONFIG.version,
|
|
|
|
|
+ apiBaseUrl: SERVER_CONFIG.apiBaseUrl
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // MCP endpoint
|
|
|
|
|
+ app.post('/mcp', async (req, res) => {
|
|
|
|
|
+ // Create a new transport for each request (stateless, prevents request ID collisions)
|
|
|
|
|
+ const transport = new StreamableHTTPServerTransport({
|
|
|
|
|
+ sessionIdGenerator: undefined,
|
|
|
|
|
+ enableJsonResponse: true
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // Clean up transport when response closes
|
|
|
|
|
+ res.on('close', () => transport.close());
|
|
|
|
|
+
|
|
|
|
|
+ // Connect server to transport and handle request
|
|
|
|
|
+ await server.connect(transport);
|
|
|
|
|
+ await transport.handleRequest(req, res, req.body);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // Start listening
|
|
|
|
|
+
|
|
|
|
|
+ app.listen(SERVER_CONFIG.port, () => {
|
|
|
|
|
+ // eslint-disable-next-line no-console
|
|
|
|
|
+ console.error(`🚀 ${SERVER_CONFIG.name} v${SERVER_CONFIG.version}`);
|
|
|
|
|
+ // eslint-disable-next-line no-console
|
|
|
|
|
+ console.error(`📡 MCP endpoint: http://localhost:${SERVER_CONFIG.port}/mcp`);
|
|
|
|
|
+ // eslint-disable-next-line no-console
|
|
|
|
|
+ console.error(`🏥 Health check: http://localhost:${SERVER_CONFIG.port}/health`);
|
|
|
|
|
+ // eslint-disable-next-line no-console
|
|
|
|
|
+ console.error(`🔌 API backend: ${SERVER_CONFIG.apiBaseUrl}`);
|
|
|
|
|
+ // eslint-disable-next-line no-console
|
|
|
|
|
+ console.error('');
|
|
|
|
|
+ // eslint-disable-next-line no-console
|
|
|
|
|
+ console.error(`To connect to this MCP server, use: http://localhost:${SERVER_CONFIG.port}/mcp`);
|
|
|
|
|
+ });
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+// Main Entry Point
|
|
|
|
|
+// ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+runHTTP().catch((error) => {
|
|
|
|
|
+ // eslint-disable-next-line no-console
|
|
|
|
|
+ console.error('Failed to start server:', error);
|
|
|
|
|
+ process.exit(1);
|
|
|
|
|
+});
|