TaskLite

net.tasklitePublished by tasklite.netOfficial publisherv0.14.4Updated Oct 24, 2026

tasklite.net: hosted backend, REST API and admin for apps built by AI agents

VerifiedStreamable HTTPWeb executableDatabasesCloud & InfrastructureDeveloper Tools

Overview

AI-generated overview

TaskLite is a hosted backend and admin for apps built by AI agents, letting an assistant create projects, typed boards, rows, REST endpoints and frontend…

What you can do
  • Create and manage structure: projects, boards, typed columns, reorder, export
  • Read and write data: query, create and update items, set cells with compare-and-set, delete
  • Handle item threads: list, add, edit and delete comments
  • Manage files: request upload links, list uploaded files, revoke links
  • Build apps and APIs: create and publish apps, endpoints, API keys, settings, email usage
  • Administer app users, roles, policies, access checks and item history
When to use it
Use it when you want an assistant to stand up a working backend for a small business app from a description: schema, data, a REST API with keys, an admin interface and optionally a hosted frontend, then hand it over to non-technical operators.
Requirements
Either the hosted endpoint at mcp.tasklite.net (OAuth sign-in, or an Authorization Bearer header with a tl_ API key) or the local npm package @tasklite/mcp run over stdio. A TaskLite account and organization; the local sign_up tool can create one. Optional TASKLITE_API_URL and TASKLITE_APP_URL environment variables.
Before you install
Tools write, change and delete data: delete_project, delete_board, delete_column, delete_item and delete_comment are destructive and not undoable, and type changes in update_column can clear values. Upload links let anyone holding the address add files until revoked. send_test_push reaches real phones. App API keys belong in server-side environment variables, never browser code. The tl_ key grants the owner's own permissions.

Installation

In SourceWeft

  1. Open TaskLite in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/net.tasklite%2Fmcp/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "tasklite": {
      "type": "http",
      "url": "https://mcp.tasklite.net/mcp"
    }
  }
}

README

@tasklite/mcp

[npm] [MCP Registry] [license]

A backend and an admin for apps built by AI agents. tasklite.net · docs

Describe a system and get the thing behind it: a project with typed tables and relations, rows, REST endpoints, an API key, and an admin interface the business itself operates afterwards. From Claude Code, Claude Desktop, ChatGPT, Gemini, Cursor or VS Code. Deploy a frontend onto it and hand the whole thing over.

Not the CLI task manager. There is an older, unrelated project also called TaskLite, ad-si/TaskLite at tasklite.org, a command-line task manager. This is a different product from a different author: a hosted backend at tasklite.net, published as @tasklite/mcp and as net.tasklite/mcp in the MCP registry.

The 78 tools

78 when installed locally, 73 over the hosted server (the five account tools sign_up connect login disconnect connection_status exist only locally; hosted connections sign in with OAuth). Every tool declares readOnlyHint, destructiveHint, idempotentHint and openWorldHint, so a client can tell what is safe to run unattended.

AreaTools
Accountsign_up connect login disconnect connection_status list_organizations configure_external_access
Structurecreate_project create_board create_column update_board update_column delete_board delete_column delete_project reorder_columns get_board_schema list_projects list_boards export_project
Dataquery_items create_item update_item set_cell get_cells set_cells_if_unchanged delete_item search fetch
Commentslist_comments add_comment update_comment delete_comment
Filesrequest_file_upload list_uploaded_files revoke_upload_link
Signaturescreate_signature_request list_signature_requests get_signature_request signature_link void_signature_request
Apps and APIbuild_backend create_app publish_app list_apps get_app_spec create_app_endpoint list_app_endpoints update_app_endpoint delete_app_endpoint create_app_api_key configure_app_settings get_email_usage
App users, invites and linkslist_app_users add_app_user set_app_user_role remove_app_user create_app_invite list_app_invites revoke_app_invite check_invite_code link_app_user list_app_user_links unlink_app_user
Roles, policies and historylist_app_roles define_app_role delete_app_role grant_app_role revoke_app_role list_app_role_grants get_policy_identity set_policy_identity get_board_policy set_board_policy delete_board_policy explain_access simulate_request get_item_history
Frontend hostingdeploy_frontend list_deployments get_deployment_files rollback_deployment get_frontend_prompt
Automation and pushcreate_automation update_automation list_automations push_status send_test_push

Apps with two kinds of users

An endpoint's rowLevelSecurity.mode decides which rows a signed-in user reaches: owner (the rows they created), shared (every row, for authorized users), phone (the rows that carry their verified phone) or relation (the rows linked through a relation column to the row that stands for them). A coaching app, coaches and their trainees in one organization, is built from these:

BoardEndpoint security
Coachesmode: "phone", phoneColumn: the phone column. Each coach reads and edits his own row.
Traineesmode: "relation", relationColumn: Trainees.Coach, identityPhoneColumn: Coaches.Phone, allowInvites: true. A coach sees only his trainees and can invite each to her row.
Weigh-ins (coach)mode: "relation", relationColumn: Weigh-ins.Trainee, viaColumn: Trainees.Coach. One more hop: the weigh-ins of all his trainees.
Weigh-ins (trainee)A second endpoint on the same board: mode: "relation", relationColumn: Weigh-ins.Trainee.

A user "is" a row through an invite code (create_app_invite, or minted by a coach inside the app when the endpoint has allowInvites), through link_app_user, or with no link at all when their verified phone or email is written in the row (identityPhoneColumn, identityEmailColumn). configure_external_access with registrationPolicy: "invite" lets new people in only with a code. rowLevelSecurity accepts only the keys the server reads: an unknown key is refused, never dropped.

build_backend is the one to reach for first: it takes a description of a system and creates the project, the boards, their typed columns including the relations between them, sample rows, and a published REST API with a key, in one call, instead of a dozen.

