|
|
@@ -0,0 +1,318 @@
|
|
|
+/**
|
|
|
+ * Company Management Tools
|
|
|
+ *
|
|
|
+ * MCP tools for managing companies in the admin system.
|
|
|
+ */
|
|
|
+
|
|
|
+import { getApiClient } from '../services/api-client.js';
|
|
|
+import {
|
|
|
+ CompanyListInputSchema,
|
|
|
+ CompanyGetInputSchema,
|
|
|
+ CompanyCreateInputSchema,
|
|
|
+ CompanyUpdateInputSchema,
|
|
|
+ CompanyDeleteInputSchema
|
|
|
+} from '../schemas/index.js';
|
|
|
+import type {
|
|
|
+ CompanyListInput,
|
|
|
+ CompanyGetInput,
|
|
|
+ CompanyCreateInput,
|
|
|
+ CompanyUpdateInput,
|
|
|
+ CompanyDeleteInput
|
|
|
+} from '../schemas/index.js';
|
|
|
+import { CHARACTER_LIMIT, ResponseFormat } from '../constants.js';
|
|
|
+import type { Company, PaginatedResponse } from '../types.js';
|
|
|
+
|
|
|
+/**
|
|
|
+ * Format company data for markdown output
|
|
|
+ */
|
|
|
+function formatCompanyMarkdown(company: Company): string {
|
|
|
+ const lines = [
|
|
|
+ `## Company: ${company.companyName} (ID: ${company.id})`,
|
|
|
+ '',
|
|
|
+ `**Company Name**: ${company.companyName}`,
|
|
|
+ company.contactPerson ? `**Contact Person**: ${company.contactPerson}` : null,
|
|
|
+ company.contactPhone ? `**Contact Phone**: ${company.contactPhone}` : null,
|
|
|
+ company.contactEmail ? `**Contact Email**: ${company.contactEmail}` : null,
|
|
|
+ company.address ? `**Address**: ${company.address}` : null,
|
|
|
+ company.platform ? `**Platform**: ${company.platform.name} (ID: ${company.platformId})` : null,
|
|
|
+ `**Status**: ${company.status === 1 ? 'Enabled' : 'Disabled'}`,
|
|
|
+ `**Created At**: ${new Date(company.createTime).toLocaleString('zh-CN')}`,
|
|
|
+ ''
|
|
|
+ ].filter(Boolean);
|
|
|
+
|
|
|
+ return lines.join('\n');
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Format company list for markdown output
|
|
|
+ */
|
|
|
+function formatCompanyListMarkdown(companies: Company[], total: number, current: number, pageSize: number): string {
|
|
|
+ const lines = [
|
|
|
+ `# Company List`,
|
|
|
+ '',
|
|
|
+ `Total: ${total} companies | Page: ${current} | Page Size: ${pageSize}`,
|
|
|
+ ''
|
|
|
+ ];
|
|
|
+
|
|
|
+ for (const company of companies) {
|
|
|
+ lines.push(formatCompanyMarkdown(company));
|
|
|
+ }
|
|
|
+
|
|
|
+ return lines.join('\n');
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * List companies tool
|
|
|
+ */
|
|
|
+export const companyListTool = async (args: CompanyListInput) => {
|
|
|
+ const apiClient = getApiClient();
|
|
|
+
|
|
|
+ try {
|
|
|
+ const { page, pageSize, keyword, sortBy, sortOrder, filters, response_format } = args;
|
|
|
+
|
|
|
+ const params: Record<string, unknown> = {
|
|
|
+ page: page || 1,
|
|
|
+ pageSize: pageSize || 20
|
|
|
+ };
|
|
|
+
|
|
|
+ if (keyword) params.keyword = keyword;
|
|
|
+ if (sortBy) params.sortBy = sortBy;
|
|
|
+ if (sortOrder) params.sortOrder = sortOrder;
|
|
|
+ if (filters) params.filters = filters;
|
|
|
+
|
|
|
+ const response = await apiClient.get<PaginatedResponse<Company>>('/api/v1/company', params);
|
|
|
+
|
|
|
+ const companies = response.data || [];
|
|
|
+ const total = response.pagination?.total || 0;
|
|
|
+
|
|
|
+ const structuredOutput = {
|
|
|
+ total,
|
|
|
+ count: companies.length,
|
|
|
+ current: page || 1,
|
|
|
+ pageSize: pageSize || 20,
|
|
|
+ companies: companies.map((c: Company) => ({
|
|
|
+ id: c.id,
|
|
|
+ companyName: c.companyName,
|
|
|
+ contactPerson: c.contactPerson,
|
|
|
+ contactPhone: c.contactPhone,
|
|
|
+ contactEmail: c.contactEmail,
|
|
|
+ address: c.address,
|
|
|
+ platformId: c.platformId,
|
|
|
+ platformName: c.platform?.name,
|
|
|
+ status: c.status,
|
|
|
+ createTime: c.createTime
|
|
|
+ })),
|
|
|
+ hasMore: total > (page || 1) * (pageSize || 20)
|
|
|
+ };
|
|
|
+
|
|
|
+ let textContent: string;
|
|
|
+ if (response_format === ResponseFormat.JSON) {
|
|
|
+ textContent = JSON.stringify(structuredOutput, null, 2);
|
|
|
+ } else {
|
|
|
+ let markdown = formatCompanyListMarkdown(companies, total, page || 1, pageSize || 20);
|
|
|
+
|
|
|
+ // Check character limit
|
|
|
+ if (markdown.length > CHARACTER_LIMIT) {
|
|
|
+ const halfLength = Math.floor(companies.length / 2);
|
|
|
+ const truncatedCompanies = companies.slice(0, halfLength);
|
|
|
+ markdown = formatCompanyListMarkdown(truncatedCompanies, total, page || 1, pageSize || 20);
|
|
|
+ markdown += `\n---\n⚠️ **Response truncated**: Showing ${halfLength} of ${companies.length} results. Use pagination to see more.\n`;
|
|
|
+ }
|
|
|
+
|
|
|
+ textContent = markdown;
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ content: [{ type: 'text', text: textContent }],
|
|
|
+ structuredContent: structuredOutput
|
|
|
+ };
|
|
|
+ } catch (error) {
|
|
|
+ return {
|
|
|
+ content: [{
|
|
|
+ type: 'text',
|
|
|
+ text: `Error: ${error instanceof Error ? error.message : 'Failed to list companies'}`
|
|
|
+ }]
|
|
|
+ };
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * Get single company tool
|
|
|
+ */
|
|
|
+export const companyGetTool = async (args: CompanyGetInput) => {
|
|
|
+ const apiClient = getApiClient();
|
|
|
+
|
|
|
+ try {
|
|
|
+ const { id } = args;
|
|
|
+ const response = await apiClient.get<Company>(`/api/v1/company/${id}`);
|
|
|
+
|
|
|
+ const company = response;
|
|
|
+
|
|
|
+ const structuredOutput = {
|
|
|
+ id: company.id,
|
|
|
+ companyName: company.companyName,
|
|
|
+ contactPerson: company.contactPerson,
|
|
|
+ contactPhone: company.contactPhone,
|
|
|
+ contactEmail: company.contactEmail,
|
|
|
+ address: company.address,
|
|
|
+ platformId: company.platformId,
|
|
|
+ platformName: company.platform?.name,
|
|
|
+ status: company.status,
|
|
|
+ createTime: company.createTime,
|
|
|
+ updateTime: company.updateTime
|
|
|
+ };
|
|
|
+
|
|
|
+ const markdown = formatCompanyMarkdown(company);
|
|
|
+
|
|
|
+ return {
|
|
|
+ content: [{ type: 'text', text: markdown }],
|
|
|
+ structuredContent: structuredOutput
|
|
|
+ };
|
|
|
+ } catch (error) {
|
|
|
+ return {
|
|
|
+ content: [{
|
|
|
+ type: 'text',
|
|
|
+ text: `Error: ${error instanceof Error ? error.message : 'Failed to get company'}`
|
|
|
+ }]
|
|
|
+ };
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * Create company tool
|
|
|
+ */
|
|
|
+export const companyCreateTool = async (args: CompanyCreateInput) => {
|
|
|
+ const apiClient = getApiClient();
|
|
|
+
|
|
|
+ try {
|
|
|
+ const response = await apiClient.post<Company>('/api/v1/company', args);
|
|
|
+
|
|
|
+ const company = response;
|
|
|
+
|
|
|
+ const structuredOutput = {
|
|
|
+ id: company.id,
|
|
|
+ companyName: company.companyName,
|
|
|
+ contactPerson: company.contactPerson,
|
|
|
+ contactPhone: company.contactPhone,
|
|
|
+ contactEmail: company.contactEmail,
|
|
|
+ address: company.address,
|
|
|
+ platformId: company.platformId,
|
|
|
+ status: company.status,
|
|
|
+ createTime: company.createTime
|
|
|
+ };
|
|
|
+
|
|
|
+ const markdown = `✅ **Company Created Successfully**\n\n${formatCompanyMarkdown(company)}`;
|
|
|
+
|
|
|
+ return {
|
|
|
+ content: [{ type: 'text', text: markdown }],
|
|
|
+ structuredContent: structuredOutput
|
|
|
+ };
|
|
|
+ } catch (error) {
|
|
|
+ return {
|
|
|
+ content: [{
|
|
|
+ type: 'text',
|
|
|
+ text: `Error: ${error instanceof Error ? error.message : 'Failed to create company'}`
|
|
|
+ }]
|
|
|
+ };
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * Update company tool
|
|
|
+ */
|
|
|
+export const companyUpdateTool = async (args: CompanyUpdateInput) => {
|
|
|
+ const apiClient = getApiClient();
|
|
|
+
|
|
|
+ try {
|
|
|
+ const { id, ...updateData } = args;
|
|
|
+ const response = await apiClient.put<Company>(`/api/v1/company/${id}`, updateData);
|
|
|
+
|
|
|
+ const company = response;
|
|
|
+
|
|
|
+ const structuredOutput = {
|
|
|
+ id: company.id,
|
|
|
+ companyName: company.companyName,
|
|
|
+ contactPerson: company.contactPerson,
|
|
|
+ contactPhone: company.contactPhone,
|
|
|
+ contactEmail: company.contactEmail,
|
|
|
+ address: company.address,
|
|
|
+ platformId: company.platformId,
|
|
|
+ status: company.status,
|
|
|
+ updateTime: company.updateTime
|
|
|
+ };
|
|
|
+
|
|
|
+ const markdown = `✅ **Company Updated Successfully**\n\n${formatCompanyMarkdown(company)}`;
|
|
|
+
|
|
|
+ return {
|
|
|
+ content: [{ type: 'text', text: markdown }],
|
|
|
+ structuredContent: structuredOutput
|
|
|
+ };
|
|
|
+ } catch (error) {
|
|
|
+ return {
|
|
|
+ content: [{
|
|
|
+ type: 'text',
|
|
|
+ text: `Error: ${error instanceof Error ? error.message : 'Failed to update company'}`
|
|
|
+ }]
|
|
|
+ };
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * Delete company tool
|
|
|
+ */
|
|
|
+export const companyDeleteTool = async (args: CompanyDeleteInput) => {
|
|
|
+ const apiClient = getApiClient();
|
|
|
+
|
|
|
+ try {
|
|
|
+ const { id } = args;
|
|
|
+ await apiClient.delete<{ success: boolean }>(`/api/v1/company/${id}`);
|
|
|
+
|
|
|
+ const markdown = `✅ **Company Deleted Successfully**\n\nCompany ID ${id} has been deleted.`;
|
|
|
+
|
|
|
+ const structuredOutput = {
|
|
|
+ success: true,
|
|
|
+ deletedCompanyId: id
|
|
|
+ };
|
|
|
+
|
|
|
+ return {
|
|
|
+ content: [{ type: 'text', text: markdown }],
|
|
|
+ structuredContent: structuredOutput
|
|
|
+ };
|
|
|
+ } catch (error) {
|
|
|
+ return {
|
|
|
+ content: [{
|
|
|
+ type: 'text',
|
|
|
+ text: `Error: ${error instanceof Error ? error.message : 'Failed to delete company'}`
|
|
|
+ }]
|
|
|
+ };
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// Export tool registration configs
|
|
|
+export const companyTools = {
|
|
|
+ companyList: {
|
|
|
+ name: 'admin_list_companies',
|
|
|
+ schema: CompanyListInputSchema,
|
|
|
+ handler: companyListTool
|
|
|
+ },
|
|
|
+ companyGet: {
|
|
|
+ name: 'admin_get_company',
|
|
|
+ schema: CompanyGetInputSchema,
|
|
|
+ handler: companyGetTool
|
|
|
+ },
|
|
|
+ companyCreate: {
|
|
|
+ name: 'admin_create_company',
|
|
|
+ schema: CompanyCreateInputSchema,
|
|
|
+ handler: companyCreateTool
|
|
|
+ },
|
|
|
+ companyUpdate: {
|
|
|
+ name: 'admin_update_company',
|
|
|
+ schema: CompanyUpdateInputSchema,
|
|
|
+ handler: companyUpdateTool
|
|
|
+ },
|
|
|
+ companyDelete: {
|
|
|
+ name: 'admin_delete_company',
|
|
|
+ schema: CompanyDeleteInputSchema,
|
|
|
+ handler: companyDeleteTool
|
|
|
+ }
|
|
|
+};
|