@asd412id/mcp-context-manager 1.0.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.
@@ -0,0 +1,196 @@
1
+ import * as z from 'zod';
2
+ import { getStore } from '../storage/file-store.js';
3
+ const TRACKER_FILE = 'tracker.json';
4
+ async function getTrackerStore() {
5
+ const store = getStore();
6
+ return store.read(TRACKER_FILE, { entries: [] });
7
+ }
8
+ async function saveTrackerStore(data) {
9
+ const store = getStore();
10
+ await store.write(TRACKER_FILE, data);
11
+ }
12
+ export function registerTrackerTools(server) {
13
+ server.registerTool('tracker_log', {
14
+ title: 'Tracker Log',
15
+ description: 'Log a decision, change, todo, note, or error to the project tracker.',
16
+ inputSchema: {
17
+ type: z.enum(['decision', 'change', 'todo', 'note', 'error']).describe('Type of entry'),
18
+ content: z.string().describe('Description of the entry'),
19
+ tags: z.array(z.string()).optional().describe('Tags for categorization'),
20
+ metadata: z.record(z.unknown()).optional().describe('Additional metadata')
21
+ }
22
+ }, async ({ type, content, tags, metadata }) => {
23
+ const trackerStore = await getTrackerStore();
24
+ const now = new Date().toISOString();
25
+ const entry = {
26
+ id: `${type}_${Date.now()}`,
27
+ type,
28
+ content,
29
+ metadata,
30
+ tags: tags || [],
31
+ status: type === 'todo' ? 'pending' : undefined,
32
+ createdAt: now,
33
+ updatedAt: now
34
+ };
35
+ trackerStore.entries.push(entry);
36
+ await saveTrackerStore(trackerStore);
37
+ return {
38
+ content: [{
39
+ type: 'text',
40
+ text: `Logged ${type}: "${content}" (ID: ${entry.id})`
41
+ }]
42
+ };
43
+ });
44
+ server.registerTool('tracker_status', {
45
+ title: 'Tracker Status',
46
+ description: 'Get current project status including recent decisions, pending todos, and recent changes.',
47
+ inputSchema: {
48
+ limit: z.number().optional().describe('Maximum entries per type (default: 5)')
49
+ }
50
+ }, async ({ limit = 5 }) => {
51
+ const trackerStore = await getTrackerStore();
52
+ const entries = trackerStore.entries;
53
+ const decisions = entries
54
+ .filter(e => e.type === 'decision')
55
+ .slice(-limit);
56
+ const pendingTodos = entries
57
+ .filter(e => e.type === 'todo' && e.status === 'pending')
58
+ .slice(-limit);
59
+ const recentChanges = entries
60
+ .filter(e => e.type === 'change')
61
+ .slice(-limit);
62
+ const recentErrors = entries
63
+ .filter(e => e.type === 'error')
64
+ .slice(-limit);
65
+ const status = {
66
+ projectName: trackerStore.projectName,
67
+ totalEntries: entries.length,
68
+ decisions: decisions.map(d => ({ id: d.id, content: d.content, date: d.createdAt })),
69
+ pendingTodos: pendingTodos.map(t => ({ id: t.id, content: t.content, tags: t.tags })),
70
+ recentChanges: recentChanges.map(c => ({ id: c.id, content: c.content, date: c.createdAt })),
71
+ recentErrors: recentErrors.map(e => ({ id: e.id, content: e.content, date: e.createdAt }))
72
+ };
73
+ return {
74
+ content: [{ type: 'text', text: JSON.stringify(status, null, 2) }]
75
+ };
76
+ });
77
+ server.registerTool('tracker_todo_update', {
78
+ title: 'Update Todo',
79
+ description: 'Update the status of a todo item.',
80
+ inputSchema: {
81
+ id: z.string().describe('Todo ID to update'),
82
+ status: z.enum(['pending', 'done', 'cancelled']).describe('New status')
83
+ }
84
+ }, async ({ id, status }) => {
85
+ const trackerStore = await getTrackerStore();
86
+ const entry = trackerStore.entries.find(e => e.id === id);
87
+ if (!entry) {
88
+ return {
89
+ content: [{ type: 'text', text: `Entry not found: ${id}` }]
90
+ };
91
+ }
92
+ if (entry.type !== 'todo') {
93
+ return {
94
+ content: [{ type: 'text', text: `Entry ${id} is not a todo` }]
95
+ };
96
+ }
97
+ entry.status = status;
98
+ entry.updatedAt = new Date().toISOString();
99
+ await saveTrackerStore(trackerStore);
100
+ return {
101
+ content: [{ type: 'text', text: `Todo "${entry.content}" marked as ${status}` }]
102
+ };
103
+ });
104
+ server.registerTool('tracker_search', {
105
+ title: 'Tracker Search',
106
+ description: 'Search tracker entries by type, tags, or content.',
107
+ inputSchema: {
108
+ type: z.enum(['decision', 'change', 'todo', 'note', 'error']).optional().describe('Filter by type'),
109
+ tags: z.array(z.string()).optional().describe('Filter by tags'),
110
+ query: z.string().optional().describe('Search in content'),
111
+ limit: z.number().optional().describe('Maximum results (default: 20)')
112
+ }
113
+ }, async ({ type, tags, query, limit = 20 }) => {
114
+ const trackerStore = await getTrackerStore();
115
+ let results = trackerStore.entries;
116
+ if (type) {
117
+ results = results.filter(e => e.type === type);
118
+ }
119
+ if (tags && tags.length > 0) {
120
+ results = results.filter(e => tags.some(tag => e.tags.includes(tag)));
121
+ }
122
+ if (query) {
123
+ const lowerQuery = query.toLowerCase();
124
+ results = results.filter(e => e.content.toLowerCase().includes(lowerQuery));
125
+ }
126
+ results = results.slice(-limit);
127
+ return {
128
+ content: [{
129
+ type: 'text',
130
+ text: results.length > 0
131
+ ? JSON.stringify(results, null, 2)
132
+ : 'No entries found'
133
+ }]
134
+ };
135
+ });
136
+ server.registerTool('tracker_set_project', {
137
+ title: 'Set Project Name',
138
+ description: 'Set the current project name for context.',
139
+ inputSchema: {
140
+ name: z.string().describe('Project name')
141
+ }
142
+ }, async ({ name }) => {
143
+ const trackerStore = await getTrackerStore();
144
+ trackerStore.projectName = name;
145
+ await saveTrackerStore(trackerStore);
146
+ return {
147
+ content: [{ type: 'text', text: `Project name set to: ${name}` }]
148
+ };
149
+ });
150
+ server.registerTool('tracker_export', {
151
+ title: 'Export Tracker',
152
+ description: 'Export all tracker entries as markdown format for documentation.',
153
+ inputSchema: {}
154
+ }, async () => {
155
+ const trackerStore = await getTrackerStore();
156
+ const entries = trackerStore.entries;
157
+ let md = `# Project Tracker${trackerStore.projectName ? `: ${trackerStore.projectName}` : ''}\n\n`;
158
+ md += `Generated: ${new Date().toISOString()}\n\n`;
159
+ const decisions = entries.filter(e => e.type === 'decision');
160
+ if (decisions.length > 0) {
161
+ md += `## Decisions\n\n`;
162
+ for (const d of decisions) {
163
+ md += `- **${d.createdAt.split('T')[0]}**: ${d.content}\n`;
164
+ }
165
+ md += '\n';
166
+ }
167
+ const todos = entries.filter(e => e.type === 'todo');
168
+ if (todos.length > 0) {
169
+ md += `## Todos\n\n`;
170
+ for (const t of todos) {
171
+ const checkbox = t.status === 'done' ? '[x]' : '[ ]';
172
+ md += `- ${checkbox} ${t.content}${t.status === 'cancelled' ? ' _(cancelled)_' : ''}\n`;
173
+ }
174
+ md += '\n';
175
+ }
176
+ const changes = entries.filter(e => e.type === 'change');
177
+ if (changes.length > 0) {
178
+ md += `## Changes\n\n`;
179
+ for (const c of changes) {
180
+ md += `- **${c.createdAt.split('T')[0]}**: ${c.content}\n`;
181
+ }
182
+ md += '\n';
183
+ }
184
+ const errors = entries.filter(e => e.type === 'error');
185
+ if (errors.length > 0) {
186
+ md += `## Errors/Issues\n\n`;
187
+ for (const e of errors) {
188
+ md += `- **${e.createdAt.split('T')[0]}**: ${e.content}\n`;
189
+ }
190
+ md += '\n';
191
+ }
192
+ return {
193
+ content: [{ type: 'text', text: md }]
194
+ };
195
+ });
196
+ }
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@asd412id/mcp-context-manager",
3
+ "version": "1.0.0",
4
+ "description": "MCP tools for context management - summarizer, memory store, project tracker, checkpoints, and smart file loader",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "mcp-context-manager": "./dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "dev": "tsc --watch",
17
+ "start": "node dist/index.js",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "keywords": [
21
+ "mcp",
22
+ "context",
23
+ "ai",
24
+ "memory",
25
+ "llm",
26
+ "model-context-protocol",
27
+ "claude",
28
+ "anthropic"
29
+ ],
30
+ "author": "",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": ""
35
+ },
36
+ "engines": {
37
+ "node": ">=18.0.0"
38
+ },
39
+ "dependencies": {
40
+ "@modelcontextprotocol/sdk": "^1.0.0",
41
+ "zod": "^3.23.0"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^20.0.0",
45
+ "typescript": "^5.0.0"
46
+ }
47
+ }