fixed 3 tools
This commit is contained in:
414
src/index.ts
414
src/index.ts
@@ -26,6 +26,7 @@ import {
|
|||||||
Role,
|
Role,
|
||||||
IndexType
|
IndexType
|
||||||
} from "node-appwrite";
|
} from "node-appwrite";
|
||||||
|
import { InputFile } from "node-appwrite/file";
|
||||||
import { readFileSync, existsSync } from "fs";
|
import { readFileSync, existsSync } from "fs";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import * as dotenv from "dotenv";
|
import * as dotenv from "dotenv";
|
||||||
@@ -666,12 +667,12 @@ class AppwriteMCPServer {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "update_user_labels",
|
name: "update_user_labels",
|
||||||
description: "Update user labels",
|
description: "Update user labels (alphanumeric only: A-Z, a-z, 0-9)",
|
||||||
inputSchema: {
|
inputSchema: {
|
||||||
type: "object",
|
type: "object",
|
||||||
properties: {
|
properties: {
|
||||||
userId: { type: "string", description: "User ID" },
|
userId: { type: "string", description: "User ID" },
|
||||||
labels: { type: "array", description: "User labels", items: { type: "string" } }
|
labels: { type: "array", description: "User labels (max 1000, 1-36 chars each, alphanumeric only)", items: { type: "string" } }
|
||||||
},
|
},
|
||||||
required: ["userId", "labels"]
|
required: ["userId", "labels"]
|
||||||
}
|
}
|
||||||
@@ -1664,7 +1665,7 @@ class AppwriteMCPServer {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "delete_session",
|
name: "delete_session",
|
||||||
description: "Delete a user session",
|
description: "Delete a user session (requires 'account' scope in API key)",
|
||||||
inputSchema: {
|
inputSchema: {
|
||||||
type: "object",
|
type: "object",
|
||||||
properties: {
|
properties: {
|
||||||
@@ -2639,12 +2640,12 @@ ${attribute.default !== undefined ? `- Default: ${attribute.default}` : ''}`
|
|||||||
break;
|
break;
|
||||||
case 'integer':
|
case 'integer':
|
||||||
attribute = await this.databases.updateIntegerAttribute(
|
attribute = await this.databases.updateIntegerAttribute(
|
||||||
databaseId, collectionId, key, required, min, max, defaultValue
|
databaseId, collectionId, key, required, min, max, defaultValue || null
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 'float':
|
case 'float':
|
||||||
attribute = await this.databases.updateFloatAttribute(
|
attribute = await this.databases.updateFloatAttribute(
|
||||||
databaseId, collectionId, key, required, min, max, defaultValue
|
databaseId, collectionId, key, required, min, max, defaultValue || null
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 'boolean':
|
case 'boolean':
|
||||||
@@ -3127,13 +3128,26 @@ ${attribute.default !== undefined ? `- Default: ${attribute.default}` : ''}`
|
|||||||
|
|
||||||
const { userId, labels } = args;
|
const { userId, labels } = args;
|
||||||
|
|
||||||
const user = await this.users.updateLabels(userId, labels) as any;
|
// Validate labels: alphanumeric only, 1-36 chars each
|
||||||
|
const validLabels = labels.filter((label: string) => {
|
||||||
|
const isValid = /^[A-Za-z0-9]{1,36}$/.test(label);
|
||||||
|
if (!isValid) {
|
||||||
|
console.warn(`Invalid label: "${label}" - must be alphanumeric, 1-36 characters`);
|
||||||
|
}
|
||||||
|
return isValid;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (validLabels.length !== labels.length) {
|
||||||
|
throw new Error(`Invalid labels detected. Labels must be alphanumeric (A-Z, a-z, 0-9) and 1-36 characters long. Invalid: ${labels.filter((l: string) => !/^[A-Za-z0-9]{1,36}$/.test(l)).join(', ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await this.users.updateLabels(userId, validLabels) as any;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
type: "text",
|
type: "text",
|
||||||
text: `User ${userId} labels updated:\n${labels.join(', ')}`
|
text: `User ${userId} labels updated:\n${validLabels.join(', ')}`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@@ -3178,20 +3192,42 @@ ${attribute.default !== undefined ? `- Default: ${attribute.default}` : ''}`
|
|||||||
|
|
||||||
const { userId } = args;
|
const { userId } = args;
|
||||||
|
|
||||||
const identities = await this.users.listIdentities(userId) as any;
|
try {
|
||||||
|
// Try without queries first
|
||||||
const identityList = identities.identities.map((identity: any) =>
|
let identities;
|
||||||
`- Provider: ${identity.provider} - ID: ${identity.$id}`
|
try {
|
||||||
).join('\n');
|
identities = await this.users.listIdentities(userId) as any;
|
||||||
|
} catch (error: any) {
|
||||||
return {
|
if (error.message.includes('queries')) {
|
||||||
content: [
|
// If queries error, try with empty array
|
||||||
{
|
identities = await (this.users as any).listIdentities(userId, []);
|
||||||
type: "text",
|
} else {
|
||||||
text: `User ${userId} identities (${identities.total}):\n${identityList}`
|
throw error;
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
};
|
|
||||||
|
const identityList = identities.identities.map((identity: any) =>
|
||||||
|
`- Provider: ${identity.provider} - ID: ${identity.$id}`
|
||||||
|
).join('\n');
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `User ${userId} identities (${identities.total}):\n${identityList}`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
} catch (error: any) {
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Error listing identities: ${error.message}`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async deleteUserIdentity(args: any) {
|
private async deleteUserIdentity(args: any) {
|
||||||
@@ -3525,13 +3561,16 @@ ${attribute.default !== undefined ? `- Default: ${attribute.default}` : ''}`
|
|||||||
throw new Error(`File not found: ${filePath}`);
|
throw new Error(`File not found: ${filePath}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For now, return a message indicating file upload capability
|
// Create InputFile from path and upload
|
||||||
// In a full implementation, we would use InputFile.fromPath()
|
const fileName = filePath.split(/[\\/]/).pop() || 'file';
|
||||||
|
const file = InputFile.fromPath(filePath, fileName);
|
||||||
|
const result = await this.storage.createFile(bucketId, fid, file, permissions) as any;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
type: "text",
|
type: "text",
|
||||||
text: `File upload prepared for bucket ${bucketId}:\n- Target ID: ${fid}\n- Source: ${filePath}\n- Note: File upload requires InputFile implementation`
|
text: `File uploaded successfully:\n- File ID: ${result.$id}\n- Name: ${result.name}\n- Size: ${result.sizeOriginal} bytes\n- MIME Type: ${result.mimeType}`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@@ -3540,7 +3579,7 @@ ${attribute.default !== undefined ? `- Default: ${attribute.default}` : ''}`
|
|||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
type: "text",
|
type: "text",
|
||||||
text: `Error preparing file upload: ${error.message}`
|
text: `Error uploading file: ${error.message}`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@@ -3910,30 +3949,109 @@ ${attribute.default !== undefined ? `- Default: ${attribute.default}` : ''}`
|
|||||||
const { providerId, name, type, enabled } = args;
|
const { providerId, name, type, enabled } = args;
|
||||||
const pid = providerId || ID.unique();
|
const pid = providerId || ID.unique();
|
||||||
|
|
||||||
// Note: Messaging provider creation depends on the specific provider type
|
try {
|
||||||
// For now, return a placeholder response
|
let result;
|
||||||
return {
|
|
||||||
content: [
|
// Create provider based on type
|
||||||
{
|
switch (type) {
|
||||||
type: "text",
|
case 'email':
|
||||||
text: `Messaging provider placeholder created:\n- ID: ${pid}\n- Name: ${name}\n- Type: ${type}\n- Note: Use specific provider methods (createFcmProvider, createMailgunProvider, etc.)`
|
// Create SMTP provider (most common email provider)
|
||||||
}
|
result = await this.messaging.createSmtpProvider(
|
||||||
]
|
pid,
|
||||||
};
|
name,
|
||||||
|
'smtp.gmail.com', // default host
|
||||||
|
587, // default port
|
||||||
|
'', // username (to be configured later)
|
||||||
|
'', // password (to be configured later)
|
||||||
|
'tls' as any, // encryption
|
||||||
|
false, // autoTLS
|
||||||
|
'' as any, // mailer
|
||||||
|
enabled || true
|
||||||
|
) as any;
|
||||||
|
break;
|
||||||
|
case 'sms':
|
||||||
|
// Create Twilio provider (most common SMS provider)
|
||||||
|
result = await this.messaging.createTwilioProvider(
|
||||||
|
pid,
|
||||||
|
name,
|
||||||
|
'', // Account SID (to be configured later)
|
||||||
|
'', // Auth token (to be configured later)
|
||||||
|
'', // From number (to be configured later)
|
||||||
|
enabled || true
|
||||||
|
) as any;
|
||||||
|
break;
|
||||||
|
case 'push':
|
||||||
|
// Create FCM provider (most common push provider)
|
||||||
|
result = await this.messaging.createFcmProvider(
|
||||||
|
pid,
|
||||||
|
name,
|
||||||
|
{}, // Service account JSON (to be configured later)
|
||||||
|
enabled || true
|
||||||
|
) as any;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error(`Unsupported provider type: ${type}. Use 'email', 'sms', or 'push'`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `${type.toUpperCase()} provider created:\n- ID: ${result.$id}\n- Name: ${result.name}\n- Type: ${result.type}\n- Enabled: ${result.enabled}\n- Note: Configure credentials in Appwrite Console`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
} catch (error: any) {
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Error creating ${type} provider: ${error.message}`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async listMessagingProviders() {
|
private async listMessagingProviders() {
|
||||||
if (!this.messaging) throw new Error("Messaging service not initialized");
|
if (!this.messaging) throw new Error("Messaging service not initialized");
|
||||||
|
|
||||||
// Note: Use specific provider list methods (listFcmProviders, listMailgunProviders, etc.)
|
try {
|
||||||
return {
|
const providers = await this.messaging.listProviders() as any;
|
||||||
content: [
|
|
||||||
{
|
if (providers.providers.length === 0) {
|
||||||
type: "text",
|
return {
|
||||||
text: `Messaging providers: Use specific provider methods (listFcmProviders, listMailgunProviders, etc.)`
|
content: [
|
||||||
}
|
{
|
||||||
]
|
type: "text",
|
||||||
};
|
text: "No messaging providers configured"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const providerList = providers.providers.map((provider: any) =>
|
||||||
|
`- ${provider.name} (${provider.type}) - ID: ${provider.$id} - Enabled: ${provider.enabled}`
|
||||||
|
).join('\n');
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Messaging providers (${providers.providers.length}):\n${providerList}`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
} catch (error: any) {
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Error listing providers: ${error.message}`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getMessagingProvider(args: any) {
|
private async getMessagingProvider(args: any) {
|
||||||
@@ -3958,16 +4076,66 @@ ${attribute.default !== undefined ? `- Default: ${attribute.default}` : ''}`
|
|||||||
|
|
||||||
const { providerId, name, enabled } = args;
|
const { providerId, name, enabled } = args;
|
||||||
|
|
||||||
// Note: Use specific provider update methods (updateFcmProvider, updateMailgunProvider, etc.)
|
try {
|
||||||
|
// First get the provider to determine its type
|
||||||
return {
|
const provider = await this.messaging.getProvider(providerId) as any;
|
||||||
content: [
|
|
||||||
{
|
let result;
|
||||||
type: "text",
|
switch (provider.type) {
|
||||||
text: `Messaging provider ${providerId} updated successfully`
|
case 'smtp':
|
||||||
}
|
result = await this.messaging.updateSmtpProvider(
|
||||||
]
|
providerId,
|
||||||
};
|
name || provider.name,
|
||||||
|
provider.host,
|
||||||
|
provider.port,
|
||||||
|
provider.username,
|
||||||
|
provider.password,
|
||||||
|
provider.encryption,
|
||||||
|
provider.autoTLS,
|
||||||
|
provider.mailer,
|
||||||
|
enabled !== undefined ? enabled : provider.enabled
|
||||||
|
) as any;
|
||||||
|
break;
|
||||||
|
case 'twilio':
|
||||||
|
result = await this.messaging.updateTwilioProvider(
|
||||||
|
providerId,
|
||||||
|
name || provider.name,
|
||||||
|
provider.accountSid,
|
||||||
|
provider.authToken,
|
||||||
|
provider.from,
|
||||||
|
enabled !== undefined ? enabled : provider.enabled
|
||||||
|
) as any;
|
||||||
|
break;
|
||||||
|
case 'fcm':
|
||||||
|
result = await this.messaging.updateFcmProvider(
|
||||||
|
providerId,
|
||||||
|
name || provider.name,
|
||||||
|
provider.serviceAccountJSON,
|
||||||
|
enabled !== undefined ? enabled : provider.enabled
|
||||||
|
) as any;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error(`Unsupported provider type: ${provider.type}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `${provider.type.toUpperCase()} provider updated:\n- ID: ${result.$id}\n- Name: ${result.name}\n- Enabled: ${result.enabled}`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
} catch (error: any) {
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Error updating provider: ${error.message}`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async deleteMessagingProvider(args: any) {
|
private async deleteMessagingProvider(args: any) {
|
||||||
@@ -3993,15 +4161,45 @@ ${attribute.default !== undefined ? `- Default: ${attribute.default}` : ''}`
|
|||||||
const { messageId, subject, content, topics, users, targets } = args;
|
const { messageId, subject, content, topics, users, targets } = args;
|
||||||
const mid = messageId || ID.unique();
|
const mid = messageId || ID.unique();
|
||||||
|
|
||||||
// Note: Use createEmail, createSms, or createPush methods
|
try {
|
||||||
return {
|
// Check if any email providers are available
|
||||||
content: [
|
const providers = await this.messaging.listProviders() as any;
|
||||||
{
|
const emailProviders = providers.providers.filter((p: any) =>
|
||||||
type: "text",
|
p.type === 'smtp' || p.type === 'mailgun' || p.type === 'sendgrid'
|
||||||
text: `Message placeholder created:\n- ID: ${mid}\n- Subject: ${subject || 'No subject'}\n- Note: Use specific message methods (createEmail, createSms, createPush)`
|
);
|
||||||
}
|
|
||||||
]
|
if (emailProviders.length === 0) {
|
||||||
};
|
throw new Error("No email providers configured. Please create an email provider first using create_messaging_provider.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create email message (assuming email provider since most common)
|
||||||
|
const result = await this.messaging.createEmail(
|
||||||
|
mid,
|
||||||
|
subject || "No Subject",
|
||||||
|
content,
|
||||||
|
topics,
|
||||||
|
users,
|
||||||
|
targets
|
||||||
|
) as any;
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Email message created and queued:\n- ID: ${result.$id}\n- Subject: ${result.subject}\n- Status: ${result.status}\n- Scheduled: ${result.scheduledAt || 'Immediate'}`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
} catch (error: any) {
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Error creating message: ${error.message}`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async listMessagingMessages(args: any) {
|
private async listMessagingMessages(args: any) {
|
||||||
@@ -4245,9 +4443,11 @@ ${attribute.default !== undefined ? `- Default: ${attribute.default}` : ''}`
|
|||||||
|
|
||||||
const countries = await this.locale.listCountries() as any;
|
const countries = await this.locale.listCountries() as any;
|
||||||
|
|
||||||
const countryList = countries.countries.map((country: any) =>
|
const countryList = countries.countries.map((country: any) => {
|
||||||
`- ${country.name} (${country.code}) - Phone: +${country.countryCode}`
|
// Try to find the actual numeric phone code property
|
||||||
).join('\n');
|
const phoneCode = country.phoneCode || country.dialCode || country.countryCode || country.callingCode || country.dialingCode;
|
||||||
|
return `- ${country.name} (${country.code}) - Phone: +${phoneCode || 'N/A'}`;
|
||||||
|
}).join('\n');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
content: [
|
content: [
|
||||||
@@ -4319,20 +4519,59 @@ ${attribute.default !== undefined ? `- Default: ${attribute.default}` : ''}`
|
|||||||
private async listPhoneCodes() {
|
private async listPhoneCodes() {
|
||||||
if (!this.locale) throw new Error("Locale service not initialized");
|
if (!this.locale) throw new Error("Locale service not initialized");
|
||||||
|
|
||||||
// Use listCountries which includes phone codes
|
try {
|
||||||
|
// Try using the dedicated listPhones API if available
|
||||||
|
const phones = await (this.locale as any).listPhones() as any;
|
||||||
|
|
||||||
|
if (phones && phones.phones) {
|
||||||
|
const phoneCodeList = phones.phones.map((phone: any) =>
|
||||||
|
`- ${phone.countryName}: +${phone.countryCode}`
|
||||||
|
).join('\n');
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Phone codes (${phones.phones.length}):\n${phoneCodeList}`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Fall back to countries endpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: Use listCountries
|
||||||
const countries = await this.locale.listCountries() as any;
|
const countries = await this.locale.listCountries() as any;
|
||||||
|
|
||||||
const phoneCodeList = countries.countries
|
// Debug: Check actual structure
|
||||||
.filter((country: any) => country.countryCode)
|
if (countries.countries && countries.countries.length > 0) {
|
||||||
.map((country: any) =>
|
const sampleCountry = countries.countries[0];
|
||||||
`- ${country.name}: +${country.countryCode}`
|
const availableProps = Object.keys(sampleCountry).join(', ');
|
||||||
).join('\n');
|
|
||||||
|
const phoneCodeList = countries.countries
|
||||||
|
.map((country: any) => {
|
||||||
|
const phoneCode = country.phoneCode || country.dialCode || country.countryCode || country.callingCode;
|
||||||
|
return phoneCode ? `- ${country.name}: +${phoneCode}` : null;
|
||||||
|
})
|
||||||
|
.filter(Boolean)
|
||||||
|
.join('\n');
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Phone codes (${countries.countries.length}):\n${phoneCodeList || 'No phone codes found'}\n\nDebug - Sample country properties: ${availableProps}`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
type: "text",
|
type: "text",
|
||||||
text: `Phone codes (${countries.countries.length}):\n${phoneCodeList}`
|
text: `No countries data found. Response structure: ${JSON.stringify(countries, null, 2)}`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@@ -5956,16 +6195,23 @@ For accurate usage tracking, consider:
|
|||||||
|
|
||||||
const { sessionId } = args;
|
const { sessionId } = args;
|
||||||
|
|
||||||
await this.account.deleteSession(sessionId);
|
try {
|
||||||
|
await this.account.deleteSession(sessionId);
|
||||||
return {
|
|
||||||
content: [
|
return {
|
||||||
{
|
content: [
|
||||||
type: "text",
|
{
|
||||||
text: `Session ${sessionId} deleted successfully`
|
type: "text",
|
||||||
}
|
text: `Session ${sessionId} deleted successfully`
|
||||||
]
|
}
|
||||||
};
|
]
|
||||||
|
};
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.message.includes('missing scope (account)')) {
|
||||||
|
throw new Error("API key missing 'account' scope. Please add 'account.read' and 'account.write' permissions to your API key in the Appwrite Console.");
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async listSessions(args: any) {
|
private async listSessions(args: any) {
|
||||||
@@ -6064,13 +6310,13 @@ For accurate usage tracking, consider:
|
|||||||
private async getHealthDb() {
|
private async getHealthDb() {
|
||||||
if (!this.health) throw new Error("Health service not initialized");
|
if (!this.health) throw new Error("Health service not initialized");
|
||||||
|
|
||||||
const health = await this.health.getDB();
|
const health = await this.health.getDB() as any;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
type: "text",
|
type: "text",
|
||||||
text: `Database Health: ${health.status}\n- Ping: ${health.ping}ms`
|
text: `Database Health: ${health.status || 'OK'}\n- Ping: ${health.ping || health.duration || 'N/A'}ms`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
"module": "ESNext",
|
"module": "Node16",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node16",
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
|||||||
Reference in New Issue
Block a user