Integration details
Description
Val Town helps users create, inspect, run, and deploy apps; manage files, branches, schedules, environment variables, SQLite data, and blob storage; and debug executions through ChatGPT.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- AI App & Website Builders
- Secondary Subcategories
- None listed
- Brand
- Val Town
- Access
- Account required
- First tracked
- 2026-07-23
- Tool count
- 55
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
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

Competing in ChatGPT AI App & Website Builders
View Category55 tools agents can invoke
Allow an org (or, by handle, a user's personal org) to reach a restricted val's HTTP endpoints. This only matters while the val is restricted (see set_http_privacy); on a public val it has no visible effect but is remembered for when the val is later restricted. Pass a `handle` to grant a specific user (their personal org); pass an `orgId` to grant a team org. Adding the same target twice is a no-op.
Add a new environment variable to a val/project. The value will be securely encrypted. If an environment variable with the same key already exists, this will fail - use update instead.
Append content to the end of a file. Useful for adding new functions, exports, or code sections without knowing the file length. Supports editing on any branch.
Copy files or whole directories from one val to another, like the 'cp' command (directories are copied recursively). Prefer this over reading code and re-writing it whenever you want to bring existing, working code from another val into the one you're editing — copying preserves exact imports and behavior, where regenerating risks subtle drift. Use `remix_val` instead when starting a brand-new val from a template. Source requires read access; destination requires write access (the source may be any public val). Provide both vals in 'handle/valName' format.
Create a new branch in a val/project by forking from an existing branch. This creates an independent copy of the source branch's files that can be edited separately. Provide the val in 'handle/valName' format (use the 'identifier' field from list_vals or get_val_detail responses).
Create an access bypass token for a val. A bypass token lets automation (e.g. a Stripe webhook, a cron job) reach a restricted val's HTTP endpoints by presenting the secret, without a logged-in viewer. The plaintext token is returned ONLY this once — store it securely; it is not retrievable later. Present it as the `X-Val-Town-Access: <token>` header or `?val_town_access=<token>` query param. Tokens never expire; revoke with revoke_bypass_token to invalidate one. At most 10 non-revoked tokens may exist per val.
Create a new directory (folder) in a val/project. Parent directories must exist before creating nested directories. Use this to organize files into folders.
Create a new file in a val/project. Supports nested paths, different file types (http, script, interval, email, file), and editing on any branch. Val Town uses Deno: use 'npm:package' imports. Provide the val in 'handle/valName' format (use the 'identifier' field from list_vals or get_val_detail responses).
Create a new val (project) on Val Town. Creates a project with a default main branch. Optionally specify an organization ID to create the val in that org (requires membership). The response includes an 'identifier' field (format: handle/valName) that can be used in subsequent tool calls. Optionally add initial content, tags, and specify privacy level. Privacy 'private' and 'unlisted' require the destination org to be on pro or business tier (not the caller's tier — call list_orgs to see each org's tier). If privacy is omitted, the default is 'private' when the destination org allows it and 'public' otherwise. `httpPrivacy` is app access — who can call the val's HTTP endpoints ('public' = anyone with the URL, 'restricted' = only granted orgs and bypass-token holders). It is a separate axis from `privacy`, which is code visibility. It is not an input here — the platform decides it, and vals created in a team org that has restricted access enabled default to 'restricted'. Always read `httpPrivacy` back off the response before sharing or testing an endpoint URL; call set_http_privacy if the val should be reachable by anyone.
Delete a blob from storage. Note: Deleting a non-existent blob succeeds silently (this is standard S3 behavior). **Storage Selection (REQUIRED)**: You MUST specify which blob store via the `storage` parameter. Choose one of: - `{ type: "val", val: "owner/valName" }` — that val's project-scoped blob storage. Requires edit access to the val. - `{ type: "deprecated_global", org: "handle" }` — that org/account's global blob storage. Pass your OWN handle for your personal global blobs. This per-org/account global storage is deprecated but still supported. For application code in Vals, use `import { blob } from "https://esm.town/v/std/blob/main.ts"` to access the val's project-scoped blobs and `import { blob } from "https://esm.town/v/std/blob/global.ts"` for account-global blobs. Never use the bare `std/blob` import — it resolves to global storage.
Delete a branch from a val/project. The 'main' branch cannot be deleted (delete the val instead). Any pending pull requests that involve this branch are cancelled. The branch is soft-deleted. Provide the val in 'handle/valName' format (use the 'identifier' field from list_vals or get_val_detail responses).
Delete a file from a val/project. Supports deleting on any branch. The file will be marked as deleted but can be recovered if needed. Provide the val in 'handle/valName' format (use the 'identifier' field from list_vals or get_val_detail responses).
Permanently remove a val from the user's account. After deletion the val leaves listings and its HTTP endpoint stops resolving (its *.val.run URL returns 404). This is a SOFT delete: the underlying data (code history, the val's SQLite database, blobs, and env vars) is retained and can be restored by Val Town on request if needed. There is no self-serve undo, so always confirm with the user before calling. Provide the val in 'handle/valName' format (use the 'identifier' field from list_vals or get_val_detail responses).
Make HTTP requests to val endpoints with full curl-like functionality. Supports all HTTP methods (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS) with custom headers and request bodies. Only works with HTTP-type vals. Requires edit access to the val. Mutating operations (POST, PUT, PATCH, DELETE) require user approval. Redirects are followed (up to 5) only while they stay on the val's own origin; a redirect to any other host is refused. Use this tool to test HTTP vals — do not construct endpoint URLs yourself, this tool resolves the correct URL automatically. Note: if you just edited the file, prefer passing `run: { kind: "fetch_val_endpoint", ... }` to `update_file`/`replace_in_file` to avoid an extra round trip.
List Val Town's official starter templates. When creating a new val, pick the closest template and fork it with `remix_val` rather than building from scratch — templates handle the boilerplate (entrypoints, imports, build config) and track current platform patterns. Each result includes an `identifier` (handle/valName) to pass straight to `remix_val`. To start from an existing val instead (the user references one, or wants something "like" another val), use `remix_val` on that val directly. A simple cron-only job (monitoring, alerts, periodic polling) doesn't need a template — create a single `interval`-type file directly.
Search for Val Town platform skills — markdown guides covering specific patterns, APIs, and best practices for building on Val Town. Call this when the user's task involves a topic that may need platform-specific guidance (e.g. storing data, building HTTP endpoints, scheduling jobs, handling email, third-party integrations). Returns the full content of matching skills inline; do not call a follow-up tool to fetch a skill body. Results include both official Val Town skills and any skills the user authored in their own vals (under the skills/<name>/SKILL.md convention); each match is labeled with its "source" ("official" or "personal"). Available official skills: blob-storage, cron-and-intervals, email, http-endpoints, oauth, react-ui, sqlite-storage, templates, third-party-integrations
Get console logs. If `truncated: true`, pass the returned `next_end` as `end` to fetch older logs, or narrow by `traceIds`
Fetch recent telemetry traces (execution runs) for a file — HTTP details, status, errors, timing.
Get detailed information about a specific val/project including metadata, tags, author, available branches, and links. Provide the val in 'handle/valName' format. Returns both of the val's access axes. `httpPrivacy` is app access — who can call the val's HTTP endpoints ('public' = anyone with the URL, 'restricted' = only granted orgs and bypass-token holders). It is a separate axis from `privacy`, which is code visibility. Check `httpPrivacy` before testing or sharing an endpoint URL: a restricted val answers unauthenticated callers — including fetch_val_endpoint — with a 302 redirect to login rather than the val's own response, so a failure there is expected and not a bug in the val's code. Use list_allowed_users to see who has access.
Fetch commit history for a val/branch. Returns commits with user information, file changes, pull requests, merges, and reverts. Commits are grouped by version number and sorted from newest to oldest.
Insert text at a specific line number in a file. The text is inserted before the specified line (pushing existing content down). Line numbers start at 1. Supports editing on any branch.
List all blobs in your blob storage. Optionally filter by key prefix. Returns blob metadata including key, size, and last modified timestamp. **Storage Selection (REQUIRED)**: You MUST specify which blob store via the `storage` parameter. Choose one of: - `{ type: "val", val: "owner/valName" }` — that val's project-scoped blob storage. Requires edit access to the val. - `{ type: "deprecated_global", org: "handle" }` — that org/account's global blob storage. Pass your OWN handle for your personal global blobs. This per-org/account global storage is deprecated but still supported. For application code in Vals, use `import { blob } from "https://esm.town/v/std/blob/main.ts"` to access the val's project-scoped blobs and `import { blob } from "https://esm.town/v/std/blob/global.ts"` for account-global blobs. Never use the bare `std/blob` import — it resolves to global storage.
List which organizations are allowed to reach a val's restricted HTTP endpoints (its http_read grants), with each granted org's handle and id. Requires edit access to the val. A public val usually has no grants (they only take effect once the val is restricted). Use the returned `orgId`s with remove_allowed_user.
List all branches for a specific val/project, including branch names, versions, and metadata. Provide the val in 'handle/valName' format (use the 'identifier' field from list_vals or get_val_detail responses).
List the access bypass tokens that exist for a val, as metadata only (public id, name, creation and revocation times). The plaintext secret is never returned — it is shown only once at creation. Requires edit access to the val. Use the returned `publicId` with revoke_bypass_token.
List all environment variable keys for a val/project. Returns keys, descriptions, and metadata only. Does NOT return actual secret values for security reasons.
List files and directories in a val/project. Optionally provide a path to browse subdirectories. Provide the val in 'handle/valName' format. HTTP-type files include a `links.endpoint` field with the live deployed URL — always use this URL rather than constructing endpoint URLs yourself.
List all organizations the authenticated user can act on, including their personal org. Returns each org's handle, avatar, display name, tier (free/pro/business), the user's role, and whether it's their personal org. Tier-gated limits (val privacy, interval minimum delay, std/email recipients) are governed by the destination org's tier — check the 'tier' field here before choosing a privacy value on create_val, an interval delay on write_interval_settings, or an email recipient at runtime.
List the tags in use on one org's vals, most-used first, with how many vals carry each one. Call this before tagging a val with create_val or update_val and reuse an existing tag whenever one fits, rather than inventing a near-duplicate. This reads a SINGLE org — with no handle, your personal account only, not the team orgs you belong to (unlike list_vals). Pass a team's handle to read its tags; you must be a member.
List all vals (projects) for the authenticated user, including name, description, tags, both access settings, creation date, and links. Each val includes an 'identifier' field (format: handle/valName) that can be used directly in other tools that require val identification. Pass 'tag' to list only the vals carrying that tag — use list_tags to see which tags exist. `httpPrivacy` is app access — who can call the val's HTTP endpoints ('public' = anyone with the URL, 'restricted' = only granted orgs and bypass-token holders). It is a separate axis from `privacy`, which is code visibility.
Merge a branch into the branch it was forked from (its parent/target) — e.g. merge a feature branch back into 'main'. The branch must be a fork (created from another branch). If merging would cause conflicts, the merge is refused and the conflicting file paths are returned so they can be resolved in the editor (or by updating the branch from its target) first. Provide the val in 'handle/valName' format (use the 'identifier' field from list_vals or get_val_detail responses).
Move a file or directory to a new location within a val/project. Works for both files and directories (moves the entire directory tree). Set newParentPath to null to move to root, or provide a directory path like 'src/utils'.
Prepend content to the beginning of a file. Useful for adding imports, file headers, or license comments. Val Town uses Deno: use 'npm:package' for imports. Supports editing on any branch.
Read the content of a blob. Returns a safe window of content regardless of the file type or size (large files are ok so feel free to read any file to get more context!) and returns file metadata if content is binary. Use offsetBytes to paginate through large blobs. **Storage Selection (REQUIRED)**: You MUST specify which blob store via the `storage` parameter. Choose one of: - `{ type: "val", val: "owner/valName" }` — that val's project-scoped blob storage. Requires edit access to the val. - `{ type: "deprecated_global", org: "handle" }` — that org/account's global blob storage. Pass your OWN handle for your personal global blobs. This per-org/account global storage is deprecated but still supported. For application code in Vals, use `import { blob } from "https://esm.town/v/std/blob/main.ts"` to access the val's project-scoped blobs and `import { blob } from "https://esm.town/v/std/blob/global.ts"` for account-global blobs. Never use the bare `std/blob` import — it resolves to global storage.
Read the code or raw content of a specific file in a val/project. Returns content with line numbers by default. Provide the val in 'handle/valName' format.
Get the interval schedule configuration for an interval file within a val. The file must have fileType='interval'. Returns the type (delay or cron), delay value, unit, and cron expression. Provide the val in 'handle/valName' format and the file path.
Remix (fork) an existing val to create a copy in your account or an organization. Copies all files, env var keys, and database schema. Provide the source val in 'handle/valName' format. When remixing within the same account, a new name is required. Use the description field to set a description for the new val (recommended when remixing a template). The response includes all files with their contents. Optionally set the remix's `privacy`; if omitted, a public source is remixed as 'private' when the destination org allows private vals (pro/business tier) and stays 'public' otherwise, while a private/unlisted source keeps its privacy.`httpPrivacy` is app access — who can call the val's HTTP endpoints ('public' = anyone with the URL, 'restricted' = only granted orgs and bypass-token holders). It is a separate axis from `privacy`, which is code visibility. The remix does not inherit the source val's app access — it takes the destination org's default, which is 'restricted' for a team org that has restricted access enabled. Read `httpPrivacy` off the response before sharing or testing the new val's endpoint URL.
Revoke an org's access to a restricted val's HTTP endpoints. Pass the `orgId` to remove (use list_allowed_users to find it). Removing a grant that doesn't exist is a no-op. Note: removing the owning org's grant will lock its own members out of the val's restricted endpoints.
Rename a file or directory within a val/project. This only changes the name, not the location. Works for both files and directories.
Preferred tool for editing existing files. Performs exact string replacements without resending the whole file, which keeps each edit fast. Use this for any small or targeted change — bug fixes, renames, tweaks. Reach for `update_file` only when rewriting most of the file. Supports editing on any branch. The old_string must match exactly (case-sensitive) for safety. Can replace first occurrence or all occurrences. After editing, prefer passing the `run` field to verify the change in the same call instead of issuing a separate run_file/fetch_val_endpoint — saves a round trip.
Request a URL to upload file content out-of-band. Use this for files larger than ~10KB to avoid passing the full content through the conversation. The flow is: 1. Call this tool to get an upload URL and upload_id 2. Upload the file using the returned curl command (e.g. in a code execution sandbox) 3. Call create_file, update_file, or storeBlobFromUrl with the upload_id instead of content/url The upload URL expires in 5 minutes and is single-use. Maximum upload size is 1024KB. For small files, prefer passing content directly to create_file/update_file.
Revert a branch or individual file to a previous version. If fileId is provided, only that file is reverted. Otherwise, the entire branch is reverted to the specified version. This creates a new commit with the reverted content.
Revoke an access bypass token so it no longer bypasses a val's restricted HTTP gate. The token's cached validity is cleared, so the revocation takes effect immediately. Find the `publicId` via list_bypass_tokens. A revoked token cannot be unrevoked — mint a new one with create_bypass_token if needed.
Run a val file and return the execution results and logs. Supports script, http, interval, and email file types. The execution runs in the Val Town runtime environment with access to the val's environment variables and permissions. Use this to test val code or trigger executions. Note: if you just edited the file, prefer passing `run: { kind: "run_file" }` to `update_file`/`replace_in_file` to avoid an extra round trip.
Set or change the custom subdomain for an HTTP val. The val's HTTP endpoint becomes 'https://<subdomain>.val.run'. Each file has at most one subdomain, so this both creates a new subdomain and edits an existing one (it replaces whatever was there). Subdomains are 3-63 chars, lowercase letters/digits/hyphens (no leading/trailing or double hyphens), and must be globally unique — claiming a taken or reserved name fails.
Change the type of a file in a val/project. Supported types: 'script' (library/utility code), 'http' (web endpoint), 'email' (email handler), 'interval' (scheduled cron), 'file' (plain file).
Toggle whether a val's HTTP endpoints are public (reachable by anyone) or restricted (only reachable by members of orgs you grant access to). Restricting a val is a feature-flagged capability; if it is not enabled for the val's organization the request is rejected. When you restrict a val its owning organization is automatically granted access so its own members are not locked out. Use add_allowed_user / remove_allowed_user to manage which other orgs may reach a restricted val, and create_bypass_token to mint a secret for automation (e.g. webhooks) to bypass the gate.
Execute multiple SQL statements atomically in a single transaction against a Turso database. All statements succeed or all fail together (rollback on error). **Database Selection (REQUIRED)**: You MUST specify which database to run against via the `database` parameter. Choose one of: - `{ type: "val", val: "owner/valName" }` — that val's per-val (project-scoped) database. Requires edit access to the val. - `{ type: "deprecated_org_global_db", org: "handle" }` — that org/account's global database. Pass your OWN handle (e.g. "stevekrouse") to reach your personal global DB. This per-account/org global DB is deprecated but still supported for legacy reasons. **Returns**: Object with { results: Array<{ columns, columnTypes, rows, rowsAffected, lastInsertRowid }> } - Each result has same format as sqlite_execute - columns: Array of column names, rows: Array of row objects - Note: for organization global databases, rows are returned as an array of arrays and therefore need to be mapped to objects using column names Examples: - Val DB: { statements: [{ sql: "SELECT * FROM users" }], database: { type: "val", val: "alice/myproject" } } - Personal global DB: { statements: [{ sql: "CREATE TABLE users (id INT)" }, { sql: "INSERT INTO users VALUES (1)" }], database: { type: "deprecated_org_global_db", org: "yourHandle" } } - Org global DB: { statements: [{ sql: "SELECT * FROM users" }], database: { type: "deprecated_org_global_db", org: "myteam" } } - With params: { statements: [{ sql: "INSERT INTO users VALUES (?)", args: [1] }, { sql: "INSERT INTO users VALUES (?)", args: [2] }], database: { type: "val", val: "alice/myproject" } } - Read-only: { statements: [{ sql: "SELECT * FROM users" }], mode: "read", database: { type: "val", val: "alice/myproject" } } Use this for debugging or one-time operations. For application code in Vals, instead use `import { sqlite } from "https://esm.town/v/std/sqlite/main.ts"` for a val's project-scoped database and `import { sqlite } from "https://esm.town/v/std/sqlite/global.ts"` for an organization's database. See https://docs.turso.tech/sdk/ts/reference#batch-transactions for more details.
Execute a single SQL statement against a Turso database (libSQL/SQLite-compatible) and return results. Supports SELECT, INSERT, UPDATE, DELETE, and other SQL operations. **Database Selection (REQUIRED)**: You MUST specify which database to run against via the `database` parameter. Choose one of: - `{ type: "val", val: "owner/valName" }` — that val's per-val (project-scoped) database. Requires edit access to the val. - `{ type: "deprecated_org_global_db", org: "handle" }` — that org/account's global database. Pass your OWN handle (e.g. "stevekrouse") to reach your personal global DB. This per-account/org global DB is deprecated but still supported for legacy reasons. **Returns**: Object with { columns: string[], columnTypes: string[], rows: Record<string,unknown>[], rowsAffected: number, lastInsertRowid: bigint|null } - columns: Array of column names ["id", "name"] - rows: Array of row arrays [{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }] - Note: for an organization's global database, the return type for the `rows` field is different. It is `rows: any[][]` - Note: rows need to be mapped to objects using column names Examples: - Val DB: { sql: "SELECT * FROM users", database: { type: "val", val: "alice/myproject" } } - Personal global DB: { sql: "SELECT * FROM users", database: { type: "deprecated_org_global_db", org: "yourHandle" } } - Org global DB: { sql: "SELECT * FROM users", database: { type: "deprecated_org_global_db", org: "myteam" } } - Positional params: { sql: "SELECT * FROM users WHERE id = ?", args: [123], database: { type: "val", val: "alice/myproject" } } - Named params: { sql: "SELECT * FROM users WHERE name = :name", args: { name: "Alice" }, database: { type: "val", val: "alice/myproject" } } Use this for debugging or one-time operations. For application code in Vals, instead use `import { sqlite } from "https://esm.town/v/std/sqlite/main.ts"` for a val's project-scoped database and `import { sqlite } from "https://esm.town/v/std/sqlite/global.ts"` for an organization's database. See https://docs.turso.tech/sdk/ts/reference for more details.
Store UTF-8 text data in blob storage. Maximum content size is 100KB. **Storage Selection (REQUIRED)**: You MUST specify which blob store via the `storage` parameter. Choose one of: - `{ type: "val", val: "owner/valName" }` — that val's project-scoped blob storage. Requires edit access to the val. - `{ type: "deprecated_global", org: "handle" }` — that org/account's global blob storage. Pass your OWN handle for your personal global blobs. This per-org/account global storage is deprecated but still supported. For application code in Vals, use `import { blob } from "https://esm.town/v/std/blob/main.ts"` to access the val's project-scoped blobs and `import { blob } from "https://esm.town/v/std/blob/global.ts"` for account-global blobs. Never use the bare `std/blob` import — it resolves to global storage.
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.
What are Val Town alternatives on ChatGPT?
As of 2026-09-13, Val Town competes with Adalo, AI Roleplay Chat Simulator, AppDeploy, Base44, Buildfire, Charming, Craftian, Floot, FluxBuilder, FreakUI, GoodBarber, Hatchable, Hercules, Hostinger, Lovable, Macaly Cloud, MiniUp, ProductOS, Replit, Sticklight, Zite in ChatGPT AI App & Website Builders, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.