Project Management
Create, retrieve, update, and reorder projects — the top-level containers for documents
Overview
Projects (PRO-*) are the top-level containers in Closedloop. Every document — PRD, implementation plan, or feature — belongs to a project. Projects are typically weekly or thematic (e.g. a sprint week or an "Enterprise" theme).
All project tools accept either a UUID or a human-readable slug (e.g. PRO-7). Pass the slug verbatim — the API resolves it server-side. Newly created projects return an assigned PRO-* slug, which is the preferred handle for follow-up calls.
| Field | Values | Description |
|---|---|---|
priority | LOW, MEDIUM, HIGH, URGENT | Project priority |
status | NOT_STARTED, IN_PROGRESS, COMPLETED, ARCHIVED | Project lifecycle status |
Listing Projects
Use list-projects to retrieve the projects available to the authenticated user. The returned slug values (PRO-*) are the preferred user-facing handles for follow-up calls.
Tool: list-projects
Underlying API: GET /projects
list-projects(
limit?: number, // 1–100, default 25
offset?: number // Pagination offset, default 0
)The response is a paginated envelope. Each item includes id, name, slug, status, and updatedAt:
{
"total": 12,
"offset": 0,
"limit": 25,
"returned": 12,
"hasMore": false,
"nextOffset": null,
"items": [
{
"id": "...",
"name": "5/11–15",
"slug": "PRO-25",
"status": "IN_PROGRESS",
"updatedAt": "2025-01-15T10:00:00Z"
}
]
}Fetching a Single Project
Use get-project to read one project by UUID or slug. When the user references a project by its slug (e.g. "tell me about PRO-7"), pass that slug as projectId directly.
Tool: get-project
Underlying API: GET /projects/:projectId
get-project(
projectId: string // PRO-* slug or UUID
)Listing Teams
Every project belongs to a team, so list-teams is where the teamId that create-project requires comes from. Teams are identified by UUID only — there is no slug form.
Tool: list-teams
Underlying API: GET /teams
list-teams(
limit?: number, // 1–100, default 25
offset?: number // Pagination offset, default 0
)The response is the same paginated envelope list-projects returns. Each item includes id, name, slug, memberCount, projectCount, and updatedAt:
{
"total": 2,
"offset": 0,
"limit": 25,
"returned": 2,
"hasMore": false,
"nextOffset": null,
"items": [
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"name": "Platform",
"slug": "platform",
"memberCount": 6,
"projectCount": 12,
"updatedAt": "2025-01-15T10:00:00Z"
}
]
}The organization is resolved from the connection you authenticated with, so a caller only ever sees its own organization's teams.
Creating a Project
Use create-project to create a new top-level container for documents. The assigned slug (PRO-*) is returned in the response and is the preferred handle for future calls.
A project must belong to a team. Pass teamId. A project with no team has no
URL in the web app, so a human cannot open it or see the documents inside it.
Tool: create-project
Underlying API: POST /projects
create-project(
name: string,
teamId?: string, // UUID; required in practice — see below
description?: string,
priority?: "LOW" | "MEDIUM" | "HIGH" | "URGENT",
status?: "NOT_STARTED" | "IN_PROGRESS" | "COMPLETED" | "ARCHIVED"
)teamId is optional in the tool schema so that a call without one still reaches
the server, where it is refused with a 400 that lists the teams in this
organization — so a wrong call self-corrects without a prior lookup. That
message is bounded by a character budget; when an organization has more teams
than fit, the error says how many were omitted and points at list-teams, which
is the complete set.
Example workflow:
1. create-project(
name: "Enterprise Onboarding",
teamId: "7c9e6679-7425-40de-944b-e07fc1f90ae7",
priority: "HIGH"
)
→ returns { slug: "PRO-26", ... }
// Don't know the team id? Call list-teams, or call without it and
// read the 400: "At least one team is required. Teams in this
// organization: Platform (7c9e6679-...), Growth (2b1f...)." Then retry.
2. create-document(
title: "Onboarding Revamp",
type: "FEATURE",
projectId: "PRO-26",
content: "..."
)Updating a Project
Use update-project to change a project's metadata or status by UUID or slug. Only the fields you pass are modified.
Tool: update-project
Underlying API: PUT /projects/:projectId
update-project(
projectId: string, // PRO-* slug or UUID
name?: string,
description?: string,
priority?: "LOW" | "MEDIUM" | "HIGH" | "URGENT",
status?: "NOT_STARTED" | "IN_PROGRESS" | "COMPLETED" | "ARCHIVED"
)Reordering Project Artifacts
Use move-artifact to reorder a root artifact within its project's stack rank — the human-curated priority order shown on the project page. This is a write-scope operation.
Tool: move-artifact
Underlying API: POST /projects/:projectId/artifacts/move
move-artifact(
projectId: string, // PRO-* slug or UUID
artifactId: string, // Artifact to move (PRD-*, PLN-*, FEA-*, or UUID)
position: "top" | "bottom" | "before" | "after",
referenceArtifactId?: string // Required for "before"/"after"; omit for "top"/"bottom"
)Stack rank is a project-wide, root-level ordering: only top-level documents and features participate, not nested children. Use top / bottom to move to the ends, or before / after with referenceArtifactId to position relative to another artifact. Read sortOrder from list-documents / get-document to see the current order (lower sorts first).
The response echoes the move and reports the new sort order:
{
"moved": true,
"artifactId": "FEA-42",
"position": "before",
"referenceArtifactId": "FEA-40",
"newSortOrder": 3
}