Publish a tool you built with Claude Code, Cursor or ChatGPT
You asked Claude Code, Cursor or ChatGPT for a tool, and it wrote one. The tool works on your machine. Now other people must use it too, and they have no Python and no terminal. This Guide publishes your tool on Abyss as a Widget. Then people run it from a form in their browser, and code calls it through the API.
Your coding agent does most of the work. You make the decisions, and you press the buttons on Abyss.
Check that your tool fits
A Widget works in runs. A run takes inputs, does one job and returns an output. It keeps nothing from one run to the next. Your tool fits when it does the same. For example, it reads a PDF and returns a summary, or it takes a sheet and a date and returns a report.
Abyss runs Python only. When your tool is in another language, the agent writes its logic again in Python.
Abyss is the wrong tool when your tool must stay up or wait. Do not publish these as a Widget:
- •an app with accounts or pages of its own;
- •a bot or a server, which must stay up between requests;
- •a sync, a monitor or a schedule, whose work is to watch and react;
- •a tool that needs a person to sign in on every run.
Such a tool can hold one job that fits. Then that job becomes the Widget, and the rest stays outside and calls it.
Give your agent the skill and /llms.txt
Two things teach your agent what Abyss needs.
The `abyss-widget` skill. It tells the agent what a Widget must be, and it holds the steps from your code to a published Widget. Install it in your project:
npx skills add Abysshub/abysshub-sdk --skill abyss-widget -a claude-code-a names your agent. When your agent cannot install a skill, give it the address of the skill's folder on GitHub.
[/llms.txt](/llms.txt). It is a short page for coding agents. It says what Abyss is, how code calls a Widget with the abysshub library, and where the Docs are as Markdown.
Then tell the agent to make your tool into an Abyss Widget.
What the agent does
The agent follows the skill's steps, in this order. Each step says what it asks of you.
1. It agrees the shape with you. It names what one run takes and what it returns. Each input becomes a Field of the form (see Field types). Each output becomes a file in output/ (see Outputs). The agent checks both against the Run limits. It also asks whether to put the Widget on Abyss, or only to prepare its folder.
2. It writes the project. run.py reads each input from an environment variable and writes each output into output/. interface.json describes the Fields. requirements.txt pins each package. The project says what each file holds.
3. It keeps the keys out of the code. Your tool may use a key, for example an OpenAI key. The agent names the variable. You write its value into .env in the project's folder yourself. Never paste a key into the chat. Environment variables tells how Abyss gives the key to each run.
4. It runs the Widget on your machine. It writes a few sample inputs, and one input that must fail. It runs each one the way Abyss runs a Widget, and reads the outputs and the logs. It fixes the code until each sample gives the right output.
Give the agent inputs from your real work for the samples. Then the Widget is checked on your real cases, not only on cases that the agent made up.
Run a Test Run, and set the Example Run
You put the Widget on Abyss yourself. The agent gives you each step.
- •Press Publish in the navbar, and drag the project's folder into the uploader. Drag the folder, not a zip.
- •Check that the form shows each Field, and that each key is under Environment variables. What isn't uploaded says why
.envstays out of the Widget's files. - •Press Test Run, fill in the form with one sample input, and press RUN. Read the outputs and the logs.
Publish needs a Test Run that succeeded. When a Test Run fails, give its log to the agent. The agent fixes the code. Then you drag the folder in again and press Test Run again. Troubleshooting gives the fix for each common error.
When you publish, your Test Run becomes the Example Run. The people who open the Widget see it before they run it. So use inputs that you can show to anyone: no client data and nothing personal. Test, publish, price says who sees it.
Publish the Widget
Fill in the listing: the title, the thumbnail, a tag, the price, and who can see the Widget. Name the title after the job, for example "Summarize a contract", not after the agent that wrote the code. Then press Publish, and the Widget is live. Test, publish, price says what Publish needs, what the price can be, and what you earn.
To change the code later, ask the agent again. It changes the project and runs the samples again. Then, in the three-dot menu on the Widget's page, press Edit project, drag the folder in, and press Test Run and Publish.
Share it
When you publish, you choose who can see the Widget:
- •PUBLIC. The Widget is listed on the Widgets page. Anyone can find it and run it.
- •PRIVATE. Only the people who have its Private Link can open it. The skill's steps tell you to choose PRIVATE. Choose PUBLIC when anyone may run the Widget.
On the Widget's page, press Share. It copies the Widget's link. Send the link to the people who will run the Widget. They fill in the form and press RUN, and they install nothing. How people run your Widget shows what they see.
Share a Python script with people who do not code tells more: a Private Link for each client with Pro, and what the people who run the Widget pay.
Call the Widget from your code
Your own code can run the Widget too. For example, a webhook, a schedule or another tool calls it and uses its outputs. The code uses the abysshub library, for JavaScript and Python, or plain HTTP.
- •Create an API key in your Cave. A key acts as you, and its runs are paid from your Byssium.
- •Give the key a small Spend Cap. Spending safely tells how.
- •Put the key in your environment, never in your code and never in a browser.
The Widget's page has an API button with the code that calls that Widget. Give the agent the address of the Widget's page and /llms.txt, and it writes the call for you. Quickstart shows the same call in each language, and Call Abyss from your code tells the rest: files, what comes back, errors and long runs.