Architecture
Sally is a TypeScript-first project management system with three main surfaces: a web app for humans, an HTTP API for integrations, and MCP interfaces for agent tooling.
The goal is not maximum feature count. The goal is a clean operational core with a real programmable interface.
Monorepo layout
Apps
apps/web— Next.js application used by humansapps/api— Fastify API and hosted MCP serverapps/create-sally— installer and bootstrap packageapps/mcp— local stdio MCP server package
Packages
packages/db— Prisma schema and DB clientpackages/types— shared TypeScript types and contractspackages/ui— shared UI pieces
Runtime boundaries
Web app
The web app handles login, workspace selection, project and task views, profile controls, and low-noise operator workflows. It should be treated as a normal client of the API, not a privileged bypass.
API
The API is the main source of truth for auth, sessions, keys, workspaces, projects, tasks, clients, timesheets, uploads, notifications, activity logging, and hosted MCP.
Installer
create-sally handles guided setup, managed-simple and existing-infra flows, config writing, and bootstrapping the first workspace and superadmin.
Local stdio MCP
sally-mcp exposes Sally functionality to stdio MCP clients and translates tool calls into normal Sally HTTP API calls.
Data model direction
At a high level, Sally centers around accounts, workspaces, memberships, projects, statuses, tasks, labels, todos, comments, notifications, clients, timesheets, and credentials such as API keys or MCP keys.
Permission model
Permissions are layered:
- Platform role —
NONEorSUPERADMIN - Workspace role —
OWNER,MEMBER,VIEWER - Project role —
OWNER,MEMBER,VIEWER
The same data is visible through the web app, API, and MCP. MCP is not a bypass layer.
Why hosted MCP lives inside the API
Hosted MCP is implemented inside the API so it can reuse the existing permission model, auth logic, workspace logic, and business rules instead of creating a second shadow integration layer.
Design principles
- TypeScript-first — one language, shared types
- API-first — programmable access is part of the product core
- Human + agent parity — neither side should be a workaround for the other
- Low-noise UI — operators should move fast without decorative clutter
- Self-hostable operational core — teams should be able to run Sally on infrastructure they control
Request flow summary
- Human flow: browser → web app → Sally API → Prisma/Postgres
- API integration flow: script/tool → Sally API → Prisma/Postgres
- Hosted MCP flow: MCP client →
/mcpon Sally API → normal Sally API logic → Prisma/Postgres - Local stdio MCP flow: MCP client →
sally-mcpstdio process → Sally API → Prisma/Postgres
Current rough edges
- response envelopes are not fully uniform yet
- some docs still point to other docs rather than being generated from code
- hosted MCP and stdio MCP have overlapping but non-identical tool coverage
- some aggregated API routes would benefit from generated schemas
- upload handling is currently JSON/base64 based instead of multipart or signed-upload flows