kyp-mem 0.2.0 → 0.2.2

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 CHANGED
@@ -1,21 +1,27 @@
1
1
  # KYP-MEM — Know Your Project Memory
2
2
 
3
- **Headless Obsidian for AI agents.** A markdown knowledge base with wikilinks, backlinks, tags, related notes, and a neon web UI — all powered by an MCP server so Claude (or any AI) can read and write your project knowledge directly.
3
+ **Headless knowledge base for AI agents.** Markdown notes with wikilinks, backlinks, tags, related notes, and a neon web UI — all powered by an MCP server so Claude (or any AI) can read and write your project knowledge directly.
4
4
 
5
5
  ## Install
6
6
 
7
7
  ```bash
8
- pip install kyp-mem
8
+ npx -y kyp-mem
9
+ ```
10
+
11
+ Or install the command globally:
12
+
13
+ ```bash
14
+ npm install -g kyp-mem
9
15
  ```
10
16
 
11
17
  ## Setup (3 commands)
12
18
 
13
19
  ```bash
14
20
  # 1. Choose where your vault (knowledge base) lives
15
- kyp-mem init
21
+ npx -y kyp-mem init
16
22
 
17
23
  # 2. Connect to Claude Code — auto-configures MCP
18
- kyp-mem setup-claude
24
+ npx -y kyp-mem setup-claude
19
25
 
20
26
  # 3. Restart Claude Code — done!
21
27
  # kyp-mem now runs headlessly every session.
@@ -27,10 +33,10 @@ That's it. Claude now has `kyp_read`, `kyp_write`, `kyp_search`, and 7 other too
27
33
  ## Optional: Web UI
28
34
 
29
35
  ```bash
30
- kyp-mem ui
36
+ npx -y kyp-mem ui
31
37
  ```
32
38
 
33
- Opens an Obsidian-like interface at `localhost:3333` with:
39
+ Opens a rich interface at `localhost:3333` with:
34
40
  - Collapsible folder tree
35
41
  - Rendered markdown with syntax highlighting
36
42
  - Clickable `[[wikilinks]]`
@@ -50,7 +56,7 @@ Opens an Obsidian-like interface at `localhost:3333` with:
50
56
  ```
51
57
 
52
58
  - **Headless by default** — runs as an MCP server (stdio), no GUI needed
53
- - **Markdown files on disk** — same format as Obsidian, no database
59
+ - **Markdown files on disk** — plain `.md` files with YAML frontmatter, no database
54
60
  - **In-memory index** — links, backlinks, tags, search, similarity scoring
55
61
  - **Web UI optional** — `kyp-mem ui` when you want to browse visually
56
62
 
@@ -59,7 +65,7 @@ Opens an Obsidian-like interface at `localhost:3333` with:
59
65
  | Command | What it does |
60
66
  |---------|-------------|
61
67
  | `kyp-mem init` | First-time setup — choose vault location |
62
- | `kyp-mem setup-claude` | Auto-configure Claude Code MCP settings |
68
+ | `kyp-mem setup-claude` | Register the MCP server with Claude Code for this project |
63
69
  | `kyp-mem setup-claude --global` | Configure globally (all projects) |
64
70
  | `kyp-mem serve` | Start MCP server (used by Claude, not you) |
65
71
  | `kyp-mem ui` | Open web UI at localhost:3333 |
@@ -83,7 +89,7 @@ Opens an Obsidian-like interface at `localhost:3333` with:
83
89
 
84
90
  ## Note Format
85
91
 
86
- Standard markdown with YAML frontmatter — same as Obsidian:
92
+ Standard markdown with YAML frontmatter:
87
93
 
88
94
  ```markdown
89
95
  ---
@@ -104,21 +110,11 @@ Settings are defined in `HedgeConfig`. See [[Risk Management]] for safety checks
104
110
 
105
111
  If you prefer to configure manually instead of using `setup-claude`:
106
112
 
107
- ```json
108
- {
109
- "mcpServers": {
110
- "kyp-mem": {
111
- "command": "kyp-mem",
112
- "args": ["serve"],
113
- "env": {
114
- "KYP_VAULT": "~/.kyp-mem/vault"
115
- }
116
- }
117
- }
118
- }
113
+ ```bash
114
+ claude mcp add -s local -e KYP_VAULT="$HOME/.kyp-mem/vault" kyp-mem -- npx -y kyp-mem serve
119
115
  ```
120
116
 
