deploy_project
Deploy a project using its .ploi.json configuration file and wait for completion. Use this when the user says 'deploy' without specifying a site.
Instructions
Deploy the current project using .ploi.json config file and wait for completion. Use this when the user says 'deploy' without specifying a site.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_path | Yes | The path to the project directory containing .ploi.json |
Implementation Reference
- src/tools/index.ts:1-26 (registration)The tool registration entry point - registerSiteTools is called from registerAllTools which is invoked from main().
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import type { PloiClient } from "../client.js"; import { registerServerTools } from "./servers.js"; import { registerSiteTools } from "./sites.js"; import { registerDatabaseTools } from "./databases.js"; export function registerAllTools(server: McpServer, client: PloiClient) { registerServerTools(server, client); registerSiteTools(server, client); registerDatabaseTools(server, client); } - src/tools/sites.ts:191-254 (registration)The 'deploy_project' tool is registered via server.tool() with name 'deploy_project', description, Zod schema (project_path), and async handler.
server.tool( "deploy_project", "Deploy the current project using .ploi.json config file and wait for completion. Use this when the user says 'deploy' without specifying a site.", { project_path: z.string().describe("The path to the project directory containing .ploi.json"), }, async ({ project_path }) => { const config = await readPloiConfig(project_path); if (!config) { return { content: [ { type: "text" as const, text: `No .ploi.json config found in ${project_path}. Create one with:\n{\n "server_id": YOUR_SERVER_ID,\n "site_id": YOUR_SITE_ID\n}\n\nOr use: "link this project to yourdomain.com"`, }, ], }; } const initialSite = await client.getSite(config.server_id, config.site_id); await client.deploySite(config.server_id, config.site_id); // Poll until deployment completes (max 5 minutes) const maxAttempts = 60; const pollInterval = 5000; // 5 seconds for (let attempt = 0; attempt < maxAttempts; attempt++) { await new Promise(resolve => setTimeout(resolve, pollInterval)); const site = await client.getSite(config.server_id, config.site_id); if (site.status === "active") { return { content: [ { type: "text" as const, text: `✅ Deployment successful!\n\nSite: ${site.domain}\nStatus: ${site.status}`, }, ], }; } if (site.status !== "deploying") { return { content: [ { type: "text" as const, text: `⚠️ Deployment ended with status: ${site.status}\n\nSite: ${site.domain}`, }, ], }; } } return { content: [ { type: "text" as const, text: `⏱️ Deployment still in progress after 5 minutes for ${initialSite.domain}. Check status manually.`, }, ], }; } ); - src/tools/sites.ts:194-196 (schema)Input schema defines a single required parameter: project_path (string) described as 'The path to the project directory containing .ploi.json'.
{ project_path: z.string().describe("The path to the project directory containing .ploi.json"), }, - src/tools/sites.ts:197-253 (handler)Handler reads .ploi.json config, triggers deploy via client.deploySite(), then polls getSite() every 5 seconds up to 60 attempts (5 min), returning success/error/timeout messages.
async ({ project_path }) => { const config = await readPloiConfig(project_path); if (!config) { return { content: [ { type: "text" as const, text: `No .ploi.json config found in ${project_path}. Create one with:\n{\n "server_id": YOUR_SERVER_ID,\n "site_id": YOUR_SITE_ID\n}\n\nOr use: "link this project to yourdomain.com"`, }, ], }; } const initialSite = await client.getSite(config.server_id, config.site_id); await client.deploySite(config.server_id, config.site_id); // Poll until deployment completes (max 5 minutes) const maxAttempts = 60; const pollInterval = 5000; // 5 seconds for (let attempt = 0; attempt < maxAttempts; attempt++) { await new Promise(resolve => setTimeout(resolve, pollInterval)); const site = await client.getSite(config.server_id, config.site_id); if (site.status === "active") { return { content: [ { type: "text" as const, text: `✅ Deployment successful!\n\nSite: ${site.domain}\nStatus: ${site.status}`, }, ], }; } if (site.status !== "deploying") { return { content: [ { type: "text" as const, text: `⚠️ Deployment ended with status: ${site.status}\n\nSite: ${site.domain}`, }, ], }; } } return { content: [ { type: "text" as const, text: `⏱️ Deployment still in progress after 5 minutes for ${initialSite.domain}. Check status manually.`, }, ], }; } - src/tools/sites.ts:12-24 (helper)Helper function readPloiConfig() reads and parses .ploi.json from project_path, returning {server_id, site_id} or null.
async function readPloiConfig(projectPath: string): Promise<PloiConfig | null> { try { const configPath = join(projectPath, ".ploi.json"); const content = await readFile(configPath, "utf-8"); const config = JSON.parse(content) as PloiConfig; if (typeof config.server_id === "number" && typeof config.site_id === "number") { return config; } return null; } catch { return null; } }