write-script-nativets
MUST use when writing Native TypeScript scripts.
Install
mkdir -p .claude/skills/write-script-nativets && curl -L -o skill.zip "https://mcp.directory/api/skills/download/5264" && unzip -o skill.zip -d .claude/skills/write-script-nativets && rm skill.zipInstalls to .claude/skills/write-script-nativets
About this skill
CLI Commands
Place scripts in a folder. After writing, tell the user they can run:
wmill script generate-metadata- Generate .script.yaml and .lock fileswmill sync push- Deploy to Windmill
Do NOT run these commands yourself. Instead, inform the user that they should run them.
Use wmill resource-type list --schema to discover available resource types.
TypeScript (Native)
Native TypeScript execution with fetch only - no external imports allowed.
Structure
Export a single async function called main:
export async function main(param1: string, param2: number) {
// Your code here
return { result: param1, count: param2 };
}
Do not call the main function.
Resource Types
On Windmill, credentials and configuration are stored in resources and passed as parameters to main.
Use the RT namespace for resource types:
export async function main(stripe: RT.Stripe) {
// stripe contains API key and config from the resource
}
Only use resource types if you need them to satisfy the instructions. Always use the RT namespace.
Before using a resource type, check the rt.d.ts file in the project root to see all available resource types and their fields. This file is generated by wmill resource-type generate-namespace.
Imports
No imports allowed. Use the globally available fetch function:
export async function main(url: string) {
const response = await fetch(url);
return await response.json();
}
Windmill Client
The windmill client is not available in native TypeScript mode. Use fetch to call APIs directly.
Preprocessor Scripts
For preprocessor scripts, the function should be named preprocessor and receives an event parameter:
type Event = {
kind:
| "webhook"
| "http"
| "websocket"
| "kafka"
| "email"
| "nats"
| "postgres"
| "sqs"
| "mqtt"
| "gcp";
body: any;
headers: Record<string, string>;
query: Record<string, string>;
};
export async function preprocessor(event: Event) {
return {
param1: event.body.field1,
param2: event.query.id
};
}
TypeScript SDK (windmill-client)
Import: import * as wmill from 'windmill-client'
/**
- Initialize the Windmill client with authentication token and base URL
- @param token - Authentication token (defaults to WM_TOKEN env variable)
- @param baseUrl - API base URL (defaults to BASE_INTERNAL_URL or BASE_URL env variable) */ setClient(token?: string, baseUrl?: string): void
/**
- Create a client configuration from env variables
- @returns client configuration */ getWorkspace(): string
/**
- Get a resource value by path
- @param path path of the resource, default to internal state path
- @param undefinedIfEmpty if the resource does not exist, return undefined instead of throwing an error
- @returns resource value */ async getResource(path?: string, undefinedIfEmpty?: boolean): Promise<any>
/**
- Get the true root job id
- @param jobId job id to get the root job id from (default to current job)
- @returns root job id */ async getRootJobId(jobId?: string): Promise<string>
/**
- @deprecated Use runScriptByPath or runScriptByHash instead */ async runScript(path: string | null = null, hash_: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
/**
- Run a script synchronously by its path and wait for the result
- @param path - Script path in Windmill
- @param args - Arguments to pass to the script
- @param verbose - Enable verbose logging
- @returns Script execution result */ async runScriptByPath(path: string, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
/**
- Run a script synchronously by its hash and wait for the result
- @param hash_ - Script hash in Windmill
- @param args - Arguments to pass to the script
- @param verbose - Enable verbose logging
- @returns Script execution result */ async runScriptByHash(hash_: string, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
/**
- Append a text to the result stream
- @param text text to append to the result stream */ appendToResultStream(text: string): void
/**
- Stream to the result stream
- @param stream stream to stream to the result stream */ async streamResult(stream: AsyncIterable<string>): Promise<void>
/**
- Run a flow synchronously by its path and wait for the result
- @param path - Flow path in Windmill
- @param args - Arguments to pass to the flow
- @param verbose - Enable verbose logging
- @returns Flow execution result */ async runFlow(path: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
/**
- Wait for a job to complete and return its result
- @param jobId - ID of the job to wait for
- @param verbose - Enable verbose logging
- @returns Job result when completed */ async waitJob(jobId: string, verbose: boolean = false): Promise<any>
/**
- Get the result of a completed job
- @param jobId - ID of the completed job
- @returns Job result */ async getResult(jobId: string): Promise<any>
/**
- Get the result of a job if completed, or its current status
- @param jobId - ID of the job
- @returns Object with started, completed, success, and result properties */ async getResultMaybe(jobId: string): Promise<any>
/**
- @deprecated Use runScriptByPathAsync or runScriptByHashAsync instead */ async runScriptAsync(path: string | null, hash_: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null): Promise<string>
/**
- Run a script asynchronously by its path
- @param path - Script path in Windmill
- @param args - Arguments to pass to the script
- @param scheduledInSeconds - Schedule execution for a future time (in seconds)
- @returns Job ID of the created job */ async runScriptByPathAsync(path: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null): Promise<string>
/**
- Run a script asynchronously by its hash
- @param hash_ - Script hash in Windmill
- @param args - Arguments to pass to the script
- @param scheduledInSeconds - Schedule execution for a future time (in seconds)
- @returns Job ID of the created job */ async runScriptByHashAsync(hash_: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null): Promise<string>
/**
- Run a flow asynchronously by its path
- @param path - Flow path in Windmill
- @param args - Arguments to pass to the flow
- @param scheduledInSeconds - Schedule execution for a future time (in seconds)
- @param doNotTrackInParent - If false, tracks state in parent job (only use when fully awaiting the job)
- @returns Job ID of the created job */ async runFlowAsync(path: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null, // can only be set to false if this the job will be fully await and not concurrent with any other job // as otherwise the child flow and its own child will store their state in the parent job which will // lead to incorrectness and failures doNotTrackInParent: boolean = true): Promise<string>
/**
- Resolve a resource value in case the default value was picked because the input payload was undefined
- @param obj resource value or path of the resource under the format
$res:path - @returns resource value */ async resolveDefaultResource(obj: any): Promise<any>
/**
- Get the state file path from environment variables
- @returns State path string */ getStatePath(): string
/**
- Set a resource value by path
- @param path path of the resource to set, default to state path
- @param value new value of the resource to set
- @param initializeToTypeIfNotExist if the resource does not exist, initialize it with this type */ async setResource(value: any, path?: string, initializeToTypeIfNotExist?: string): Promise<void>
/**
- Set the state
- @param state state to set
- @deprecated use setState instead */ async setInternalState(state: any): Promise<void>
/**
- Set the state
- @param state state to set
- @param path Optional state resource path override. Defaults to
getStatePath(). */ async setState(state: any, path?: string): Promise<void>
/**
- Set the progress
- Progress cannot go back and limited to 0% to 99% range
- @param percent Progress to set in %
- @param jobId? Job to set progress for */ async setProgress(percent: number, jobId?: any): Promise<void>
/**
- Get the progress
- @param jobId? Job to get progress from
- @returns Optional clamped between 0 and 100 progress value */ async getProgress(jobId?: any): Promise<number | null>
/**
- Set a flow user state
- @param key key of the state
- @param value value of the state */ async setFlowUserState(key: string, value: any, errorIfNotPossible?: boolean): Promise<void>
/**
- Get a flow user state
- @param path path of the variable */ async getFlowUserState(key: string, errorIfNotPossible?: boolean): Promise<any>
/**
- Get the internal state
- @deprecated use getState instead */ async getInternalState(): Promise<any>
/**
- Get the state shared across executions
- @param path Optional state resource path override. Defaults to
getStatePath(). */ async getState(path?: string): Promise<any>
/**
- Get a variable by path
- @param path path of the variable
- @returns variable value */ async getVariable(path: string): Promise<string>
/**
- Set a variable by path, create if not exist
- @param path path of the variable
- @param value value of the variable
- @param isSecretIfNotExist if the variable does not exist, create it as secret or not (default: false)
- @param descriptionIfNotExist if the variable does not exist, create it with this description (default: "") */ async setVariable(path: string, value: string, isSecretIfNotExist?: boolean, descriptionIfNotExist?: string): Promise<void>
/**
- Build a Postg
Content truncated.
More by windmill-labs
View all skills by windmill-labs →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
fastapi-templates
wshobson
Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
Related MCP Servers
Browse all serversRSS Feed Parser is a powerful rss feed generator and rss link generator with RSSHub integration, perfect for creating cu
Use Honeycomb to manage datasets and events with a TypeScript-based interface, offering an alternative to Datadog API an
Enhance software testing with Playwright MCP: Fast, reliable browser automation, an innovative alternative to Selenium s
Create modern React UI components instantly with Magic AI Agent. Integrates with top IDEs for fast, stunning design and
Effortlessly create 25+ chart types with MCP Server Chart. Visualize complex datasets using TypeScript and AntV for powe
Mobile Next offers fast, seamless mobile automation for iOS and Android. Automate apps, extract data, and simplify mobil
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.