telos-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,134 @@
1
+ # telos-mcp
2
+
3
+ Task planning and tracking for AI agents. An MCP server with markdown file storage.
4
+
5
+ ## What it does
6
+
7
+ Gives any MCP-compatible AI agent persistent task management:
8
+ - **Create, update, list, delete** tasks with full status tracking
9
+ - **Dependencies** — blockedBy/blocks relationships between tasks
10
+ - **Markdown files** — each task is a human-readable `.md` file with frontmatter
11
+ - **Zero native addons** — pure JavaScript, works on any Node version without rebuild
12
+ - **Multi-agent** — owner tracking so you know who's doing what
13
+
14
+ ## Quick start
15
+
16
+ ```bash
17
+ npx telos-mcp
18
+ ```
19
+
20
+ ### Stable install
21
+
22
+ ```bash
23
+ npm install -g telos-mcp
24
+ ```
25
+
26
+ Or from source:
27
+
28
+ ```bash
29
+ git clone https://github.com/skye-flyhigh/telos-mcp.git
30
+ cd telos-mcp && npm install && npm run build
31
+ ```
32
+
33
+ Then point your client to `"command": "node", "args": ["/path/to/telos-mcp/dist/index.js"]`.
34
+
35
+ ## Configuration
36
+
37
+ | Variable | Default | Description |
38
+ |----------|---------|-------------|
39
+ | `TELOS_DIR` | `~/.telos` | Directory where task files are stored |
40
+
41
+ ## Client Setup
42
+
43
+ ### Claude Code
44
+
45
+ Add to `.claude.json`:
46
+
47
+ ```json
48
+ {
49
+ "mcpServers": {
50
+ "telos": {
51
+ "type": "stdio",
52
+ "command": "npx",
53
+ "args": ["telos-mcp"],
54
+ "env": {}
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ ### Claude Desktop
61
+
62
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
63
+
64
+ ```json
65
+ {
66
+ "mcpServers": {
67
+ "telos": {
68
+ "command": "npx",
69
+ "args": ["telos-mcp"]
70
+ }
71
+ }
72
+ }
73
+ ```
74
+
75
+ ## Tools
76
+
77
+ | Tool | Description |
78
+ |------|-------------|
79
+ | `task_create` | Create a new task with subject, description, tags, dependencies |
80
+ | `task_update` | Update status, dependencies, or details of an existing task |
81
+ | `task_get` | Get full details of a task by ID |
82
+ | `task_list` | List all tasks (summary view), with optional filters |
83
+ | `task_delete` | Delete a task by ID |
84
+
85
+ ## Status Workflow
86
+
87
+ ```
88
+ pending → in_progress → completed
89
+ ```
90
+
91
+ Use `status: "deleted"` in `task_update` to remove a task (same as `task_delete`).
92
+
93
+ ## Dependencies
94
+
95
+ Tasks can block each other:
96
+
97
+ - `blockedBy: [1, 3]` — this task can't start until tasks 1 and 3 complete
98
+ - When a task is completed, it's automatically removed from dependents' `blockedBy`
99
+ - When a task is deleted, all dependency references are cleaned up
100
+
101
+ ## Storage Format
102
+
103
+ Each task is a markdown file at `~/.telos/{id}-{slug}.md`:
104
+
105
+ ```markdown
106
+ ---
107
+ id: 1
108
+ subject: Fix authentication bug
109
+ status: pending
110
+ created: 2026-03-06T10:00:00Z
111
+ updated: 2026-03-06T10:00:00Z
112
+ owner: echo
113
+ activeForm: Fixing authentication bug
114
+ blockedBy: []
115
+ blocks: [2]
116
+ tags: [backend, auth]
117
+ metadata_sources: https://docs.example.com
118
+ metadata_pr: #42
119
+ ---
120
+
121
+ Detailed description with full markdown support.
122
+ ```
123
+
124
+ Filenames use slugified subjects for readability: `1-fix-authentication-bug.md`.
125
+
126
+ Metadata is stored as `metadata_` prefixed keys in frontmatter, reconstructed into a `{ key: value }` object on read.
127
+
128
+ A `.next_id` counter file tracks the next available task ID (prevents ID reuse after deletion). It's a dotfile — hidden by default.
129
+
130
+ Human-readable, git-friendly, works with Obsidian/any markdown viewer.
131
+
132
+ ## License
133
+
134
+ MIT
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { readFileSync } from "node:fs";
5
+ import { z } from "zod";
6
+ import { TaskStore } from "./store.js";
7
+ import { loadConfig } from "./types.js";
8
+ const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
9
+ const config = loadConfig();
10
+ const store = new TaskStore(config.dir);
11
+ const server = new McpServer({
12
+ name: "telos-mcp",
13
+ version: pkg.version,
14
+ });
15
+ const descriptionStructure = `
16
+ Structured description, details points when applicable:
17
+ - Context: explain the why, and overall view how to solve the problem
18
+ - Task details
19
+ - Task location: where the task takes place
20
+ - Architecture: final structure of the expected output
21
+ - Dependencies: explain what are required for delivery
22
+ - Examples of the deliverable and expectations
23
+ - Reasoning for the offered solution
24
+ - Foreseen barriers and solution (from task context)
25
+ - Implementation steps: real, commitable implementation steps, questions to ask the user for clarification and decision
26
+ - Testing plan
27
+ - Deployment plan
28
+ `;
29
+ // ── task_create ─────────────────────────────────────────────────
30
+ server.registerTool("task_create", {
31
+ description: "Create a new task for tracking work",
32
+ inputSchema: {
33
+ subject: z.string().describe("Brief imperative title (e.g. 'Fix auth bug')"),
34
+ description: z.string().optional().describe(`Detailed markdown description. \n ${descriptionStructure}`),
35
+ activeForm: z
36
+ .string()
37
+ .optional()
38
+ .describe("Present-continuous form shown in spinner when task is in_progress. Subject is imperative ('Fix auth bug'), activeForm is what's happening now ('Fixing auth bug'). Displayed as: ⠋ Fixing auth bug..."),
39
+ owner: z.string().optional().describe("Who owns this task"),
40
+ blockedBy: z.array(z.number()).optional().describe("Task IDs that must complete first"),
41
+ tags: z.array(z.string()).optional().describe("Categorization tags"),
42
+ metadata: z.record(z.string()).optional().describe("Arbitrary key-value pairs (e.g. { sources: 'https://...', pr: '#42' })"),
43
+ }
44
+ }, async (params) => {
45
+ const task = store.create(params);
46
+ return {
47
+ content: [{ type: "text", text: JSON.stringify(task, null, 2) }],
48
+ };
49
+ });
50
+ // ── task_update ─────────────────────────────────────────────────
51
+ server.registerTool("task_update", {
52
+ description: "Update an existing task's status, dependencies, or details",
53
+ inputSchema: {
54
+ taskId: z.number().describe("The task ID to update"),
55
+ status: z
56
+ .enum(["pending", "in_progress", "completed", "deleted"])
57
+ .optional()
58
+ .describe("New status (deleted removes the task)"),
59
+ subject: z.string().optional().describe("New subject"),
60
+ description: z.string().optional().describe(`New description with structure: \n ${descriptionStructure}`),
61
+ activeForm: z.string().optional().describe("New spinner text"),
62
+ owner: z.string().optional().describe("New owner"),
63
+ addBlockedBy: z.array(z.number()).optional().describe("Task IDs to add as blockers"),
64
+ addBlocks: z.array(z.number()).optional().describe("Task IDs that this task blocks"),
65
+ tags: z.array(z.string()).optional().describe("Replace tags"),
66
+ metadata: z.record(z.string().nullable()).optional().describe("Merge metadata keys into the task. Set a key to null to delete it."),
67
+ }
68
+ }, async (params) => {
69
+ const { taskId, ...fields } = params;
70
+ const task = store.update(taskId, fields);
71
+ if (!task && fields.status === "deleted") {
72
+ return {
73
+ content: [{ type: "text", text: `Task ${taskId} deleted.` }],
74
+ };
75
+ }
76
+ if (!task) {
77
+ return {
78
+ content: [{ type: "text", text: `Task ${taskId} not found.` }],
79
+ isError: true,
80
+ };
81
+ }
82
+ return {
83
+ content: [{ type: "text", text: JSON.stringify(task, null, 2) }],
84
+ };
85
+ });
86
+ // ── task_get ────────────────────────────────────────────────────
87
+ server.registerTool("task_get", { description: "Get full details of a task by ID",
88
+ inputSchema: {
89
+ taskId: z.number().describe("The task ID to retrieve"),
90
+ } }, async ({ taskId }) => {
91
+ const task = store.get(taskId);
92
+ if (!task) {
93
+ return {
94
+ content: [{ type: "text", text: `Task ${taskId} not found.` }],
95
+ isError: true,
96
+ };
97
+ }
98
+ return {
99
+ content: [{ type: "text", text: JSON.stringify(task, null, 2) }],
100
+ };
101
+ });
102
+ // ── task_list ───────────────────────────────────────────────────
103
+ server.registerTool("task_list", { description: "List all tasks (summary view: id, subject, status, owner, blockedBy)",
104
+ inputSchema: {
105
+ status: z
106
+ .enum(["pending", "in_progress", "completed"])
107
+ .optional()
108
+ .describe("Filter by status"),
109
+ owner: z.string().optional().describe("Filter by owner"),
110
+ tag: z.string().optional().describe("Filter by tag"),
111
+ } }, async (params) => {
112
+ const tasks = store.list(params);
113
+ if (tasks.length === 0) {
114
+ return {
115
+ content: [{ type: "text", text: "No tasks found." }],
116
+ };
117
+ }
118
+ const lines = tasks.map((t) => {
119
+ const owner = t.owner ? ` @${t.owner}` : "";
120
+ const tags = t.tags.length > 0 ? ` ${t.tags.map((tag) => `#${tag}`).join(" ")}` : "";
121
+ const blocked = t.blockedBy.length > 0 ? ` (blocked by: ${t.blockedBy.join(", ")})` : "";
122
+ return `[${t.id}] ${t.status} — ${t.subject}${owner}${tags}${blocked}`;
123
+ });
124
+ return {
125
+ content: [{ type: "text", text: lines.join("\n") }],
126
+ };
127
+ });
128
+ // ── task_delete ─────────────────────────────────────────────────
129
+ server.registerTool("task_delete", { description: "Delete a task by ID (removes the file)",
130
+ inputSchema: {
131
+ taskId: z.number().describe("The task ID to delete"),
132
+ } }, async ({ taskId }) => {
133
+ const deleted = store.delete(taskId);
134
+ if (!deleted) {
135
+ return {
136
+ content: [{ type: "text", text: `Task ${taskId} not found.` }],
137
+ isError: true,
138
+ };
139
+ }
140
+ return {
141
+ content: [{ type: "text", text: `Task ${taskId} deleted.` }],
142
+ };
143
+ });
144
+ // ── Start ───────────────────────────────────────────────────────
145
+ async function main() {
146
+ const transport = new StdioServerTransport();
147
+ await server.connect(transport);
148
+ console.error(`[telos] Task server running on stdio (${store.count()} tasks in ${config.dir})`);
149
+ }
150
+ main().catch((err) => {
151
+ console.error("[telos] Fatal error:", err);
152
+ process.exit(1);
153
+ });
154
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { Task, TaskSummary, TaskStatus, ListFilters } from "./types.js";
2
+ export declare class TaskStore {
3
+ private dir;
4
+ constructor(dir: string);
5
+ create(fields: {
6
+ subject: string;
7
+ description?: string;
8
+ activeForm?: string;
9
+ owner?: string;
10
+ blockedBy?: number[];
11
+ tags?: string[];
12
+ metadata?: Record<string, string>;
13
+ }): Task;
14
+ get(id: number): Task | null;
15
+ list(filters?: ListFilters): TaskSummary[];
16
+ update(id: number, fields: {
17
+ status?: TaskStatus | "deleted";
18
+ subject?: string;
19
+ description?: string;
20
+ activeForm?: string;
21
+ owner?: string;
22
+ addBlockedBy?: number[];
23
+ addBlocks?: number[];
24
+ tags?: string[];
25
+ metadata?: Record<string, string | null>;
26
+ }): Task | null;
27
+ delete(id: number): boolean;
28
+ count(): number;
29
+ private nextId;
30
+ private taskPath;
31
+ /** Find a task file by ID prefix (handles slug changes) */
32
+ private findTaskFile;
33
+ private taskFiles;
34
+ private readTask;
35
+ private writeTask;
36
+ /** Remove this task's ID from all dependents' blockedBy arrays */
37
+ private unblockDependents;
38
+ /** Remove this task's ID from all blockers' blocks arrays */
39
+ private removeFromBlockers;
40
+ }
41
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI7E,qBAAa,SAAS;IACpB,OAAO,CAAC,GAAG,CAAS;gBAER,GAAG,EAAE,MAAM;IAKvB,MAAM,CAAC,MAAM,EAAE;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACnC,GAAG,IAAI;IAiCR,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAM5B,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,WAAW,EAAE;IAwB1C,MAAM,CACJ,EAAE,EAAE,MAAM,EACV,MAAM,EAAE;QACN,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;QAChC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;KAC1C,GACA,IAAI,GAAG,IAAI;IAkFd,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAY3B,KAAK,IAAI,MAAM;IAMf,OAAO,CAAC,MAAM;IAsBd,OAAO,CAAC,QAAQ;IAKhB,2DAA2D;IAC3D,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,QAAQ;IAoBhB,OAAO,CAAC,SAAS;IAmBjB,kEAAkE;IAClE,OAAO,CAAC,iBAAiB;IAczB,6DAA6D;IAC7D,OAAO,CAAC,kBAAkB;CAa3B"}
package/dist/store.js ADDED
@@ -0,0 +1,260 @@
1
+ import { mkdirSync, readFileSync, writeFileSync, readdirSync, unlinkSync, existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { VALID_STATUSES } from "./types.js";
4
+ import { parseFrontmatter, serializeFrontmatter, isoNow, slugify } from "./utils.js";
5
+ export class TaskStore {
6
+ dir;
7
+ constructor(dir) {
8
+ this.dir = dir;
9
+ mkdirSync(dir, { recursive: true });
10
+ }
11
+ create(fields) {
12
+ const now = isoNow();
13
+ const id = this.nextId();
14
+ const task = {
15
+ id,
16
+ subject: fields.subject,
17
+ description: fields.description ?? "",
18
+ status: "pending",
19
+ created: now,
20
+ updated: now,
21
+ owner: fields.owner ?? "",
22
+ activeForm: fields.activeForm ?? "",
23
+ blockedBy: fields.blockedBy ?? [],
24
+ blocks: [],
25
+ tags: fields.tags ?? [],
26
+ metadata: fields.metadata ?? {},
27
+ };
28
+ // Update reverse dependencies: add this task to each blocker's `blocks`
29
+ for (const blockerId of task.blockedBy) {
30
+ const blocker = this.get(blockerId);
31
+ if (blocker && !blocker.blocks.includes(id)) {
32
+ blocker.blocks.push(id);
33
+ blocker.updated = now;
34
+ this.writeTask(blocker);
35
+ }
36
+ }
37
+ this.writeTask(task);
38
+ return task;
39
+ }
40
+ get(id) {
41
+ const path = this.findTaskFile(id);
42
+ if (!path)
43
+ return null;
44
+ return this.readTask(path);
45
+ }
46
+ list(filters) {
47
+ const files = this.taskFiles();
48
+ const results = [];
49
+ for (const file of files) {
50
+ const task = this.readTask(join(this.dir, file));
51
+ if (filters?.status && task.status !== filters.status)
52
+ continue;
53
+ if (filters?.owner && task.owner !== filters.owner)
54
+ continue;
55
+ if (filters?.tag && !task.tags.includes(filters.tag))
56
+ continue;
57
+ results.push({
58
+ id: task.id,
59
+ subject: task.subject,
60
+ status: task.status,
61
+ owner: task.owner,
62
+ blockedBy: task.blockedBy,
63
+ tags: task.tags,
64
+ });
65
+ }
66
+ return results.sort((a, b) => a.id - b.id);
67
+ }
68
+ update(id, fields) {
69
+ // Handle delete via status
70
+ if (fields.status === "deleted") {
71
+ this.delete(id);
72
+ return null;
73
+ }
74
+ const oldPath = this.findTaskFile(id);
75
+ if (!oldPath)
76
+ return null;
77
+ const task = this.readTask(oldPath);
78
+ const now = isoNow();
79
+ if (fields.status && VALID_STATUSES.includes(fields.status)) {
80
+ task.status = fields.status;
81
+ }
82
+ if (fields.subject !== undefined)
83
+ task.subject = fields.subject;
84
+ if (fields.description !== undefined)
85
+ task.description = fields.description;
86
+ if (fields.activeForm !== undefined)
87
+ task.activeForm = fields.activeForm;
88
+ if (fields.owner !== undefined)
89
+ task.owner = fields.owner;
90
+ if (fields.tags !== undefined)
91
+ task.tags = fields.tags;
92
+ // Merge metadata (null values delete keys)
93
+ if (fields.metadata) {
94
+ for (const [key, val] of Object.entries(fields.metadata)) {
95
+ if (val === null) {
96
+ delete task.metadata[key];
97
+ }
98
+ else {
99
+ task.metadata[key] = val;
100
+ }
101
+ }
102
+ }
103
+ // Add blocking dependencies
104
+ if (fields.addBlockedBy) {
105
+ for (const blockerId of fields.addBlockedBy) {
106
+ if (!task.blockedBy.includes(blockerId)) {
107
+ task.blockedBy.push(blockerId);
108
+ // Update reverse: add this task to blocker's `blocks`
109
+ const blocker = this.get(blockerId);
110
+ if (blocker && !blocker.blocks.includes(id)) {
111
+ blocker.blocks.push(id);
112
+ blocker.updated = now;
113
+ this.writeTask(blocker);
114
+ }
115
+ }
116
+ }
117
+ }
118
+ // Add tasks that this one blocks
119
+ if (fields.addBlocks) {
120
+ for (const blockedId of fields.addBlocks) {
121
+ if (!task.blocks.includes(blockedId)) {
122
+ task.blocks.push(blockedId);
123
+ // Update reverse: add this task to blocked's `blockedBy`
124
+ const blocked = this.get(blockedId);
125
+ if (blocked && !blocked.blockedBy.includes(id)) {
126
+ blocked.blockedBy.push(id);
127
+ blocked.updated = now;
128
+ this.writeTask(blocked);
129
+ }
130
+ }
131
+ }
132
+ }
133
+ // When completing, unblock dependents
134
+ if (fields.status === "completed") {
135
+ this.unblockDependents(id, now);
136
+ }
137
+ task.updated = now;
138
+ // Delete old file if path changed (subject change or pre-slug migration)
139
+ const newPath = this.taskPath(task.id, task.subject);
140
+ if (oldPath !== newPath) {
141
+ unlinkSync(oldPath);
142
+ }
143
+ this.writeTask(task);
144
+ return task;
145
+ }
146
+ delete(id) {
147
+ const path = this.findTaskFile(id);
148
+ if (!path)
149
+ return false;
150
+ // Clean up dependencies before removing
151
+ this.unblockDependents(id, isoNow());
152
+ this.removeFromBlockers(id, isoNow());
153
+ unlinkSync(path);
154
+ return true;
155
+ }
156
+ count() {
157
+ return this.taskFiles().length;
158
+ }
159
+ // ── Private ────────────────────────────────────────────────────
160
+ nextId() {
161
+ const counterPath = join(this.dir, ".next_id");
162
+ let nextId = 1;
163
+ if (existsSync(counterPath)) {
164
+ const stored = parseInt(readFileSync(counterPath, "utf-8").trim(), 10);
165
+ if (!Number.isNaN(stored))
166
+ nextId = stored;
167
+ }
168
+ // Also check existing files in case counter is stale
169
+ const files = this.taskFiles();
170
+ if (files.length > 0) {
171
+ const maxExisting = Math.max(...files.map((f) => parseInt(f.split("-")[0], 10)).filter((n) => !Number.isNaN(n)));
172
+ if (maxExisting >= nextId)
173
+ nextId = maxExisting + 1;
174
+ }
175
+ writeFileSync(counterPath, String(nextId + 1), "utf-8");
176
+ return nextId;
177
+ }
178
+ taskPath(id, subject) {
179
+ const slug = slugify(subject);
180
+ return join(this.dir, slug ? `${id}-${slug}.md` : `${id}.md`);
181
+ }
182
+ /** Find a task file by ID prefix (handles slug changes) */
183
+ findTaskFile(id) {
184
+ const files = this.taskFiles();
185
+ const match = files.find((f) => {
186
+ const fileId = parseInt(f.split("-")[0], 10);
187
+ return fileId === id;
188
+ });
189
+ return match ? join(this.dir, match) : null;
190
+ }
191
+ taskFiles() {
192
+ if (!existsSync(this.dir))
193
+ return [];
194
+ return readdirSync(this.dir).filter((f) => /^\d+(-[a-z0-9-]+)?\.md$/.test(f));
195
+ }
196
+ readTask(path) {
197
+ const raw = readFileSync(path, "utf-8");
198
+ const { data, body } = parseFrontmatter(raw);
199
+ return {
200
+ id: data.id,
201
+ subject: data.subject ?? "",
202
+ description: body,
203
+ status: data.status ?? "pending",
204
+ created: data.created ?? "",
205
+ updated: data.updated ?? "",
206
+ owner: data.owner ?? "",
207
+ activeForm: data.activeForm ?? "",
208
+ blockedBy: data.blockedBy ?? [],
209
+ blocks: data.blocks ?? [],
210
+ tags: data.tags ?? [],
211
+ metadata: data.metadata ?? {},
212
+ };
213
+ }
214
+ writeTask(task) {
215
+ const data = {
216
+ id: task.id,
217
+ subject: task.subject,
218
+ status: task.status,
219
+ created: task.created,
220
+ updated: task.updated,
221
+ owner: task.owner,
222
+ activeForm: task.activeForm,
223
+ blockedBy: task.blockedBy,
224
+ blocks: task.blocks,
225
+ tags: task.tags,
226
+ metadata: task.metadata,
227
+ };
228
+ const content = serializeFrontmatter(data, task.description);
229
+ writeFileSync(this.taskPath(task.id, task.subject), content, "utf-8");
230
+ }
231
+ /** Remove this task's ID from all dependents' blockedBy arrays */
232
+ unblockDependents(id, now) {
233
+ const task = this.get(id);
234
+ if (!task)
235
+ return;
236
+ for (const blockedId of task.blocks) {
237
+ const blocked = this.get(blockedId);
238
+ if (blocked) {
239
+ blocked.blockedBy = blocked.blockedBy.filter((bid) => bid !== id);
240
+ blocked.updated = now;
241
+ this.writeTask(blocked);
242
+ }
243
+ }
244
+ }
245
+ /** Remove this task's ID from all blockers' blocks arrays */
246
+ removeFromBlockers(id, now) {
247
+ const task = this.get(id);
248
+ if (!task)
249
+ return;
250
+ for (const blockerId of task.blockedBy) {
251
+ const blocker = this.get(blockerId);
252
+ if (blocker) {
253
+ blocker.blocks = blocker.blocks.filter((bid) => bid !== id);
254
+ blocker.updated = now;
255
+ this.writeTask(blocker);
256
+ }
257
+ }
258
+ }
259
+ }
260
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ export type TaskStatus = "pending" | "in_progress" | "completed";
2
+ export declare const VALID_STATUSES: TaskStatus[];
3
+ export interface Task {
4
+ id: number;
5
+ subject: string;
6
+ description: string;
7
+ status: TaskStatus;
8
+ created: string;
9
+ updated: string;
10
+ owner: string;
11
+ activeForm: string;
12
+ blockedBy: number[];
13
+ blocks: number[];
14
+ tags: string[];
15
+ metadata: Record<string, string>;
16
+ }
17
+ export interface TaskSummary {
18
+ id: number;
19
+ subject: string;
20
+ status: TaskStatus;
21
+ owner: string;
22
+ blockedBy: number[];
23
+ tags: string[];
24
+ }
25
+ export interface ListFilters {
26
+ status?: TaskStatus;
27
+ owner?: string;
28
+ tag?: string;
29
+ }
30
+ export interface TelosConfig {
31
+ dir: string;
32
+ }
33
+ export declare function loadConfig(): TelosConfig;
34
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;AAEjE,eAAO,MAAM,cAAc,EAAE,UAAU,EAA4C,CAAC;AAEpF,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,UAAU,IAAI,WAAW,CAIxC"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+ export const VALID_STATUSES = ["pending", "in_progress", "completed"];
4
+ export function loadConfig() {
5
+ return {
6
+ dir: process.env.TELOS_DIR ?? join(homedir(), ".telos"),
7
+ };
8
+ }
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,MAAM,CAAC,MAAM,cAAc,GAAiB,CAAC,SAAS,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;AAoCpF,MAAM,UAAU,UAAU;IACxB,OAAO;QACL,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC;KACxD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Minimal frontmatter parser/serializer.
3
+ * Handles strings, numbers, booleans, and flat arrays — no nested objects.
4
+ */
5
+ export declare function parseFrontmatter(raw: string): {
6
+ data: Record<string, unknown>;
7
+ body: string;
8
+ };
9
+ export declare function serializeFrontmatter(data: Record<string, unknown>, body: string): string;
10
+ export declare function slugify(text: string, maxLength?: number): string;
11
+ export declare function isoNow(): string;
12
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAsC7F;AA8BD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CA6BxF;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAK,GAAG,MAAM,CAO5D;AAED,wBAAgB,MAAM,IAAI,MAAM,CAE/B"}
package/dist/utils.js ADDED
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Minimal frontmatter parser/serializer.
3
+ * Handles strings, numbers, booleans, and flat arrays — no nested objects.
4
+ */
5
+ export function parseFrontmatter(raw) {
6
+ const data = {};
7
+ if (!raw.startsWith("---")) {
8
+ return { data, body: raw };
9
+ }
10
+ const end = raw.indexOf("\n---", 3);
11
+ if (end === -1) {
12
+ return { data, body: raw };
13
+ }
14
+ const frontmatter = raw.slice(4, end).trim();
15
+ const body = raw.slice(end + 4).trim();
16
+ for (const line of frontmatter.split("\n")) {
17
+ const colonIdx = line.indexOf(":");
18
+ if (colonIdx === -1)
19
+ continue;
20
+ const key = line.slice(0, colonIdx).trim();
21
+ const val = line.slice(colonIdx + 1).trim();
22
+ data[key] = parseValue(val);
23
+ }
24
+ // Reconstruct metadata_ prefixed keys into a metadata object
25
+ const metadata = {};
26
+ for (const key of Object.keys(data)) {
27
+ if (key.startsWith("metadata_")) {
28
+ metadata[key.slice(9)] = String(data[key]);
29
+ delete data[key];
30
+ }
31
+ }
32
+ if (Object.keys(metadata).length > 0) {
33
+ data.metadata = metadata;
34
+ }
35
+ return { data, body };
36
+ }
37
+ function parseValue(val) {
38
+ // Array: [a, b, c] or [1, 2, 3]
39
+ if (val.startsWith("[") && val.endsWith("]")) {
40
+ const inner = val.slice(1, -1).trim();
41
+ if (inner === "")
42
+ return [];
43
+ return inner.split(",").map((item) => {
44
+ const trimmed = item.trim();
45
+ const num = Number(trimmed);
46
+ return Number.isNaN(num) ? trimmed : num;
47
+ });
48
+ }
49
+ // Number
50
+ const num = Number(val);
51
+ if (val !== "" && !Number.isNaN(num))
52
+ return num;
53
+ // Boolean
54
+ if (val === "true")
55
+ return true;
56
+ if (val === "false")
57
+ return false;
58
+ // String (strip surrounding quotes if present)
59
+ if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) {
60
+ return val.slice(1, -1);
61
+ }
62
+ return val;
63
+ }
64
+ export function serializeFrontmatter(data, body) {
65
+ const lines = ["---"];
66
+ for (const [key, val] of Object.entries(data)) {
67
+ if (val === undefined || val === null)
68
+ continue;
69
+ // Expand metadata object into metadata_ prefixed keys
70
+ if (key === "metadata" && typeof val === "object" && !Array.isArray(val)) {
71
+ for (const [mk, mv] of Object.entries(val)) {
72
+ if (mv === undefined || mv === null)
73
+ continue;
74
+ lines.push(`metadata_${mk}: ${mv}`);
75
+ }
76
+ continue;
77
+ }
78
+ if (Array.isArray(val)) {
79
+ lines.push(`${key}: [${val.join(", ")}]`);
80
+ }
81
+ else {
82
+ lines.push(`${key}: ${val}`);
83
+ }
84
+ }
85
+ lines.push("---");
86
+ if (body) {
87
+ lines.push("", body);
88
+ }
89
+ return lines.join("\n") + "\n";
90
+ }
91
+ export function slugify(text, maxLength = 50) {
92
+ return text
93
+ .toLowerCase()
94
+ .replace(/[^a-z0-9]+/g, "-")
95
+ .replace(/^-|-$/g, "")
96
+ .slice(0, maxLength)
97
+ .replace(/-$/, "");
98
+ }
99
+ export function isoNow() {
100
+ return new Date().toISOString();
101
+ }
102
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,IAAI,GAA4B,EAAE,CAAC;IAEzC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IAC7B,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IAC7B,CAAC;IAED,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7C,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAEvC,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,QAAQ,KAAK,CAAC,CAAC;YAAE,SAAS;QAE9B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAE5C,IAAI,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,6DAA6D;IAC7D,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,IAAI,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAChC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,gCAAgC;IAChC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,KAAK,KAAK,EAAE;YAAE,OAAO,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAC5B,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS;IACT,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,GAAG,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAEjD,UAAU;IACV,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAElC,+CAA+C;IAC/C,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC7F,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAA6B,EAAE,IAAY;IAC9E,MAAM,KAAK,GAAa,CAAC,KAAK,CAAC,CAAC;IAEhC,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9C,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI;YAAE,SAAS;QAEhD,sDAAsD;QACtD,IAAI,GAAG,KAAK,UAAU,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACzE,KAAK,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAA6B,CAAC,EAAE,CAAC;gBACrE,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,IAAI;oBAAE,SAAS;gBAC9C,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YACtC,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,GAAG,EAAE,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAElB,IAAI,IAAI,EAAE,CAAC;QACT,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,SAAS,GAAG,EAAE;IAClD,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC;SACnB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,MAAM;IACpB,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "telos-mcp",
3
+ "version": "0.1.0",
4
+ "description": "Task planning MCP server with markdown file storage",
5
+ "type": "module",
6
+ "bin": {
7
+ "telos-mcp": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "scripts": {
15
+ "test": "vitest run",
16
+ "build": "tsc",
17
+ "start": "node dist/index.js",
18
+ "dev": "tsc --watch",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "keywords": [
22
+ "mcp",
23
+ "tasks",
24
+ "planning",
25
+ "todo",
26
+ "agent",
27
+ "model-context-protocol"
28
+ ],
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/skye-flyhigh/telos-mcp.git"
32
+ },
33
+ "homepage": "https://github.com/skye-flyhigh/telos-mcp#readme",
34
+ "bugs": {
35
+ "url": "https://github.com/skye-flyhigh/telos-mcp/issues"
36
+ },
37
+ "dependencies": {
38
+ "@modelcontextprotocol/sdk": "^1.12.1",
39
+ "zod": "^3.25.67"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^22.15.21",
43
+ "typescript": "^5.8.3",
44
+ "vitest": "^4.0.18"
45
+ },
46
+ "engines": {
47
+ "node": ">=20"
48
+ },
49
+ "license": "MIT",
50
+ "author": "Skye"
51
+ }