Roles, policies and history

When people in one app may see different things (a manager sees every case, an agent only his own, bookkeeping the money columns), an endpoint uses rowLevelSecurity.mode: "policy" and the board carries a policy: define_app_role and grant_app_role (or set_policy_identity, which reads the roles from an employees board), then set_board_policy with the document, then explain_access and simulate_request to prove it. get_item_history reads who changed which field of a row, from what to what. The tools need a backend with the permissions routes; see docs/app-access.md.

Setup

Install the package (and Claude Code if you don't have it), then add the server by its binary. That avoids a known Windows issue where claude mcp add mis-parses npx -y.

bash
npm install -g @anthropic-ai/claude-code @tasklite/mcpclaude mcp add tasklite -- tasklite-mcp

Add -s user to claude mcp add to make it available in every project (claude mcp add -s user tasklite -- tasklite-mcp); the default scope is the current project only.

Then tell Claude what you want to build. The sign_up tool creates your account, organization, and connection from the conversation (a strong random password is generated locally and never shown; use "forgot password" with your email for web access).

Already have an account? Create a key at TaskLite → Integrations → "Connect Claude Code" and use:

bash
claude mcp add tasklite -e TASKLITE_API_KEY=tl_xxx -- tasklite-mcp

Hosted (no install)

Point any MCP client at the hosted server; there is nothing to install locally:

bash
claude mcp add --transport http tasklite https://mcp.tasklite.net/mcp \  --header "Authorization: Bearer tl_xxx"

The hosted server is stateless: every request carries its own credential, so one endpoint serves every account safely.

Simplest of all: the connector. In Claude (claude.ai or the desktop app), Settings → Connectors → add TaskLite, or add it by address using the URL above. You sign in once over OAuth; there is no key to create or store. Note that the tools appear in a new chat, not in the conversation you were already in.

Optional env: TASKLITE_API_URL (default https://api.tasklite.net), TASKLITE_APP_URL (default https://app.tasklite.net).

Other clients

One hosted server, every MCP client. Full setup notes: https://tasklite.net/docs/guides/connector-from-cursor-codex-desktop

  • Cursor: Add to Cursor or put {"mcpServers":{"tasklite":{"url":"https://mcp.tasklite.net/mcp"}}} in .cursor/mcp.json.
  • VS Code: Install in VS Code or .vscode/mcp.json with {"servers":{"tasklite":{"type":"http","url":"https://mcp.tasklite.net/mcp"}}}.
  • ChatGPT: Settings → Connectors (developer mode) → add https://mcp.tasklite.net/mcp. The server implements search and fetch.
  • Gemini CLI: gemini extensions install https://github.com/tasklite-net/tasklite-mcp (this repo ships gemini-extension.json), or add httpUrl + oauth to ~/.gemini/settings.json.
  • OpenAI Responses API / Agents SDK, Gemini API: pass the hosted URL with Authorization: Bearer tl_….

Typical flow (what Claude Code does)

  1. create_project → create_board → create_column × N builds the schema.
  2. create_item / query_items seed and inspect data.
  3. create_app → create_app_endpoint (with exposedColumns + RLS) → create_app_api_key expose the REST surface for your frontend.
  4. get_app_spec / get_frontend_prompt generate the frontend against it.
  5. Every tool returns an adminUrl, the ready-made admin for the end client.

Hosting your frontend

deploy_frontend puts a static frontend on https://{slug}.tasklite.dev. No server, no hosting account, no CI to configure. Hand the site over in one of three ways:

deploy_frontend(appId: "app-xxxxxx", files: [{ path: "index.html", content: "<!doctype html>…" }, { path: "app.js", content: "…" }])deploy_frontend(appId: "app-xxxxxx", zipUrl: "https://github.com/you/site/releases/download/v1/dist.zip")deploy_frontend(appId: "app-xxxxxx", dir: "./dist")

files is the path from ChatGPT or any hosted client: the assistant writes the page and deploys it in the same turn. zipUrl takes an export from Lovable, Bolt or a GitHub release. dir is for an MCP running on the machine with the build output.

Hosted pages call the app API through the relative path /api/{endpoint}. The hosting proxy attaches the app identity server-side, so the browser never carries an API key. list_deployments shows the versions and rollback_deployment points the live URL back at an earlier one.

Security model

  • The tl_ key is exchanged for a short-lived JWT (POST /public/v1/auth/session); all calls run with the key owner's own permissions, never super-admin.
  • App API keys belong in server-side env vars (Next.js API routes), never in browser code. Frontends hosted on tasklite.dev need no key at all.

Development

bash
npm installnpm run buildTASKLITE_API_KEY=tl_xxx TASKLITE_API_URL=http://localhost:3333 node dist/index.js

License

MIT

Source: README.md at commit 5c6b8ec

Tools

78

list_organizations

List organizations

List the organizations the authenticated user belongs to. Use the returned id as organizationId in other tools.

Takes no parameters.

get_email_usage

Get email usage

How much of the monthly email quota an organization has used: emails sent this month, emails waiting in the queue, the plan limit (Free 300, Plus 3000, Pro 20000; null means unlimited), whether the plan allows marketing email, and whether sending is paused for the organization (too many bounces or complaints). Covers email sent by automations, the communications endpoints and app servers (POST /apps/<slug>/api/_email/send).

ParametersorganizationId

configure_external_access

Configure external user access

Read or change how EXTERNAL users (people who sign up to your app through TaskLite auth) get into an organization. This policy governs sign-up by email and password and by Google. Sign-in by a phone code (POST /auth/otp/send, then /auth/otp/verify) obeys only "invite": under "closed", "approval" and "open" any phone that verifies a code becomes an external member of the organization, who reaches nothing until an endpoint's row-level security or the app's access list (add_app_user) gives them something; under "invite" a new phone needs an invite code or an add_app_user grant. The two ways in that obey the whole policy: email and password (POST /auth/register-external with this organizationId, then POST /auth/login), or Google (POST /auth/google-external with a Google ID token and this organizationId). Either way the answer carries a token the app sends as Authorization: Bearer on every App API call. registrationPolicy: "open", in at once; "approval", an organization admin approves each signup (TaskLite mails the admins on every signup, and the person once approved; unapproved users are never billed); "invite", a new person gets in only with an invite code (create_app_invite, or a code a user of the app minted on a relation endpoint with allowInvites): the app sends it as inviteCode with POST /auth/otp/verify, /auth/register-external or /auth/google-external, a sign-up without one is refused with 403 INVITE_REQUIRED and a bad code with 403 INVITE_INVALID, while people who are already members keep signing in as before; "closed" (the default), self-signup refused, external users are created by an admin. Under every policy a valid invite code admits its holder as if the organization were open, so "invite" is the policy for an app where people join only through someone who invited them (a coach inviting trainees). appLoginUrl: the page of YOUR app where these users log in, it becomes the "Log in" button in the approval email, so set it whenever you deploy an app that uses

ParametersappLoginUrlorganizationIdregistrationPolicy

list_projects

List projects

List projects in an organization. The API returns 50 per page, an organization with more than that needs page 2 and beyond, so check the returned total before assuming a project does not exist.

ParameterspagelimitorganizationId

list_boards

List boards

List the boards inside a project, id, name, description. Every other board tool needs a boardId, and this is the only way to discover one without being handed a URL.

ParameterspagelimitprojectIdrequired

create_project

Create project

Create a project (a business process container). Boards with data live inside projects.

ParametersnamerequireddescriptionorganizationId

create_board

Create board

Create a board (a data table) inside a project. Add typed columns with create_column afterwards. kind: "tasks" (default) also gives the board the built-in task columns, status, priority, assignee, due date, tags, for work people track; "data" creates a plain table with only the columns you add, for records such as customers, products or orders (requires a TaskLite server from 2026-09-06; older servers ignore kind).

ParameterskindnamerequiredprojectIdrequireddescription

create_column

Add column

Add a typed column to a board. Valid types: text, rich_text, number, status, date, datetime, duration, people, checkbox, dropdown, label, priority, link, email, phone, relation, lookup, rollup, formula, rating, currency, file. Choose by meaning, date for dates, phone for phones, number/currency for amounts, dropdown/status (with settings.options as an array of labels) for closed choices; text is for free text only. An obvious name/type mismatch is rejected with the suggested type; pass force:true to override. Rules go in settings.validation: { unique, min, max, minLength, maxLength, pattern, patternMessage }, enforced on every write (UI, MCP, App API). Closed choices (dropdown/status) reject values outside settings.options unless settings.allowCustom is true.

ParametersnamerequiredtyperequiredforceboardIdrequiredsettingsprojectIdrequiredisRequired

get_board_schema

Read board schema

Get a board with its full column schema (ids, names, types, settings). Call this before creating items with cells.

ParametersboardIdrequiredprojectIdrequired

update_board

Update board

Rename a board or change its description. Structure (columns) is changed with update_column / delete_column / reorder_columns.

ParametersnameboardIdrequiredprojectIdrequireddescription

delete_board

Delete board

Delete a board with every item on it. Destructive and not undoable, confirm with the user first, and prefer delete_column when only part of the model is wrong.

ParametersboardIdrequiredprojectIdrequired

delete_project

Delete project

Delete a project with every board, column and row inside it. Destructive: confirm with the user first, and name the project in the confirmation. The project goes to the organization recycle bin, so it can be restored from the admin until it is emptied.

ParametersprojectIdrequiredorganizationId

update_column

Update column

Change a column after the fact: rename it, change its type (e.g. number -> currency), replace settings (dropdown options), or set isRequired / isHidden. A type change converts existing values (number↔currency, text→number/date/checkbox, anything→text) and clears the ones that cannot convert; the response carries conversion: { converted, cleared }. settings.validation rules apply here too.

ParametersnametypeforceboardIdrequiredcolumnIdrequiredisHiddensettingsprojectIdrequiredisRequireddescription

delete_column

Delete column

Delete a column and every value stored in it. Destructive, confirm with the user first. Use update_column when the column is right but its name, type or options are wrong.

ParametersboardIdrequiredcolumnIdrequiredprojectIdrequired

reorder_columns

Reorder columns

Set the display order of a board's columns. Pass every column id in the wanted order (get_board_schema lists them).

ParametersboardIdrequiredcolumnIdsrequiredprojectIdrequired

export_project

Export project as JSON

The whole project as JSON, boards, columns with settings, items with their cells keyed by column id. For migrations, backups and reading a system back. Items are capped per board for the model's sake; the REST endpoint GET /organizations/{orgId}/projects/{projectId}/export.json returns everything.

ParametersprojectIdrequiredorganizationIdmaxItemsPerBoard

query_items

List items

List items (rows) of a board, including their cell values. Returns all items unless limit/page are given (the API defaults to 50 per page when unpaged, so the tool pages through and concatenates). Narrow the result with search, status, priority and sort instead of fetching everything. This is the admin view; the REST endpoints of a published app take a fuller grammar, filter[column][gte], relation filters, per-field search, see get_app_spec.

ParameterspagesortlimitsearchstatusboardIdrequiredarchivedpriorityprojectIdrequiredexcludeStatus

create_item

Create item

Create an item (row) with all of its data in one call. cells maps columnId -> value (use get_board_schema for column ids); every cell is saved with the row. Use set_cell only for later edits.

ParameterstagscellstitlerequiredstatusboardIdrequireddueDatepriorityprojectIdrequireddescription

update_item

Update item

Update item fields (title, description, status, priority, dueDate, tags). On a data board the task fields (status, priority, dueDate, tags) are hidden: its columns, status included, are set with set_cell.

ParameterstagstitleitemIdrequiredstatusboardIdrequireddueDatepriorityprojectIdrequireddescription

set_cell

Set cell value

Set a single cell value on an item by columnId.

ParametersvaluerequireditemIdrequiredboardIdrequiredcolumnIdrequiredprojectIdrequired

get_cells

Get cells

Read cells of one item from the database (not a cache): one current value per column, the value set_cells_if_unchanged compares. Use it to decide a conditional write, and pass each value back as `expected` exactly as it came.

ParametersitemIdrequiredboardIdrequiredcolumnIdsprojectIdrequired

set_cells_if_unchanged

Set cells if unchanged

Compare-and-set on cells of one item, all or none. Each cell carries the value you read (`expected`, null = empty) and the value to write. If any cell no longer holds its `expected`, nothing is written and the answer is an error with code CELL_CONFLICT and `conflicts` [{columnId, current}]: read again (use `current`), decide again, and never resend the same call. CELL_BUSY (the row is being written) also writes nothing: read again, then retry. Plain columns only (not relation, file, lookup, rollup, formula, button or system columns). Use set_cell for a write that needs no precondition.

ParameterscellsrequireditemIdrequiredboardIdrequiredprojectIdrequired

delete_item

Delete item

Delete an item. Destructive, confirm with the user before calling.

ParametersitemIdrequiredboardIdrequiredprojectIdrequired

list_comments

List item comments

List the comments (the correspondence thread) on an item, oldest first. Each comment includes its author and any @mentions. Needs projectId and itemId (get itemId from query_items).

ParameterspagelimititemIdrequiredprojectIdrequired

add_comment

Add a comment to an item

Post a comment on an item's thread. To notify people, pass their user ids in mentionedUserIds (each also appears as an @mention). attachmentIds references already-uploaded files. Needs projectId and itemId.

ParametersitemIdrequiredcontentrequiredprojectIdrequiredattachmentIdsmentionedUserIds

update_comment

Edit a comment

Edit the text of an existing comment. Only the author can edit their comment. Needs projectId, itemId and the commentId.

ParametersitemIdrequiredcontentrequiredcommentIdrequiredprojectIdrequired

delete_comment

Delete a comment

Delete a comment from an item thread. Destructive, confirm with the user before calling. Needs projectId, itemId and the commentId.

ParametersitemIdrequiredcommentIdrequiredprojectIdrequired

request_file_upload

Create a file upload link

Create a link that puts files onto an item from outside TaskLite: the customer's photos, a signed contract, a logo, a build zip. Returns an address like https://app.tasklite.net/upload/<token> that anyone you hand it to can use with no account, no login and no API key; pass clientEmail and TaskLite emails the link for you. What arrives lands as attachments on that item, and list_uploaded_files reads them back with a download URL. This is the answer when the person has the file and the model does not: a hosted client cannot read a folder on someone's machine. The link is public for as long as it lasts, so keep expiryDays short and maxFiles tight, and revoke_upload_link when the material is in.

ParametersitemIdrequiredmessagemaxFilesclientNameexpiryDaysclientEmailclientPhoneorganizationId

list_uploaded_files

List files on an item

The files attached to an item, including everything that came in through a request_file_upload link, each with a download URL that is signed and short lived (mint a fresh one by calling again). Also lists the upload links on the item and how many files each has taken, which is how to tell whether the person you asked has delivered.

ParametersitemIdrequiredorganizationId

create_app

Create app

Create an app, a named API surface over the boards of a project, for an external frontend. Then add endpoints and an API key.

ParametersnamerequiredprojectIdrequiredorganizationId

push_status

Push status

Whether an app can send push notifications to phones, and how many devices are registered. Push goes out through the customer's OWN Firebase project, so it has to be configured once per app before send_push automations do anything. This tool never returns the key.

ParametersappIdrequiredorganizationId

send_test_push

Send a test push

Send one real push notification to the given app users, to prove the chain works before an automation depends on it. Confirm with the user first: this reaches actual phones.

ParametersbodyappIdrequiredtitleuserIdsrequiredorganizationId

publish_app

Publish app

Publish an app, required before its API endpoints accept external calls.

ParametersappIdrequiredorganizationId

create_app_endpoint

Create app endpoint

Expose a board as a REST endpoint of an app: /apps/{appSlug}/api/{slug}. exposedColumns limits which columns are readable/writable. rowLevelSecurity.enabled makes the endpoint per-user: the developer's server sends `X-App-User: <their user id>` next to the API key, and the endpoint returns, updates and deletes ONLY that user's rows (401 without the header). Use it whenever the app has its own users. rowLevelSecurity.mode chooses which rows a user reaches: owner (the rows they created), shared (all rows, for authorized users), phone (the rows that carry their verified phone) or relation (the rows linked through a relation column to the row that stands for them). An app with two kinds of people in one organization, coaches and their trainees, is built from these: the Coaches board in mode phone (phoneColumn = its phone column), so each coach reads and edits his own row; Trainees in mode relation with relationColumn = its Coach column and identityPhoneColumn = the Coaches phone column, so a coach who signed in by phone sees only his trainees; boards one hop further (weigh-ins of a trainee) in mode relation with relationColumn = the Trainee column and viaColumn = Trainees.Coach for the coach, plus a second endpoint on the same board without viaColumn for the trainee herself. A trainee becomes her row through an invite code (create_app_invite, or allowInvites so the coach mints it in the app) or link_app_user.

ParametersnamerequiredslugrequiredappIdrequiredboardIdrequiredallowedMethodsexposedColumnsorganizationIdrowLevelSecurity

list_app_endpoints

List app endpoints

List an app's REST endpoints, slug, board, allowed methods, and how many columns each exposes. An endpoint exposing 0 columns is broken: it returns only item metadata and silently discards writes.

ParametersappIdrequiredorganizationId

update_app_endpoint

Update app endpoint

Change an existing endpoint, most often to set exposedColumns on one that was created without them. Get the endpoint id from list_app_endpoints and the column ids from get_board_schema.

ParametersnameslugappIdrequiredisActiveendpointIdrequiredallowedMethodsexposedColumnsorganizationIdrowLevelSecurity

delete_app_endpoint

Delete app endpoint

Delete an endpoint of an app for good: /apps/{appSlug}/api/{slug} stops answering at once and the endpoint cannot be brought back (create it again with create_app_endpoint). The board and its rows are not touched. Confirm with the user first: a frontend that calls this endpoint breaks. To take an endpoint offline and keep its definition, use update_app_endpoint with isActive false instead (list_app_endpoints shows active endpoints only, so keep the id). Get the endpoint id from list_app_endpoints.

ParametersappIdrequiredendpointIdrequiredorganizationId

configure_app_settings

Read or change app settings

Read or change the settings object of an app. Call with only appId to read. To change, pass set: the keys in it are MERGED into the current settings (objects merge key by key at every depth, arrays and plain values replace, null removes a key). The server itself does not merge: PATCH replaces the whole settings object with what it is sent, so this tool reads the app, merges, and writes the full object back; two writers at the same moment can still overwrite each other, so do not run it in parallel on one app. Settings the server reads: passwordReset.returnUrls (array of up to 50 URLs the "reset password" email may send a user back to, matched by scheme, host, port and path prefix; needed only for a custom app scheme such as myapp://reset or a domain other than the app's own {slug}.tasklite.dev and its connected custom domains, which are always allowed; http is never accepted), language (the language of the password reset email: a value starting with "he" gives Hebrew, any other value English; left out, the user's own language decides), endUserDeletion.rows ("delete": when an end user deletes their account, the rows they wrote in this app are deleted with it and erased for good 30 days later; left out, the rows stay with the author shown as a deleted account). Other keys are stored as given and returned, and the server does not act on them.

ParameterssetappIdrequiredorganizationId

list_app_users

List app users

List the people of an app, as { users, pending }. users: everyone who ever called it with X-App-User or signed in to it with a code. Each has userId (the id set_app_user_role, remove_app_user, link_app_user, list_app_user_links and send_test_push take), externalId (the developer's own id for them, or null for a user who signed in by code), name, phone (the phone they proved with a code, or null), source (api or otp), role (viewer, editor or submitter), isActive, hasAccessRow, lastSeenAt and itemCount (rows they own on the app's boards). hasAccessRow says whether they are on the app's access list: when it is false, role and isActive are only defaults, and an endpoint in row-level security mode "shared" refuses them with 403 until add_app_user or set_app_user_role puts them on the list. pending: the phones add_app_user is still holding access for, each with id, phone, role, createdAt, expiresAt and status (pending, or expired); they get in on their first sign-in with a code. Use it to see who can use the app and to find the userId of a person.

ParametersappIdrequiredorganizationId

add_app_user

Give a phone access to an app

Give a person access to an app by their phone number: the phone and a role, nothing else. This is how the people who run an app (the business owner, a manager, staff) get into its admin screen, whose endpoints are in row-level security mode "shared". The person needs no invite code and does not have to sign in first. If the phone already signed in to this organization with a code, access is on at once and the answer has status "active" and their userId. Otherwise the answer has status "pending" and a pendingId: nothing is created for the number yet, and the access opens by itself the first time that phone signs in to the app with an SMS code (POST /auth/otp/send, then /auth/otp/verify). The phone is matched whatever its spelling: 054-1234567, +972 54 123 4567 and 972541234567 are one number; a number outside Israel needs its country code. Calling again for the same phone sets its role again, and switches back on a user who was switched off. Roles: editor (reads and writes), viewer (reads), submitter (creates). The app must still sign people in by phone code; a person who signs in another way (email and password, Google) is a different account, give them access with set_app_user_role after their first sign-in. Requires organization owner or admin (an editor gets 403).

ParametersroleappIdrequiredphonerequiredexpiresInDaysorganizationId

set_app_user_role

Change an app user's role or switch them off

Change what an existing user of an app may do, or switch them off or back on. Takes the userId from list_app_users and at least one of role and isActive. It also puts on the app's access list a user who is not on it yet (hasAccessRow false in list_app_users), which is what an endpoint in row-level security mode "shared" checks: use it for someone who already signed in and is refused with 403. isActive false switches the user off in every mode: their calls are refused until it is set back to true; nothing of theirs is deleted. For a person who has not signed in yet there is no userId: use add_app_user with their phone. Requires organization owner or admin (an editor gets 403).

ParametersroleappIdrequireduserIdrequiredisActiveorganizationId

remove_app_user

Take a person's app access away

Take a person's access to an app away. Pass exactly one of two ids from list_app_users: userId, for someone who already signed in, switches them off (the same as set_app_user_role with isActive false: their calls are refused in every mode, nothing of theirs is deleted, and set_app_user_role or add_app_user switches them back on); pendingId, for a phone that add_app_user is still holding access for, cancels it, so that phone's first sign-in opens nothing. Requires organization owner or admin (an editor gets 403).

ParametersappIdrequireduserIdpendingIdorganizationId

create_app_invite

Create invite code

Create an invite code for an app (8 characters shown as XXXX-XXXX, typed without regard to case or the dash). The person signs up or signs in through the app with the code: the app sends it as inviteCode with POST /auth/otp/verify, /auth/register-external or /auth/google-external, after it may check it with POST /auth/invites/check. An invite does one or both of two things, and must do at least one: itemId links the new user to that row, so they "are" the row for every endpoint in row-level security mode "relation" (invite a trainee to her own Trainees row, or a coach to his Coaches row); role puts them on the app's access list (viewer, editor or submitter), which is what mode "shared" endpoints check. A valid code also admits a new person into an organization whose registration policy is "invite" or "closed" (configure_external_access). An existing access row is never changed by an invite: it does not re-enable a user who was switched off and does not raise a role. Requires organization owner or admin (an editor gets 403). To let the app's own users invite (a coach invites his trainees from inside the app), set allowInvites on the relation endpoint instead; the app then calls POST /apps/{appSlug}/api/{endpointSlug}/{itemId}/invites.

ParametersroleappIdrequiredlabelitemIdmaxUsesexpiresInDaysorganizationId

list_app_invites

List invite codes

List the invite codes of an app, newest first (the latest 200): the ones created with create_app_invite and the ones the app's own users minted through a relation endpoint with allowInvites (createdVia admin or app). Each carries id, code, itemId, role, label, maxUses, useCount, expiresAt, revokedAt and status: active, used (no uses left), expired or revoked.

ParametersappIdrequiredorganizationId

revoke_app_invite

Revoke invite code

Revoke an invite code so nobody else can sign up with it. People who already used it stay linked to their row and keep their access; to cut one of them off use unlink_app_user. Cannot be undone, create a new invite instead. Requires organization owner or admin. Get the invite id (not the code) from list_app_invites.

ParametersappIdrequiredinviteIdrequiredorganizationId

check_invite_code

Check an invite code

Check whether an invite code works right now, the way an app does before sign-up (POST /auth/invites/check, the same public route, limited to 10 calls a minute per address). A working code answers { valid: true, organizationId, app: { name, slug }, label, expiresAt }; anything else (unknown, revoked, expired, used up, its row deleted, its app switched off or deleted) answers only { valid: false }, with no reason, by design. It does not use the code up. For the reason a code stopped working, read its status in list_app_invites.

Parameterscoderequired

list_app_roles

List an app's roles

List the business roles of an app's project, as { roles: [{ key, label }] }. Roles are what board policies (set_board_policy) name in their `roles` lists; they are separate from the app access role (viewer, editor, submitter) of add_app_user. Requires organization owner or admin.

ParametersappIdrequiredorganizationId

define_app_role

Create or rename an app role

Create a business role of an app's project, or change the label of an existing one (calling again with the same key and a label updates the label). A role is only a name; what it may do is written in the board policies. Example: key "manager", label "Agents manager". Roles can also come from the data itself with set_policy_identity (an employees board with a role column) instead of grant_app_role per person. Requires organization owner or admin.

ParameterskeyrequiredappIdrequiredlabelorganizationId

delete_app_role

Delete an app role

Delete a business role of an app's project. Check first with list_app_role_grants who holds it and with get_board_policy where policies still name it: a policy that names a role that no longer exists simply matches nobody. Requires organization owner or admin.

ParameterskeyrequiredappIdrequiredorganizationId

grant_app_role

Give a user an app role

Give an app user a business role (a user can hold several). Takes the userId from list_app_users and a role key from list_app_roles. expiresAt makes the grant temporary. Granting the same pair again changes only expiresAt. This is for personal exceptions; for a whole team prefer set_policy_identity, which reads the roles from an employees board. Requires organization owner or admin.

ParametersappIdrequireduserIdrequiredroleKeyrequiredexpiresAtorganizationId

revoke_app_role

Take an app role away from a user

Take a business role away from an app user (a grant made with grant_app_role). A role the user gets from the employees board (set_policy_identity) is not a grant: change the board row instead. Revoking a grant that does not exist also succeeds. Requires organization owner or admin.

ParametersappIdrequireduserIdrequiredroleKeyrequiredorganizationId

list_app_role_grants

List who holds which app role

List the role grants of an app's project, as { grants }: who holds which role and until when. Pass userId to see one person's. Roles that come from the employees board (set_policy_identity) are not grants and are not listed here; explain_access with a userId shows the roles a person ends up with. Requires organization owner or admin.

ParametersappIdrequireduserIdorganizationId

get_policy_identity

Read where roles come from in the data

Read the project's role identity: which board holds the people and how their rows map to roles (see set_policy_identity). Returns { identity }, null when none is set. Requires organization owner or admin.

ParametersappIdrequiredorganizationId

set_policy_identity

Derive roles from an employees board

Derive "who is this user and what is their role" from the data, instead of a grant per person: point at the employees board, its phone/email column, the column that says what each person does, and a map from that column's values to role keys. A signed-in user whose verified phone (or email) is in a row of that board gets that row's roles; a row that is not active gives none. Full replace. Example: { "board": "<Employees board id>", "phoneColumn": "<Phone column id>", "roleColumn": "<Position column id>", "roleMap": { "Agent": ["agent"], "Agents manager": ["manager"], "Owner": ["owner"] }, "activeColumn": "<Status column id>", "activeValues": ["Active"] }. Board and columns are ids (get_board_schema). A grant (grant_app_role) adds to what the board gives. Requires organization owner or admin.

ParametersappIdrequiredidentityrequiredorganizationId

get_board_policy

Read a board's access policy

Read a board's access policy: { boardId, policy, updatedAt, updatedBy }, policy null when the board has none. A policy only takes effect on endpoints whose rowLevelSecurity mode is "policy". Requires organization owner or admin.

ParametersappIdrequiredboardIdrequiredorganizationId

set_board_policy

Set a board's access policy

Set who may read, write, create and delete rows of a board, and which columns, as a JSON document (a FULL REPLACE of the board's policy; read get_board_policy first to change part of one). It is enforced on the app's endpoints of this board whose rowLevelSecurity.mode is "policy" (create_app_endpoint / update_app_endpoint). Organization owners, admins and editors using the app are let through unless internalBypass is false. Fields: - schemaVersion: 1 (required). - internalBypass: default true. - rows.read / rows.write: a list of { roles, scope }. scope is "all", { "mine": "<column id>" } (rows whose column points at the caller: a relation to the row that stands for them, their verified phone or email, or a people column; add "via": "<relation column id>" for one more hop), { "created": true } (rows they created through the app) or { "where": CONDITION } (rows a condition selects, e.g. open cases older than 3 days, for an escalation view). A user gets the union of the rules that name any of their roles; no rule for their roles means no access. - rows.create / rows.delete: plain role lists. - columns: { "<column id or reserved field>": { "read": ACCESS, "write": ACCESS } }. ACCESS is a role list, or { "roles": [...], "orMine": "<column id>" } (these roles, or anyone for whom the row is theirs by that column). A column without an entry follows the row rules. An EMPTY list ("write": []) locks the column for everyone through the app: use it for assignedTo and for any field only an admin or an action may change. Reserved fields are title, description, status, priority, dueDate and assignedTo, addressed by those names. Reserved fields are open to anyone who may write the row unless you lock them, so lock assignedTo. - CONDITION (in where, rules.when): { "all": [c...] } | { "any": [c...] } | { "not": c } | a leaf { "col": "<column id or reserved field>", "op": OP, ... }. OP: eq / neq (with "value"), in (value is a list), empty, notEmpty, isMe (the column points at the calle

ParametersappIdrequiredpolicyrequiredboardIdrequiredorganizationId

delete_board_policy

Remove a board's access policy

Remove a board's access policy. An endpoint of that board in rowLevelSecurity mode "policy" then has no policy to follow; check what it allows afterwards with explain_access before leaving it on a live app. Requires organization owner or admin.

ParametersappIdrequiredboardIdrequiredorganizationId

explain_access

Explain what a user or roles may do on a board

Say what a user, or a list of roles, may do on a board under its policy: which rows they read and write, which columns, create and delete. Pass boardId and exactly one of userId (an app user from list_app_users; the answer includes the roles that person has) or roles (role keys, to try a role before anyone holds it). Changes nothing; use it after every set_board_policy. Requires organization owner or admin.

ParametersappIdrequiredrolesuserIdboardIdrequiredorganizationId

simulate_request

Dry-run an app request for a user

Dry-run one app API request in the name of a user and get the verdict (allowed or refused, and why), changing nothing: the endpoint slug, the HTTP method (or the name of a policy action, with its itemId) and optionally the column keys the body would carry. Use it to prove that a forbidden thing is refused (an agent PATCHing assignedTo, reading another agent's row) and an allowed one passes. Requires organization owner or admin.

ParametersappIdrequiredactionitemIdmethoduserIdrequiredbodyKeysendpointrequiredorganizationId

get_item_history

Read the change history of an item

Read the change history of one item (row), newest first: who changed which field, from what to what, when, through which channel, with the event and reason when a named action made the change. Returns { items: [{ field, fieldId, from, to, at, actor: { userId, name }, channel, event, reason }], nextBefore }. Page backwards by passing nextBefore as `before`. Needs access to the item's board.

ParameterslimitbeforeitemIdrequiredorganizationId

create_app_api_key

Create app API key

Create an API key for an app. SECURITY: the key must live server-side only (env var, Next.js API routes), never in browser code. If the app has its own users, the server also sends `X-App-User: <user id>` with the key so per-user endpoints know who is acting.

ParametersnameappIdrequiredscopesorganizationId

build_backend

Build a backend in one call

Build a whole backend in one call from a spec you compose: the project, its boards, their typed columns (including relations between the boards), optional sample rows, and optionally a published REST API with one endpoint per board and a server-side key. Use it whenever the user describes a system ("a backend for my repair shop: customers, orders, payments") instead of calling create_project, create_board, create_column, create_app, publish_app, create_app_endpoint and create_app_api_key one by one. You do the design, pick column types by meaning (phone, date, currency, dropdown/status with options for closed choices), link boards with a relation column (type "relation", relatedBoard: "<board name in this spec>", relationType: many_to_one for an order→customer link), and this tool executes it and returns one compact summary. API field names are derived from column names and never collide with reserved item fields, so there is nothing to retry. Boards are created as plain data tables (kind "data": only the columns you define, no task fields); set kind "tasks" on a board where people track work to do and want status, priority, assignee and due date built in. Every row still has a title. When the API has its own users, api.rowLevelSecurity: true gives every endpoint mode "owner"; a board may carry its own rowLevelSecurity instead (mode shared, phone or relation, with columns named as in this spec), e.g. Coaches { mode: "phone", phoneColumn: "Phone" } and Trainees { mode: "relation", relationColumn: "Coach", identityPhoneColumn: "Phone", allowInvites: true }.

ParametersapiboardsrequiredprojectrequiredorganizationId

create_automation

Create automation

Create an automation on a board: when something happens, do something. The most useful action here is http_request, which calls an external API and writes the answer back into columns, pair it with the "scheduled" trigger and the board keeps itself up to date (prices, exchange rates, shipment status, weather). Triggers: item_created, status_changed, column_value_changed, date_approaching, scheduled. Actions: http_request, send_notification, send_email, send_push, change_status, set_column_value, create_cross_board_item, send_webhook. The scheduled trigger has no cron expression: the server checks once an hour, and triggerConfig takes { intervalHours, runAtHour } only (intervalHours: at least this many hours between runs, default 24; runAtHour: 0-23, run only during that hour of the day in UTC, not in the user's time zone, so convert: 08:00 in Israel is runAtHour 5 in summer and 6 in winter). A scheduled run executes the actions once for every row of the board that passes conditions, so filter with conditions. send_push sends a notification to the phones of app users through the app's own Firebase project (set up once per app: push_status; try it with send_test_push). Its config: { title, body, data, userIds, recipientsFromRelation, includeRowOwner, sound, badge, dataOnly }. title and body take {{column name}} placeholders, title defaults to the row title. Recipients are the union of: the row's owner under row-level security (includeRowOwner, default true; false leaves them out), userIds (fixed user ids, as in list_app_users), and recipientsFromRelation, a dotted path of column NAMES such as "Client.Coach.Coach user" that walks relation columns from this row and whose LAST segment must be a people column holding user ids (a single segment is a people column on this board); it does not resolve the user linked to a row by an invite or by phone, so without such a people column use userIds or the row owner. data is a flat object of strings the app reads to decide where t

ParametersnamerequiredactionsrequiredboardIdrequiredtriggerrequiredisActiveprojectIdrequiredconditionstriggerConfig

update_automation

Update automation

Change an existing automation: its actions, conditions, trigger config or name, or switch it off with isActive false. Fields left out stay as they are; actions and conditions, when given, replace the whole list. Use it to fix an automation instead of creating a second one next to it. Get the id from list_automations. For send_email actions, config.kind is transactional (default) or marketing (Pro plan or higher, verified sender domain, unsubscribe footer) and config.attachments is an array of file column ids on the row; see create_automation.

ParametersnameactionsboardIdrequiredisActiveprojectIdrequiredconditionsautomationIdrequiredtriggerConfig

list_automations

List automations

List the automations on a board, so you can see what already runs before adding another.

ParametersboardIdrequiredprojectIdrequired

list_apps

List apps

List the apps in the organization, id, slug, status. Call this first when you need an app id: the slug (app-xxxxxx) is what shows up in URLs and in generated code, and this is how you map it back to the app.

ParametersorganizationId

get_app_spec

Get app spec

Get the machine-readable spec of an app: base URL, endpoints, methods, fields, auth. Two formats: "tasklite" (default), the compact shape the frontend prompts are built from, and "openapi", a standard OpenAPI 3.1 document for developers and other tools. When the user asks for the OpenAPI spec, or wants to hand the API to a developer, pass format "openapi". appId accepts either the app UUID or its slug (app-xxxxxx); list_apps shows both. The returned baseUrl is absolute, use it verbatim, do not rebuild it from the admin URL.

ParametersappIdrequiredformatorganizationId

get_frontend_prompt

Get frontend prompt

Get a ready-made prompt describing the app backend, for pasting into a frontend generator (v0/bolt/lovable/cursor). appId accepts the app UUID or its slug (app-xxxxxx), use list_apps to find it.

ParameterstoolrequiredappIdrequiredorganizationId

fetch

Fetch one record by id

One project, board or item in full, by the id search returned (project:<id>, board:<projectId>:<boardId>, item:<projectId>:<boardId>:<itemId>) or by an app URL path. Returns { id, title, text, url, metadata }, the ChatGPT fetch contract; text is the record as JSON.

ParametersidrequiredorganizationId

deploy_frontend

Deploy frontend to TaskLite hosting

Deploy a static frontend to TaskLite hosting and get a live URL https://{slug}.tasklite.dev (HTTPS, auto-published on first deploy, versions kept for rollback_deployment). Hand over the frontend in ONE of three ways: `files`, the files inline (path + content), the way to go from ChatGPT or any hosted client: write index.html and its assets, then deploy in the same turn; `zipUrl`, a public https URL of a zip (a Lovable/Bolt export, a GitHub release asset); `dir`, a build output folder on this machine (only when the MCP runs locally next to the files); `fromAppId`, a version already hosted in the same organization, copied on the server (start a new app from an existing site, or bring an old version back as a new one; get_deployment_files reads a version first). A real build that already exists on the person's machine fits none of these from a hosted server: tell them to drop the zip on the app's Versions screen (the adminUrl of the app, then Versions), which deploys the same way and keeps the same version history. In the frontend, call the app API via relative /api/{endpoint}, the hosting proxy injects the app identity, so no key ships to the browser.

ParametersdirappIdrequiredfileszipUrlfromAppIdfromVersionorganizationId

list_deployments

List frontend deployments

List the hosted-frontend deployments of an app, versions, which one is live, and the public URL.

ParametersappIdrequiredorganizationId

get_deployment_files

Read a deployed version's files

Read back what a hosted frontend version is made of: every file with its size and its URL on that version, and the full text of the text files (HTML, CSS, JS, JSON, SVG...). This is how a new conversation continues a site an earlier one built: "take my Krispool site and keep going" starts here, not from scratch. For a site written by hand the files ARE the source. For a bundled build (Vite, React) the JS is minified output: fine to inspect, not something to edit, so ask for the project's source instead. Images and other binaries come back as URLs only. Text is capped at 512KB per file and 4MB per call; narrow with `paths` for a big site. To start another app from this version, or bring an old version back as a new one, use deploy_frontend with fromAppId.

ParametersappIdrequiredpathsversionincludeContentorganizationId

rollback_deployment

Roll back a frontend deployment

Point the live URL back at a previous deployment version (see list_deployments for available versions).

ParametersappIdrequiredversionrequiredorganizationId

Version history

1
  1. v0.14.4LatestSep 16, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts