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-server.env.example2 matches
1# Val Town API token - get from https://www.val.town/settings
2VAL_TOWN_API_TOKEN=your_api_token_here
3
val-town-http-mcp-serverconfig.ts7 matches
6// For remote: expect token in request headers, use local prompt file
7return {
8apiToken: null, // Will be set from headers
9apiBase: "https://api.val.town",
10cli: {
11preferCli: false,
22dotenvConfig({ export: true });
2324const API_TOKEN = Deno.env.get("VAL_TOWN_API_TOKEN");
25if (!API_TOKEN) {
26console.error("Error: VAL_TOWN_API_TOKEN environment variable is required");
27Deno.exit(1);
28}
46: undefined;
47return {
48apiToken: API_TOKEN,
49apiBase: "https://api.val.town",
50cli: {
51preferCli: PREFER_CLI,
20- Feature branches: `feature/description`, bug fixes: `fix/description`
21- Validate all user inputs and follow least privilege principle
22- Never commit API tokens or secrets
23- Each tool should have a clear purpose with descriptive parameters
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-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-serverapi.ts11 matches
1import {Config} from "./types.ts"
23export async function callValTownApi(
4config: Config,
5path: string,
7): Promise<any> {
8// Path conversion for endpoints that have changed in v2
9let apiPath = path
1011// If any old v1 paths are accidentally used, convert them to v2
12if (path.startsWith("/v1/projects")) {
13apiPath = path.replace("/v1/projects", "/v2/vals")
14console.warn(`Converting deprecated v1 path to v2: ${path} → ${apiPath}`)
15} else if (path.startsWith("/v1/alias/projects")) {
16apiPath = path.replace("/v1/alias/projects", "/v2/alias/vals")
17console.warn(`Converting deprecated v1 path to v2: ${path} → ${apiPath}`)
18}
1920const url = `${config.apiBase}${apiPath}`
2122if (!config.apiToken) {
23throw new Error("API token is required for ValTown API calls");
24}
2526const headers: HeadersInit = {
27'Authorization': `Bearer ${config.apiToken}`,
28'Content-Type': 'application/json',
29}
39if (!response.ok) {
40const errorText = await response.text()
41throw new Error(`API error (${response.status}): ${errorText}`)
42}
43
twilioWebhookmain.tsx3 matches
52});
5354// Send the SMS via Twilio API
55const twilioResponse = await fetch(
56`https://api.twilio.com/2010-04-01/Accounts/${sid}/Messages.json`,
57{
58method: "POST",
67if (!twilioResponse.ok) {
68const errorText = await twilioResponse.text();
69console.error("Twilio API error:", twilioResponse.status, errorText);
70return new Response(`Twilio error: ${errorText}`, { status: 500 });
71}
sqliteExplorerAppmain.tsx2 matches
27<head>
28<title>SQLite Explorer</title>
29<link rel="preconnect" href="https://fonts.googleapis.com" />
3031<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
32<link
33href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300..700&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap"
34rel="stylesheet"
35/>
sqliteExplorerAppREADME.md1 match
13## Authentication
1415Login to your SQLite Explorer with [password authentication](https://www.val.town/v/pomdtr/password_auth) with your [Val Town API Token](https://www.val.town/settings/api) as the password.
1617## Todos / Plans