121
- Add to `~/.claude/settings.json` (global) or `.claude/settings.json` (per-project).
117
+ Use `-s user` instead of `-s local` to make it available in all projects.
122
118
 
123
119
  ## Architecture
124
120
 
@@ -134,12 +130,10 @@ Add to `~/.claude/settings.json` (global) or `.claude/settings.json` (per-projec
134
130
  └── ...
135
131
  ```
136
132
 
137
- ## Publishing to PyPI
133
+ ## Publishing to npm
138
134
 
139
135
  ```bash
140
- pip install build twine
141
- python3 -m build
142
- twine upload dist/*
136
+ npm publish
143
137
  ```
144
138
 
145
139
  ## License
package/bin/cli.mjs CHANGED
@@ -1,33 +1,68 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { execFileSync, execSync } from "child_process";
3
+ import { spawnSync } from "child_process";
4
+ import { delimiter, dirname, resolve } from "path";
5
+ import { fileURLToPath } from "url";
4
6
 
5
7
  const args = process.argv.slice(2);
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ const root = resolve(__dirname, "..");
6
10
 
7
- function tryRun(cmd, cmdArgs) {
8
- try {
9
- execFileSync(cmd, cmdArgs, { stdio: "inherit" });
10
- return true;
11
- } catch {
12
- return false;
11
+ const env = {
12
+ ...process.env,
13
+ PYTHONPATH: process.env.PYTHONPATH
14
+ ? `${root}${delimiter}${process.env.PYTHONPATH}`
15
+ : root,
16
+ };
17
+
18
+ function run(command, cmdArgs, stdio = "ignore") {
19
+ return spawnSync(command, cmdArgs, { stdio, env });
20
+ }
21
+
22
+ function pythonCandidates() {
23
+ if (process.env.KYP_MEM_PYTHON) {
24
+ return [[process.env.KYP_MEM_PYTHON, []]];
25
+ }
26
+
27
+ const candidates = [
28
+ ["python3", []],
29
+ ["python", []],
30
+ ];
31
+
32
+ if (process.platform === "win32") {
33
+ candidates.unshift(["py", ["-3"]]);
34
+ }
35
+
36
+ return candidates;
37
+ }
38
+
39
+ function findPython() {
40
+ for (const [command, prefixArgs] of pythonCandidates()) {
41
+ const result = run(command, [...prefixArgs, "--version"]);
42
+ if (result.status === 0) {
43
+ return [command, prefixArgs];
44
+ }
13
45
  }
46
+
47
+ return null;
14
48
  }
15
49
 
16
- // Try the installed kyp-mem binary first
17
- if (tryRun("kyp-mem", args)) process.exit(0);
50
+ const python = findPython();
18
51
 
19
- // Fallback: python3 -m kyp_mem.cli
20
- if (tryRun("python3", ["-m", "kyp_mem.cli", ...args])) process.exit(0);
52
+ if (python) {
53
+ const [command, prefixArgs] = python;
54
+ const result = run(command, [...prefixArgs, "-m", "kyp_mem.cli", ...args], "inherit");
21
55
 
22
- // Fallback: python -m kyp_mem.cli
23
- if (tryRun("python", ["-m", "kyp_mem.cli", ...args])) process.exit(0);
56
+ if (result.signal) {
57
+ process.kill(process.pid, result.signal);
58
+ }
59
+
60
+ process.exit(result.status ?? 1);
61
+ }
24
62
 
25
63
  console.error("");
26
- console.error(" \x1b[31mError:\x1b[0m kyp-mem Python package not found.");
64
+ console.error(" \x1b[31mError:\x1b[0m Python 3 was not found.");
27
65
  console.error("");
28
- console.error(" Install it:");
29
- console.error(" \x1b[33mpip install kyp-mem\x1b[0m");
30
- console.error(" Or from source:");
31
- console.error(" \x1b[33mpip install git+https://github.com/Adhithya-Karthikeyan/KYP-MEM.git\x1b[0m");
66
+ console.error(" Install Python 3.10+ and rerun this command.");
32
67
  console.error("");
33
68
  process.exit(1);
package/bin/install.mjs CHANGED
@@ -1,36 +1,77 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { execSync } from "child_process";
3
+ import { spawnSync } from "child_process";
4
4
  import { fileURLToPath } from "url";
5
5
  import { dirname, resolve } from "path";
6
6
 
7
7
  const __dirname = dirname(fileURLToPath(import.meta.url));
8
8
  const root = resolve(__dirname, "..");
9
9
 
10
- function tryInstall(cmd) {
11
- try {
12
- execSync(cmd, { cwd: root, stdio: "pipe" });
13
- return true;
14
- } catch {
15
- return false;
10
+ function run(command, args, options = {}) {
11
+ return spawnSync(command, args, {
12
+ cwd: root,
13
+ stdio: options.stdio ?? "ignore",
14
+ env: {
15
+ ...process.env,
16
+ PIP_DISABLE_PIP_VERSION_CHECK: "1",
17
+ },
18
+ });
19
+ }
20
+
21
+ function pythonCandidates() {
22
+ if (process.env.KYP_MEM_PYTHON) {
23
+ return [[process.env.KYP_MEM_PYTHON, []]];
24
+ }
25
+
26
+ const candidates = [
27
+ ["python3", []],
28
+ ["python", []],
29
+ ];
30
+
31
+ if (process.platform === "win32") {
32
+ candidates.unshift(["py", ["-3"]]);
16
33
  }
34
+
35
+ return candidates;
36
+ }
37
+
38
+ function findPython() {
39
+ for (const [command, prefixArgs] of pythonCandidates()) {
40
+ const result = run(command, [...prefixArgs, "--version"]);
41
+ if (result.status === 0) {
42
+ return [command, prefixArgs];
43
+ }
44
+ }
45
+
46
+ return null;
17
47
  }
18
48
 
19
- // Check if already installed
20
- try {
21
- execSync("kyp-mem --help", { stdio: "pipe" });
49
+ if (process.env.KYP_MEM_SKIP_PYTHON_INSTALL === "1") {
22
50
  process.exit(0);
23
- } catch {}
51
+ }
52
+
53
+ const python = findPython();
54
+
55
+ if (!python) {
56
+ console.log(" \x1b[33m!\x1b[0m Python 3 was not found.");
57
+ console.log(" \x1b[33m!\x1b[0m Install Python 3.10+ and run: python3 -m pip install --user .");
58
+ process.exit(0);
59
+ }
60
+
61
+ const [pythonCommand, pythonPrefixArgs] = python;
24
62
 
25
63
  console.log(" Installing kyp-mem Python package...");
26
64
 
27
- if (tryInstall("pip install --user .")) {
28
- console.log(" \x1b[32m✓\x1b[0m kyp-mem installed successfully");
29
- } else if (tryInstall("pip3 install --user .")) {
30
- console.log(" \x1b[32m✓\x1b[0m kyp-mem installed successfully");
31
- } else if (tryInstall("python3 -m pip install --user .")) {
65
+ const result = run(
66
+ pythonCommand,
67
+ [...pythonPrefixArgs, "-m", "pip", "install", "--user", "."],
68
+ { stdio: "inherit" },
69
+ );
70
+
71
+ if (result.status === 0) {
32
72
  console.log(" \x1b[32m✓\x1b[0m kyp-mem installed successfully");
33
73
  } else {
34
- console.log(" \x1b[33m!\x1b[0m Could not auto-install Python package.");
35
- console.log(" \x1b[33m!\x1b[0m Run manually: pip install kyp-mem");
74
+ console.log(" \x1b[33m!\x1b[0m Could not auto-install the Python package.");
75
+ console.log(` \x1b[33m!\x1b[0m Run manually from ${root}:`);
76
+ console.log(" python3 -m pip install --user .");
36
77
  }
@@ -1,3 +1,3 @@
1
- """KYP-MEM — Know Your Project Memory. Headless Obsidian for AI agents."""
1
+ """KYP-MEM — Know Your Project Memory. Headless knowledge base for AI agents."""
2
2
 
3
- __version__ = "0.2.0"
3
+ __version__ = "0.2.1"
package/kyp_mem/cli.py CHANGED
@@ -4,6 +4,7 @@ import os
4
4
  import json
5
5
  import shutil
6
6
  import argparse
7
+ import subprocess
7
8
  from pathlib import Path
8
9
 
9
10
  C = "\033[36m" # cyan
@@ -16,7 +17,7 @@ R = "\033[0m" # reset
16
17
  def main():
17
18
  parser = argparse.ArgumentParser(
18
19
  prog="kyp-mem",
19
- description="KYP-MEM — Know Your Project Memory. Headless Obsidian for AI agents.",
20
+ description="KYP-MEM — Know Your Project Memory. Headless knowledge base for AI agents.",
20
21
  )
21
22
  parser.add_argument("--vault", default=None, help="Override vault path")
22
23
 
@@ -74,7 +75,7 @@ def _run_init():
74
75
  print(f"{C} ██║ ██╗ ██║ ██║ ██║ ╚═╝ ██║███████╗██║ ╚═╝ ██║{R}")
75
76
  print(f"{C} ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝{R}")
76
77
  print()
77
- print(f" {D}Know Your Project — Headless Obsidian for AI agents{R}")
78
+ print(f" {D}Know Your Project — Headless knowledge base for AI agents{R}")
78
79
  print()
79
80
  print(f" {Y}>> First-time setup{R}")
80
81
  print()
@@ -107,20 +108,112 @@ def _run_setup_claude(global_config: bool = False):
107
108
  from .config import get_vault_path
108
109
 
109
110
  vault_path = get_vault_path()
111
+ mcp_command, mcp_args = _get_mcp_command()
112
+ claude_scope = "user" if global_config else "local"
113
+ scope_label = "global user" if global_config else "local project"
114
+
115
+ registered, detail = _register_with_claude_mcp(
116
+ claude_scope,
117
+ mcp_command,
118
+ mcp_args,
119
+ vault_path,
120
+ )
121
+
122
+ print()
123
+ print(f" {C}KYP-MEM{R} — Claude Code Setup")
124
+ print()
125
+ if registered:
126
+ print(f" {G}✓{R} MCP server registered with Claude Code ({scope_label})")
127
+ else:
128
+ settings_path = _write_legacy_claude_settings(global_config, mcp_command, mcp_args, vault_path)
129
+ print(f" {Y}✗{R} Could not register with Claude Code's MCP manager")
130
+ print(f" {D} Reason: {detail}{R}")
131
+ print(f" {Y}!{R} Wrote legacy settings as a fallback")
132
+ print(f" {D} File: {settings_path}{R}")
133
+ print(f" {D} Command: {mcp_command} {' '.join(mcp_args)}{R}")
134
+ print(f" {D} Vault: {vault_path}{R}")
135
+ print()
136
+ print(f" {C}Done!{R} Restart Claude Code and kyp-mem will run automatically.")
137
+ print(f" Claude gets these tools: kyp_list, kyp_read, kyp_write, kyp_delete,")
138
+ print(f" kyp_search, kyp_tags, kyp_related, kyp_recent, kyp_stats")
139
+ print()
140
+ print(f" {D}To open the web UI anytime:{R} {Y}kyp-mem ui{R}")
141
+ print()
142
+
143
+
144
+ def _get_mcp_command() -> tuple[str, list[str]]:
110
145
  kyp_mem_bin = shutil.which("kyp-mem")
146
+ npx_bin = shutil.which("npx")
147
+
148
+ if kyp_mem_bin and "_npx" not in Path(kyp_mem_bin).parts:
149
+ return kyp_mem_bin, ["serve"]
150
+ if npx_bin:
151
+ return npx_bin, ["-y", "kyp-mem", "serve"]
152
+
153
+ print(f" {Y}Warning:{R} 'kyp-mem' not found in PATH.")
154
+ print(f" {D}Make sure you installed with: npm install -g kyp-mem{R}")
155
+ print()
156
+ return "kyp-mem", ["serve"]
157
+
158
+
159
+ def _register_with_claude_mcp(
160
+ scope: str,
161
+ mcp_command: str,
162
+ mcp_args: list[str],
163
+ vault_path: str,
164
+ ) -> tuple[bool, str]:
165
+ claude_bin = shutil.which("claude")
166
+ if not claude_bin:
167
+ return False, "'claude' CLI not found in PATH"
168
+
169
+ server_config = {
170
+ "type": "stdio",
171
+ "command": mcp_command,
172
+ "args": mcp_args,
173
+ "env": {
174
+ "KYP_VAULT": vault_path,
175
+ },
176
+ }
177
+
178
+ # Make setup idempotent when the user reruns it with a new vault or binary.
179
+ subprocess.run(
180
+ [claude_bin, "mcp", "remove", "-s", scope, "kyp-mem"],
181
+ stdout=subprocess.DEVNULL,
182
+ stderr=subprocess.DEVNULL,
183
+ text=True,
184
+ )
185
+
186
+ result = subprocess.run(
187
+ [
188
+ claude_bin,
189
+ "mcp",
190
+ "add-json",
191
+ "-s",
192
+ scope,
193
+ "kyp-mem",
194
+ json.dumps(server_config),
195
+ ],
196
+ capture_output=True,
197
+ text=True,
198
+ )
111
199
 
112
- if not kyp_mem_bin:
113
- print(f" {Y}Warning:{R} 'kyp-mem' not found in PATH.")
114
- print(f" {D}Make sure you installed with: pip install kyp-mem{R}")
115
- print()
116
- kyp_mem_bin = "kyp-mem"
200
+ if result.returncode == 0:
201
+ return True, result.stdout.strip()
117
202
 
203
+ detail = (result.stderr or result.stdout or "unknown error").strip()
204
+ return False, detail
205
+
206
+
207
+ def _write_legacy_claude_settings(
208
+ global_config: bool,
209
+ mcp_command: str,
210
+ mcp_args: list[str],
211
+ vault_path: str,
212
+ ) -> Path:
118
213
  if global_config:
119
214
  settings_path = Path.home() / ".claude" / "settings.json"
120
- scope = "global"
121
215
  else:
122
216
  settings_path = Path.cwd() / ".claude" / "settings.json"
123
- scope = "project"
124
217
 
125
218
  settings_path.parent.mkdir(parents=True, exist_ok=True)
126
219
 
@@ -132,31 +225,16 @@ def _run_setup_claude(global_config: bool = False):
132
225
  settings = {}
133
226
 
134
227
  mcp_servers = settings.setdefault("mcpServers", {})
135
-
136
228
  mcp_servers["kyp-mem"] = {
137
- "command": kyp_mem_bin,
138
- "args": ["serve"],
229
+ "command": mcp_command,
230
+ "args": mcp_args,
139
231
  "env": {
140
232
  "KYP_VAULT": vault_path,
141
233
  },
142
234
  }
143
235
 
144
236
  settings_path.write_text(json.dumps(settings, indent=2) + "\n")
145
-
146
- print()
147
- print(f" {C}KYP-MEM{R} — Claude Code Setup")
148
- print()
149
- print(f" {G}✓{R} MCP server added to {scope} settings")
150
- print(f" {D} File: {settings_path}{R}")
151
- print(f" {D} Command: {kyp_mem_bin} serve{R}")
152
- print(f" {D} Vault: {vault_path}{R}")
153
- print()
154
- print(f" {C}Done!{R} Restart Claude Code and kyp-mem will run automatically.")
155
- print(f" Claude gets these tools: kyp_list, kyp_read, kyp_write, kyp_delete,")
156
- print(f" kyp_search, kyp_tags, kyp_related, kyp_recent, kyp_stats")
157
- print()
158
- print(f" {D}To open the web UI anytime:{R} {Y}kyp-mem ui{R}")
159
- print()
237
+ return settings_path
160
238
 
161
239
 
162
240
  def _run_stats():
@@ -204,22 +282,37 @@ def _run_doctor():
204
282
  else:
205
283
  print(f" {Y}✗{R} Vault not found: {vault_path}")
206
284
 
207
- # Claude Code config
208
- for label, path in [
285
+ # Claude Code MCP registration
286
+ claude_bin = shutil.which("claude")
287
+ if claude_bin:
288
+ result = subprocess.run(
289
+ [claude_bin, "mcp", "get", "kyp-mem"],
290
+ capture_output=True,
291
+ text=True,
292
+ )
293
+ if result.returncode == 0 and "Status: ✓ Connected" in result.stdout:
294
+ print(f" {G}✓{R} Claude Code MCP: kyp-mem connected")
295
+ elif result.returncode == 0:
296
+ print(f" {Y}✗{R} Claude Code MCP: kyp-mem registered but not connected")
297
+ else:
298
+ print(f" {Y}✗{R} Claude Code MCP: kyp-mem not active")
299
+ else:
300
+ print(f" {Y}✗{R} Claude Code CLI not found in PATH")
301
+
302
+ legacy_paths = [
209
303
  ("project", Path.cwd() / ".claude" / "settings.json"),
210
304
  ("global", Path.home() / ".claude" / "settings.json"),
211
- ]:
212
- if path.exists():
213
- try:
214
- s = json.loads(path.read_text())
215
- if "kyp-mem" in s.get("mcpServers", {}):
216
- print(f" {G}✓{R} Claude Code ({label}): kyp-mem configured")
217
- else:
218
- print(f" {D}·{R} Claude Code ({label}): exists but kyp-mem not configured")
219
- except json.JSONDecodeError:
220
- print(f" {Y}✗{R} Claude Code ({label}): invalid JSON")
221
- else:
222
- print(f" {D}·{R} Claude Code ({label}): no settings file")
305
+ ]
306
+ for label, path in legacy_paths:
307
+ if not path.exists():
308
+ continue
309
+ try:
310
+ s = json.loads(path.read_text())
311
+ except json.JSONDecodeError:
312
+ print(f" {Y}{R} Legacy Claude settings ({label}): invalid JSON")
313
+ continue
314
+ if "kyp-mem" in s.get("mcpServers", {}):
315
+ print(f" {D}·{R} Legacy Claude settings ({label}): kyp-mem entry present")
223
316
 
224
317
  # Binary
225
318
  kyp_bin = shutil.which("kyp-mem")
@@ -243,7 +336,7 @@ def _run_doctor():
243
336
  def _print_banner():
244
337
  print()
245
338
  print(f"{C} KYP-MEM{R} — Know Your Project Memory")
246
- print(f" {D}Headless Obsidian for AI agents{R}")
339
+ print(f" {D}Headless knowledge base for AI agents{R}")
247
340
  print()
248
341
 
249
342
 
package/kyp_mem/server.py CHANGED
@@ -7,7 +7,7 @@ from .vault import Vault
7
7
 
8
8
  vault = Vault(get_vault_path())
9
9
 
10
- mcp = FastMCP("kyp-mem", description="Know Your Project — headless knowledge base like Obsidian")
10
+ mcp = FastMCP("kyp-mem")
11
11
 
12
12
 
13
13
  @mcp.tool()
package/kyp_mem/ui.py CHANGED
@@ -1,4 +1,4 @@
1
- """KYP-MEM web UI — Obsidian-like interface for browsing the vault."""
1
+ """KYP-MEM web UI — interactive interface for browsing the vault."""
2
2
 
3
3
  import webbrowser
4
4
  from pathlib import Path
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "kyp-mem",
3
- "version": "0.2.0",
4
- "description": "Know Your Project — Headless Obsidian for AI agents. MCP-powered knowledge base with neon web UI.",
3
+ "version": "0.2.2",
4
+ "description": "Know Your Project — Headless knowledge base for AI agents. MCP-powered with wikilinks, backlinks, and neon web UI.",
5
5
  "bin": {
6
- "kyp-mem": "./bin/cli.mjs"
6
+ "kyp-mem": "bin/cli.mjs"
7
7
  },
8
8
  "files": [
9
9
  "bin/",
10
- "kyp_mem/",
10
+ "kyp_mem/*.py",
11
+ "kyp_mem/static/",
11
12
  "pyproject.toml",
12
13
  "README.md",
13
14
  "LICENSE"
@@ -17,7 +18,7 @@
17
18
  },
18
19
  "keywords": [
19
20
  "knowledge-base",
20
- "obsidian",
21
+ "markdown",
21
22
  "ai",
22
23
  "mcp",
23
24
  "claude",
@@ -29,7 +30,7 @@
29
30
  "license": "MIT",
30
31
  "repository": {
31
32
  "type": "git",
32
- "url": "https://github.com/Adhithya-Karthikeyan/KYP-MEM.git"
33
+ "url": "git+https://github.com/Adhithya-Karthikeyan/KYP-MEM.git"
33
34
  },
34
35
  "homepage": "https://github.com/Adhithya-Karthikeyan/KYP-MEM"
35
36
  }
package/pyproject.toml CHANGED
@@ -4,15 +4,15 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "kyp-mem"
7
- version = "0.2.0"
8
- description = "Know Your Project — Headless Obsidian for AI agents. MCP-powered knowledge base with neon web UI."
7
+ version = "0.2.2"
8
+ description = "Know Your Project — Headless knowledge base for AI agents. MCP-powered with wikilinks, backlinks, and neon web UI."
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
11
11
  requires-python = ">=3.10"
12
12
  authors = [
13
- {name = "KDB AI Agency", email = "dfreakhitman@gmail.com"}
13
+ {name = "KDB AI Agency", email = "skadhithya95@gmail.com"}
14
14
  ]
15
- keywords = ["knowledge-base", "obsidian", "ai", "mcp", "notes", "wiki", "second-brain"]
15
+ keywords = ["knowledge-base", "markdown", "ai", "mcp", "notes", "wiki", "second-brain"]
16
16
  classifiers = [
17
17
  "Development Status :: 3 - Alpha",
18
18
  "Intended Audience :: Developers",