Ullbek
Build and publish websites
- Category
- Pending
- Primary Subcategory
- Pending
Integration details
Description
Describe your business or idea in plain words and Ullbek builds a real, custom website around it — actual pages written for you, not template blocks with a ceiling. Watch it come together through live preview links, ask for any change in plain language, and publish it to the web when it's ready. Every site gets a free address with free hosting included; premium hosting connects your own custom domain. No templates, no drag-and-drop, no coding — you describe it, it's built, it's live.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Category
- Pending
- Primary Subcategory
- Pending
- Secondary Subcategories
- None listed
- Brand
- Ullbek
- Access
- Account required
- First tracked
- 2026-09-25
- Tool count
- 49
- Geography
- US
The broad Category that contains the Primary Subcategory.
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Get alerts for Ullbek
Get updates when Ullbek’s Discoverability Score or category rank changes.
ChatGPT Plugin Discovery Score
ChatGPT Plugin discovery is coming soon
ChatGPT can surface a Plugin when it matches a user's request.Your Plugin Discovery Score measures how often yours appears.
No spam. Unsubscribe any time.
What discovery looks like

Competitive lineup
49 tools agents can invoke
Apply ONE find-and-replace across MANY files in a single call — the sweep tool: renaming a label everywhere, updating every page's nav, fixing a class name site-wide. `paths` is a JSON array of explicit /www paths (list them from grep or list_files — there is no glob; every file you touch is named on purpose). Every occurrence of `find` in every listed file is replaced (use edit_file for a single precise change in one file). Set `isRegex: true` for a regular expression ($1…$n captures in `replace`). Need several different edits? Issue several bulk_edit calls — they are fast. Safe by design: a find that matches NOWHERE aborts the call with nothing written (fix the string and retry), and every write is conditional on the file's version, so concurrent changes are reported, never clobbered. The result counts replacements per file and — important — lists any `unmatched` files (listed by you, but the find didn't occur there): check those; a page variant (e.g. an active-class nav) often needs its own follow-up edit. No diffs are returned; spot-check with read_file or the preview if unsure.
Check whether a custom domain's A record has propagated to our load balancer IP yet. Defaults to the site's custom domain. Use this to tell the user whether their DNS change has taken effect.
The newest domain purchase's progress (pending_checkout → paid → registered, or failed with a reason) plus the domain row itself. Once `registered`, serving progress lives in verify_custom_domain / get_publish_state as usual. pending_checkout means payment wasn't completed; `checkout_opened` says whether the user ever opened the card's checkout (false = payment never started — nothing failed), and `note` says what to tell them.
Fetch a live URL over HTTPS exactly the way a visitor's browser would and report what happened: `ok` with the HTTP status and page title, or a classified failure (`dns` = doesn't resolve, `tls` = certificate not served at the edge yet, `connect`, `timeout`, `http` = non-2xx). Defaults to checking every host the site should be live on. ALWAYS run this after publishing or after a domain goes active, BEFORE telling the user a URL is live — only report a URL as working when its check is ok.
Static-site correctness check — the stand-in for a compiler this site doesn't have. It scans every text file for internal references (href="...", src="...", CSS url(...), and ES `import` specifiers) and reports the ones that point at a file which doesn't exist — i.e. broken links you'd otherwise only discover in the browser. It also reports orphaned `.html` pages (other than /www/index.html and /www/_internal/) that nothing else links to. References are URL paths (a URL `/x` is the file `/www/x`): external and non-file refs (http(s)://, //, data:, mailto:, tel:, and #anchors) are ignored, relative paths are resolved against the referencing file's directory, a clean URL like `/about` resolves to the file `/www/about.html`, and a trailing `/` resolves to its `index.html`. Run this after moving or deleting files and before publishing. Returns { broken: [{ from, ref, resolved, line }], orphaned: [{ path }], checked }. `from` and `orphaned[].path` are /www-rooted file paths; `resolved` is the URL path the broken ref points at. The `broken` list is capped at 200 and `orphaned` at 200.
Check whether a subdomain is usable for this site WITHOUT changing anything. Returns a status: `available` (free to take), `taken` (someone else has it), `invalid` (bad format or a reserved name — see `reason`), or `current` (already this site's slug). Use this before `set_slug` so you can confirm a name is free instead of guessing, and to answer "is X available?".
Remove the site's custom domain: tear down its certificate, unbind it, free its load-balancer slot, and move the site's content back under its slug. The slug host keeps working. Confirm with the user first.
Copy a file into the site at an absolute path. `from` can be a site path (to duplicate a page/template) OR a stored-file id — `ast_…` (a user asset), `att_…` (a chat attachment), or `dwl_…` (a file you downloaded). `to` is the destination site path (e.g. `/www/images/logo.png`), served at the path minus `/www` — reference it from your HTML/CSS as `/images/logo.png`. This is how you bring an asset, attachment, or download into the rendered site (they aren't part of it until copied). For images you can downscale/convert in one step with `optimize_image` instead.
Create a new site. Returns its site_id (the handle for every other tool) and the reserved free slug it will publish under. Start here for a brand-new website, then write files with write_file.
Crop an image to EXACTLY a canonical `aspectRatio`, subject-aware — the fix for an upload or asset whose shape doesn't match its slot. A vision model finds the subject, then a deterministic crop takes the largest window of the target ratio around it — nothing is stretched, distorted, or regenerated. Pass `subject` ("the two swans", "the person on the left") whenever you know what must be kept — from the user's words or the page's purpose; omit it and the most prominent subject is used. `path` is the image's absolute path (e.g. `/uploads/photo.jpg`); the result is written to `destPath` (e.g. `/www/images/hero.jpg`, served at the path minus `/www`; extension sets the format). Use this BEFORE placing a mismatched image instead of letting CSS `object-fit: cover` chop it. Set `maxWidth` to also downscale to display size. Returns the new dimensions plus a preview — verify the framing kept what matters. `optimize_image` is the shape-preserving cousin (resize/convert only).
Delete files by absolute path — up to 50 in ONE call (`paths`, e.g. `["/www/old.html", "/uploads/draft.png"]`). Idempotent: each result says whether a file was there (`deleted: false` means nothing was). Folders aren't deleted as such — a folder is gone once its last file is. Deleting a /www file removes its URL, so make sure nothing still links to it — run `check_references` afterwards if other pages might point here. Tool calls made together run at the same time: to delete a file another call is creating or moving, wait for that call's result first.
Download a file from the internet into this site's downloads area — for self-hosting a font you found, or pulling an image/video when migrating a site. Give an http(s) `url` (optionally a `filename`). Returns a `downloadId` (`dwl_…`); the file is NOT on the site yet — bring it in with `copy_file` (any file) or `optimize_image` (images) referencing that id. The download is size-capped and restricted to public internet hosts.
Edit ONE file with a JSON array of find-and-replace edits applied in order — batch every edit you need in this file into a SINGLE call (parallel edit_file calls on the same file conflict on the version and waste retries; one call = one atomic write). Each edit's `find` is copied verbatim from the file and must match exactly once — add surrounding context to disambiguate, or set `replaceAll: true` on that edit; set `isRegex: true` on an edit for a regular expression ($1…$n captures, no look-around). A later edit sees the earlier edits' output. Atomic: if ANY edit fails to match, nothing is written — fix it and retry. Prefer this over write_file for changing parts of a file; for the SAME edit across many files use bulk_edit. The write is conditional on the file's current version, so a concurrent change is reported rather than clobbered. The result returns per-edit replacement counts and a `hunk` — line-numbered windows showing every change in place with its NEW line numbers — so you do NOT need to re-read the file afterwards.
Read an external web page or resource. For HTML pages the default `digest` view returns a structured extraction that answers most needs in one small result: page metadata, the readable CONTENT as markdown, LINKS (the site's nav map), MEDIA (every image URL with alt text, video embed IDs, background images), and ASSETS (stylesheet + font URLs) — use it for reading an existing site you're rebuilding, researching a topic, finding a logo or photos, or mapping a site's structure. All URLs in the digest are exact and absolute — pass them straight to download_file. Non-HTML resources (JSON APIs, CSS, SVG, JS) always return their raw body; pass view:"raw" only when you need a page's actual HTML markup. If a result is truncated it names the exact `offset` to continue from. `urls` is a JSON array of 1 to 5 strings — a single page is a one-element array like ["https://example.com"]; pass several to read the key pages of a site in one call. This reads external resources only — it does NOT read this site's files (use the file tools for those).
Generate an original image from a text `brief` — for hero shots, photos, illustrations, backgrounds, or icons; the way to source every image the user hasn't uploaded. Photographic briefs render as real-looking photographs, so describe subjects, ages, light and lens like a photo shoot when that's the goal. Expect ~15 s per image: fire independent generations in the same turn, in parallel, never one after another. `aspectRatio` is REQUIRED: pass the ratio of the SLOT the image will fill ("16:9" hero, "1:1" tile, "3:4" portrait card, …) so the image is born the right shape instead of being squeezed by CSS later. `path` is where the full-resolution image is saved — normally straight into the site (`/www/images/hero.jpg`, referenced as `/images/hero.jpg`); the extension sets the encoding. Returns a small preview to check and the saved path. Each generation consumes AI credits.
Read the provisioning state of the site's custom-domain TLS certificate (provisioning / active / failed). Use this to explain to the user why a custom domain isn't live yet.
The site's custom domain as its two hostnames: the canonical host (serves the site — visitors see it) and the redirect host (301s to the canonical), each with its wiring status and, while pending, the exact DNS records still needed. Use this to narrate domain status; use set_canonical_host to swap which hostname serves.
Mint a time-limited signed URL to the LIVE working version of this site — the real files, served exactly as they will publish. The link requires no login. Use it two ways: (1) give it to the user so they can see their site in their browser right now, before publishing; (2) open it YOURSELF in your own browser to inspect the running site — view the rendered result, check layout and content, and debug — it is your window into the live site, not an opaque string to forward. Links expire after 30 minutes; mint a fresh one whenever needed.
Read the site's full publishing state: whether it's live, its hosts (`hosts` lists exactly what serves — the slug host only when `slug_serving` is on, plus the custom domain when active), the custom-domain status and the records the user must add (the A-record target in `domain_a_record_target` is the load balancer the domain is assigned to). ALWAYS call this first when you take over a publishing conversation, so you reason from real state.
One orientation read for an existing site: its files, name, slug, publish state, custom-domain state, and subscription status. Call this before working on a site you didn't just create.
This site's commercial picture: plan (premium/free), status, renewal date, pending cancel, the domain serving it, and whether its included free domain is still unclaimed. Call it before any billing/subscription conversation — and mention the unclaimed included domain when relevant.
Search every file in the site for one or more strings or regexes, returning each matching line with its file path and 1-based line number. `queries` is a JSON array of 1 to 15 strings — a single lookup is a one-element array like [".hero"]. When several lookups are related (a handful of selectors, variables, paths), batch them into one call: the files are scanned once for all queries together, which is far cheaper than one call per query. Queries are matched as literal, case-sensitive substrings exactly as written — `<`, quotes, and backslashes are ordinary characters, so search for `<section` or `class="card"` as-is. Never HTML-encode (`<` will not match `<`) and never regex-escape (`\.hero` will not match `.hero` — write `.hero`). Set `isRegex` to true to compile every query as a regular expression instead (a bad pattern returns a clear error). `glob` is REQUIRED and states which files are scanned — /www-rooted like every other path: `/www/css/*.css` scans only the css folder (one level), `/www/**/*.{html,css}` every HTML and CSS file site-wide (braces cover several extensions), `/www/**` the whole site — the right scope for reference-integrity checks before renaming or deleting a file. Each hit is `{ path, line, text }` where `text` is the matched line trimmed and clamped to ~200 characters. `maxResults` caps hits PER QUERY (default 100); a capped query sets `truncated: true` — there is no pagination, so narrow with a more specific query or a `glob` and re-run. Returns `{ results: [{ query, matches, count, truncated }], totalCount }`, one entry per query in input order. Binary (non-UTF-8) files are skipped. Use grep for reference integrity — find every place a CSS class, asset file, anchor id, or URL path is referenced before renaming or deleting it — and for locating a rule you already know you need. To survey a whole file's structure (every CSS selector, heading, or id with line numbers) use `outline` instead; to see how the page actually RENDERS (computed colors, backgrounds, spacing, what visually merges with what) use `inspect_preview_css` or a screenshot rather than reconstructing the cascade from source.
Get an image's width, height, format, byte size and nearest canonical aspect ratio without loading its pixels into context. `path` is the image's absolute path (e.g. `/uploads/photo.jpg`). Use it before placing an uploaded image: compare `nearestAspectRatio` with the slot's ratio and `crop_image` when they differ, and spot a 4000px / 3 MB upload that should be downscaled with `optimize_image`.
The workspace's domain portfolio: every domain owned through Ullbek with status, registration and expiry dates, who pays its renewals, and which site (if any) it points at. `undo_until` = our estimate of how long a purchase can still be cancelled for a full refund with revoke_domain; the registry is the judge, so a recent purchase is worth trying even if the field is empty. `past` = history, not actionable: names this workspace once ordered that are no longer its domains (cancelled and refunded, registration failed, checkout never completed) with when and why — the answer to 'what happened to X'. The place to start any 'my domains' conversation.
List files and folders. Works like `ls` with a `find` mode: list one folder, drill into a sub-folder, list a folder recursively, or find files by glob. Every entry has `path` (absolute, e.g. `/www/index.html`; a /www file's URL is its path minus `/www`), `size` in bytes, and `version`. Examples: list_files() → the top-level folders: /www, /uploads, … list_files(path: "/www") → the site's top level: sub-folders + pages list_files(path: "/www/images") → one folder's files list_files(path: "/uploads") → what the user uploaded list_files(path: "/www", recursive: true) → every file on the site, paged list_files(glob: "/www/**/*.html") → every page, wherever it is list_files(glob: "/uploads/*.{png,jpg}") → the user's images Globs: `*` matches within one folder level, `**` recurses, `{a,b}` covers alternatives. Start at a folder and drill in; recurse or glob only when you need the whole set. Long listings page with `offset` and `limit` (default 100); the response reports `total` and `truncated`.
List every site in the user's workspace: site_id, name, slug, publish state. Call this first on any reconnect to orient — the site_id is the handle every site-scoped tool needs.
Load a curated Ullbek skill: our recommended approach for a recurring build task, returned as a short guide to combine with your own expertise and current web info. Skills are guidance, not rules — keep using your world knowledge. Load one just-in-time when a request fits. Available skills: - form_submit: collecting visitor input (contact, signup, feedback, booking forms) via Ullbek's built-in form backend — submissions are emailed to the site owner and readable with read_form_submissions. - icons: whenever a site needs icons — a curated shortlist of CDN icon libraries matched to the site's aesthetic, with pinned CDN snippets, instead of hand-rolling SVGs for standard concepts. - charts: showing the user's data (growth, results, stats) — chart library ladder from Chart.js up to D3, with the non-negotiables. - selling: taking payments (products, services, subscriptions) via hosted providers like Stripe Payment Links — never first-party checkout. - maps: showing a location, directions, or service area — keyless embeds first, Leaflet for custom pins. - embeds: third-party widgets — appointment booking (Calendly/Cal.com), YouTube/Vimeo video, social posts — with the responsive/privacy rules. - galleries: image grids and masonry with a lightbox, wired to our image pipeline for real thumbnails. - local_seo: publish-time polish for local businesses — LocalBusiness JSON-LD, titles/descriptions, social cards, favicons.
Find out who runs a domain, so you can name the user's providers yourself instead of asking them. Returns the registrar of record (via RDAP, with its IANA id) and the domain's authoritative nameservers. IMPORTANT: DNS records must be added wherever the NAMESERVERS point (e.g. `*.ns.cloudflare.com` → Cloudflare, `ns*.wixdns.net` → Wix, `*.domaincontrol.com` → GoDaddy) — that's the registrar's own dashboard only when the nameservers are the registrar's. Some country TLDs publish no RDAP; then `registrar` is null (see `note`) and you identify the DNS provider from the nameservers alone.
Move or rename a file from one absolute path to another (e.g. `/www/old.html` → `/www/new.html`). Note: a file's URL is its path minus `/www`, so moving it changes the URL — afterwards, run `check_references` (or update any `href`/`src`/`import` that pointed at the old URL) so nothing breaks.
Convert/resize one source image into one or more written site files in a single call. `path` is the image's absolute path (e.g. `/uploads/logo.svg`, `/www/images/photo.jpg`) — raster or SVG; `outputs` (≤8) each write a `destPath` (under `/www`, served at the path minus `/www`; the extension sets the format unless `format` is given) with optional `maxWidth`/`maxHeight` and `quality` (1–100, default 80, JPEG/WebP). Raster sources downscale only (aspect preserved, never upscaled) — serving an image at its display size is the biggest performance win. SVG sources rasterize at exactly the requested size (pass `maxWidth`), so icons from a vector logo stay crisp. `ico` output packs a standard 16/32/48 favicon.ico. One intention = one call: a favicon set (`/www/favicon-32.png` 32px + `/www/apple-touch-icon.png` 180px + `/www/favicon.ico`) or a responsive srcset (480/960/1600 JPEGs) is a single call with several outputs. Returns a per-output manifest (format, dimensions, size) with per-output errors.
Return the cheap SHAPE of one site file so you can target a `read_file` slice (by `offset`/`limit`) instead of reading the whole file. Give it an absolute `path` (e.g. `/www/index.html`); it picks a strategy by extension and returns a flat list of symbols, each with `name`, `kind`, and 1-based `line`. For HTML: headings (kind `heading`, name = inner text), every element with an `id` (kind `id`, name = the id), and `<title>` (kind `title`). For CSS: the selector text before each `{` (kind `selector`). For JS/MJS: top-level-ish declarations — function/class/const/let/export (kind `decl`, name = the identifier). For any other file the symbol list is empty. This uses lightweight regex scanning, not a real parser, so it is approximate. Symbols are capped at 200 and each name is clamped to ~120 chars; use the line numbers to read the exact region you care about.
Publish the site live: save it, push its files to the hosting CDN, and mark it published. Idempotent — call again to push the latest changes. Returns the live URL(s). The site serves on whichever hosts are ON: the free slug address (unless turned off via set_slug_serving) and the custom domain when one is active. With no host on at all, this returns `blocked.reason: no_host` — relay the choice to the user instead of retrying.
Read files' contents as line-numbered text — up to 10 files or slices in ONE call (`files`, an array of `{path, offset, limit}`). Several related reads (a script and its stylesheet, three ranges of one file) belong in one call, not several. `path` is the file's absolute path (e.g. `/www/index.html` — a /www file's URL is the path minus `/www`, so `/www/about.html` is served at `/about.html`; or `/uploads/notes.md`, a file the user gave you). Use this for text files (HTML, CSS, JS, Markdown, JSON, …). For a large file, page with `offset` (1-based start line) and `limit` so you only read the part you need. Each result includes a `version` — pass it to `write_file` as `expectedVersion` for a safe conditional overwrite. A file that can't be read reports its own `error` without failing the others. To LOOK AT an image or PDF instead of reading text, use `view_file`.
Read this site's contact-form submissions (newest first): the submitted fields, which page they came from, the spam verdict, and whether the email notification was sent to the site owner. Use it to verify a form you built end-to-end (submit a test through the live form, then read it back here) and to answer questions like "did I get any messages?". Submissions marked test came from the builder preview. If your own test shows verdict spam, resubmit with a realistic customer-style message - junk text gets filtered.
Read the site's metadata: the name the user typed when creating the site, its slug, whether it's published, its public URL, and any custom domain, plus `form_endpoint` — the exact URL the site's forms post to. Call it when building or updating the site brief, choosing titles/branding, wiring a form, or answering what the site's URL is or whether it's live. Read-only — publishing actions still go through the publishing specialist.
Record a piece of feedback into our continuous-improvement log. Use it in two ways. (1) AUTONOMOUSLY: when a tool fails, behaves wrong, or a capability you needed is missing, file it as `source: agent` with the details — then keep working and solve the user's request by other means. This is a side-channel to the Ullbek team, not a substitute for finishing the job, and you never need the user's permission to file it. (2) RELAY: when the user expresses how they feel — praise or a complaint about the product/agent (not a normal build request) — capture it as `source: user` with their wording in `detail`. Pick `sentiment` positive/negative, a one-line `summary`, and a short `category`. Filing feedback is quick and must never block or delay the user's actual request.
Look up a hostname's public A records (IPv4) right now, to help debug a custom domain that isn't resolving. Returns the addresses it currently resolves to (empty if it doesn't resolve).
Swap which of the custom domain's two hostnames serves the site (the canonical host); the other becomes the redirect host and 301s to it. Answers "make it www.rosie-bean.com instead" in one call. The hostname must already be wired (its certificate live) — check get_domain_hosts first if unsure. The swap runs in the background and takes a minute or two; the returned state's `flip` field tracks it (poll get_domain_hosts or publish state to see it finish). Tell the user the switch has started and continues on its own — both addresses keep working throughout.
Begin custom-domain setup for the site. Assigns the domain to one of our load balancers, provisions a TLS certificate, and returns the DNS records the user must add at their registrar: a CNAME for validation and an A record pointing at the assigned load balancer's IP (read it from `domain_a_record_target` in the returned state) — just those two; keep the first setup minimal. After they add the records, call verify_custom_domain. Tell the user the exact records. (The domain's other spelling can forward here too — an opt-in via set_redirect_host, best offered once the domain is live.)
The forwarding OPT-IN: set up the domain's other spelling as a redirect host (301 → the canonical host), when the customer wants it. For a domain registered through us the DNS records are written automatically — nothing for the customer to do. For a BYO domain, give them the records from the returned state (`redirect_hostname` A → `domain_a_record_target`, plus the `redirect_cname_*` CNAME); it activates on a later verify whenever they add them.
Rename the site — the label the user sees on their dashboard and in the builder, NOT the public URL. Use it when the user asks to rename their site, or when the placeholder name from creation is settled into a real one with the user's agreement. It never changes the slug, domain, or anything published — changing the web address is the publishing specialist's set_slug.
Change the site's subdomain (the friendly host `{slug}.{suffix}`). The slug must be a valid DNS label and globally unique. If the site is live, the new subdomain takes effect immediately and the old one stops resolving.
Turn the site's free slug address (`{slug}.{suffix}`) on or off. The slug and a custom domain are independent places the site can serve — off means the slug address 404s and the site serves only on its custom domain (domain-only hosting, what users mean by 'I don't want the free address'). On (the default) means the slug serves the site — or redirects to the custom domain when one is active. Takes effect immediately on a live site. Confirm before turning it OFF on a live site with no active custom domain: that takes the site fully offline. Returns the fresh publish state.
Render the site fresh in a stateless headless browser and capture it. Each call renders independently and sees NOTHING you did to the user's preview, so set the state you need here: `path` — which page (e.g. "about.html", default the root); `device` — "phone" (390×844), "tablet" (768×1024) or "desktop" (1280×800, the default); `width` — a custom viewport width when no preset fits (pass one of `device`/`width`, not both); `run_js` — JavaScript run before the shot (toggle a theme, open a menu, freeze an animation); `wait_for` — extra wait (ms, a CSS selector to await, or "load"); every capture settles briefly on its own. Framing, narrowest first: `selector` crops to the element matching a CSS selector; `section` scrolls that element into view and captures one viewport around it; the default is the page's top viewport; `full_page: true` is the whole page in one image — the page is scrolled through first so reveal animations and lazy media render, and tall pages are downscaled, so fine text won't be legible. To capture what the user is currently looking at instead (their live viewport + state), use `capture_preview`.
Take the site offline (docs/73): every address it serves on — its own domain, any www/apex redirect, and the free ullbek.site address — shows a not-found page until it is published again. Reversible and non-destructive: the site's files, its reserved free address, and a connected custom domain (DNS, certificate) all stay, so publishing again restores the same addresses instantly. It does NOT cancel Premium hosting — that is a separate, explicit decision (`cancel_subscription`, at period end). Requires `confirm: true`; refused otherwise. Before calling, tell the user which addresses go offline, what stays, and that Premium keeps running — then ask (`ask_user`). Idempotent on an already-offline site.
Check a file for structural problems a browser won't report: JS syntax errors (a full parse — a syntax error silently disables the whole script file), unbalanced CSS braces, unterminated strings or comments, an unclosed HTML comment, and the CSS inside `<style>` blocks. This is the compiler stand-in. `write_file` and `edit_file` already run these checks automatically and return any `warnings`, so you usually don't need to call this — use it to re-check a file, or to validate `content` before writing it. Returns `{ path, ok, issues: [{ line, severity, message }] }`.
Check a pending custom domain now: when the certificate is active AND the DNS A record resolves to our load balancer, the domain goes live and is bound to the site. Otherwise it reports what's still pending. Run this after the user has added the DNS records. On activation the response includes a `live_check` — an end-to-end fetch of the domain. Only tell the user the domain works when `live_check.ok` is true; a `tls` failure means the edge isn't serving the new certificate yet (it can take ~15–30 minutes), so say it's verified but still rolling out.
Look at a file as an image or PDF that you (the model) can see — it loads into YOUR context, not the user's chat. `path` is the file's absolute path (e.g. `/uploads/logo.png` for something the user gave you, `/www/images/hero.jpg` for a file on the site). Use this to view a logo to match, a photo, a sketch to turn into a layout, or a whole PDF at once. A PDF loads whole only on a model that reads PDFs; otherwise this tool points you at `read_pdf_as_text` (its words, cheap) and `view_pdf_as_images` (its pages), which work on every model and are the better first stop for a long document anyway. To show an image to the USER (e.g. a generated image to approve), use `ask_user` with an image preview instead. To READ a text file (HTML, CSS, JS, Markdown, …) use `read_file` instead — point view_file at text and it will tell you to.
Create or overwrite a file at an absolute site path (e.g. `/www/index.html`). Writes the full `content` — the file is served exactly as written and is immediately live in the preview at the path minus `/www` (file `/www/about.html` is the URL `/about.html`). Write only browser-native code: HTML, CSS, vanilla JS, ES modules, import maps, CDN imports — there is no build step. Set `createOnly` to avoid clobbering an existing file, or pass `expectedVersion` (from `read_file`) for a safe conditional overwrite. To change part of an existing file, prefer `edit_file`.
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.