* feat(clickup): add ClickUp integration with OAuth + API-token auth, 23 tools, block, and attachment upload
- 23 tools covering tasks (create/get/update/delete/list/search), comments
(create/get/update/delete), attachment upload, tags, members, custom
fields, and the workspace/space/folder/list hierarchy
- OAuth provider wiring (authorization-code flow, non-expiring tokens) plus
clickup-service-account token-paste credential (personal pk_ API tokens),
with a shared clickupAuthorizationHeader helper (pk_ tokens sent bare,
OAuth tokens as Bearer)
- File upload follows the internal-route pattern: contract-validated
/api/tools/clickup/upload-attachment builds the multipart form and
returns UserFiles
- ClickUp block with per-operation subBlocks, canonical file param,
BlockMeta templates/skills, and gradient brand icon
- Generated integration docs page + hand-written service-account guide
* fix(clickup): apply validation-audit fixes across tools, block, and upload route
- Map documented task fields that were dropped: markdown_description,
subtasks, watchers, custom_fields, time_spent, folder, space — making
the include_subtasks / include_markdown_description options observable
- Expand verified filters: assignees/tags/due-date ranges on get_tasks and
search_tasks, include_closed on search_tasks; add due_date_time /
start_date_time flags and update-task assignee add/remove
- Guard update_comment against an empty body and require comment text in
the block; prefer markdown_content over content on create_list and make
markdown reachable for lists in the UI
- Drop the unverified 'required' field from custom-field outputs; read
both err and error keys from ClickUp error bodies; correct notify_all
wording
- Upload route: 100MB size cap, shared attachment mapper with full
documented response fields (version, thumbnails), base-URL constant
* fix(docs): restore clickup-service-account guide and shield it from doc generation
The generator prunes integration pages it does not derive from blocks;
add the hand-written ClickUp API-token guide to
HANDWRITTEN_INTEGRATION_DOCS so regeneration cannot delete it.
* fix(clickup): address review findings — dedupe catalog entries, config-time list parent validation, upload memory cap, unique icon gradient ids
- Remove duplicated clickup entries in docs meta.json and integrations.json
introduced by a double docs regeneration
- Add a Location dropdown for Get Lists / Create List so the folder ID or
space ID is conditionally required at configuration time instead of
failing at run time
- Pass the 100MB cap into downloadServableFileFromStorage so oversized
files abort during download instead of after full buffering
- Use useId()-derived SVG gradient ids for ClickUpIcon in both icon files
* chore(clickup): format integrations.json entry per biome
* improvement(clickup): final validation-pass refinements across tools and block
- create_task: add doc-backed sprint points param (parity with update)
- get_tasks/search_tasks: expose include_markdown_description
- update_task legacy numeric priority in list responses mapped instead of
dropped; create_comment omits absent response fields instead of
emitting sentinel ''/0 values
- order_by only sent when explicitly chosen (Default sentinel); comment
text no longer UI-required for update_comment (resolve-only and
assignee-only updates are valid per the tool contract, which still
rejects an empty body)
- add_tag_to_task sends no request body per docs; upload tool tolerates
non-JSON error responses
* fix(clickup): tolerate nested user wrapper in member mapping
The task/list member endpoints document a flat member object; accept the
workspace-members-style nested { user: {...} } wrapper as well so both
shapes map correctly.
* fix(clickup): map size-limit errors from download/compile to a 400 upload-size response
downloadServableFileFromStorage enforces maxBytes on both the raw download
and the resolved (compiled) artifact via PayloadSizeLimitError; catch it in
the route so oversized content returns the intended 400 instead of
bubbling to the generic 500 handler.
* feat(clickup): add custom field values, checklists, and time tracking (15 tools, 38 total)
- Set/remove custom field values on tasks (PUT/DELETE /task/{id}/field/{field_id});
block value input parses JSON for structured field types, plain values pass through
- Checklist CRUD: create/rename/reorder/delete checklists and create/update/
delete checklist items (assign, resolve, nest), mapped from the documented
{checklist} response shape
- Time tracking: list entries in a date range (assignee/location filters,
task-tag and location-name includes), create/update/delete entries, start/
stop timers, and read the currently running timer; entries mapped from the
documented data envelope with negative-duration running semantics
- Block gains 15 operations with conditionally-required fields, timestamp
wand configs, tri-state billable/resolved dropdowns, and a single-location
filter selector matching the API's one-location-filter rule
* fix(clickup): new-tools audit fixes — POST for set custom field value, tolerant time-entry envelopes, richer mappings
- Set Custom Field Value uses POST per the live reference OpenAPI (the
llms mirror shows PUT; the reference console spec is authoritative)
- delete_time_entry maps the documented array envelope; create_time_entry
tolerates both data-wrapped and flat echo bodies
- Time entries surface task_tags and task_location so the include switches
are observable; checklists carry date_created
- Custom field value input parses any JSON literal (numbers, booleans,
arrays, objects) and passes plain text through
- Update Time Entry supports duration edits; single-assignee time ops get
their own field so a comma-separated list can't silently NaN out
* fix(clickup): send explicit date-time flags whenever a date is set
The due/start date-time switches previously only transmitted true; a
timed date could never be flipped back to date-only. The flag is now sent
as an explicit boolean whenever the corresponding date is provided and
omitted otherwise.
* improvement(clickup): final per-tool audit polish — checklist item children, tolerant comment date
- Checklist items surface the documented children array of nested item IDs
- create_comment tolerates a string-typed date in the response
* fix(clickup): reject empty update_task bodies with a clear local error, matching sibling update tools
A workspace to build, deploy and manage AI agents and workflows.
Quickstart
Cloud-hosted: sim.ai
Self-hosted
npx simstudio
Docker must be installed and running. Use -p, --port <port> to run Sim on a different port, or --no-pull to skip pulling the latest Docker images.
Capabilities
- Connect 1,000+ integrations and every major LLM
- Add Slack, Notion, HubSpot, Salesforce, databases, and more
- Build agents visually, conversationally, or with code
- Ingest files, knowledge bases, and structured table data
- Monitor runs, logs, schedules, and workflow activity
One workspace, every surface
Chat and workflows are just the start — tables, files, knowledge, and scheduled tasks all live in the same workspace.
Tables — a database, built in |
Files — one store for your team and every agent |
Knowledge — your agents' memory |
Scheduled tasks — runs on your schedule |
Self-hosting
Docker Compose
git clone https://github.com/simstudioai/sim.git && cd sim
docker compose -f docker-compose.prod.yml up -d
Sim also supports local models via Ollama and vLLM. See the Docker self-hosting docs for setup details.
Manual Setup
Requirements: Bun, Node.js v20+, PostgreSQL 12+ with pgvector
- Clone and install:
git clone https://github.com/simstudioai/sim.git
cd sim
bun install
bun run prepare # Set up pre-commit hooks
- Set up PostgreSQL with pgvector:
docker run --name simstudio-db -e POSTGRES_PASSWORD=your_password -e POSTGRES_DB=simstudio -p 5432:5432 -d pgvector/pgvector:pg17
Or install manually via the pgvector guide.
- Configure environment:
cp apps/sim/.env.example apps/sim/.env
# Create your secrets
perl -i -pe "s/your_encryption_key/$(openssl rand -hex 32)/" apps/sim/.env
perl -i -pe "s/your_internal_api_secret/$(openssl rand -hex 32)/" apps/sim/.env
perl -i -pe "s/your_api_encryption_key/$(openssl rand -hex 32)/" apps/sim/.env
# DB configs for migration
cp packages/db/.env.example packages/db/.env
# Edit both .env files to set DATABASE_URL="postgresql://postgres:your_password@localhost:5432/simstudio"
- Run migrations:
cd packages/db && bun run db:migrate
- Start development servers:
bun run dev:full # Starts Next.js app and realtime socket server
Or run separately: bun run dev (Next.js) and cd apps/sim && bun run dev:sockets (realtime).
Chat API Keys
Chat is a Sim-managed service. To use Chat on a self-hosted instance:
- Go to https://sim.ai → Settings → Chat keys and generate a Chat API key
- Set
COPILOT_API_KEYenvironment variable in your self-hosted apps/sim/.env file to that value
Environment Variables
See the environment variables reference for the full list, or apps/sim/.env.example for defaults.
Tech Stack
Next.js · Bun · PostgreSQL · Drizzle · Better Auth · Tailwind — and the rest of the stack
- Framework: Next.js (App Router)
- Runtime: Bun
- Database: PostgreSQL with Drizzle ORM
- Authentication: Better Auth
- Schema Validation: Zod
- UI: Shadcn, Tailwind CSS
- Streaming Markdown: Streamdown
- State Management: Zustand, TanStack Query
- Flow Editor: ReactFlow
- Docs: Fumadocs
- Monorepo: Turborepo
- Realtime: Socket.io
- Background Jobs: Trigger.dev
- Remote Code Execution: E2B
- Isolated Code Execution: isolated-vm
Contributing
We welcome contributions! Please see our Contributing Guide for details.
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.





