Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions marketplace/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ Prefer the **daily.dev MCP server** (`https://api.daily.dev/mcp`) if it is conne

Never ask the user to paste a token into the chat if the MCP server or an environment variable is available. Never print, log, or store the token.

**Mind the quota.** Every API call and MCP tool call counts against the user's daily.dev API quota, which is shared with every token, app and agent acting as them, and free accounts only get a small monthly allowance. Make each call count: one page of bookmarks per batch, no polling, no re-fetching the pile to check a delete.

| Step | MCP tool | HTTP |
| ---------------- | ------------------- | ------------------------------------------ |
| Load the pile | `getBookmarks` | `GET /bookmarks/?limit=50&cursor=<cursor>` |
| Load a batch | `getBookmarks` | `GET /bookmarks/?limit=50&cursor=<cursor>` |
| Pull the trigger | `deleteBookmarksId` | `DELETE /bookmarks/{id}` → `204` |

`{id}` is the bookmark's `id` field from the list response (it is the post id).
Expand All @@ -41,17 +43,19 @@ Send `DELETE` without a body and without a `Content-Type: application/json` head

## How to play

### 1. Load the pile
### 1. Load a batch

Fetch **one page** with `limit=50`: that is one request, and the chamber for this round. Do not walk every page up front. Keep `pagination.cursor` and `pagination.hasNextPage` for later.

Fetch bookmarks with `limit=50`. While `pagination.hasNextPage` is true, fetch the next page with `pagination.cursor`. Stop after **10 pages (500 bookmarks)** to stay well within rate limits, and mention it if the pile was bigger.
The API always lists the newest bookmarks first and has no sort option, so the oldest, most forgotten ones are on later pages (see step 5).

If the user only wants bookmarks they never opened, add `unreadOnly=true`.

If the pile is empty, congratulate them: the town is clean. End the game.
If the first page is empty, congratulate them: the town is clean. End the game.

### 2. Spin

Pick one bookmark uniformly at random from the bookmarks not yet drawn this session. Never draw the same one twice.
Pick one bookmark uniformly at random from the current batch, among those not yet drawn. Never draw the same one twice.

### 3. Face the outlaw

Expand All @@ -78,12 +82,16 @@ Then ask: **Spare it, or pull the trigger?**

### 5. Keep riding

Show the running tally (`🪦 buried · 📖 pardoned · in chamber`) and offer another spin. Stop when the user says so or the pile is empty, then give the final tally.
Show the running tally (`🪦 buried · 📖 pardoned · in chamber`) and offer another spin.

When the batch is empty and `hasNextPage` was true, offer to **ride on to older bookmarks**: fetch the next page with the saved `cursor` (one more request) and keep playing. Only do it if the user says yes.

Stop when the user says so or there are no more pages, then give the final tally.

## Errors

- **401:** the token is missing, expired, or revoked. Ask the user to reconnect the MCP server or create a new token under daily.dev Settings → API.
- **403 with `insufficient_scope`:** the user did not grant `write`. Explain that sparing still works, but pulling the trigger needs write access, and how to reconnect with it.
- **404 on delete:** the API could not find it, so there is nothing left to remove. Count it as buried and move on.
- **429:** rate limited. Wait a little and retry once; if it fails again, pause the game and tell the user.
- **429:** rate limit or monthly quota reached. If the `retry-after` header asks for a minute or less, wait that long and retry once. Otherwise, or if it fails again, stop the game and tell the user their daily.dev API quota is used up for now. Never loop on retries.
- Anything else: show the status code, do not retry deletes blindly, and treat the bookmark as spared.
60 changes: 60 additions & 0 deletions marketplace/listing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Marketplace listing

The fields of the daily.dev marketplace plugin, kept here so updates start from what is live. The SKILL.md field is [`SKILL.md`](./SKILL.md). The About field can't contain links or images.

## Name

daily.dev Roulette

## Link

https://daily-dev-roulette.vercel.app

## Short description

Your bookmarks pile up and rot. Spin the cylinder and one forgotten bookmark comes up: spare it and go read it, or pull the trigger and it's deleted from daily.dev for good. Try the demo first, no account needed.

## About

<!-- about:start -->

## What it is

A Wild West duel against your bookmark backlog. Every link you saved "for later" and never opened is an outlaw. Spin the cylinder, one bookmark comes up, and you decide: **spare it** (go read it) or **pull the trigger** (it's removed from your daily.dev bookmarks, for good).

## How to play

1. **Spin** the cylinder to draw a random bookmark.
2. **Face the outlaw**: title, source, read time and when you saved it.
3. **Read 'em or bury 'em.** Your tally of buried and pardoned bookmarks is kept for the run.

Bookmarks come in batches of 50. Clear a batch and you ride on to older ones, so the most forgotten bookmarks get their turn too.

## Demo mode

Runs entirely in your browser on a fake bookmark pile. No account, no token, nothing is deleted.

## Agent skill

Prefer the terminal? The included SKILL.md lets your coding agent run the same duel through the daily.dev MCP server or the Public API, one bookmark at a time, and it only removes a bookmark when you explicitly pull the trigger.

## API quota

Playing uses your daily.dev API quota, which is shared with your other tokens, apps and agents, and is small on free accounts. The app keeps it lean: loading the roulette costs two requests (your profile and one batch of 50 bookmarks), plus one per bookmark you shoot.

## Access it asks for

Sign in with daily.dev (OAuth). The app never asks for a personal API token. It requests:

- **read**: to list your bookmarks
- **write**: only used to delete a bookmark when you pull the trigger. You can untick it on the consent screen and still browse.
- **profile / openid**: to show your name and avatar
- **offline_access**: to refresh the session while you play

Tokens live in httpOnly cookies (8-hour session) and every API call goes through the app's server. No bookmarks or personal data are stored; your browser only remembers which batch you were on. Signing out revokes the token.

## Built with

Astro on Vercel, open source under the MIT license.

<!-- about:end -->
Loading