added general attribute creation tool, bulk attribute creatin, bulk attribute removal, user authentication

This commit is contained in:
2025-07-27 15:36:30 +03:00
parent 8a2f79dddb
commit 5f7fc55d09
2 changed files with 278 additions and 146 deletions

View File

@@ -197,15 +197,11 @@ Once integrated, you should be able to use commands like:
</details>
<details>
<summary><strong>🏷️ Attribute Management (7 tools)</strong></summary>
<summary><strong>🏷️ Attribute Management (3 tools)</strong></summary>
| Tool | Description |
|------|-------------|
| `create_string_attribute` | Create a string attribute in a collection |
| `create_integer_attribute` | Create an integer attribute in a collection |
| `create_boolean_attribute` | Create a boolean attribute in a collection |
| `create_email_attribute` | Create an email attribute in a collection |
| `create_datetime_attribute` | Create a datetime attribute in a collection |
| `create_attribute` | Create any attribute type (string, integer, float, boolean, datetime, email, IP, URL, enum, relationship) |
| `list_attributes` | List all attributes in a collection |
| `delete_attribute` | Delete an attribute from a collection |
@@ -236,17 +232,19 @@ Once integrated, you should be able to use commands like:
</details>
<details>
<summary><strong>👥 User Management (7 tools)</strong></summary>
<summary><strong>👥 User Management (9 tools)</strong></summary>
| Tool | Description |
|------|-------------|
| `create_user` | Create a new user |
| `list_users` | List all users |
| `list_users` | List all users ✨ *with verification status* |
| `get_user` | Get a user by ID |
| `update_user_email` | Update user email |
| `update_user_name` | Update user name |
| `update_user_password` | Update user password |
| `delete_user` | Delete a user |
| `verify_user_email` | ✨ Verify a user's email address |
| `unverify_user_email` | ✨ Unverify a user's email address |
</details>
@@ -352,10 +350,12 @@ Once integrated, you should be able to use commands like:
</details>
<details>
<summary><strong>⚡ Bulk Operations (6 tools)</strong></summary>
<summary><strong>⚡ Bulk Operations (8 tools)</strong></summary>
| Tool | Description |
|------|-------------|
| `bulk_create_attributes` | ✨ Create multiple attributes at once in a collection |
| `bulk_delete_attributes` | ✨ Delete multiple attributes at once from a collection |
| `bulk_create_users` | ✨ Create multiple users at once |
| `bulk_update_users` | ✨ Update multiple users at once |
| `bulk_delete_users` | ✨ Delete multiple users at once |
@@ -412,11 +412,14 @@ Once integrated, you can use natural language commands with Claude to interact w
<summary><strong>🏷️ Schema & Attributes</strong></summary>
```
✨ "Add a string attribute called 'name' to the products collection with max size 255"
✨ "Create a boolean attribute 'in_stock' in the products collection"
✨ "Create a string attribute called 'name' in the products collection with max size 255"
✨ "Add a boolean attribute 'in_stock' to the products collection"
✨ "Create an enum attribute 'status' with values active, inactive, pending"
✨ "Add a relationship attribute linking products to categories"
✨ "Bulk create attributes: name (string), price (float), in_stock (boolean)"
✨ "Bulk delete attributes: old_field1, deprecated_field2, unused_field3"
✨ "List all attributes in the products collection"
✨ "Create a unique index on the 'sku' attribute"
✨ "Add an email attribute for 'contact_email'"
```
</details>
@@ -441,6 +444,8 @@ Once integrated, you can use natural language commands with Claude to interact w
✨ "Create a new user with email john@example.com and password SecurePass123"
✨ "List all users in the project"
✨ "Update user xyz123's name to 'John Doe'"
✨ "Verify user abc123's email address"
✨ "Unverify user xyz456's email verification"
✨ "Create a session for user john@example.com"
✨ "Bulk create 10 test users for demo purposes"
```
@@ -451,6 +456,10 @@ Once integrated, you can use natural language commands with Claude to interact w
<summary><strong>⚡ Advanced Features (Exclusive)</strong></summary>
```
🚀 "Create a complete product schema with string, enum, float, and relationship attributes"
🚀 "Bulk create 10 attributes at once for my e-commerce collection"
🚀 "Add a relationship attribute linking orders to customers with two-way binding"
🚀 "Create an enum attribute for user roles with admin, user, moderator values"
🚀 "Analyze this sample data and create a collection schema automatically"
🚀 "Suggest optimal indexes for my users collection based on usage"
🚀 "Validate this document data before creating it"

View File

