memtask 0.0.1__tar.gz → 0.0.2__tar.gz

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.
Files changed (26) hide show
  1. memtask-0.0.2/PKG-INFO +89 -0
  2. memtask-0.0.2/README.md +79 -0
  3. {memtask-0.0.1 → memtask-0.0.2}/pyproject.toml +1 -1
  4. {memtask-0.0.1 → memtask-0.0.2}/src/memtask/__init__.py +1 -1
  5. {memtask-0.0.1 → memtask-0.0.2}/src/memtask/cli.py +115 -75
  6. {memtask-0.0.1 → memtask-0.0.2}/src/memtask/storage.py +12 -1
  7. memtask-0.0.2/src/memtask.egg-info/PKG-INFO +89 -0
  8. {memtask-0.0.1 → memtask-0.0.2}/tests/test_cli.py +54 -15
  9. memtask-0.0.1/PKG-INFO +0 -104
  10. memtask-0.0.1/README.md +0 -94
  11. memtask-0.0.1/src/memtask.egg-info/PKG-INFO +0 -104
  12. {memtask-0.0.1 → memtask-0.0.2}/MANIFEST.in +0 -0
  13. {memtask-0.0.1 → memtask-0.0.2}/docs/assets/memtask-logo.png +0 -0
  14. {memtask-0.0.1 → memtask-0.0.2}/setup.cfg +0 -0
  15. {memtask-0.0.1 → memtask-0.0.2}/src/memtask/__main__.py +0 -0
  16. {memtask-0.0.1 → memtask-0.0.2}/src/memtask/api.py +0 -0
  17. {memtask-0.0.1 → memtask-0.0.2}/src/memtask/app.py +0 -0
  18. {memtask-0.0.1 → memtask-0.0.2}/src/memtask/manager.py +0 -0
  19. {memtask-0.0.1 → memtask-0.0.2}/src/memtask.egg-info/SOURCES.txt +0 -0
  20. {memtask-0.0.1 → memtask-0.0.2}/src/memtask.egg-info/dependency_links.txt +0 -0
  21. {memtask-0.0.1 → memtask-0.0.2}/src/memtask.egg-info/entry_points.txt +0 -0
  22. {memtask-0.0.1 → memtask-0.0.2}/src/memtask.egg-info/requires.txt +0 -0
  23. {memtask-0.0.1 → memtask-0.0.2}/src/memtask.egg-info/top_level.txt +0 -0
  24. {memtask-0.0.1 → memtask-0.0.2}/tests/test_memories.py +0 -0
  25. {memtask-0.0.1 → memtask-0.0.2}/tests/test_server_contract.py +0 -0
  26. {memtask-0.0.1 → memtask-0.0.2}/tests/test_tasks.py +0 -0
