UNPKG

run402-mcp

Version:

MCP server for Run402 — full-stack backend infrastructure for AI agents: Postgres, auth, storage, serverless functions and atomic deploys. Paid with x402/MPP. Includes $0.03 image generation.

120 lines • 4.99 kB
/** * `domains` namespace — ProjectDomain lifecycle. * * Domain operations are project-scoped control-plane actions. They use the * SDK credential provider's server auth (SIWX, control-plane session, or * grant key) and deliberately do not require local project-key cache entries. */ import { LocalError } from "../errors.js"; function domainPath(projectId, domain) { return `/projects/v1/${encodeURIComponent(projectId)}/domains/${encodeURIComponent(domain)}`; } function authMeta(method, projectId) { return { method, target: { project_id: projectId } }; } function waitSatisfied(domain, until) { if (until === "active") return domain.status === "active"; if (until === "receive-active") { const email = domain.effective.email; return email?.receive?.active === true; } return domain.checks.every((check) => !check.blocking || check.status === "passed"); } function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } export class Domains { client; constructor(client) { this.client = client; } /** * Connect a custom domain to a project, or change what an already-connected * domain should serve: `POST /projects/v1/:project_id/domains { domain, desired }`. * Returns the ProjectDomain state with `dns_records` and `next_actions`. */ async connect(projectId, input) { return this.client.request(`/projects/v1/${encodeURIComponent(projectId)}/domains`, { method: "POST", body: { domain: input.domain, desired: input.desired }, authMeta: authMeta("domains.connect", projectId), context: "connecting project domain", }); } async get(projectId, domain) { return this.client.request(domainPath(projectId, domain), { authMeta: authMeta("domains.get", projectId), context: "getting project domain", }); } async list(projectId) { return this.client.request(`/projects/v1/${encodeURIComponent(projectId)}/domains`, { authMeta: authMeta("domains.list", projectId), context: "listing project domains", }); } async check(projectId, domain) { return this.client.request(`${domainPath(projectId, domain)}/actions/check`, { method: "POST", authMeta: authMeta("domains.check", projectId), context: "checking project domain", }); } async apply(projectId, domain) { return this.client.request(`${domainPath(projectId, domain)}/actions/apply`, { method: "POST", authMeta: authMeta("domains.apply", projectId), context: "applying project domain", }); } async repair(projectId, domain) { return this.client.request(`${domainPath(projectId, domain)}/actions/repair`, { method: "POST", authMeta: authMeta("domains.repair", projectId), context: "repairing project domain", }); } async testReceive(projectId, domain, to) { return this.client.request(`${domainPath(projectId, domain)}/actions/test_receive`, { method: "POST", body: { to }, authMeta: authMeta("domains.testReceive", projectId), context: "creating project domain receive test", }); } async activate(projectId, domain) { return this.client.request(`${domainPath(projectId, domain)}/actions/activate_mailbox_addresses`, { method: "POST", authMeta: authMeta("domains.activate", projectId), context: "activating project domain mailbox addresses", }); } async disconnect(projectId, domain) { return this.client.request(domainPath(projectId, domain), { method: "DELETE", authMeta: authMeta("domains.disconnect", projectId), context: "disconnecting project domain", }); } async wait(projectId, domain, opts = {}) { const until = opts.until ?? "active"; const timeoutMs = opts.timeoutMs ?? 120_000; const intervalMs = opts.intervalMs ?? 5_000; const started = Date.now(); let last = await this.check(projectId, domain); while (!waitSatisfied(last, until)) { if (Date.now() - started >= timeoutMs) { throw new LocalError(`Timed out waiting for project domain ${domain} to reach ${until}`, "waiting for project domain", { code: "DOMAIN_WAIT_TIMEOUT", details: { project_id: projectId, domain, until, last_status: last.status, checks: last.checks }, next_actions: [{ type: "check", command: `run402 domains check ${domain} --project ${projectId}` }], }); } await sleep(intervalMs); last = await this.check(projectId, domain); } return last; } } //# sourceMappingURL=domains.js.map