@@ -176,81 +176,102 @@ class AppwriteMCPServer {
// Attribute Operations
{
name: "create_string_attribute",
description: "Create a string attribute in a collection",
name: "create_attribute",
description: "Create any type of attribute in a collection (string, integer, float, boolean, datetime, email, IP, URL, enum, relationship)",
inputSchema: {
type: "object",
properties: {
databaseId: { type: "string", description: "ID of the database" },
collectionId: { type: "string", description: "ID of the collection" },
key: { type: "string", description: "Attribute key" },
size: { type: "number", description: "Maximum size of the string" },
type: {
type: "string",
description: "Attribute type",
enum: ["string", "integer", "float", "boolean", "datetime", "email", "ip", "url", "enum", "relationship"]
},
required: { type: "boolean", description: "Is attribute required" },
default: { type: "string", description: "Default value (optional)" }
default: { type: "string", description: "Default value (optional)" },
size: { type: "number", description: "Size for string/ip/url attributes (optional)" },
min: { type: "number", description: "Minimum value for integer/float attributes (optional)" },
max: { type: "number", description: "Maximum value for integer/float attributes (optional)" },
elements: {
type: "array",
items: { type: "string" },
description: "Array of allowed values for enum attributes (required for enum type)"
},
relatedCollection: { type: "string", description: "Related collection ID for relationship attributes (required for relationship type)" },
relationType: {
type: "string",
description: "Relationship type (required for relationship type)",
enum: ["oneToOne", "oneToMany", "manyToOne", "manyToMany"]
},
twoWay: { type: "boolean", description: "Is relationship two-way (optional for relationship type)" },
twoWayKey: { type: "string", description: "Two-way relationship key (optional for relationship type)" }
},
required: ["databaseId", "collectionId", "key", "size", "required"]
required: ["databaseId", "collectionId", "key", "type", "required"]
}
},
{
name: "create_integer_attribute",
description: "Create an integer attribute in a collection",
name: "bulk_create_attributes",
description: "Create multiple attributes at once in a collection",
inputSchema: {
type: "object",
properties: {
databaseId: { type: "string", description: "ID of the database" },
collectionId: { type: "string", description: "ID of the collection" },
key: { type: "string", description: "Attribute key" },
required: { type: "boolean", description: "Is attribute required" },
min: { type: "number", description: "Minimum value (optional)" },
max: { type: "number", description: "Maximum value (optional)" },
default: { type: "number", description: "Default value (optional)" }
attributes: {
type: "array",
description: "Array of attribute definitions",
items: {
type: "object",
properties: {
key: { type: "string", description: "Attribute key" },
type: {
type: "string",
description: "Attribute type",
enum: ["string", "integer", "float", "boolean", "datetime", "email", "ip", "url", "enum", "relationship"]
},
required: { type: "boolean", description: "Is attribute required" },
default: { type: "string", description: "Default value (optional)" },
size: { type: "number", description: "Size for string/ip/url attributes (optional)" },
min: { type: "number", description: "Minimum value for integer/float attributes (optional)" },
max: { type: "number", description: "Maximum value for integer/float attributes (optional)" },
elements: {
type: "array",
items: { type: "string" },
description: "Array of allowed values for enum attributes (required for enum type)"
},
relatedCollection: { type: "string", description: "Related collection ID for relationship attributes (required for relationship type)" },
relationType: {
type: "string",
description: "Relationship type (required for relationship type)",
enum: ["oneToOne", "oneToMany", "manyToOne", "manyToMany"]
},
twoWay: { type: "boolean", description: "Is relationship two-way (optional for relationship type)" },
twoWayKey: { type: "string", description: "Two-way relationship key (optional for relationship type)" }
},
required: ["key", "type", "required"]
}
}
},
required: ["databaseId", "collectionId", "key", "required"]
required: ["databaseId", "collectionId", "attributes"]
}
},
{
name: "create_boolean_attribute",
description: "Create a boolean attribute in a collection",
name: "bulk_delete_attributes",
description: "Delete multiple attributes at once from a collection",
inputSchema: {
type: "object",
properties: {
databaseId: { type: "string", description: "ID of the database" },
collectionId: { type: "string", description: "ID of the collection" },
key: { type: "string", description: "Attribute key" },
required: { type: "boolean", description: "Is attribute required" },
default: { type: "boolean", description: "Default value (optional)" }
attributeKeys: {
type: "array",
description: "Array of attribute keys to delete",
items: { type: "string" }
}
},
required: ["databaseId", "collectionId", "key", "required"]
}
},
{
name: "create_email_attribute",
description: "Create an email attribute in a collection",
inputSchema: {
type: "object",
properties: {
databaseId: { type: "string", description: "ID of the database" },
collectionId: { type: "string", description: "ID of the collection" },
key: { type: "string", description: "Attribute key" },
required: { type: "boolean", description: "Is attribute required" },
default: { type: "string", description: "Default value (optional)" }
},
required: ["databaseId", "collectionId", "key", "required"]
}
},
{
name: "create_datetime_attribute",
description: "Create a datetime attribute in a collection",
inputSchema: {
type: "object",
properties: {
databaseId: { type: "string", description: "ID of the database" },
collectionId: { type: "string", description: "ID of the collection" },
key: { type: "string", description: "Attribute key" },
required: { type: "boolean", description: "Is attribute required" },
default: { type: "string", description: "Default value (optional)" }
},
required: ["databaseId", "collectionId", "key", "required"]
required: ["databaseId", "collectionId", "attributeKeys"]
}
},
{
@@ -476,6 +497,28 @@ class AppwriteMCPServer {
required: ["userId"]
}
},
{
name: "verify_user_email",
description: "Verify a user's email address",
inputSchema: {
type: "object",
properties: {
userId: { type: "string", description: "User ID" }
},
required: ["userId"]
}
},
{
name: "unverify_user_email",
description: "Unverify a user's email address",
inputSchema: {
type: "object",
properties: {
userId: { type: "string", description: "User ID" }
},
required: ["userId"]
}
},
// Storage Operations
{
@@ -1040,16 +1083,12 @@ class AppwriteMCPServer {
return await this.deleteCollection(request.params.arguments);
// Attribute Operations
case "create_string_attribute":
return await this.createStringAttribute(request.params.arguments);
case "create_integer_attribute":
return await this.createIntegerAttribute(request.params.arguments);
case "create_boolean_attribute":
return await this.createBooleanAttribute(request.params.arguments);
case "create_email_attribute":
return await this.createEmailAttribute(request.params.arguments);
case "create_datetime_attribute":
return await this.createDatetimeAttribute(request.params.arguments);
case "create_attribute":
return await this.createAttribute(request.params.arguments);
case "bulk_create_attributes":
return await this.bulkCreateAttributes(request.params.arguments);
case "bulk_delete_attributes":
return await this.bulkDeleteAttributes(request.params.arguments);
case "list_attributes":
return await this.listAttributes(request.params.arguments);
case "delete_attribute":
@@ -1090,6 +1129,10 @@ class AppwriteMCPServer {
return await this.updateUserPassword(request.params.arguments);
case "delete_user":
return await this.deleteUser(request.params.arguments);
case "verify_user_email":
return await this.verifyUserEmail(request.params.arguments);
case "unverify_user_email":
return await this.unverifyUserEmail(request.params.arguments);
// Storage Operations
case "create_bucket":
@@ -1316,119 +1359,165 @@ class AppwriteMCPServer {
}
// Attribute Operations
private async createStringAttribute(args: any) {
private async createAttribute(args: any) {
if (!this.databases) throw new Error("Databases not initialized");
const { databaseId, collectionId, key, size, required, default: defaultValue } = args;
const attribute = await this.databases.createStringAttribute(
const {
databaseId,
collectionId,
key,
size,
type,
required,
defaultValue
);
default: defaultValue,
size,
min,
max,
elements,
relatedCollection,
relationType,
twoWay,
twoWayKey
} = args;
let attribute;
switch (type) {
case 'string':
attribute = await this.databases.createStringAttribute(
databaseId, collectionId, key, size || 255, required, defaultValue
);
break;
case 'integer':
attribute = await this.databases.createIntegerAttribute(
databaseId, collectionId, key, required, min, max, defaultValue
);
break;
case 'float':
attribute = await this.databases.createFloatAttribute(
databaseId, collectionId, key, required, min, max, defaultValue
);
break;
case 'boolean':
attribute = await this.databases.createBooleanAttribute(
databaseId, collectionId, key, required, defaultValue
);
break;
case 'datetime':
attribute = await this.databases.createDatetimeAttribute(
databaseId, collectionId, key, required, defaultValue
);
break;
case 'email':
attribute = await this.databases.createEmailAttribute(
databaseId, collectionId, key, required, defaultValue
);
break;
case 'ip':
attribute = await this.databases.createIpAttribute(
databaseId, collectionId, key, required, defaultValue
);
break;
case 'url':
attribute = await this.databases.createUrlAttribute(
databaseId, collectionId, key, required, defaultValue
);
break;
case 'enum':
if (!elements || elements.length === 0) {
throw new Error("Enum attributes require 'elements' array with allowed values");
}
attribute = await this.databases.createEnumAttribute(
databaseId, collectionId, key, elements, required, defaultValue
);
break;
case 'relationship':
if (!relatedCollection || !relationType) {
throw new Error("Relationship attributes require 'relatedCollection' and 'relationType'");
}
attribute = await this.databases.createRelationshipAttribute(
databaseId, collectionId, relatedCollection, relationType, twoWay, key, twoWayKey
);
break;
default:
throw new Error(`Unsupported attribute type: ${type}`);
}
return {
content: [
{
type: "text",
text: `String attribute '${key}' created successfully in collection ${collectionId}`
text: `${type.charAt(0).toUpperCase() + type.slice(1)} attribute '${key}' created successfully in collection ${collectionId}`
}
]
};
}
private async createIntegerAttribute(args: any) {
private async bulkCreateAttributes(args: any) {
if (!this.databases) throw new Error("Databases not initialized");
const { databaseId, collectionId, key, required, min, max, default: defaultValue } = args;
const { databaseId, collectionId, attributes } = args;
const attribute = await this.databases.createIntegerAttribute(
databaseId,
collectionId,
key,
required,
min,
max,
defaultValue
);
const results = [];
const errors = [];
for (const attr of attributes) {
try {
await this.createAttribute({
databaseId,
collectionId,
...attr
});
results.push(`${attr.key} (${attr.type})`);
} catch (error) {
errors.push(`${attr.key} (${attr.type}): ${error}`);
}
}
return {
content: [
{
type: "text",
text: `Integer attribute '${key}' created successfully in collection ${collectionId}`
text: `Bulk Attribute Creation Results:
Successful (${results.length}):
${results.join('\n')}
${errors.length > 0 ? `Failed (${errors.length}):
${errors.join('\n')}` : ''}`
}
]
};
}
private async createBooleanAttribute(args: any) {
private async bulkDeleteAttributes(args: any) {
if (!this.databases) throw new Error("Databases not initialized");
const { databaseId, collectionId, key, required, default: defaultValue } = args;
const { databaseId, collectionId, attributeKeys } = args;
const attribute = await this.databases.createBooleanAttribute(
databaseId,
collectionId,
key,
required,
defaultValue
);
const results = [];
const errors = [];
for (const key of attributeKeys) {
try {
await this.databases.deleteAttribute(databaseId, collectionId, key);
results.push(`${key}`);
} catch (error) {
errors.push(`${key}: ${error}`);
}
}
return {
content: [
{
type: "text",
text: `Boolean attribute '${key}' created successfully in collection ${collectionId}`
}
]
};
}
text: `Bulk Attribute Deletion Results:
private async createEmailAttribute(args: any) {
if (!this.databases) throw new Error("Databases not initialized");
const { databaseId, collectionId, key, required, default: defaultValue } = args;
const attribute = await this.databases.createEmailAttribute(
databaseId,
collectionId,
key,
required,
defaultValue
);
return {
content: [
{
type: "text",
text: `Email attribute '${key}' created successfully in collection ${collectionId}`
}
]
};
}
Successful (${results.length}):
${results.join('\n')}
private async createDatetimeAttribute(args: any) {
if (!this.databases) throw new Error("Databases not initialized");
const { databaseId, collectionId, key, required, default: defaultValue } = args;
const attribute = await this.databases.createDatetimeAttribute(
databaseId,
collectionId,
key,
required,
defaultValue
);
return {
content: [
{
type: "text",
text: `Datetime attribute '${key}' created successfully in collection ${collectionId}`
${errors.length > 0 ? `Failed (${errors.length}):
${errors.join('\n')}` : ''}`
}
]
};
@@ -1665,7 +1754,7 @@ class AppwriteMCPServer {
const users = await this.users.list(queries || []);
const userList = users.users.map((user: any) =>
`- ${user.name || 'No name'} (${user.email}) - ID: ${user.$id}`
`- ${user.name || 'No name'} (${user.email}) - ID: ${user.$id} - ${user.emailVerification ? '✅ Verified' : '❌ Unverified'}`
).join('\n');
return {
@@ -1763,6 +1852,40 @@ class AppwriteMCPServer {
};
}
private async verifyUserEmail(args: any) {
if (!this.users) throw new Error("Users service not initialized");
const { userId } = args;
await this.users.updateEmailVerification(userId, true);
return {
content: [
{
type: "text",
text: `User ${userId} email verification status updated to verified ✅`
}
]
};
}
private async unverifyUserEmail(args: any) {
if (!this.users) throw new Error("Users service not initialized");
const { userId } = args;
await this.users.updateEmailVerification(userId, false);
return {
content: [
{
type: "text",
text: `User ${userId} email verification status updated to unverified ❌`
}
]
};
}
// Storage Operations
private async createBucket(args: any) {
if (!this.storage) throw new Error("Storage service not initialized");