1213Projects can include multiple file types:
14- `http`: HTTP handler files for web APIs and sites
15- `script`: Importable module files
16- `cron`: Scheduled job files that run at intervals
36* For AI-generated images, use: https://maxm-imggenurl.web.val.run/[description]
37* DO NOT use Deno KV module, alert(), prompt(), or confirm() methods
38* For weather data, use open-meteo (no API key required)
39* Add a view source link with import.meta.url.replace("esm.town", "val.town")
40* For client-side code, include <script src="https://esm.town/v/std/catch"></script>
101โ โ โโโ queries.ts
102โ โโโ routes/
103โ โโโ api.ts
104โ โโโ static.ts
105โ โโโ index.ts
116## Val Town Access Methods
117118As an assistant, you'll help users work with Val Town through an integrated approach using both MCP tools and the vt CLI together. The MCP server automatically checks if the vt CLI is installed and accessible, using it when available or falling back to API calls when needed.
119120### MCP Tools with CLI Integration
2import {z} from "npm:zod"
3import {Config} from "../lib/types.ts"
4import {callValTownApi} from "../lib/api.ts"
5import {getErrorMessage} from "../lib/errorUtils.ts"
615async ({statement}: {statement: string}) => {
16try {
17const data = await callValTownApi(config, "/v1/sqlite/execute", {
18method: "POST",
19body: JSON.stringify({statement}),
46}) => {
47try {
48const data = await callValTownApi(config, "/v1/sqlite/batch", {
49method: "POST",
50body: JSON.stringify({statements, mode}),
73async ({statement}: {statement: string}) => {
74try {
75const data = await callValTownApi(config, "/v1/sqlite/query", {
76method: "POST",
77body: JSON.stringify({statement}),
104}) => {
105try {
106const data = await callValTownApi(config, "/v1/sqlite/exec", {
107method: "POST",
108body: JSON.stringify({statements, mode}),
val-town-http-mcp-servervalsTools.ts27 matches
1import {McpServer} from "npm:@modelcontextprotocol/sdk/server/mcp.js"
2import {Config} from "../lib/types.ts"
3import {callValTownApi} from "../lib/api.ts"
4import {getErrorMessage} from "../lib/errorUtils.ts"
5import {getCliAvailability, runVtCommand, parseCliJsonOutput} from "../lib/vtCli.ts"
37}
38
39console.error(`CLI error when getting val, falling back to API: ${result.error}`);
40// Fall back to API on error
41} catch (error) {
42console.error("CLI error, falling back to API:", getErrorMessage(error));
43// Fall back to API on error
44}
45}
4647// API implementation (original code)
48try {
49const data = await callValTownApi(
50config,
51`/v2/alias/vals/${encodeURIComponent(username)}/${encodeURIComponent(valName)}`
75async ({query, limit, offset}) => {
76try {
77const data = await callValTownApi(
78config,
79`/v1/search/vals?query=${encodeURIComponent(query)}&limit=${limit}&offset=${offset}`
135}
136
137console.error(`CLI error when creating val, falling back to API: ${result.error}`);
138// Fall back to API on error
139} catch (error) {
140console.error("CLI error, falling back to API:", getErrorMessage(error));
141// Fall back to API on error
142}
143}
144145// API implementation (original code)
146try {
147const requestBody = {
151}
152153const data = await callValTownApi(
154config,
155`/v2/vals`,
192
193// Use prepareValWorkspace first (would need to implement special workspace setup)
194// For now, we'll use the API implementation instead of complex workspace management
195
196// This could be implemented with temporary directory setup if needed,
197// but for now we'll use the API for deletion as it's simpler
198console.log("Deletion via CLI requires workspace setup, using API instead");
199} catch (error) {
200console.error("CLI error, falling back to API:", getErrorMessage(error));
201// Fall back to API on error
202}
203}
204205// API implementation (original code)
206try {
207await callValTownApi(
208config,
209`/v2/vals/${valId}`,
262}
263
264console.error(`CLI error when listing vals, falling back to API: ${result.error}`);
265// Fall back to API on error
266} catch (error) {
267console.error("CLI error, falling back to API:", getErrorMessage(error));
268// Fall back to API on error
269}
270}
271272// API implementation (original code)
273try {
274const data = await callValTownApi(
275config,
276`/v2/me/vals?limit=${limit}&offset=${offset}`
val-town-http-mcp-serverbranchTools.ts22 matches
1import {McpServer} from "npm:@modelcontextprotocol/sdk/server/mcp.js"
2import {Config} from "../lib/types.ts"
3import {callValTownApi} from "../lib/api.ts"
4import {getErrorMessage} from "../lib/errorUtils.ts"
5import {getCliAvailability, runVtCommand, parseCliJsonOutput, prepareValWorkspace, cleanupTempDirectory} from "../lib/vtCli.ts"
48}
49
50console.error(`CLI error when listing branches, falling back to API: ${workspace.error || "Unknown error"}`);
51// Fall back to API on error
52} catch (error) {
53console.error("CLI error, falling back to API:", getErrorMessage(error));
54// Fall back to API on error
55}
56}
5758// API implementation (original code)
59try {
60const data = await callValTownApi(
61config,
62`/v2/vals/${valId}/branches?limit=${limit}&offset=${offset}`
85async ({valId, branchId}) => {
86try {
87const data = await callValTownApi(
88config,
89`/v2/vals/${valId}/branches/${branchId}`
132console.error(`Failed to checkout source branch: ${checkoutResult.error}`);
133await cleanupTempDirectory(workspace.workspacePath);
134// Fall back to API
135console.error("CLI error when checking out source branch, falling back to API");
136throw new Error("Failed to checkout source branch");
137}
155}
156
157console.error(`CLI error when creating branch, falling back to API: ${workspace.error || "Unknown error"}`);
158// Fall back to API on error
159} catch (error) {
160console.error("CLI error, falling back to API:", getErrorMessage(error));
161// Fall back to API on error
162}
163}
164165// API implementation (original code)
166try {
167const requestBody = {
170}
171172const data = await callValTownApi(
173config,
174`/v2/vals/${valId}/branches`,
227}
228
229console.error(`CLI error when deleting branch, falling back to API: ${workspace.error || "Unknown error"}`);
230// Fall back to API on error
231} catch (error) {
232console.error("CLI error, falling back to API:", getErrorMessage(error));
233// Fall back to API on error
234}
235}
236237// API implementation (original code)
238try {
239await callValTownApi(
240config,
241`/v2/vals/${valId}/branches/${branchId}`,
val-town-http-mcp-serverfileTools.ts30 matches
1import {McpServer} from "npm:@modelcontextprotocol/sdk/server/mcp.js"
2import {Config} from "../lib/types.ts"
3import {callValTownApi} from "../lib/api.ts"
4import {getErrorMessage} from "../lib/errorUtils.ts"
5import {getCliAvailability, runVtCommand, parseCliJsonOutput, prepareValWorkspace, cleanupTempDirectory} from "../lib/vtCli.ts"
122console.error(`Failed to checkout branch: ${checkoutResult.error}`)
123await cleanupTempDirectory(workspace.workspacePath!)
124// Fall back to API
125console.error("CLI error when checking out branch, falling back to API")
126throw new Error("Failed to checkout branch")
127}
147}
148149console.error(`CLI error when listing files, falling back to API: ${workspace.error || "Unknown error"}`)
150// Fall back to API on error
151} catch (error) {
152console.error("CLI error, falling back to API:", getErrorMessage(error))
153// Fall back to API on error
154}
155}
156157// API implementation (original code)
158try {
159let queryParams = `?path=${encodeURIComponent(path)}&recursive=${recursive}&limit=${limit}&offset=${offset}`
162}
163164const data = await callValTownApi(
165config,
166`/v2/vals/${valId}/files${queryParams}`
197198const response = await fetch(
199`${config.apiBase}/v2/vals/${valId}/files/content${queryParams}`,
200{
201headers: {
202'Authorization': `Bearer ${config.apiToken}`,
203},
204}
207if (!response.ok) {
208const errorText = await response.text()
209throw new Error(`API error (${response.status}): ${errorText}`)
210}
211295}
296} else {
297console.error(`CLI error when creating ${type}, falling back to API: ${result.error}`)
298// Fall back to API
299}
300} catch (error) {
301console.error("CLI error, falling back to API:", getErrorMessage(error))
302// Fall back to API on error
303}
304}
305306// API implementation (original code)
307try {
308let queryParams = `?path=${encodeURIComponent(filePath)}`
316}
317318const data = await callValTownApi(
319config,
320`/v2/vals/${valId}/files${queryParams}`,
384}
385} else {
386console.error(`CLI error when updating file, falling back to API: ${result.error}`)
387// Fall back to API
388}
389} catch (error) {
390console.error("CLI error, falling back to API:", getErrorMessage(error))
391// Fall back to API on error
392}
393}
394395// API implementation (original code)
396try {
397let queryParams = `?path=${encodeURIComponent(filePath)}`
400}
401402const data = await callValTownApi(
403config,
404`/v2/vals/${valId}/files${queryParams}`,
488}
489} else {
490console.error(`CLI error when deleting path, falling back to API: ${result.error}`)
491// Fall back to API
492}
493} catch (error) {
494console.error("CLI error, falling back to API:", getErrorMessage(error))
495// Fall back to API on error
496}
497}
498499// API implementation (original code)
500try {
501let queryParams = `?path=${encodeURIComponent(filePath)}&recursive=${recursive}`
504}
505506await callValTownApi(
507config,
508`/v2/vals/${valId}/files${queryParams}`,
val-town-http-mcp-serverblobTools.ts9 matches
2import {z} from "npm:zod"
3import {Config} from "../lib/types.ts"
4import {callValTownApi} from "../lib/api.ts"
5import {getErrorMessage} from "../lib/errorUtils.ts"
616try {
17const queryParams = prefix ? `?prefix=${encodeURIComponent(prefix)}` : ""
18const data = await callValTownApi(config, `/v1/blob${queryParams}`)
1920return {
41try {
42// For blobs, we need to handle binary data differently
43const url = `${config.apiBase}/v1/blob/${encodeURIComponent(key)}`
44const response = await fetch(url, {
45headers: {
46"Authorization": `Bearer ${config.apiToken}`,
47},
48})
50if (!response.ok) {
51const errorText = await response.text()
52throw new Error(`API request failed: ${response.status} ${response.statusText}\n${errorText}`)
53}
54109}
110111const url = `${config.apiBase}/v1/blob/${encodeURIComponent(key)}`
112const response = await fetch(url, {
113method: "POST",
114headers: {
115"Authorization": `Bearer ${config.apiToken}`,
116"Content-Type": contentType,
117},
121if (!response.ok) {
122const errorText = await response.text()
123throw new Error(`API request failed: ${response.status} ${response.statusText}\n${errorText}`)
124}
125146async ({key}: {key: string}) => {
147try {
148await callValTownApi(config, `/v1/blob/${encodeURIComponent(key)}`, {
149method: "DELETE",
150})
val-town-http-mcp-serveruserTools.ts3 matches
2import {z} from "npm:zod"
3import {Config} from "../lib/types.ts"
4import {callValTownApi} from "../lib/api.ts"
5import {getErrorMessage} from "../lib/errorUtils.ts"
615async ({username}: {username: string}) => {
16try {
17const data = await callValTownApi(config, `/v1/alias/${encodeURIComponent(username)}`)
1819return {
37async () => {
38try {
39const data = await callValTownApi(config, "/v1/me")
4041return {
2import {z} from "npm:zod"
3import {Config} from "../lib/types.ts"
4import {callValTownApi} from "../lib/api.ts"
5import {getCliAvailability, runVtCommand} from "../lib/vtCli.ts"
616async ({limit, offset}: {limit: number; offset: number}) => {
17try {
18const data = await callValTownApi(
19config,
20`/v1/me/projects?limit=${limit}&offset=${offset}`
44async ({projectId}: {projectId: string}) => {
45try {
46const data = await callValTownApi(config, `/v1/projects/${projectId}`)
4748return {
84}
85}
86// If CLI fails, fall back to API
87} catch (error) {
88console.error("CLI error:", error)
89// Continue to API fallback
90}
91}
9293// Fallback to original API implementation
94try {
95const data = await callValTownApi(
96config,
97`/v1/alias/projects/${encodeURIComponent(username)}/${encodeURIComponent(projectName)}`
162}
163164const data = await callValTownApi(config, "/v1/projects", {
165method: "POST",
166body: JSON.stringify(payload),
190async ({projectId}: {projectId: string}) => {
191try {
192await callValTownApi(config, `/v1/projects/${projectId}`, {
193method: "DELETE",
194})
Glancer_README.md1 match
1## /api
23This directory holds the endpoints that serve JSON for the /demo, and a few other endpoints that handle POSTS and GETs from the /frontend.
Glancerapi.routes.ts6 matches
23// Import route modules
4import cobrowse from "./cobrowse.api.routes.ts";
5import database from "./database.api.routes.ts";
6import demo from "./demo.api.routes.ts";
7import page from "./page.api.routes.ts";
8import action from "./action.api.routes.ts";
9import actions from "./actions.api.routes.ts";
1011const app = new Hono();