Configuration
md2do uses hierarchical configuration with multiple sources that merge together.
Quick Start
The easiest way to configure md2do is with the interactive wizard:
md2do config initThis will guide you through setting up:
- Your username (for filtering tasks)
- Work hours (for time-based due dates)
- Output preferences (format, colors)
- Warning levels (recommended/strict/off)
Or manually create .md2do.json in your project root:
{
"defaultAssignee": "yourname",
"workday": {
"startTime": "09:00",
"endTime": "18:00",
"defaultDueTime": "end"
},
"todoist": {
"apiToken": "your-api-token",
"defaultProject": "Inbox"
}
}That's it! md2do will find and use this config automatically.
Configuration Precedence
Configs merge in this order (later overrides earlier):
- Default values (built into md2do)
- Global config (
~/.md2do.json) - Project config (
./.md2do.json) - Environment variables (
TODOIST_API_TOKEN)
Example flow:
# Global config sets your default name
~/.md2do.json: { "defaultAssignee": "alice" }
# Project config sets Todoist project
./project/.md2do.json: { "todoist": { "defaultProject": "Work" } }
# Environment overrides API token
export TODOIST_API_TOKEN="secret-token"
# Final merged config:
{
"defaultAssignee": "alice", # from global
"todoist": {
"apiToken": "secret-token", # from environment
"defaultProject": "Work" # from project
}
}Config File Locations
Global Config
Place in your home directory:
~/.md2do.json~/.md2do.yaml~/.md2do.js
Use for: Settings you want across all projects (your username, output preferences).
Project Config
Place in project root:
./.md2do.json./.md2do.yaml./.md2do.js./md2do.config.js
Use for: Project-specific settings (Todoist project, markdown paths, team tags).
Supported Formats
JSON
.md2do.json:
{
"defaultAssignee": "alice",
"output": {
"format": "pretty",
"colors": true
}
}YAML
.md2do.yaml:
defaultAssignee: alice
output:
format: pretty
colors: trueJavaScript
.md2do.js:
module.exports = {
defaultAssignee: 'alice',
output: {
format: 'pretty',
colors: true,
},
};Configuration Options
Markdown Settings
Control file scanning:
{
"markdown": {
"root": "./docs",
"pattern": "**/*.md",
"exclude": ["node_modules/**", "drafts/**", ".git/**"]
}
}Options:
root- Directory to start scanning (default:.)pattern- Glob pattern for markdown files (default:**/*.md)exclude- Patterns to skip (default:["node_modules/**", ".git/**"])
Todoist Settings
Configure Todoist integration:
{
"todoist": {
"apiToken": "your-token",
"defaultProject": "Inbox",
"autoSync": false,
"syncDirection": "both"
}
}Options:
apiToken- Your Todoist API tokendefaultProject- Default project name for new tasksautoSync- Auto-sync after task changes (default:false)syncDirection- Sync mode:"push","pull", or"both"(default:"both")
See Todoist Integration for setup details.
Output Settings
Customize output formatting:
{
"output": {
"format": "pretty",
"colors": true,
"paths": true
}
}Options:
format- Output style:"pretty","table", or"json"(default:"pretty")colors- Enable colored output (default:true)paths- Show file paths (default:true)
Default Assignee
Set your username:
{
"defaultAssignee": "yourname"
}Useful for filtering "my tasks" quickly.
Warning Settings
Control validation warnings for markdown task syntax:
{
"warnings": {
"enabled": true,
"rules": {
"unsupported-bullet": "warn",
"malformed-checkbox": "warn",
"missing-space-after": "warn",
"missing-space-before": "warn",
"relative-date-no-context": "warn",
"missing-due-date": "off",
"missing-completed-date": "off",
"duplicate-todoist-id": "error",
"file-read-error": "error"
}
}
}Complementary Linting
md2do warnings focus on task-specific validation (metadata, task semantics). For comprehensive markdown syntax checking, consider using markdownlint alongside md2do.
Options:
enabled- Enable/disable all warnings (default:true)rules- Per-rule severity levels:"error","warn","info", or"off"
Available Warning Rules:
| Rule | Description | Default |
|---|---|---|
unsupported-bullet | Using * or + instead of - for tasks | warn |
malformed-checkbox | Extra spaces in checkbox syntax | warn |
missing-space-after | No space after checkbox [x] | warn |
missing-space-before | No space before checkbox | warn |
relative-date-no-context | Relative date without heading date | warn |
missing-due-date | Incomplete task without due date | off |
missing-completed-date | Completed task without completion date | off |
duplicate-todoist-id | Same Todoist ID used multiple times | error |
file-read-error | Failed to read markdown file | error |
Preset Configurations:
Use built-in presets instead of specifying individual rules:
Recommended (default) - Validates markdown format, metadata optional:
{
"warnings": "recommended"
}Strict - All warnings enabled, enforces complete metadata:
{
"warnings": "strict"
}Disable All - Turn off all warnings:
{
"warnings": {
"enabled": false
}
}Custom - Mix presets with overrides:
{
"warnings": {
"enabled": true,
"rules": {
"missing-due-date": "warn",
"missing-completed-date": "off"
}
}
}Environment Variables
Override config with environment variables:
# Todoist API token (most common)
export TODOIST_API_TOKEN="your-token"
# Default assignee
export MD2DO_DEFAULT_ASSIGNEE="alice"Environment variables always win - they override all config files.
Common Configurations
Personal Setup
~/.md2do.json:
{
"defaultAssignee": "yourname",
"output": {
"format": "pretty",
"colors": true
},
"todoist": {
"apiToken": "your-personal-token"
}
}Team Project
.md2do.json (committed to git):
{
"markdown": {
"root": "./docs",
"exclude": ["drafts/**", "archive/**"]
},
"todoist": {
"defaultProject": "Team Project"
},
"warnings": "strict"
}Important: Don't commit apiToken! Use environment variables or global config for secrets.
Note: Team projects often use "warnings": "strict" to enforce consistent task formatting.
Work vs Personal
Global config (~/.md2do.json):
{
"defaultAssignee": "alice",
"output": {
"colors": true
}
}Work project (~/work/project/.md2do.json):
{
"todoist": {
"apiToken": "work-token",
"defaultProject": "Client Work"
}
}Personal project (~/personal/.md2do.json):
{
"todoist": {
"apiToken": "personal-token",
"defaultProject": "Personal"
}
}Documentation Project
For projects with markdown docs:
{
"markdown": {
"root": "./documentation",
"pattern": "**/*.md",
"exclude": ["node_modules/**", "build/**", "api-reference/**"]
},
"defaultAssignee": "docs-team",
"warnings": {
"enabled": true,
"rules": {
"missing-due-date": "off",
"missing-completed-date": "off"
}
}
}Solo Developer
For personal projects with flexible task formatting:
{
"defaultAssignee": "me",
"warnings": {
"enabled": true,
"rules": {
"missing-due-date": "off",
"missing-completed-date": "off",
"unsupported-bullet": "off"
}
}
}Security Best Practices
Never Commit Secrets
Add to .gitignore:
# md2do config with secrets
.md2do.json
.md2do.local.jsonUse Environment Variables
For CI/CD or shared machines:
# .env file (also add to .gitignore)
TODOIST_API_TOKEN=your-secret-token
# Use in scripts
export $(cat .env | xargs)
md2do listRestrict File Permissions
Protect your config:
chmod 600 ~/.md2do.jsonShare Structure, Not Secrets
Commit this:
{
"markdown": {
"root": "./docs"
},
"todoist": {
"defaultProject": "Team Project"
// apiToken loaded from environment
}
}Not this:
{
"todoist": {
"apiToken": "abc123secret" // ❌ Never commit!
}
}Validation
md2do validates your config automatically. Invalid configs show helpful errors:
$ md2do list
Error: Invalid configuration:
- todoist.syncDirection must be 'push', 'pull', or 'both'Managing Configuration
Use the config command to manage settings:
# View merged configuration
md2do config list
# Show config sources
md2do config list --show-origin
# Set specific value
md2do config set workday.startTime "09:00"
# Get specific value
md2do config get workday.startTime
# Edit in $EDITOR
md2do config edit
# Validate current config
md2do config validateSee config command reference for all options.
Complete Example
Full configuration with all options:
{
"markdown": {
"root": "./documentation",
"pattern": "**/*.md",
"exclude": ["node_modules/**", "drafts/**", ".git/**", "dist/**"]
},
"defaultAssignee": "alice",
"todoist": {
"apiToken": "your-token-here",
"defaultProject": "Work",
"autoSync": false,
"syncDirection": "both"
},
"output": {
"format": "pretty",
"colors": true,
"paths": true
},
"warnings": {
"enabled": true,
"rules": {
"unsupported-bullet": "warn",
"malformed-checkbox": "warn",
"missing-space-after": "warn",
"missing-space-before": "warn",
"relative-date-no-context": "warn",
"missing-due-date": "off",
"missing-completed-date": "off",
"duplicate-todoist-id": "error",
"file-read-error": "error"
}
}
}Next Steps
- Todoist Integration - Configure Todoist sync
- Task Format - Learn task syntax
- Filtering - Query your tasks
- Examples - Real-world setups