Go quote API
app.unfazed.dev/go-quotes open (opens in new tab)write me a small HTTP service in Go (standard library only, no third-party dependencies): GET / returns a random programming quote as JSON like {"quote":"...","author":"..."}, and GET /health returns 200. listen on the PORT environment variable. deploy it on unfazed as a service and give me the public link.
I'll start by reading the unfazed docs to understand how to deploy a Go service (the defaults mention a TS entrypoint, so I need to check Go support).
ToolSearch(query: "select:ReadMcpResourceTool,mcp__unfazed_…", max_results: 10)
{
"query": "select:ReadMcpResourceTool,mcp__unfazed__create_workspace,mcp__unfazed__write_workspace_text_file,mcp__unfazed__create_service_deployment",
"max_results": 10
}[
{
"type": "tool_reference",
"tool_name": "ReadMcpResourceTool"
},
{
"type": "tool_reference",
"tool_name": "mcp__unfazed__create_workspace"
},
{
"type": "tool_reference",
"tool_name": "mcp__unfazed__write_workspace_text_file"
},
{
"type": "tool_reference",
"tool_name": "mcp__unfazed__create_service_deployment"
}
]ReadMcpResourceTool(server: "unfazed", uri: "unfazed://reference")
{
"server": "unfazed",
"uri": "unfazed://reference"
}{
"contents": [
{
"uri": "unfazed://reference",
"mimeType": "text/plain; charset=utf-8",
"text": "# Unfazed Reference\n\nAPI \u0026 auth, identity, MCP tools, App State, Realtime Streams, env/secrets, and\nlimits. For how to deploy, see https://unfazed.dev/deploy.md (MCP resource:\nunfazed://deploy).\n\n## Endpoints \u0026 auth\n\n- MCP (preferred): https://unfazed.dev/mcp — Streamable HTTP, OAuth bearer tokens.\n- GraphQL fallback: https://unfazed.dev/query — use it when MCP can't be added as\n a trusted server (don't hand-roll MCP JSON-RPC with curl). Introspection is on.\n Auth: `Authorization: Bearer \u003cUNFZ_API_TOKEN\u003e`, or `X-Unfz-Token: \u003ctoken\u003e`, or\n `Authorization: Bearer \u003cagent_access_token\u003e` from /agents/register.\n- Published deployment URLs (https://app.unfazed.dev/\u003calias\u003e) are public; no token.\n\nDiscovery:\n\n- https://unfazed.dev/auth.md\n- POST https://unfazed.dev/agents/register — self-service agent tokens.\n- OAuth: /.well-known/oauth-protected-resource/mcp, /.well-known/oauth-authorization-server,\n /.well-known/openid-configuration\n\n### Claiming (optional)\n\nAgent registration may return claim.url. Claiming is optional and only for human\nmanagement of limits, domains, billing, revocation, or handoff. After a successful\ndeploy, while the account is unclaimed, deploy results carry agent_claimed: false\nand a claim_hint. When a human is in the loop, offer the claim once alongside the\napp URL (create_claim_attempt returns the url to show them); a human signed in\nwith GitHub claims in one click. Never block on claiming and don't repeat the\noffer every deploy. If the initial claim URL/code is lost, call create_claim_attempt\n(or POST /agents/claim-attempts with the agent bearer token).\n\n## Identity (whoami)\n\nCall whoami first when identity matters. It returns the current actor kind, nested\nuser/agent identity, linked agents for a user, scopes, claim state, and free-tier\nusage/resource counters. The actor kinds:\n\n- agent: an automated caller using a self-registered bearer token — the usual case\n for you. Subject to free-tier usage/resource limits; a human can claim it to\n link it to their account.\n- user: a human signed in via GitHub OAuth, who manages their linked agents and apps.\n- owner: the operator of this Unfazed instance, authenticated with the owner token.\n Full access, no free-tier limits.\n\n## MCP tools\n\nget_service_info, whoami, create_claim_attempt, create_workspace,\nimport_github_repo, sync_github_repo, unlink_github_repo, install_github_webhook,\nset_github_token, write_workspace_text_file, write_workspace_base64_file,\nread_workspace_file, list_workspace_files, list_workspace_env, set_workspace_env,\nset_workspace_secret, delete_workspace_env, list_deployments,\nlist_deployment_events, create_static_deployment, create_service_deployment,\nget_service_status, get_service_logs, restart_service, stop_service,\ndelete_deployment, delete_workspace. (Plus get_app_state / set_app_state /\nlist_app_state / delete_app_state — see App State below.)\n\nList/read/log tools are context-safe by default:\n\n- list_deployments, list_deployment_events, list_workspace_files, list_workspace_env\n return pages with total, limit, offset, has_more, next_offset. Continue with\n offset: next_offset while has_more is true.\n- list_deployments, list_deployment_events, list_workspace_env default to\n format: \"compact\". Use format: \"full\" only when you need detailed fields, event\n metadata, or plaintext non-secret env values.\n- read_workspace_file returns a text chunk; continue with offset: next_offset while\n truncated is true.\n- get_service_logs returns recent stdout/stderr tails; tail_bytes is capped at\n 64 KiB per stream.\n- write_workspace_text_file writes UTF-8; write_workspace_base64_file writes bytes\n (or use uploadWorkspaceFile over GraphQL multipart).\n\n## Env \u0026 secrets\n\nset_workspace_env / setWorkspaceEnv for non-secret config; set_workspace_secret /\nsetWorkspaceSecret for credentials. Secrets are encrypted at rest, never returned\nby API tools (redacted in list_workspace_env), and injected only into SERVICE\nruntime VMs. Env/secrets are snapshotted when a deployment is created — changing\nworkspace env later does not mutate older deployments.\n\nReserved env names (rejected): UNFZ_*, LD_*, DYLD_*, BUN_*, and HOST, PORT, PATH,\nHOME, PWD, USER, SHELL, TERM, TMPDIR, NODE_OPTIONS. The UNFZ_* names are reserved\nbecause the platform injects them at boot (see below).\n\n## Public URL\n\nAn aliased SERVICE is injected with UNFZ_PUBLIC_URL at boot — its canonical\nexternal base URL, e.g. https://app.unfazed.dev/\u003calias\u003e (no trailing slash). Use\nit whenever the app needs to know its own public address: OAuth issuer/redirect\nURLs, links it emits, absolute asset URLs. Do NOT derive your URL from the request\nhost or X-Forwarded-Prefix — internally the app is served under /a/\u003calias\u003e/, which\nis not the public path; UNFZ_PUBLIC_URL is the only authoritative source.\nAlias-less deployments do not get it (no stable public URL).\n\n## App State (durable per-app storage)\n\nAn aliased SERVICE deployment gets a durable key/value store keyed by the app's\nstable alias, so data survives redeploys and VM restarts — the place to keep app\ndata (todo lists, counters, records). Two env vars are injected into the VM at\nboot (aliased SERVICE only; alias-less deployments get neither — fall back to\nin-memory for local dev):\n\n- UNFZ_STATE_URL: base URL of this app's state API (e.g. http://10.254.0.1:9000).\n- UNFZ_STATE_TOKEN: per-alias bearer for every state and streams call.\n\nHTTP API (call from server.ts; every call carries `Authorization: Bearer ${UNFZ_STATE_TOKEN}`):\n\n- GET ${UNFZ_STATE_URL}/state/\u003ckey\u003e -\u003e 200 raw bytes, or 404.\n- PUT ${UNFZ_STATE_URL}/state/\u003ckey\u003e body = raw bytes -\u003e 204 (\u003c=64 KiB/value).\n- DELETE ${UNFZ_STATE_URL}/state/\u003ckey\u003e -\u003e 204.\n- GET ${UNFZ_STATE_URL}/state -\u003e 200 {\"keys\":[...]}.\n\nStore JSON via JSON.stringify on PUT and JSON.parse on GET. Agents can also seed\nor inspect state out-of-band with get_app_state / set_app_state / list_app_state /\ndelete_app_state (by alias).\n\nExample (persist a list across requests):\n\n const URL = process.env.UNFZ_STATE_URL, TOK = process.env.UNFZ_STATE_TOKEN;\n const auth = { authorization: `Bearer ${TOK}` };\n async function load() {\n const r = await fetch(`${URL}/state/todos`, { headers: auth });\n return r.status === 404 ? [] : JSON.parse(await r.text());\n }\n async function save(v) {\n await fetch(`${URL}/state/todos`, { method: \"PUT\",\n headers: { ...auth, \"content-type\": \"application/json\" }, body: JSON.stringify(v) });\n }\n\n## Realtime Streams (Durable Streams)\n\nAn aliased SERVICE deployment gets a per-alias endpoint speaking the Durable\nStreams protocol — a conformant implementation (passes the official v0.3.5\nconformance suite) — for pushing realtime updates (UI patches, progress, events)\nto browsers. The full protocol (streams, offsets, content types,\nproducers/consumers, live modes, fork) is at https://durablestreams.com/llms.txt;\nbelow is only what is unfazed-specific. Injected env (aliased SERVICE only):\n\n- UNFZ_STREAMS_URL: base URL of this app's producer surface (server-side writes).\n- UNFZ_STATE_TOKEN: per-alias bearer for writes (Authorization: Bearer).\n\n- Write (server-side only): PUT UNFZ_STREAMS_URL/\u003cpath\u003e to create, POST to append\n (Content-Type: application/json stores the body as discrete JSON messages).\n Writes are namespaced to the app's alias; an app can never touch another's streams.\n- Read (browser, read-only): subscribe at the app-relative path _streams/\u003cpath\u003e\n under https://app.unfazed.dev/\u003calias\u003e/, e.g.\n new EventSource(\"_streams/\u003cpath\u003e?offset=-1\u0026live=sse\"); resume via the\n Stream-Next-Offset response header. The public path allows only GET/HEAD (405\n otherwise). See the spec for offset/live-mode semantics; example examples/streams-ui.ts.\n\nCaveat: the backend is in-memory today — streams do NOT survive a platform restart\n(a durable file-backed backend is planned). Treat them as live transport; keep\ndurable data in App State or your own store.\n\n## Apps can be MCP servers\n\nA SERVICE app can itself be a remote MCP server: serve Streamable HTTP MCP from\nserver.ts (POST JSON-RPC: initialize, tools/list, tools/call) and keep data in App\nState. Deploy with an alias (on_demand is fine — it cold-starts on the first MCP\nrequest) and connect an MCP client to https://app.unfazed.dev/\u003calias\u003e. Tool results\nmay embed a text/html ui:// resource that MCP-Apps hosts render as a card.\n\n## Constraints \u0026 limits\n\n- Deployment kinds are STATIC and SERVICE.\n- Workspace file paths must be relative and cannot contain \"..\".\n- Aliases may contain letters, digits, - and _ only.\n- The GraphQL file API currently accepts text content.\n- Do not put secrets into static deployment files (they are public).\n- SERVICE deployments require server.ts (BUN runtime) or a go.mod + main package\n (GO runtime), or an unfazed.json entry/build. A Go service listens on $PORT.\n- SERVICE serviceMode defaults to ON_DEMAND; ALWAYS_ON keeps the VM warm and\n replaces older always-on VMs when the same alias is redeployed.\n- Self-registered agent tokens are limited to 5 workspaces and 5 SERVICE\n deployments. STATIC deployments are not capped.\n"
}
]
}ReadMcpResourceTool(server: "unfazed", uri: "unfazed://deploy")
{
"server": "unfazed",
"uri": "unfazed://deploy"
}{
"contents": [
{
"uri": "unfazed://deploy",
"mimeType": "text/plain; charset=utf-8",
"text": "# Deploying on Unfazed\n\nHow to deploy static sites and Bun/Hono services, via MCP (https://unfazed.dev/mcp)\nor the GraphQL fallback (https://unfazed.dev/query, same bearer token). For API \u0026\nauth, identity, App State, Realtime Streams, limits and constraints, see\nhttps://unfazed.dev/reference.md (MCP resource: unfazed://reference).\n\nA deployment is STATIC (serve files) or SERVICE (run an HTTP server). A SERVICE\nruns one of two runtimes: BUN (default — a TypeScript/JavaScript server bundled\nwith Bun) or GO (a compiled Go module). For a GitHub import the kind and runtime\nare detected from the repo root (root server.ts -\u003e SERVICE/BUN, root go.mod +\nmain.go -\u003e SERVICE/GO, otherwise root index.html -\u003e STATIC); direct deployments\npass the kind explicitly and may set runtime (omit it to auto-detect).\n\n## unfazed.json (build step, custom entry / output)\n\nA root unfazed.json overrides detection and can add a build step. Every field is\noptional; with no unfazed.json a root server.ts/index.html deploys as before.\n\n- kind: STATIC | SERVICE — force the kind.\n- runtime: BUN | GO — force the SERVICE runtime (default BUN; auto-detected as GO\n for a Go module). Ignored for STATIC.\n- install: dependency install command. BUN default \"bun install\" (becomes\n \"bun install --frozen-lockfile\" when a bun lockfile is committed); GO default\n \"go mod download\".\n- build: command run in the isolated build VM after install. GO default\n \"CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -o service \u003centry\u003e\".\n- output: STATIC publish dir (default \"dist\" when build is set). An output with\n no build republishes a committed directory (e.g. a checked-in dist/) as-is,\n without booting the build VM.\n- entry: SERVICE entrypoint. BUN default server.ts; GO default \".\" (the main\n package at the module root) — set e.g. \"./cmd/server\" for a non-root main.\n- spa: STATIC SPA fallback (serve index.html for unknown paths).\n\nUse it to build first, point at an entry in a subdirectory, or publish a built\ndirectory.\n\n## Static deployments\n\nPublish HTML reports, small sites, CSS, JavaScript, images, or other assets.\nFiles can be added incrementally.\n\nMCP:\n\n- create_workspace({ name })\n- write_workspace_text_file({ workspace_id, path, text })\n- write_workspace_base64_file({ workspace_id, path, content_base64 }) for local\n files or binary assets\n- create_static_deployment({ workspace_id, alias, spa_mode: true })\n- share the deployment url\n\nGraphQL:\n\n- createWorkspace(input: { name })\n- writeWorkspaceTextFile(input: { workspaceID, path, text })\n- writeWorkspaceBase64File(input: { workspaceID, path, contentBase64 }) for bytes\n- uploadWorkspaceFile(input: { workspaceID, path, file }) when the GraphQL client\n supports multipart upload\n- createDeployment(input: { workspaceID, kind: STATIC, alias, spaMode })\n- share deployment.url\n\nURLs:\n\n- Stable alias: https://app.unfazed.dev/\u003calias\u003e\n- Immutable snapshot: https://app.unfazed.dev/d/\u003cdeployment-id\u003e\n\nDeploying again with the same alias moves the alias URL to the newest snapshot;\nolder /d/\u003cdeployment-id\u003e URLs remain immutable.\n\n## Service deployments\n\nPublish a small HTTP backend or combined app. The workspace must contain server.ts\n(or set entry/build in unfazed.json). Include package.json if it has dependencies.\nBuild and runtime happen inside isolated Bun VMs.\n\nserver.ts must default-export one of: a fetch(req) function, a Hono app, or an\nobject with fetch. It serves on port 3000.\n\nMinimal server.ts:\n\n import { Hono } from \"hono\";\n const app = new Hono();\n app.get(\"/\", (c) =\u003e c.text(\"hello\"));\n export default app;\n\nMCP:\n\n- create_workspace({ name })\n- write_workspace_text_file({ workspace_id, path: \"package.json\", text })\n- write_workspace_text_file({ workspace_id, path: \"server.ts\", text })\n- write_workspace_text_file again for each additional source file\n- optional: set_workspace_env / set_workspace_secret (see reference.md)\n- create_service_deployment({ workspace_id, alias })\n- share the deployment url\n\nGraphQL: createDeployment(input: { workspaceID, kind: SERVICE, alias }).\n\n### Go services\n\nA Go SERVICE is a Go module (a go.mod plus a main package) whose main package\nstarts an HTTP server. unfazed compiles it in the build VM (CGO_ENABLED=0, static\nbinary) and runs the binary directly — no Bun. The runtime is auto-detected from\na root go.mod + main.go, or set it explicitly (runtime: GO).\n\nContract for your Go code:\n\n- Listen on 0.0.0.0 and the port in $PORT (default 3000); HOST and PORT are set\n in the environment.\n- For service_mode always_on with a health_path, that path must return 2xx.\n- Read platform values with os.Getenv: UNFZ_PUBLIC_URL (your canonical external\n URL, e.g. https://app.unfazed.dev/\u003calias\u003e — use it for OAuth issuer/redirects and\n any absolute links; do not infer it from the request host), UNFZ_STATE_URL,\n UNFZ_STREAMS_URL, UNFZ_STATE_TOKEN (per-alias App State / Realtime Streams), plus\n any env/secrets you set on the workspace.\n\nMinimal main.go (module root):\n\n package main\n\n import (\n \"net/http\"\n \"os\"\n )\n\n func main() {\n http.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n w.Write([]byte(\"hello from go\"))\n })\n port := os.Getenv(\"PORT\")\n if port == \"\" {\n port = \"3000\"\n }\n http.ListenAndServe(\"0.0.0.0:\"+port, nil)\n }\n\nMCP: write go.mod and main.go, then\ncreate_service_deployment({ workspace_id, alias, runtime: \"GO\" }) (or omit\nruntime to auto-detect). GraphQL: createDeployment(input: { workspaceID, kind:\nSERVICE, runtime: GO, alias }). A non-root main package uses unfazed.json\n{ \"runtime\": \"GO\", \"entry\": \"./cmd/server\" }. Everything else — lifecycle,\ncron, status, logs, App State, Streams — is identical to a Bun service.\n\n### Lifecycle: prefer on_demand\n\nA service defaults to on_demand: it sleeps and cold-starts on the first request —\ncheap and right for most apps. Leave service_mode unset.\n\n- Always warm (low first-request latency, or background work between requests):\n create_service_deployment({ workspace_id, alias, service_mode: \"always_on\", health_path: \"/health\" })\n (GraphQL: serviceMode: ALWAYS_ON, healthPath). The watchdog is platform-managed;\n with health_path set, unfazed probes it and restarts on failure, else it checks\n TCP reachability.\n- Periodic work: keep on_demand and add a cron schedule — do NOT use always_on:\n create_service_deployment({ workspace_id, alias, cron_schedule: \"0 * * * *\" })\n (GraphQL: cronSchedule, cronPath). Each tick is a POST to cron_path (default\n /cron) with header X-Unfz-Trigger: cron and a signed X-Unfz-Cron-Token equal to\n UNFZ_STATE_TOKEN (verify it to confirm the tick is platform-originated). An\n on-demand service cold-starts for each tick; an always-on one is reused.\n cron_schedule requires an alias.\n\n### Runtime control\n\n- list_deployment_events / deploymentEventsPage: recent persistent events\n (deployment.created, service.build_succeeded, service.vm_started/_stopped,\n service.watchdog_restart, service.restart_requested, service.stop_requested).\n- get_service_status / serviceStatus: live VM health, vm id, in-flight count,\n restart count, last runtime error.\n- get_service_logs / serviceLogs: bounded stdout/stderr tails (secrets redacted).\n- restart_service / stop_service: recreate or stop the service VM.\n- delete_deployment frees the alias and stops the VM; delete_workspace refuses\n while deployments still reference it — delete those first.\n\n## GitHub import\n\n- optional for private repos: set_github_token({ token })\n- import_github_repo({ repo: \"owner/name\", alias, auto_deploy: true })\n- share the deployment url\n- install_github_webhook({ workspace_id }) registers the push webhook (idempotent;\n needs a connected token with repo access). Or add it manually from\n git_source.webhook_url / git_source.webhook_secret (content type\n application/json; HMAC SHA-256). Pushes to the tracked branch enqueue a deploy.\n- sync_github_repo({ workspace_id }) re-imports now.\n- unlink_github_repo({ workspace_id }) stops future push deploys; existing\n deployments stay live.\n\nImported private repository contents become public at the deployment URL; .env\nand .env.* files are skipped. If a repo isn't deployable yet (no root entry, no\nunfazed.json), the files are still imported — add an unfazed.json (or a root\nentry) and deploy the workspace's current files (deployWorkspace) without\nre-fetching git.\n\n## TypeScript lambdas\n\n- registerFunction(input: { name, file, packageJSON, bunLock }) uploads a module\n (it must export a default function).\n- invokeFunction(input: { functionID, payload }) runs it in an isolated VM.\n\nLambdas are Bun/TypeScript only — there is no Go lambda runtime. For Go\nrequest/response work, deploy a SERVICE with serviceMode ON_DEMAND: it\ncold-starts on the first request and parks when idle (scale-to-zero), which is\nthe lambda-equivalent for Go.\n\n## Minimal GraphQL\n\n mutation Create($name: String!) {\n createWorkspace(input: { name: $name }) { workspace { id name } }\n }\n\n mutation Write($workspaceID: ID!, $path: String!, $text: String!) {\n writeWorkspaceTextFile(input: { workspaceID: $workspaceID, path: $path, text: $text }) {\n file { path sizeBytes sha256 updatedAt }\n }\n }\n\n mutation DeployStatic($workspaceID: ID!, $alias: String!) {\n createDeployment(input: { workspaceID: $workspaceID, kind: STATIC, alias: $alias, spaMode: true }) {\n deployment { id url alias status filesCount sizeBytes spaMode createdAt }\n }\n }\n\n # Most services need nothing more than this (serviceMode omitted -\u003e ON_DEMAND,\n # runtime omitted -\u003e auto-detected: BUN for server.ts, GO for a go.mod module).\n mutation DeployService($workspaceID: ID!, $alias: String!) {\n createDeployment(input: { workspaceID: $workspaceID, kind: SERVICE, alias: $alias }) {\n deployment { id url alias kind runtime serviceMode status createdAt }\n }\n }\n\n # Force the Go runtime explicitly (else it auto-detects from a root go.mod).\n mutation DeployGoService($workspaceID: ID!, $alias: String!) {\n createDeployment(input: { workspaceID: $workspaceID, kind: SERVICE, runtime: GO, alias: $alias }) {\n deployment { id url alias kind runtime serviceMode status createdAt }\n }\n }\n\n # Periodic work: stay ON_DEMAND, add a cron schedule (not ALWAYS_ON).\n mutation DeployScheduled($workspaceID: ID!, $alias: String!) {\n createDeployment(input: { workspaceID: $workspaceID, kind: SERVICE, alias: $alias, cronSchedule: \"0 * * * *\", cronPath: \"/cron\" }) {\n deployment { id url alias serviceMode cronSchedule cronPath status }\n }\n }\n\n query ServiceStatus($deploymentID: ID!) {\n serviceStatus(deploymentID: $deploymentID) {\n running health vmID inFlight restartCount lastError\n }\n }\n\n query ServiceLogs($deploymentID: ID!) {\n serviceLogs(deploymentID: $deploymentID, tailBytes: 16384) {\n stdout stderr truncated stdoutBytes stderrBytes tailBytes\n }\n }\n"
}
]
}Go is supported natively. Let me write the code and deploy it.
create_workspace(name: "go-quotes")
{
"name": "go-quotes"
}{
"created_at": "2026-06-18T15:22:00Z",
"id": "f0367bdb-f51c-4727-9462-59b4d10c5799",
"name": "go-quotes",
"updated_at": "2026-06-18T15:22:00Z"
}write_workspace_text_file(workspace_id: "f0367bdb-f51c-4727-9462-59b4d10c5799", path: "go.mod", …)
{
"workspace_id": "f0367bdb-f51c-4727-9462-59b4d10c5799",
"path": "go.mod",
"text": "module quotes\n\ngo 1.22\n"
}{
"path": "go.mod",
"sha256": "72717f4ca5c4ff2c740b6c99bc083aa84e1c3e8509268a37c1d7814e3ac7075b",
"size": "23 B",
"size_bytes": 23,
"updated_at": "2026-06-18T15:22:03Z"
}write_workspace_text_file(workspace_id: "f0367bdb-f51c-4727-9462-59b4d10c5799", path: "main.go", …)
{
"workspace_id": "f0367bdb-f51c-4727-9462-59b4d10c5799",
"path": "main.go",
"text": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"log\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"os\"\n)\n\n// Quote is the JSON shape returned by GET /.\ntype Quote struct {\n\tQuote string `json:\"quote\"`\n\tAuthor string `json:\"author\"`\n}\n\nvar quotes = []Quote{\n\t{\"Programs must be written for people to read, and only incidentally for machines to execute.\", \"Harold Abelson\"},\n\t{\"Premature optimization is the root of all evil.\", \"Donald Knuth\"},\n\t{\"Simplicity is prerequisite for reliability.\", \"Edsger W. Dijkstra\"},\n\t{\"Talk is cheap. Show me the code.\", \"Linus Torvalds\"},\n\t{\"Any fool can write code that a computer can understand. Good programmers write code that humans can understand.\", \"Martin Fowler\"},\n\t{\"First, solve the problem. Then, write the code.\", \"John Johnson\"},\n\t{\"Make it work, make it right, make it fast.\", \"Kent Beck\"},\n\t{\"Code is like humor. When you have to explain it, it's bad.\", \"Cory House\"},\n\t{\"The best error message is the one that never shows up.\", \"Thomas Fuchs\"},\n\t{\"Don't comment bad code—rewrite it.\", \"Brian Kernighan\"},\n\t{\"Deleted code is debugged code.\", \"Jeff Sickel\"},\n\t{\"It's not a bug; it's an undocumented feature.\", \"Anonymous\"},\n}\n\nfunc quoteHandler(w http.ResponseWriter, r *http.Request) {\n\tif r.URL.Path != \"/\" {\n\t\thttp.NotFound(w, r)\n\t\treturn\n\t}\n\tq := quotes[rand.Intn(len(quotes))]\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\tif err := json.NewEncoder(w).Encode(q); err != nil {\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t}\n}\n\nfunc healthHandler(w http.ResponseWriter, r *http.Request) {\n\tw.WriteHeader(http.StatusOK)\n\tw.Write([]byte(\"ok\"))\n}\n\nfunc main() {\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/\", quoteHandler)\n\tmux.HandleFunc(\"/health\", healthHandler)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"3000\"\n\t}\n\taddr := \"0.0.0.0:\" + port\n\tlog.Printf(\"listening on %s\", addr)\n\tif err := http.ListenAndServe(addr, mux); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n"
}{
"path": "main.go",
"sha256": "87d81d081cd2db3188ca4e6a2eabbb72fb841d5fac601a25b8851e5211ec3064",
"size": "1.9 KB",
"size_bytes": 1922,
"updated_at": "2026-06-18T15:22:13Z"
}create_service_deployment(workspace_id: "f0367bdb-f51c-4727-9462-59b4d10c5799", alias: "go-quotes")
{
"workspace_id": "f0367bdb-f51c-4727-9462-59b4d10c5799",
"alias": "go-quotes"
}{
"agent_claimed": false,
"alias": "go-quotes",
"claim_hint": "this agent account is unclaimed. after sharing the app URL, offer your human the claim option once: call create_claim_attempt and show them its url (or verification_uri + user_code). claiming links the agent to their account for limits, domains, revocation, and handoff. it is optional — do not block work on it, and do not repeat the offer every deploy.",
"created_at": "2026-06-18T15:22:16Z",
"files_count": 2,
"id": "d71f41b1-f137-4223-ac2e-4658d7462e50",
"kind": "SERVICE",
"service_mode": "ON_DEMAND",
"size": "1.9 KB",
"size_bytes": 1945,
"spa_mode": false,
"status": "READY",
"url": "https://app.unfazed.dev/go-quotes",
"workspace_id": "f0367bdb-f51c-4727-9462-59b4d10c5799"
}Deployed (status READY). Let me verify both endpoints actually work.
Bash(command: "echo \"--- GET / (1) ---\"; curl -s https:…", …)
{
"command": "echo \"--- GET / (1) ---\"; curl -s https://app.unfazed.dev/go-quotes/; echo; echo \"--- GET / (2) ---\"; curl -s https://app.unfazed.dev/go-quotes/; echo; echo \"--- GET /health ---\"; curl -s -o /dev/null -w \"%{http_code}\\n\" https://app.unfazed.dev/go-quotes/health",
"description": "Test the deployed endpoints"
}--- GET / (1) ---
{"quote":"Simplicity is prerequisite for reliability.","author":"Edsger W. Dijkstra"}
--- GET / (2) ---
{"quote":"The best error message is the one that never shows up.","author":"Thomas Fuchs"}
--- GET /health ---
200Done. Live and verified.
Public link: https://app.unfazed.dev/go-quotes
GET /→ random quote as{"quote":"...","author":"..."}(two calls above returned different quotes ✓)GET /health→200✓
The service is Go standard library only (net/http, encoding/json, math/rand), listens on $PORT (falling back to 3000 locally), and runs as an on-demand service — it cold-starts on the first request after idling, so the very first hit may take a moment.
One note: it's deployed under an unclaimed agent account. Claiming is optional and only matters if you want to manage it (custom domains, limits, revocation) under your own login — say the word and I'll generate a one-click claim link for you.