Skip to main content
Glama

deploy_site

Deploy static websites by uploading HTML/CSS/JS files to S3 and serving them via CloudFront with a unique URL for $0.05 USDC.

Instructions

Deploy a static site (HTML/CSS/JS). Files are uploaded to S3 and served via CloudFront at a unique URL. Costs $0.05 USDC via x402.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameYesSite name (e.g. 'family-todo', 'portfolio')
projectNoOptional project ID to link this deployment to an existing Run402 project
targetNoDeployment target (e.g. 'production'). Tracked in DB for future alias support.
filesYesArray of files to deploy. Must include at least index.html.

Implementation Reference

  • The handleDeploySite async function executes the deploy_site tool logic. It makes a POST API request to /v1/deployments with site name, project, target, and files. It handles 402 payment required responses by formatting payment details for the user, formats errors, and returns a formatted markdown response with deployment details (id, url, status, files count, size) on success.
    export async function handleDeploySite(args: {
      name: string;
      project?: string;
      target?: string;
      files: Array<{ file: string; data: string; encoding?: string }>;
    }): Promise<{ content: Array<{ type: "text"; text: string }>; isError?: boolean }> {
      const res = await apiRequest("/v1/deployments", {
        method: "POST",
        body: {
          name: args.name,
          project: args.project,
          target: args.target,
          files: args.files,
        },
      });
    
      if (res.is402) {
        const body = res.body as Record<string, unknown>;
        const lines = [
          `## Payment Required`,
          ``,
          `To deploy a static site, an x402 payment of **$0.05 USDC** is needed.`,
          ``,
        ];
        if (body.x402) {
          lines.push(`**Payment details:**`);
          lines.push("```json");
          lines.push(JSON.stringify(body.x402, null, 2));
          lines.push("```");
        } else {
          lines.push(`**Server response:**`);
          lines.push("```json");
          lines.push(JSON.stringify(body, null, 2));
          lines.push("```");
        }
        lines.push(``);
        lines.push(
          `The user's wallet or payment agent must send the required amount. ` +
          `Once payment is confirmed, retry this tool call.`,
        );
        return { content: [{ type: "text", text: lines.join("\n") }] };
      }
    
      if (!res.ok) return formatApiError(res, "deploying site");
    
      const body = res.body as {
        id: string;
        name: string;
        url: string;
        project_id: string | null;
        status: string;
        created_at: string;
        files_count: number;
        total_size: number;
      };
    
      const lines = [
        `## Site Deployed`,
        ``,
        `| Field | Value |`,
        `|-------|-------|`,
        `| id | \`${body.id}\` |`,
        `| url | ${body.url} |`,
        `| status | ${body.status} |`,
        `| files | ${body.files_count} |`,
        `| size | ${(body.total_size / 1024).toFixed(1)} KB |`,
        ``,
        `The site is live at **${body.url}**`,
      ];
    
      if (body.project_id) {
        lines.push(`Linked to project \`${body.project_id}\``);
      }
    
      return { content: [{ type: "text", text: lines.join("\n") }] };
    }
  • The deploySiteSchema defines the input validation using Zod. It specifies: 'name' (required string for site name), 'project' (optional string for project ID), 'target' (optional string for deployment target like 'production'), and 'files' (required array of objects with file path, data content, and optional encoding as utf-8 or base64).
    export const deploySiteSchema = {
      name: z
        .string()
        .describe("Site name (e.g. 'family-todo', 'portfolio')"),
      project: z
        .string()
        .optional()
        .describe("Optional project ID to link this deployment to an existing Run402 project"),
      target: z
        .string()
        .optional()
        .describe("Deployment target (e.g. 'production'). Tracked in DB for future alias support."),
      files: z
        .array(
          z.object({
            file: z.string().describe("File path (e.g. 'index.html', 'assets/logo.png')"),
            data: z.string().describe("File content (text or base64-encoded)"),
            encoding: z
              .enum(["utf-8", "base64"])
              .optional()
              .describe("Encoding: 'utf-8' (default) for text, 'base64' for binary files"),
          }),
        )
        .describe("Array of files to deploy. Must include at least index.html."),
    };
  • src/index.ts:199-204 (registration)
    Registration of the deploy_site tool with the MCP server. Uses server.tool() with name 'deploy_site', description explaining it deploys static sites (HTML/CSS/JS) to S3/CloudFront for $0.05 USDC via x402, the deploySiteSchema for validation, and an async wrapper that calls handleDeploySite.
    server.tool(
      "deploy_site",
      "Deploy a static site (HTML/CSS/JS). Files are uploaded to S3 and served via CloudFront at a unique URL. Costs $0.05 USDC via x402.",
      deploySiteSchema,
      async (args) => handleDeploySite(args),
    );

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/kychee-com/run402'

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