Skip to main content
Glama

create_asset

Create NFT assets by uploading files or base64 data to specified collections, supporting both ERC721 and ERC1155 standards with customizable metadata.

Instructions

Create a new NFT asset from a local file or base64 data

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
filePathNoAbsolute path to the media file (for local files)
fileDataNoBase64 encoded file data (for Claude Desktop)
fileNameNoOriginal filename (required when using fileData)
mimeTypeNoMIME type of the file (required when using fileData, e.g., 'image/png')
contractIdYesID of the collection to mint the asset in
titleYesAsset title (3-120 characters)
descriptionNoAsset description (optional, max 255 characters)
locationNoLocation where the asset was created (optional, max 100 characters)
editionsNoNumber of editions (for ERC1155 collections only, 1-1000)
shareWithCommunityNoMake the asset discoverable by the community (optional, default: false)

Implementation Reference

  • The core handler function that executes the create_asset tool: parses input, handles file input from path or base64, performs upload using UploadPrimitives, and initiates NFT minting via api.assets.startMinting.
    export async function createAsset(params: CreateAssetInput): Promise<CreateAssetResult> { try { // Validate input using our schema const validatedParams = createAssetInputSchema.parse(params); // Determine how to create the file - either from disk or base64 data let file: NodeFileData; if (validatedParams.fileData && validatedParams.fileName && validatedParams.mimeType) { // Option 1: Create file from base64 data (for Claude Desktop) file = createNodeFileFromData(validatedParams.fileData, validatedParams.fileName, validatedParams.mimeType); } else if (validatedParams.filePath) { // Option 2: Create file from disk path if (!fs.existsSync(validatedParams.filePath)) { return { success: false, error: `File not found: ${validatedParams.filePath}`, }; } file = createNodeFileFromPath(validatedParams.filePath); } else { return { success: false, error: "Either filePath or (fileData + fileName + mimeType) must be provided", }; } const fileType = detectFileTypeFromMimeType(file.type); if (fileType === FileType.Unknown) { return { success: false, error: `Unsupported file type: ${file.type}`, }; } // Create upload primitives instance const uploader = new UploadPrimitives({ disableThumbnail: false, isPrivate: false, }); // Stage 1: Prepare upload const fileMetadata = JSON.stringify({ lastModified: file.lastModified, size: file.size, type: file.type, name: file.name, }); await uploader.prepareUpload({ file, metadata: fileMetadata, fileType, source: FileSource.Upload, deviceId: MCP_CONFIG.DEVICE_ID, }); if (!uploader.fileId) { throw new Error("Failed to prepare file upload"); } // Stage 2: Upload all chunks await uploader.uploadAllChunks(); // Stage 3: Finalize upload await uploader.finalizeUpload(); // Stage 4: Start minting const mintResponse = await api.assets.startMinting({ fileId: uploader.fileId, editions: validatedParams.editions, contractId: validatedParams.contractId, shareWithCommunity: validatedParams.shareWithCommunity ?? false, isEncrypted: false, // Not supporting encryption in MCP for now metadata: { attributes: [ { key: "title", value: validatedParams.title, type: Metadata_AttributeType.STRING, }, ...(validatedParams.description ? [ { key: "description", value: validatedParams.description, type: Metadata_AttributeType.STRING, }, ] : []), ...(validatedParams.location ? [ { key: "location", value: validatedParams.location, type: Metadata_AttributeType.STRING, }, ] : []), { key: "appName", value: "Uranium MCP", type: Metadata_AttributeType.STRING, }, { key: "appVersion", value: "1.0.0", type: Metadata_AttributeType.STRING, }, ], }, }); if (mintResponse.status !== "ok") { return { success: false, error: mintResponse.errorCode || "Failed to start minting", }; } return { success: true, data: { asset: { fileId: uploader.fileId, contractId: validatedParams.contractId, title: validatedParams.title, description: validatedParams.description, location: validatedParams.location, editions: validatedParams.editions, shareWithCommunity: validatedParams.shareWithCommunity, }, message: `Asset "${validatedParams.title}" created successfully and is being minted!`, progress: { stage: "Minting NFT...", percentage: 100, }, }, }; } catch (error) { if (error instanceof z.ZodError) { const errorMessages = error.issues.map((err) => err.message).join(", "); return { success: false, error: `Validation error: ${errorMessages}`, }; } return { success: false, error: error instanceof Error ? error.message : "Unknown error occurred", }; } }
  • Zod schema defining the input parameters for createAsset, including validation for title, contractId, file inputs (path or base64), etc.
    export const createAssetSchema = z .object({ title: z .string() .min(3, "Title must be at least 3 characters long") .max(120, "Title must be no more than 120 characters long"), description: z.string().max(255, "Description must be no more than 255 characters long").optional(), location: z.string().max(100, "Location must be no more than 100 characters long").optional(), contractId: z.string().min(1, "Please select a collection"), editions: z .number() .min(1, "Editions must be at least 1") .max(1000, "Editions must be no more than 1000") .optional(), shareWithCommunity: z.boolean().optional().default(false), // Option 1: File from disk filePath: z.string().optional(), // Option 2: Base64 data (for Claude Desktop) fileData: z.string().optional(), // base64 encoded data fileName: z.string().optional(), // original filename mimeType: z.string().optional(), // MIME type }) .refine((data) => data.filePath || (data.fileData && data.fileName && data.mimeType), { message: "Either filePath OR (fileData + fileName + mimeType) must be provided", path: ["filePath"], // This will show the error on the filePath field });
  • src/server.ts:77-89 (registration)
    MCP server request handler registration for the 'create_asset' tool, which validates arguments and calls the createAsset handler.
    case "create_asset": { // Validate and parse arguments const validatedArgs = createAssetInputSchema.parse(args); const result = await createAsset(validatedArgs); return { content: [ { type: "text", text: JSON.stringify(result, null, 2), }, ], }; }
  • Re-exports the input schema and derives TypeScript type for createAsset.
    export const createAssetInputSchema = createAssetSchema; export type CreateAssetInput = z.infer<typeof createAssetInputSchema>;
  • TypeScript interface defining the return type of createAsset.
    export interface CreateAssetResult { success: boolean; data?: { asset: { fileId: string; contractId: string; title: string; description?: string; location?: string; editions?: number; shareWithCommunity?: boolean; }; message: string; progress?: { stage: string; percentage?: number; }; }; error?: string; }

Latest Blog Posts

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/xkelxmc/uranium-mcp'

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