Very Simple Projects
Tickets de proyectos en los que tú y tu agente de IA trabajan juntos: tickets numerados, estados, etiquetas, archivos y un hilo de comentarios. MCP remoto con OAuth; apps para iPhone, iPad y Mac.
Servidor MCP alojado
npx add-mcp 'https://verysimpleprojects.com/mcp'Se instala en Claude Code, Codex, Cursor y más
Documentación
Two ways in, both supported, with the same sign-in and the same token:
- MCP server:
https://verysimpleprojects.com/mcp. For Claude and every other MCP client. Nothing to install; listed in the MCP Registry ascom.verysimpleprojects/mcp. - REST API:
https://verysimpleprojects.com/api/v1. For your own code, with a token the person pastes from the app (an API key) or one your app gets over OAuth.
A token usually opens exactly one project, and then there is no project parameter. A token for all projects names the project per call (see Authentication). Tickets are numbered 1, 2, 3 per project, the way the person says it. You file, you write in the thread, you attach a screenshot or a log, you change status. You delete only what should never have existed.
Base URL: https://verysimpleprojects.com/api/v1. Auth: Authorization: Bearer TOKEN. Short copy: /llms.txt.
Getting started in Claude
Add Very Simple Projects to Claude, and Claude can file tickets, report in the thread and change status in one of your projects.
- In Claude, open Customize, then Connectors.
- Press + and choose Add custom connector.
- Name it Very Simple Projects and paste
https://verysimpleprojects.com/mcp. Press Add. - Press Connect, sign in with Apple or Google, and pick the project Claude may work in, or All my projects.
- Ask Claude something like "file a ticket for the broken login button" or "what is open?".
A connection opens the project you picked. Pick All my projects and Claude can work in every project, asking or being told which one each time; one project is the safer choice. To change it, disconnect and connect again. It works the same in Claude on the web, on desktop and on your phone. Claude plans can add custom connectors, and the free plan allows one. You can see and revoke the connection in the project's settings under Connect.
In Claude Code, add it from the terminal, then run /mcp to sign in and pick the project, or all of them:
claude mcp add --transport http very-simple-projects https://verysimpleprojects.com/mcp
MCP server and tools
Server URL: https://verysimpleprojects.com/mcp (Streamable HTTP). Any MCP client that supports OAuth connects on its own: a call without a token answers 401 and points at /.well-known/oauth-protected-resource, the client registers itself and sends the person to sign in and pick a project, or all of them. A token pasted from the app works too, as Authorization: Bearer TOKEN.
list_projects: only for a connection to all projects; every other tool then takes aproject, by id or name.get_project: the project, its labels, and every status you may set.list_tickets: open, closed, all, or one status, optionally by label.read_ticket: one ticket by number, with its thread.create_ticket: file a ticket with title, body, labels and star.update_ticket: change status with a note, title, body, labels or star.list_commentsandadd_comment: the ticket's thread.read_file: one of the ticket's files by number; a text file comes back as text, a picture as the picture, so Claude can look at a screenshot.attach_file: add a file to the ticket, as text or base64; it gets the next number and a line in the thread.delete_ticket: remove a ticket that should never have existed. It goes to the person's Recently deleted, where they can restore it for 30 days.
The tools follow the same rules as the REST API below: blocked needs a note, reads always work, and new content needs the person's subscription.
REST API quickstart
- If you have a
client_id, open the authorize URL. The person signs in and picks the project. You swap the code for a token. - If you do not, they mint a token in that project's Connect list and paste it: an API key that works exactly like the OAuth one.
- Call
GET /api/v1/me. You get the project, the labels you may use, and the statuses. - List open tickets before you file a new one. One ticket per problem. Cancel rather than delete.
curl https://verysimpleprojects.com/api/v1/me \
-H "Authorization: Bearer TOKEN"
Authentication
Bearer token, scoped to one project or to all of them. The person revokes it in the project's settings. Tokens do not expire on their own. Whether it was pasted from the app or minted over OAuth makes no difference.
A token for all projects (offered to every client at connect) names the project on every call with X-Project: PROJECT_ID. GET /projects, or GET /me without the header, lists the projects. A call that needs a project and has none answers 400 project_required.
Authorization: Bearer TOKEN
Reads always work. New tickets, comments, and title/body edits need an active subscription (402 otherwise). Status, star, and labels still work if the plan has lapsed, so a ticket can always be closed.
How to behave
- One ticket per distinct problem. List open tickets first and look.
- The report goes in the body. Follow-ups go in comments. A screenshot or a log is attached, not described.
- Title is one line. Not a user story.
blockedneeds a note that is a concrete ask.donewhen the work is finished.deployedonly when it is actually live, not because you pushed.- Use only labels and statuses that
/melists. Never invent one. - Closing is a status. Delete only a ticket that should never have existed, such as a duplicate you just filed.
Statuses
Six are built in and never change: new, in_progress, blocked, done, deployed, cancelled. Open is the first three. The person can add the project's own, like review, each open or closed. You set those by key like any other, but you cannot make, rename or delete one; /me lists every key you may set. Any status may follow any other. A status change with a note is written into the thread.
GET /me
Connect check: the project, your token's name, labels, statuses.
GET https://verysimpleprojects.com/api/v1/me
Authorization: Bearer TOKEN
{
"project": { "id": "…", "name": "Agent Heim", "color": "#F2724B" },
"token": { "name": "Agent Heim · Agnes" },
"labels": [{ "id": "…", "name": "bug", "color": "#8A8178" }],
"statuses": ["new", "in_progress", "blocked", "done", "deployed", "cancelled", "review"],
"open": ["new", "in_progress", "blocked", "review"],
"statusInfo": [{ "key": "new", "name": "New", "color": "#8A8178", "closed": false, "builtIn": true }, …]
}
DELETE /me
Revoke this token. Call it before you store a new one on reconnect.
DELETE https://verysimpleprojects.com/api/v1/me
Authorization: Bearer TOKEN
{ "ok": true }
GET /labels
Labels the person has made. You cannot add one from here.
GET https://verysimpleprojects.com/api/v1/labels
Authorization: Bearer TOKEN
GET /statuses
Every status in the project, the six built in first, with its name, colour and whether it counts as closed.
GET https://verysimpleprojects.com/api/v1/statuses
Authorization: Bearer TOKEN
GET /tickets
Query status=open|closed|all|<status> (default open), optional label=name. Starred first, then newest activity.
GET https://verysimpleprojects.com/api/v1/tickets?status=open
Authorization: Bearer TOKEN
{
"tickets": [
{
"id": "…",
"number": 12,
"title": "Login sheet stays open",
"preview": "First line of the body",
"status": "in_progress",
"important": false,
"labels": [{ "id": "…", "name": "bug", "color": "#8A8178" }],
"commentCount": 3,
"updatedAt": "2026-09-11T12:00:00.000Z",
"closedAt": null
}
]
}
GET /tickets/:number
One ticket by number, with body and comment thread.
GET https://verysimpleprojects.com/api/v1/tickets/12
Authorization: Bearer TOKEN
POST /tickets
File a ticket. title required. labels is a list of existing names. Needs an active subscription.
POST https://verysimpleprojects.com/api/v1/tickets
Authorization: Bearer TOKEN
Content-Type: application/json
{ "title": "Login sheet stays open", "body": "## Steps\n1. Tap Continue with Apple", "labels": ["bug"] }
Returns the full ticket with its new number, 201.
PATCH /tickets/:number
Update title, body, status, note, labels, important. blocked requires note. Title and body edits need a subscription; status, star and labels do not.
PATCH https://verysimpleprojects.com/api/v1/tickets/12
Authorization: Bearer TOKEN
Content-Type: application/json
{ "status": "blocked", "note": "Needs a TestFlight build." }
DELETE /tickets/:number
Moves the ticket, its whole thread and its files to the person's Recently deleted. They can restore it in the app for 30 days; after that it is gone for good. Only the person can restore it or delete it sooner. For a duplicate you just filed or a test ticket. Work that will not be done is cancelled, so the trail stays. Comments cannot be deleted.
DELETE https://verysimpleprojects.com/api/v1/tickets/13
Authorization: Bearer TOKEN
{ "ok": true, "deletedAt": "2026-10-02T09:00:00.000Z", "purgeAt": "2026-11-01T09:00:00.000Z", "message": "..." }
Files
A ticket carries files: a screenshot, a log, a JSON dump. Each gets the next number in the ticket, never reused, so a person can say "ticket 3, file 1", and a line in the thread says who attached it. GET /tickets/:number/files lists them; GET /tickets/:number/files/:file answers the bytes with their Content-Type. Attaching needs a subscription and takes at most 10 MB, either as multipart/form-data with a file field or as raw bytes with the type in Content-Type and the name in X-File-Name. An agent cannot remove a file; the person does that in the app.
curl https://verysimpleprojects.com/api/v1/tickets/12/files -H "Authorization: Bearer TOKEN" -F file=@before.png
POST https://verysimpleprojects.com/api/v1/tickets/12/files
Authorization: Bearer TOKEN
Content-Type: text/plain
X-File-Name: crash.log
(the bytes)
Errors
400bad body, unknown status or label,blockedwithout a note, a file without a name401missing or revoked token402new content without a subscription404no ticket with that number in this project, no file with that number on it413a file over 10 MB
OAuth 2.0
The person signs in on verysimpleprojects.com and picks the project. Your server swaps the code for a project token. Discovery: /.well-known/oauth-authorization-server.
GET https://verysimpleprojects.com/oauth/authorize
?client_id=…
&redirect_uri=…
&response_type=code
&state=…
&code_challenge=…
&code_challenge_method=S256
POST https://verysimpleprojects.com/oauth/token
grant_type=authorization_code
code=…
redirect_uri=…
client_id=…
client_secret=…
code_verifier=…
→ { "access_token": "…", "token_type": "Bearer" }
PKCE S256 is supported. MCP clients and other public apps register themselves at POST /oauth/register (dynamic client registration) and must use PKCE S256. Apps with their own server and a client secret can email verysimple@portfoliobox.net. for a client_id. Agent Heim is already registered.