memtask-0.0.2/PKG-INFO ADDED
@@ -0,0 +1,89 @@
1
+ Metadata-Version: 2.4
2
+ Name: memtask
3
+ Version: 0.0.2
4
+ Summary: A local MCP server for durable agent task state and lightweight memory.
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: mcp
8
+ Provides-Extra: test
9
+ Requires-Dist: pytest>=8; extra == "test"
10
+
11
+ <p align="center">
12
+ <img src="https://raw.githubusercontent.com/PlatinumCD/memtask-mcp/master/docs/assets/memtask-logo.png" alt="MemTask logo" width="220">
13
+ </p>
14
+
15
+ <h1 align="center">MemTask</h1>
16
+
17
+ MemTask gives MCP agents a local task list and lightweight memory, backed by SQLite.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pip install MemTask
23
+ ```
24
+
25
+ ## Start
26
+
27
+ ```bash
28
+ memtask start
29
+ ```
30
+
31
+ MemTask starts a local MCP server at:
32
+
33
+ ```text
34
+ http://127.0.0.1:8000/mcp
35
+ ```
36
+
37
+ ## Add It To Codex
38
+
39
+ ```bash
40
+ memtask install
41
+ ```
42
+
43
+ That prints the exact `codex mcp add ...` commands for stdio and HTTP:
44
+
45
+ ```text
46
+ Codex
47
+
48
+ stdio server
49
+ codex mcp add memtask -- memtask start --transport stdio
50
+
51
+ HTTP server
52
+ memtask start
53
+ codex mcp add memtask --url http://127.0.0.1:8000/mcp
54
+ ```
55
+
56
+ ## Use It
57
+
58
+ Once connected, your agent gets tools for:
59
+
60
+ - tasks: add, list, focus, complete, remove, and track dependencies
61
+ - memory: remember, recall, update, and delete scoped context
62
+
63
+ ## Common Commands
64
+
65
+ ```bash
66
+ memtask status
67
+ memtask stop
68
+ memtask start --transport stdio
69
+ ```
70
+
71
+ ## What It Is
72
+
73
+ MemTask is a local MCP server for developer-built agents that need durable task state and persistent context. It gives an agent a small workspace for tracking active work, dependency order, completed tasks, and scoped memories across sessions.
74
+
75
+ State is stored locally. In this repo, MemTask uses `data/tasks.sqlite`. When installed outside this repo, it uses `~/.memtask/tasks.sqlite` by default. Set `MEMTASK_DB_PATH` to choose a specific SQLite path.
76
+
77
+ ## Development
78
+
79
+ Run tests:
80
+
81
+ ```bash
82
+ python -m pytest
83
+ ```
84
+
85
+ Compile-check the package:
86
+
87
+ ```bash
88
+ python -m py_compile src/memtask/*.py tests/*.py
89
+ ```
@@ -0,0 +1,79 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/PlatinumCD/memtask-mcp/master/docs/assets/memtask-logo.png" alt="MemTask logo" width="220">
3
+ </p>
4
+
5
+ <h1 align="center">MemTask</h1>
6
+
7
+ MemTask gives MCP agents a local task list and lightweight memory, backed by SQLite.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ pip install MemTask
13
+ ```
14
+
15
+ ## Start
16
+
17
+ ```bash
18
+ memtask start
19
+ ```
20
+
21
+ MemTask starts a local MCP server at:
22
+
23
+ ```text
24
+ http://127.0.0.1:8000/mcp
25
+ ```
26
+
27
+ ## Add It To Codex
28
+
29
+ ```bash
30
+ memtask install
31
+ ```
32
+
33
+ That prints the exact `codex mcp add ...` commands for stdio and HTTP:
34
+
35
+ ```text
36
+ Codex
37
+
38
+ stdio server
39
+ codex mcp add memtask -- memtask start --transport stdio
40
+
41
+ HTTP server
42
+ memtask start
43
+ codex mcp add memtask --url http://127.0.0.1:8000/mcp
44
+ ```
45
+
46
+ ## Use It
47
+
48
+ Once connected, your agent gets tools for:
49
+
50
+ - tasks: add, list, focus, complete, remove, and track dependencies
51
+ - memory: remember, recall, update, and delete scoped context
52
+
53
+ ## Common Commands
54
+
55
+ ```bash
56
+ memtask status
57
+ memtask stop
58
+ memtask start --transport stdio
59
+ ```
60
+
61
+ ## What It Is
62
+
63
+ MemTask is a local MCP server for developer-built agents that need durable task state and persistent context. It gives an agent a small workspace for tracking active work, dependency order, completed tasks, and scoped memories across sessions.
64
+
65
+ State is stored locally. In this repo, MemTask uses `data/tasks.sqlite`. When installed outside this repo, it uses `~/.memtask/tasks.sqlite` by default. Set `MEMTASK_DB_PATH` to choose a specific SQLite path.
66
+
67
+ ## Development
68
+
69
+ Run tests:
70
+
71
+ ```bash
72
+ python -m pytest
73
+ ```
74
+
75
+ Compile-check the package:
76
+
77
+ ```bash
78
+ python -m py_compile src/memtask/*.py tests/*.py
79
+ ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "memtask"
7
- version = "0.0.1"
7
+ version = "0.0.2"
8
8
  description = "A local MCP server for durable agent task state and lightweight memory."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -2,4 +2,4 @@
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.0.1"
5
+ __version__ = "0.0.2"
@@ -17,6 +17,7 @@ DEFAULT_PORT = 8000
17
17
  DEFAULT_SERVER_NAME = "MemTask"
18
18
  PID_FILE = "memtask.pid"
19
19
  LOG_FILE = "memtask.log"
20
+ COMMANDS = {"start", "stop", "status", "install", "install-help"}
20
21
 
21
22
 
22
23
  def _runtime_dir() -> Path:
@@ -70,65 +71,90 @@ def _mcp_url(host: str, port: int) -> str:
70
71
  return f"http://{host}:{port}/mcp"
71
72
 
72
73
 
73
- def _stdio_config_text() -> str:
74
- return json.dumps(
75
- {
76
- "mcpServers": {
77
- "memtask": {
78
- "command": "memtask",
79
- "args": ["start", "--transport", "stdio"],
80
- }
81
- }
82
- },
83
- indent=2,
84
- )
74
+ def _color(value: str, code: str, stream=None) -> str:
75
+ stream = sys.stdout if stream is None else stream
76
+ if os.environ.get("NO_COLOR") or not stream.isatty():
77
+ return value
78
+ return f"\033[{code}m{value}\033[0m"
85
79
 
86
80
 
87
- def _http_config_text(host: str, port: int) -> str:
88
- return json.dumps(
89
- {
90
- "mcpServers": {
91
- "memtask": {
92
- "url": _mcp_url(host, port),
93
- }
94
- }
95
- },
96
- indent=2,
97
- )
81
+ def _green(value: str) -> str:
82
+ return _color(value, "32")
83
+
84
+
85
+ def _yellow(value: str) -> str:
86
+ return _color(value, "33")
87
+
88
+
89
+ def _bold_white(value: str) -> str:
90
+ return _color(value, "1;97")
91
+
92
+
93
+ def _bold(value: str) -> str:
94
+ return _color(value, "1")
95
+
96
+
97
+ def _print_main_help() -> None:
98
+ print(_bold("MemTask"))
99
+ print("Local MCP task and memory server")
100
+ print()
101
+ print(_bold("Usage"))
102
+ print(" memtask start [--host 127.0.0.1] [--port 8000]")
103
+ print(" memtask stop")
104
+ print(" memtask status")
105
+ print(" memtask install")
106
+ print()
107
+ print(_bold("Common"))
108
+ print(" memtask start Start the background HTTP server")
109
+ print(" memtask install Show Codex MCP install commands")
110
+ print(" memtask status Show PID, URL, log path, and DB path")
111
+ print()
112
+ print(_bold("Stdio"))
113
+ print(" memtask start --transport stdio")
114
+ print(" Use stdio only when your MCP client launches MemTask directly.")
98
115
 
99
116
 
100
117
  def _print_stdio_guidance() -> None:
101
- print("MemTask starting over stdio.", file=sys.stderr)
102
- print("For MCP clients that launch stdio servers, configure:", file=sys.stderr)
103
- print(_stdio_config_text(), file=sys.stderr)
104
- print(f"SQLite state: {get_db_path()}", file=sys.stderr)
118
+ print("MemTask starting over stdio; this process stays attached to the MCP client.", file=sys.stderr)
105
119
 
106
120
 
107
121
  def _print_http_guidance(host: str, port: int, pid: int | None = None) -> None:
108
- print("MemTask HTTP server started.")
122
+ print(f"{_green('OK')} MemTask started")
109
123
  if pid is not None:
110
- print(f"PID: {pid}")
111
- print(f"URL: {_mcp_url(host, port)}")
112
- print(f"SQLite state: {get_db_path()}")
113
- print(f"Log file: {_log_path()}")
124
+ print(f" PID: {pid}")
125
+ print(f" URL: {_mcp_url(host, port)}")
126
+ print(f" Data: {get_db_path()}")
127
+ print(f" Logs: {_log_path()}")
114
128
  print()
115
- print("For MCP clients that connect to HTTP servers, configure:")
116
- print(_http_config_text(host, port))
129
+ print("Add it to your MCP client with:")
130
+ print(" memtask install")
117
131
 
118
132
 
119
- def _print_install_help(host: str = DEFAULT_HOST, port: int = DEFAULT_PORT) -> None:
120
- print("MemTask MCP configuration examples")
121
- print()
122
- print("Stdio launch configuration:")
123
- print(_stdio_config_text())
124
- print()
125
- print("HTTP mode:")
126
- print(f" memtask start --transport http --host {host} --port {port}")
133
+ def _running_http_url(host: str = DEFAULT_HOST, port: int = DEFAULT_PORT) -> tuple[str, bool]:
134
+ record = _read_pid_record()
135
+ if record is None:
136
+ return _mcp_url(host, port), False
137
+
138
+ pid = int(record.get("pid", 0))
139
+ if not _pid_is_running(pid):
140
+ _clear_pid_record()
141
+ return _mcp_url(host, port), False
142
+
143
+ return str(record.get("url", _mcp_url(host, port))), True
144
+
145
+
146
+ def _print_install(host: str = DEFAULT_HOST, port: int = DEFAULT_PORT) -> None:
147
+ url, running = _running_http_url(host=host, port=port)
148
+
149
+ print(_bold_white("Codex"))
127
150
  print()
128
- print("HTTP configuration:")
129
- print(_http_config_text(host, port))
151
+ print("stdio server")
152
+ print(" codex mcp add memtask -- memtask start --transport stdio")
130
153
  print()
131
- print(f"Default SQLite state: {get_db_path()}")
154
+ print("HTTP server")
155
+ if not running:
156
+ print(" memtask start")
157
+ print(f" codex mcp add memtask --url {url}")
132
158
 
133
159
 
134
160
  def _run_server(**kwargs) -> None:
@@ -152,10 +178,12 @@ def _start_http(args: argparse.Namespace) -> None:
152
178
  if record is not None:
153
179
  pid = int(record.get("pid", 0))
154
180
  if _pid_is_running(pid):
155
- print("MemTask HTTP server is already running.")
156
- print(f"PID: {pid}")
157
- print(f"URL: {record.get('url', _mcp_url(args.host, args.port))}")
158
- print(f"Stop it with: memtask stop")
181
+ print(f"{_yellow('RUNNING')} MemTask is already running")
182
+ print(f" PID: {pid}")
183
+ print(f" URL: {record.get('url', _mcp_url(args.host, args.port))}")
184
+ print()
185
+ print("Stop it with:")
186
+ print(" memtask stop")
159
187
  return
160
188
  _clear_pid_record()
161
189
 
@@ -214,14 +242,14 @@ def _start(args: argparse.Namespace) -> None:
214
242
  def _stop(_: argparse.Namespace) -> None:
215
243
  record = _read_pid_record()
216
244
  if record is None:
217
- print("No MemTask background server is registered.")
218
- print("If you are using stdio mode, your MCP client starts and stops MemTask itself.")
245
+ print(f"{_yellow('STOPPED')} MemTask is not running")
246
+ print("stdio servers are stopped by the MCP client that launched them.")
219
247
  return
220
248
 
221
249
  pid = int(record.get("pid", 0))
222
250
  if not _pid_is_running(pid):
223
251
  _clear_pid_record()
224
- print("Removed stale MemTask PID file.")
252
+ print(f"{_yellow('STALE')} Removed old MemTask PID file.")
225
253
  return
226
254
 
227
255
  os.kill(pid, signal.SIGTERM)
@@ -232,42 +260,44 @@ def _stop(_: argparse.Namespace) -> None:
232
260
  time.sleep(0.1)
233
261
 
234
262
  _clear_pid_record()
235
- print("MemTask HTTP server stopped.")
236
- print("For stdio MCP clients, no stop command is needed; the client owns the server process.")
263
+ print(f"{_green('OK')} MemTask stopped")
264
+ print("stdio servers are stopped by the MCP client that launched them.")
237
265
 
238
266
 
239
267
  def _status(_: argparse.Namespace) -> None:
240
268
  record = _read_pid_record()
241
269
  if record is None:
242
- print("MemTask background HTTP server is not running.")
243
- print(f"SQLite state: {get_db_path()}")
244
- print("For MCP client setup, run: memtask install-help")
270
+ print(f"{_yellow('STOPPED')} MemTask is not running")
271
+ print(f" Data: {get_db_path()}")
272
+ print()
273
+ print("Start it with:")
274
+ print(" memtask start")
245
275
  return
246
276
 
247
277
  pid = int(record.get("pid", 0))
248
278
  if not _pid_is_running(pid):
249
279
  _clear_pid_record()
250
- print("MemTask background HTTP server is not running. Removed stale PID file.")
251
- print(f"SQLite state: {get_db_path()}")
280
+ print(f"{_yellow('STALE')} MemTask was not running; removed old PID file.")
281
+ print(f" Data: {get_db_path()}")
252
282
  return
253
283
 
254
- print("MemTask background HTTP server is running.")
255
- print(f"PID: {pid}")
256
- print(f"URL: {record.get('url')}")
257
- print(f"SQLite state: {record.get('db_path', get_db_path())}")
258
- print(f"Log file: {record.get('log_file', _log_path())}")
284
+ print(f"{_green('RUNNING')} MemTask")
285
+ print(f" PID: {pid}")
286
+ print(f" URL: {record.get('url')}")
287
+ print(f" Data: {record.get('db_path', get_db_path())}")
288
+ print(f" Logs: {record.get('log_file', _log_path())}")
259
289
 
260
290
 
261
291
  def build_parser() -> argparse.ArgumentParser:
262
- parser = argparse.ArgumentParser(prog="memtask")
263
- subcommands = parser.add_subparsers(dest="command", required=True)
292
+ parser = argparse.ArgumentParser(prog="memtask", add_help=False)
293
+ subcommands = parser.add_subparsers(dest="command")
264
294
 
265
295
  start = subcommands.add_parser("start", help="Start the MemTask MCP server")
266
296
  start.add_argument(
267
297
  "--transport",
268
298
  choices=("stdio", "http", "streamable-http"),
269
- default="stdio",
270
- help="Use stdio in the foreground or HTTP as a background server.",
299
+ default="http",
300
+ help="Use HTTP as a background server, or stdio when launched by an MCP client.",
271
301
  )
272
302
  start.add_argument("--host", default=DEFAULT_HOST)
273
303
  start.add_argument("--port", type=int, default=DEFAULT_PORT)
@@ -280,20 +310,30 @@ def build_parser() -> argparse.ArgumentParser:
280
310
  status = subcommands.add_parser("status", help="Show background server status")
281
311
  status.set_defaults(handler=_status)
282
312
 
283
- install_help = subcommands.add_parser(
284
- "install-help",
285
- help="Print MCP client configuration examples",
286
- )
313
+ install = subcommands.add_parser("install", help="Show Codex MCP install commands")
314
+ install.add_argument("--host", default=DEFAULT_HOST)
315
+ install.add_argument("--port", type=int, default=DEFAULT_PORT)
316
+ install.set_defaults(handler=lambda args: _print_install(host=args.host, port=args.port))
317
+
318
+ install_help = subcommands.add_parser("install-help", help=argparse.SUPPRESS)
287
319
  install_help.add_argument("--host", default=DEFAULT_HOST)
288
320
  install_help.add_argument("--port", type=int, default=DEFAULT_PORT)
289
- install_help.set_defaults(
290
- handler=lambda args: _print_install_help(host=args.host, port=args.port)
291
- )
321
+ install_help.set_defaults(handler=lambda args: _print_install(host=args.host, port=args.port))
292
322
 
293
323
  return parser
294
324
 
295
325
 
296
326
  def main(argv: list[str] | None = None) -> None:
327
+ argv = sys.argv[1:] if argv is None else argv
328
+ if not argv or argv in (["-h"], ["--help"]):
329
+ _print_main_help()
330
+ return
331
+
332
+ if argv[0] not in COMMANDS:
333
+ print(f"Unknown command: {argv[0]}", file=sys.stderr)
334
+ print("Run `memtask --help` for usage.", file=sys.stderr)
335
+ raise SystemExit(2)
336
+
297
337
  parser = build_parser()
298
338
  args = parser.parse_args(argv)
299
339
  args.handler(args)
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import json
4
4
  import os
5
5
  import sqlite3
6
+ import tempfile
6
7
  from pathlib import Path
7
8
 
8
9
 
@@ -12,7 +13,17 @@ MEMTASK_DB_PATH_ENV = "MEMTASK_DB_PATH"
12
13
 
13
14
 
14
15
  def default_home() -> Path:
15
- return Path(os.environ.get(MEMTASK_HOME_ENV, Path.home() / ".memtask")).expanduser()
16
+ configured = Path(os.environ.get(MEMTASK_HOME_ENV, Path.home() / ".memtask")).expanduser()
17
+ try:
18
+ configured.mkdir(parents=True, exist_ok=True)
19
+ if os.access(configured, os.W_OK):
20
+ return configured
21
+ except OSError:
22
+ pass
23
+
24
+ fallback = Path(tempfile.gettempdir()) / f"memtask-{os.getuid()}"
25
+ fallback.mkdir(parents=True, exist_ok=True)
26
+ return fallback
16
27
 
17
28
 
18
29
  def resolve_default_db_path() -> Path:
@@ -0,0 +1,89 @@
1
+ Metadata-Version: 2.4
2
+ Name: memtask
3
+ Version: 0.0.2
4
+ Summary: A local MCP server for durable agent task state and lightweight memory.
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: mcp
8
+ Provides-Extra: test
9
+ Requires-Dist: pytest>=8; extra == "test"
10
+
11
+ <p align="center">
12
+ <img src="https://raw.githubusercontent.com/PlatinumCD/memtask-mcp/master/docs/assets/memtask-logo.png" alt="MemTask logo" width="220">
13
+ </p>
14
+
15
+ <h1 align="center">MemTask</h1>
16
+
17
+ MemTask gives MCP agents a local task list and lightweight memory, backed by SQLite.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pip install MemTask
23
+ ```
24
+
25
+ ## Start
26
+
27
+ ```bash
28
+ memtask start
29
+ ```
30
+
31
+ MemTask starts a local MCP server at:
32
+
33
+ ```text
34
+ http://127.0.0.1:8000/mcp
35
+ ```
36
+
37
+ ## Add It To Codex
38
+
39
+ ```bash
40
+ memtask install
41
+ ```
42
+
43
+ That prints the exact `codex mcp add ...` commands for stdio and HTTP:
44
+
45
+ ```text
46
+ Codex
47
+
48
+ stdio server
49
+ codex mcp add memtask -- memtask start --transport stdio
50
+
51
+ HTTP server
52
+ memtask start
53
+ codex mcp add memtask --url http://127.0.0.1:8000/mcp
54
+ ```
55
+
56
+ ## Use It
57
+
58
+ Once connected, your agent gets tools for:
59
+
60
+ - tasks: add, list, focus, complete, remove, and track dependencies
61
+ - memory: remember, recall, update, and delete scoped context
62
+
63
+ ## Common Commands
64
+
65
+ ```bash
66
+ memtask status
67
+ memtask stop
68
+ memtask start --transport stdio
69
+ ```
70
+
71
+ ## What It Is
72
+
73
+ MemTask is a local MCP server for developer-built agents that need durable task state and persistent context. It gives an agent a small workspace for tracking active work, dependency order, completed tasks, and scoped memories across sessions.
74
+
75
+ State is stored locally. In this repo, MemTask uses `data/tasks.sqlite`. When installed outside this repo, it uses `~/.memtask/tasks.sqlite` by default. Set `MEMTASK_DB_PATH` to choose a specific SQLite path.
76
+
77
+ ## Development
78
+
79
+ Run tests:
80
+
81
+ ```bash
82
+ python -m pytest
83
+ ```
84
+
85
+ Compile-check the package:
86
+
87
+ ```bash
88
+ python -m py_compile src/memtask/*.py tests/*.py
89
+ ```
@@ -5,15 +5,53 @@ import json
5
5
  from memtask import cli
6
6
 
7
7
 
8
- def test_install_help_prints_stdio_and_http_config(capsys) -> None:
9
- cli.main(["install-help", "--host", "127.0.0.1", "--port", "9000"])
8
+ def test_no_args_prints_clean_help(capsys) -> None:
9
+ cli.main([])
10
10
 
11
11
  output = capsys.readouterr().out
12
12
 
13
- assert "MemTask MCP configuration examples" in output
14
- assert '"command": "memtask"' in output
15
- assert '"args": [' in output
16
- assert "http://127.0.0.1:9000/mcp" in output
13
+ assert "Usage" in output
14
+ assert "memtask start" in output
15
+ assert "argparse" not in output
16
+
17
+
18
+ def test_install_prints_codex_commands_when_not_running(monkeypatch, tmp_path, capsys) -> None:
19
+ monkeypatch.setenv("MEMTASK_HOME", str(tmp_path))
20
+
21
+ cli.main(["install", "--host", "127.0.0.1", "--port", "9000"])
22
+
23
+ output = capsys.readouterr().out
24
+
25
+ assert output == (
26
+ "Codex\n"
27
+ "\n"
28
+ "stdio server\n"
29
+ " codex mcp add memtask -- memtask start --transport stdio\n"
30
+ "\n"
31
+ "HTTP server\n"
32
+ " memtask start\n"
33
+ " codex mcp add memtask --url http://127.0.0.1:9000/mcp\n"
34
+ )
35
+
36
+
37
+ def test_install_uses_running_http_url(monkeypatch, tmp_path, capsys) -> None:
38
+ monkeypatch.setenv("MEMTASK_HOME", str(tmp_path))
39
+ (tmp_path / "memtask.pid").write_text(
40
+ json.dumps(
41
+ {
42
+ "pid": 12345,
43
+ "url": "http://127.0.0.1:9100/mcp",
44
+ }
45
+ )
46
+ )
47
+ monkeypatch.setattr(cli, "_pid_is_running", lambda pid: True)
48
+
49
+ cli.main(["install"])
50
+
51
+ output = capsys.readouterr().out
52
+
53
+ assert "memtask start\n" not in output
54
+ assert "codex mcp add memtask --url http://127.0.0.1:9100/mcp" in output
17
55
 
18
56
 
19
57
  def test_start_stdio_prints_guidance_to_stderr(monkeypatch, capsys) -> None:
@@ -29,13 +67,13 @@ def test_start_stdio_prints_guidance_to_stderr(monkeypatch, capsys) -> None:
29
67
  captured = capsys.readouterr()
30
68
 
31
69
  assert captured.out == ""
32
- assert "MemTask starting over stdio." in captured.err
33
- assert '"command": "memtask"' in captured.err
70
+ assert "MemTask starting over stdio" in captured.err
71
+ assert "mcpServers" not in captured.err
34
72
  assert called["transport"] == "stdio"
35
73
  assert called["server_name"] == "TestTask"
36
74
 
37
75
 
38
- def test_start_http_spawns_background_process(monkeypatch, tmp_path, capsys) -> None:
76
+ def test_start_defaults_to_background_http(monkeypatch, tmp_path, capsys) -> None:
39
77
  monkeypatch.setenv("MEMTASK_HOME", str(tmp_path))
40
78
 
41
79
  captured_command = {}
@@ -54,12 +92,12 @@ def test_start_http_spawns_background_process(monkeypatch, tmp_path, capsys) ->
54
92
  monkeypatch.setattr(cli.subprocess, "Popen", fake_popen)
55
93
  monkeypatch.setattr(cli.time, "sleep", lambda _: None)
56
94
 
57
- cli.main(["start", "--transport", "http", "--host", "127.0.0.1", "--port", "9001"])
95
+ cli.main(["start", "--host", "127.0.0.1", "--port", "9001"])
58
96
 
59
97
  output = capsys.readouterr().out
60
98
  pid_record = json.loads((tmp_path / "memtask.pid").read_text())
61
99
 
62
- assert "MemTask HTTP server started." in output
100
+ assert "OK MemTask started" in output
63
101
  assert "http://127.0.0.1:9001/mcp" in output
64
102
  assert pid_record["pid"] == 12345
65
103
  assert pid_record["transport"] == "streamable-http"
@@ -77,8 +115,9 @@ def test_stop_without_pid_explains_stdio(monkeypatch, tmp_path, capsys) -> None:
77
115
 
78
116
  output = capsys.readouterr().out
79
117
 
80
- assert "No MemTask background server is registered." in output
81
- assert "stdio mode" in output
118
+ assert "MemTask background server is not registered." not in output
119
+ assert "not running" in output
120
+ assert "stdio" in output
82
121
 
83
122
 
84
123
  def test_status_without_pid_points_to_install_help(monkeypatch, tmp_path, capsys) -> None:
@@ -88,5 +127,5 @@ def test_status_without_pid_points_to_install_help(monkeypatch, tmp_path, capsys
88
127
 
89
128
  output = capsys.readouterr().out
90
129
 
91
- assert "not running" in output
92
- assert "memtask install-help" in output
130
+ assert "MemTask is not running" in output
131
+ assert "memtask start" in output
memtask-0.0.1/PKG-INFO DELETED
@@ -1,104 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: memtask
3
- Version: 0.0.1
4
- Summary: A local MCP server for durable agent task state and lightweight memory.
5
- Requires-Python: >=3.10
6
- Description-Content-Type: text/markdown
7
- Requires-Dist: mcp
8
- Provides-Extra: test
9
- Requires-Dist: pytest>=8; extra == "test"
10
-
11
- <p align="center">
12
- <img src="docs/assets/memtask-logo.png" alt="MemTask logo" width="220">
13
- </p>
14
-
15
- <h1 align="center">MemTask</h1>
16
-
17
- MemTask is a local MCP server for developer-built agents that need durable task state and lightweight memory. It combines task planning, dependency tracking, active work selection, completion history, and scoped memories in a small SQLite-backed service. The goal is to give agents a structured place to manage agency: what to do next, what depends on what, and what context should persist across sessions.
18
-
19
- ## What It Provides
20
-
21
- MemTask exposes two local primitives over MCP:
22
-
23
- - Tasks: pending work, stable task references, parent/child dependency edges, active task selection, and completed task state.
24
- - Memories: scoped pieces of context with confidence scores, optional parent memory relationships, tags, and task-memory references.
25
-
26
- The server is intentionally local-first. State lives in SQLite, the tool surface is small, and the manager layer can be tested directly without running an MCP transport.
27
-
28
- ## Quickstart
29
-
30
- Install MemTask:
31
-
32
- ```bash
33
- pip install MemTask
34
- ```
35
-
36
- Then ask MemTask for the MCP config to add to your agent:
37
-
38
- ```bash
39
- memtask install-help
40
- ```
41
-
42
- Most MCP clients should launch MemTask over stdio:
43
-
44
- ```bash
45
- memtask start --transport stdio
46
- ```
47
-
48
- If your client connects to a running HTTP server instead, start it in the background:
49
-
50
- ```bash
51
- memtask start --transport http --host 127.0.0.1 --port 8000
52
- ```
53
-
54
- For local development from this repo:
55
-
56
- ```bash
57
- PYTHONPATH=src python -m memtask start --transport stdio
58
- ```
59
-
60
- Useful HTTP commands: `memtask status` and `memtask stop`.
61
-
62
- ## Storage
63
-
64
- Runtime state in this repo is stored in `data/tasks.sqlite`.
65
-
66
- When installed outside this repo, MemTask uses `~/.memtask/tasks.sqlite` by default. Set `MEMTASK_DB_PATH` to choose a specific SQLite path.
67
-
68
- The server creates the required SQLite tables on startup using `CREATE TABLE IF NOT EXISTS`. There is no migration framework.
69
-
70
- ## Tools
71
-
72
- Task tools:
73
-
74
- - `list_tasks`
75
- - `get_task`
76
- - `add_task`
77
- - `add_batch_tasks`
78
- - `complete_task`
79
- - `remove_task`
80
- - `remove_all_tasks`
81
- - `current_tasks`
82
- - `set_current_task`
83
-
84
- Memory tools:
85
-
86
- - `remember`
87
- - `recall`
88
- - `get_memory`
89
- - `update_memory`
90
- - `delete_memory`
91
-
92
- ## Development
93
-
94
- Run tests:
95
-
96
- ```bash
97
- python -m pytest
98
- ```
99
-
100
- Compile-check the package:
101
-
102
- ```bash
103
- python -m py_compile src/memtask/*.py tests/*.py
104
- ```
memtask-0.0.1/README.md DELETED
@@ -1,94 +0,0 @@
1
- <p align="center">
2
- <img src="docs/assets/memtask-logo.png" alt="MemTask logo" width="220">
3
- </p>
4
-
5
- <h1 align="center">MemTask</h1>
6
-
7
- MemTask is a local MCP server for developer-built agents that need durable task state and lightweight memory. It combines task planning, dependency tracking, active work selection, completion history, and scoped memories in a small SQLite-backed service. The goal is to give agents a structured place to manage agency: what to do next, what depends on what, and what context should persist across sessions.
8
-
9
- ## What It Provides
10
-
11
- MemTask exposes two local primitives over MCP:
12
-
13
- - Tasks: pending work, stable task references, parent/child dependency edges, active task selection, and completed task state.
14
- - Memories: scoped pieces of context with confidence scores, optional parent memory relationships, tags, and task-memory references.
15
-
16
- The server is intentionally local-first. State lives in SQLite, the tool surface is small, and the manager layer can be tested directly without running an MCP transport.
17
-
18
- ## Quickstart
19
-
20
- Install MemTask:
21
-
22
- ```bash
23
- pip install MemTask
24
- ```
25
-
26
- Then ask MemTask for the MCP config to add to your agent:
27
-
28
- ```bash
29
- memtask install-help
30
- ```
31
-
32
- Most MCP clients should launch MemTask over stdio:
33
-
34
- ```bash
35
- memtask start --transport stdio
36
- ```
37
-
38
- If your client connects to a running HTTP server instead, start it in the background:
39
-
40
- ```bash
41
- memtask start --transport http --host 127.0.0.1 --port 8000
42
- ```
43
-
44
- For local development from this repo:
45
-
46
- ```bash
47
- PYTHONPATH=src python -m memtask start --transport stdio
48
- ```
49
-
50
- Useful HTTP commands: `memtask status` and `memtask stop`.
51
-
52
- ## Storage
53
-
54
- Runtime state in this repo is stored in `data/tasks.sqlite`.
55
-
56
- When installed outside this repo, MemTask uses `~/.memtask/tasks.sqlite` by default. Set `MEMTASK_DB_PATH` to choose a specific SQLite path.
57
-
58
- The server creates the required SQLite tables on startup using `CREATE TABLE IF NOT EXISTS`. There is no migration framework.
59
-
60
- ## Tools
61
-
62
- Task tools:
63
-
64
- - `list_tasks`
65
- - `get_task`
66
- - `add_task`
67
- - `add_batch_tasks`
68
- - `complete_task`
69
- - `remove_task`
70
- - `remove_all_tasks`
71
- - `current_tasks`
72
- - `set_current_task`
73
-
74
- Memory tools:
75
-
76
- - `remember`
77
- - `recall`
78
- - `get_memory`
79
- - `update_memory`
80
- - `delete_memory`
81
-
82
- ## Development
83
-
84
- Run tests:
85
-
86
- ```bash
87
- python -m pytest
88
- ```
89
-
90
- Compile-check the package:
91
-
92
- ```bash
93
- python -m py_compile src/memtask/*.py tests/*.py
94
- ```
@@ -1,104 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: memtask
3
- Version: 0.0.1
4
- Summary: A local MCP server for durable agent task state and lightweight memory.
5
- Requires-Python: >=3.10
6
- Description-Content-Type: text/markdown
7
- Requires-Dist: mcp
8
- Provides-Extra: test
9
- Requires-Dist: pytest>=8; extra == "test"
10
-
11
- <p align="center">
12
- <img src="docs/assets/memtask-logo.png" alt="MemTask logo" width="220">
13
- </p>
14
-
15
- <h1 align="center">MemTask</h1>
16
-
17
- MemTask is a local MCP server for developer-built agents that need durable task state and lightweight memory. It combines task planning, dependency tracking, active work selection, completion history, and scoped memories in a small SQLite-backed service. The goal is to give agents a structured place to manage agency: what to do next, what depends on what, and what context should persist across sessions.
18
-
19
- ## What It Provides
20
-
21
- MemTask exposes two local primitives over MCP:
22
-
23
- - Tasks: pending work, stable task references, parent/child dependency edges, active task selection, and completed task state.
24
- - Memories: scoped pieces of context with confidence scores, optional parent memory relationships, tags, and task-memory references.
25
-
26
- The server is intentionally local-first. State lives in SQLite, the tool surface is small, and the manager layer can be tested directly without running an MCP transport.
27
-
28
- ## Quickstart
29
-
30
- Install MemTask:
31
-
32
- ```bash
33
- pip install MemTask
34
- ```
35
-
36
- Then ask MemTask for the MCP config to add to your agent:
37
-
38
- ```bash
39
- memtask install-help
40
- ```
41
-
42
- Most MCP clients should launch MemTask over stdio:
43
-
44
- ```bash
45
- memtask start --transport stdio
46
- ```
47
-
48
- If your client connects to a running HTTP server instead, start it in the background:
49
-
50
- ```bash
51
- memtask start --transport http --host 127.0.0.1 --port 8000
52
- ```
53
-
54
- For local development from this repo:
55
-
56
- ```bash
57
- PYTHONPATH=src python -m memtask start --transport stdio
58
- ```
59
-
60
- Useful HTTP commands: `memtask status` and `memtask stop`.
61
-
62
- ## Storage
63
-
64
- Runtime state in this repo is stored in `data/tasks.sqlite`.
65
-
66
- When installed outside this repo, MemTask uses `~/.memtask/tasks.sqlite` by default. Set `MEMTASK_DB_PATH` to choose a specific SQLite path.
67
-
68
- The server creates the required SQLite tables on startup using `CREATE TABLE IF NOT EXISTS`. There is no migration framework.
69
-
70
- ## Tools
71
-
72
- Task tools:
73
-
74
- - `list_tasks`
75
- - `get_task`
76
- - `add_task`
77
- - `add_batch_tasks`
78
- - `complete_task`
79
- - `remove_task`
80
- - `remove_all_tasks`
81
- - `current_tasks`
82
- - `set_current_task`
83
-
84
- Memory tools:
85
-
86
- - `remember`
87
- - `recall`
88
- - `get_memory`
89
- - `update_memory`
90
- - `delete_memory`
91
-
92
- ## Development
93
-
94
- Run tests:
95
-
96
- ```bash
97
- python -m pytest
98
- ```
99
-
100
- Compile-check the package:
101
-
102
- ```bash
103
- python -m py_compile src/memtask/*.py tests/*.py
104
- ```
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes