Project Config
Project configuration is split into two files:
.mdp/settings.json— Schema config (statuses, priorities, labels, types). Rarely changes after creation..mdp/project.md— Project identity (title, description, instructions, health, log) with frontmatter + body content. Evolves over time.
The settings file is the sole source of truth for schema validation at runtime — no merging, no fallbacks. It is written once at project creation from a preset, with CLI flag overrides applied on top.
Complete settings.json
Below is the full settings.json generated by the default software preset. Every field is shown with its real default value:
{
"issues": {
"prefix": "ISS",
"statuses": {
"triage": [],
"backlog": [{ "name": "Backlog", "description": "Not yet triaged" }],
"unstarted": [{ "name": "To Do", "description": "Ready to be worked on" }],
"started": [{ "name": "In Progress", "description": "Actively being worked on" }],
"completed": [{ "name": "Done", "description": "Work completed" }],
"canceled": []
},
"priorities": [
{ "name": "None", "description": "No priority assigned" },
{ "name": "Low", "description": "Low priority" },
{ "name": "Medium", "description": "Medium priority" },
{ "name": "High", "description": "High priority" },
{ "name": "Urgent", "description": "Requires immediate attention" }
],
"labels": [
{ "name": "bug", "description": "Bug report" },
{ "name": "enhancement", "description": "Improvement to existing functionality" },
{ "name": "documentation", "description": "Documentation related" },
{ "name": "security", "description": "Security related" },
{ "name": "frontend", "description": "Frontend related" },
{ "name": "backend", "description": "Backend related" }
],
"types": [
{ "name": "task", "description": "General work item" },
{ "name": "bug", "description": "Something broken" },
{ "name": "feature", "description": "New functionality" },
{ "name": "chore", "description": "Maintenance, refactoring" },
{ "name": "spike", "description": "Research or investigation" }
]
},
"milestones": {
"prefix": "M",
"statuses": {
"backlog": [],
"planned": [{ "name": "Planning", "description": "Defining scope and goals" }],
"in_progress": [
{ "name": "Active", "description": "In progress" },
{ "name": "On Hold", "description": "Temporarily paused" }
],
"completed": [{ "name": "Completed", "description": "All goals met" }],
"canceled": []
},
"priorities": [
{ "name": "None", "description": "No priority assigned" },
{ "name": "Low", "description": "Low priority" },
{ "name": "Medium", "description": "Medium priority" },
{ "name": "High", "description": "High priority" },
{ "name": "Urgent", "description": "Requires immediate attention" }
],
"labels": [
{ "name": "bug", "description": "Bug report" },
{ "name": "enhancement", "description": "Improvement to existing functionality" },
{ "name": "documentation", "description": "Documentation related" },
{ "name": "security", "description": "Security related" },
{ "name": "frontend", "description": "Frontend related" },
{ "name": "backend", "description": "Backend related" }
]
}
}project.md
Project identity is stored in .mdp/project.md as a markdown file with YAML frontmatter:
---
title: My Project
description: Optional one-line project description
instructions: Optional free-text guidance for LLMs and collaborators
health: on-track
log:
- timestamp: "2025-01-15T10:00:00.000Z"
author: cli
body: Project kickoff
health: on-track
createdAt: "2025-01-01T00:00:00.000Z"
updatedAt: "2025-01-15T10:00:00.000Z"
---
## Overview
[Describe the project]The health field tracks overall project health: on-track, at-risk, or off-track. It is updated automatically when a log entry with --health is added.
Use mdp project get to read project identity and mdp project log to manage log entries.
Field Reference
settings.json
| Field | Description |
|---|---|
issues.prefix | ID prefix for issues (e.g., "ISS" produces ISS-1, ISS-2, …) |
issues.statuses | Status categories mapped to arrays of statuses. See Statuses below. |
issues.priorities | Ordered list of priorities from lowest to highest urgency. |
issues.labels | Available labels for categorizing issues. Labels not in this list produce an error. |
issues.types | Available issue types. Types not in this list produce an error. |
milestones.prefix | ID prefix for milestones (e.g., "M" produces M-1, M-2, …) |
milestones.statuses | Status categories mapped to arrays of statuses. Same structure as issue statuses but with milestone-specific categories. |
milestones.priorities | Same structure as issue priorities. |
milestones.labels | Available labels for milestones. Shared with issues by default. |
project.md
| Field | Description |
|---|---|
title | Human-readable project title (required). Defaults to directory name at creation. |
description | Optional one-line project description. |
instructions | Optional free-text guidance for LLMs and collaborators. |
health | Project health: on-track, at-risk, off-track, or null. |
log | Array of log entries, each with timestamp, author, body, and optional health. |
createdAt | ISO timestamp of project creation. |
updatedAt | ISO timestamp of last modification. |
How Configuration Works
At project creation
When you run mdp project create, a preset (built-in or custom) is selected, CLI flag overrides are applied, and the full resolved config is written to .mdp/settings.json. Project identity is written to .mdp/project.md. Both files are self-contained and portable.
The merge order at creation time is: preset → CLI flags.
Custom presets can be defined in ~/.mdp/settings.json. See Global Config for details.
At runtime
Commands read .mdp/settings.json directly for schema validation. There is no runtime merge — what you see in the file is what you get.
Use mdp project settings to display the current schema configuration, and mdp project get to display project identity.
Statuses
Statuses represent the workflow stage of an issue or milestone. They are stored in frontmatter and validated against the project configuration.
Status Categories
Every status belongs to a status category — a fixed lifecycle stage that the system uses to determine behavior (e.g., completion percentage, overdue detection). Categories are system-defined; the statuses within each category are user-customizable.
Each status has two fields:
{ "name": "In Progress", "description": "Actively being worked on" }Issue Status Categories
| Category | Meaning | Default Statuses |
|---|---|---|
triage | Inbox, needs review | (none) |
backlog | Accepted, not yet planned | Backlog |
unstarted | Planned, ready to start | To Do |
started | Work in progress | In Progress |
completed | Done successfully | Done |
canceled | Won’t do | (none) |
Milestone Status Categories
| Category | Meaning | Default Statuses |
|---|---|---|
backlog | Not yet planned | (none) |
planned | Scoped and planned | Planning |
in_progress | Actively being worked on | Active, On Hold |
completed | All goals met | Completed |
canceled | Abandoned | (none) |
How Categories Drive Behavior
The system uses status categories — not status names — to determine behavior:
- Completion percentage: Issues in the
completedcategory count as done. Custom status names like “Shipped” or “Deployed” work automatically when placed in thecompletedcategory. - Overdue detection: Issues not in
completedorcanceledwith a past due date are flagged as overdue. - Milestone progress: Milestone completion % is based on how many assigned issues are in the
completedcategory.
Invalid Status Example
mdp issue update --id ISS-1 --status "bogus"{
"ok": false,
"error": {
"code": "INVALID_STATUS",
"message": "Invalid status \"bogus\"",
"details": {}
}
}An issue file with a valid status looks like:
status: In ProgressPriorities
Priorities indicate urgency level. Changing a priority updates the YAML frontmatter in the issue/milestone file.
Default Priorities
| Priority | Description |
|---|---|
| None | No priority assigned |
| Low | Low priority |
| Medium | Medium priority |
| High | High priority |
| Urgent | Requires immediate attention |
Priorities are shared across issues and milestones. The same set is used for both.
Invalid Priority Example
mdp issue update --id ISS-1 --priority "Critical"{
"ok": false,
"error": {
"code": "INVALID_PRIORITY",
"message": "Invalid priority \"Critical\"",
"details": {}
}
}Types
Types categorize the fundamental nature of an issue (feature, bug, task, etc.). Types are issue-only — milestones do not have types.
Default Types (Software Preset)
| Type | Description |
|---|---|
task | General work item |
bug | Something broken |
feature | New functionality |
chore | Maintenance, refactoring |
spike | Research or investigation |
Types by Preset
| Preset | Types |
|---|---|
software | task, bug, feature, chore, spike |
marketing | campaign, content, email, social, analysis |
design | design, review, research, prototype, asset |
product | feature, research, experiment, feedback, spec |
social-media | post, story, campaign, engagement, analysis |
generic | task, milestone-task, review |
Invalid Type Example
mdp issue create -t "Fix button" --type "unknown"{
"ok": false,
"error": {
"code": "INVALID_TYPE",
"message": "Invalid type \"unknown\"",
"details": {}
}
}Labels
Labels are categorization tags stored in frontmatter. Labels exist on both issues and milestones.
Default Labels (Software Preset)
| Label | Description |
|---|---|
bug | Bug report |
enhancement | Improvement to existing functionality |
documentation | Documentation related |
security | Security related |
frontend | Frontend related |
backend | Backend related |
Labels by Preset
| Preset | Labels |
|---|---|
software | bug, enhancement, documentation, security, frontend, backend |
marketing | seo, paid, organic, brand, copy, design |
design | ui, ux, branding, illustration, motion |
product | mvp, growth, retention, onboarding, mobile, web |
social-media | instagram, twitter, linkedin, tiktok, youtube, facebook |
generic | urgent, documentation, question |
Invalid Label Example
mdp issue create -t "Test" -l "nonexistent"{
"ok": false,
"error": {
"code": "INVALID_LABEL",
"message": "Invalid label \"nonexistent\"",
"details": {}
}
}An issue file with labels in frontmatter:
labels:
- bug
- securityTemplates
Templates provide reusable starting points for issues and milestones. They are read once at creation time — after creation, the template has no connection to the created item.
Template Location
Templates live in .mdp/templates/ as markdown files. The filename (minus .md extension) is the template name.
.mdp/templates/
├── issue-template.md # Default issue template
├── milestone-template.md # Default milestone template
├── bug-report.md # Custom template (name: "bug-report")
└── feature-request.md # Custom template (name: "feature-request")Template Format
Templates are standard markdown files with YAML frontmatter. Any frontmatter field can be set in the template; command-line flags override template values.
Bug report template (.mdp/templates/bug-report.md):
---
title:
type: bug
status: Backlog
priority: Medium
labels:
- bug
assignee: null
estimate: null
spent: null
blockedBy: []
parent: null
relatedTo: []
checklist:
- text: Bug is fixed
done: false
- text: Tests added
done: false
- text: No regressions
done: false
log: []
---
## Description
[Describe the bug]
## Steps to Reproduce
1. Step 1
2. Step 2
## Expected Behavior
[What should happen]
## Actual Behavior
[What actually happens]Feature request template (.mdp/templates/feature-request.md):
---
title:
type: feature
status: Backlog
priority: null
labels: []
assignee: null
estimate: null
spent: null
blockedBy: []
parent: null
relatedTo: []
checklist: []
log: []
---
## Description
[Describe the feature]
## Motivation
[Why is this needed?]
## Proposed Solution
[How should it work?]Usage
# Use a template
mdp issue create -t "Login fails on Safari" --template bug-report
# Template fields are defaults — flags override them
mdp issue create -t "Login fails" --template bug-report --priority High --labels "bug,security"The resulting ISS-1-login-fails-on-safari.md file:
---
id: ISS-1
title: Login fails on Safari
type: bug
status: Backlog
priority: Medium
labels:
- bug
assignee: null
milestone: null
estimate: null
spent: null
dueDate: null
blockedBy: []
parent: null
relatedTo: []
checklist:
- text: Bug is fixed
done: false
- text: Tests added
done: false
- text: No regressions
done: false
log: []
createdAt: 2025-03-01T10:00:00.000Z
updatedAt: 2025-03-01T10:00:00.000Z
---
## Description
[Describe the bug]
## Steps to Reproduce
1. Step 1
2. Step 2
## Expected Behavior
[What should happen]
## Actual Behavior
[What actually happens]With flag overrides (--priority High --labels "bug,security"), the frontmatter changes to:
priority: High
labels:
- bug
- securityTemplate Resolution
- Look for
{name}.mdin.mdp/templates/ - If not found, produce an error with exit code 1
- Parse frontmatter and body from template
- Merge: command flags take precedence over template values
- Template body is used as the initial markdown content (unless
--contentis specified)
Validation
All validation is case-insensitive. "In Progress", "in progress", and "IN PROGRESS" all match the same status.
| Concept | On Invalid Value |
|---|---|
| Status | INVALID_STATUS error, command fails |
| Priority | INVALID_PRIORITY error, command fails |
| Type | INVALID_TYPE error, command fails |
| Labels | INVALID_LABEL error, command fails |