taru-mcp 0.1.4 → 0.1.6

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,32 @@
1
+ #!/bin/bash
2
+ # Stop hook: If WebSearch was used but store_document was not, block and remind.
3
+
4
+ INPUT=$(cat)
5
+ TRANSCRIPT=$(echo "$INPUT" | jq -r '.transcript_path')
6
+
7
+ if [ -z "$TRANSCRIPT" ] || [ ! -f "$TRANSCRIPT" ]; then
8
+ exit 0
9
+ fi
10
+
11
+ # Check if any web search/fetch was done
12
+ HAS_WEB=$(grep -c '"WebSearch"\|"WebFetch"' "$TRANSCRIPT" 2>/dev/null || echo "0")
13
+
14
+ if [ "$HAS_WEB" -eq 0 ]; then
15
+ exit 0
16
+ fi
17
+
18
+ # Check if store_document was called
19
+ HAS_STORE=$(grep -c 'store_document' "$TRANSCRIPT" 2>/dev/null || echo "0")
20
+
21
+ if [ "$HAS_STORE" -gt 0 ]; then
22
+ exit 0
23
+ fi
24
+
25
+ # Web search was done but nothing stored
26
+ cat <<'EOF'
27
+ {
28
+ "decision": "block",
29
+ "reason": "You performed web searches but did not store the findings. Use store_document to save the key information you found to the taru knowledge graph before finishing."
30
+ }
31
+ EOF
32
+ exit 0
@@ -0,0 +1,25 @@
1
+ #!/bin/bash
2
+ # PreToolUse hook: Before WebSearch, check if search_graph was already called.
3
+ # If not, block and tell Claude to search taru first.
4
+
5
+ INPUT=$(cat)
6
+ TRANSCRIPT=$(echo "$INPUT" | jq -r '.transcript_path')
7
+
8
+ if [ -z "$TRANSCRIPT" ] || [ ! -f "$TRANSCRIPT" ]; then
9
+ exit 0
10
+ fi
11
+
12
+ # Check if search_graph was already called in this conversation
13
+ if grep -q 'store_document\|search_graph' "$TRANSCRIPT" 2>/dev/null; then
14
+ # Already searched taru, allow web search
15
+ exit 0
16
+ fi
17
+
18
+ # Block: tell Claude to search taru first
19
+ cat <<'EOF'
20
+ {
21
+ "decision": "block",
22
+ "reason": "Search the taru knowledge graph first (search_graph) before using web search. The answer might already be stored."
23
+ }
24
+ EOF
25
+ exit 0
package/README.md CHANGED
@@ -6,18 +6,86 @@ Zero dependencies. Pure Node.js. Works with any MCP client.
6
6
 
7
7
  ## Quick Setup
8
8
 
9
+ ### macOS / Linux
10
+
9
11
  ```bash
10
12
  curl -fsSL https://raw.githubusercontent.com/arupa-inc/taru-mcp/main/setup.sh | bash
11
13
  ```
12
14
 
15
+ ### Windows (PowerShell)
16
+
17
+ ```powershell
18
+ irm https://raw.githubusercontent.com/arupa-inc/taru-mcp/main/setup.ps1 | iex
19
+ ```
20
+
13
21
  The script will ask you:
14
22
  1. **Project folder name** — creates the workspace directory
15
23
  2. **AI client** — Claude Code, Codex, or both
16
- 3. **API token** — optional, can add later
24
+ 3. **Workspace token** — taru workspace token (`xxv_...`). Can be entered later if you don't have it yet.
17
25
 
18
26
  It handles `npm init`, `taru-mcp` installation, agent file (`CLAUDE.md` / `AGENTS.md`) setup, and MCP registration automatically.
19
27
 
20
- Get your API token from the taru web console: **Settings > API Key**.
28
+ Get your workspace token from the taru web console: **Settings > API Key**.
29
+
30
+ ## Manual Setup
31
+
32
+ If the setup script doesn't work, follow these steps:
33
+
34
+ ### 1. Install
35
+
36
+ ```bash
37
+ mkdir my-project && cd my-project
38
+ npm init -y
39
+ npm install taru-mcp
40
+ ```
41
+
42
+ ### 2. Copy agent instructions
43
+
44
+ ```bash
45
+ # For Claude Code
46
+ cp node_modules/taru-mcp/samples/CLAUDE.md ./CLAUDE.md
47
+
48
+ # For Codex
49
+ cp node_modules/taru-mcp/samples/AGENTS.md ./AGENTS.md
50
+ ```
51
+
52
+ ### 3. Register MCP server
53
+
54
+ ```bash
55
+ # Claude Code
56
+ claude mcp add taru -- npx taru-mcp --url https://taru-api.arupa.io --token xxv_your_token
57
+
58
+ # Codex
59
+ codex mcp add taru -- npx taru-mcp --url https://taru-api.arupa.io --token xxv_your_token
60
+ ```
61
+
62
+ ### 4. Or configure MCP manually
63
+
64
+ If `claude mcp add` doesn't work, create `.mcp.json` in your project root:
65
+
66
+ ```json
67
+ {
68
+ "mcpServers": {
69
+ "taru": {
70
+ "command": "npx",
71
+ "args": ["taru-mcp", "--url", "https://taru-api.arupa.io", "--token", "xxv_your_token"]
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ For Claude Code global config (`~/.claude.json`):
78
+
79
+ ```json
80
+ {
81
+ "mcpServers": {
82
+ "taru": {
83
+ "command": "npx",
84
+ "args": ["taru-mcp", "--url", "https://taru-api.arupa.io", "--token", "xxv_your_token"]
85
+ }
86
+ }
87
+ }
88
+ ```
21
89
 
22
90
  ## Tools
23
91
 
@@ -30,8 +98,6 @@ Once connected, these MCP tools are available to the AI:
30
98
  | `store_document` | Store a document or opinion with auto-conflict detection |
31
99
  | `list_documents` | List all documents in the workspace |
32
100
  | `list_conflicts` | View pending knowledge conflicts |
33
- | `web_search` | Search the web via DuckDuckGo |
34
- | `web_fetch` | Fetch and extract text from a URL |
35
101
  | `rebalance` | Merge similar keywords, clean up orphan nodes |
36
102
 
37
103
  ## How it works
package/bin/taru-mcp.mjs CHANGED
@@ -39,7 +39,9 @@ Examples:
39
39
  }
40
40
 
41
41
  url = url.replace(/\/+$/, "");
42
- const endpoint = `${url}/mcp/${workspaceId}`;
42
+ // If workspace ID was explicitly provided, use the scoped endpoint; otherwise use token-based auto endpoint
43
+ const hasExplicitWorkspace = args.some(a => a === "--workspace-id" || a === "-w") || env.TARU_WORKSPACE_ID;
44
+ const endpoint = hasExplicitWorkspace ? `${url}/mcp/${workspaceId}` : `${url}/mcp`;
43
45
  const isHttps = endpoint.startsWith("https://");
44
46
 
45
47
  stderr.write(`[taru-mcp] endpoint: ${endpoint}\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taru-mcp",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "MCP server for taru knowledge graph — connect Claude Code or Codex to your team's shared brain",
5
5
  "bin": {
6
6
  "taru-mcp": "./bin/taru-mcp.mjs"
@@ -9,7 +9,9 @@
9
9
  "files": [
10
10
  "bin/",
11
11
  "samples/",
12
+ ".claude/",
12
13
  "setup.sh",
14
+ "setup.ps1",
13
15
  "README.md"
14
16
  ],
15
17
  "keywords": [
package/samples/AGENTS.md CHANGED
@@ -9,8 +9,6 @@ You have access to the taru MCP server — a research knowledge graph with tempo
9
9
  - store_document: Store extracted knowledge (handles embedding + graph)
10
10
  - list_documents: List all documents with status and confidence
11
11
  - list_conflicts: View pending knowledge conflicts
12
- - web_search: Search the web (DuckDuckGo)
13
- - web_fetch: Fetch text content from a URL
14
12
  - rebalance: Clean up the knowledge graph (merge keywords, remove orphans)
15
13
 
16
14
  ### Rules
@@ -39,11 +37,14 @@ You have access to the taru MCP server — a research knowledge graph with tempo
39
37
 
40
38
  7. **Source traceability.** Always set source_file: web://url, file://name, mcp://topic, or conversation://context. Set valid_from to current time for opinions.
41
39
 
42
- 8. **Capturing conversational knowledge:**
43
- - When a user expresses an opinion or idea during conversation, store it proactively.
44
- - Include the full conversational context in the content field.
45
- - Use source_file="conversation://session" to mark conversational origins.
46
- - Extract the core insight as core_claim, even if the user expressed it casually.
40
+ 8. **Proactive knowledge capture — ALWAYS store what you learn:**
41
+ - When you find useful information (web search, file reading, research), store it via store_document immediately. Do NOT wait to be asked.
42
+ - When a user expresses an opinion, makes a decision, or shares an insight, store it as doc_type="opinion".
43
+ - When you find factual information from web searches or documents, store it as doc_type="document".
44
+ - Include the full context (conversation, URL content, file content) in the content field.
45
+ - Use source_file="web://url" for web findings, "conversation://session" for conversational insights, "file://path" for local files.
46
+ - Extract the core insight as core_claim, even if it was found casually.
47
+ - Always provide a reason explaining why this knowledge is worth storing.
47
48
 
48
49
  9. **Search result interpretation:**
49
50
  - disputed_by present → present both perspectives
package/samples/CLAUDE.md CHANGED
@@ -9,8 +9,6 @@ You have access to the taru MCP server — a research knowledge graph with tempo
9
9
  - store_document: Store extracted knowledge (handles embedding + graph)
10
10
  - list_documents: List all documents with status and confidence
11
11
  - list_conflicts: View pending knowledge conflicts
12
- - web_search: Search the web (DuckDuckGo)
13
- - web_fetch: Fetch text content from a URL
14
12
  - rebalance: Clean up the knowledge graph (merge keywords, remove orphans)
15
13
 
16
14
  ### Rules
@@ -39,11 +37,14 @@ You have access to the taru MCP server — a research knowledge graph with tempo
39
37
 
40
38
  7. **Source traceability.** Always set source_file: web://url, file://name, mcp://topic, or conversation://context. Set valid_from to current time for opinions.
41
39
 
42
- 8. **Capturing conversational knowledge:**
43
- - When a user expresses an opinion or idea during conversation, store it proactively.
44
- - Include the full conversational context in the content field.
45
- - Use source_file="conversation://session" to mark conversational origins.
46
- - Extract the core insight as core_claim, even if the user expressed it casually.
40
+ 8. **Proactive knowledge capture — ALWAYS store what you learn:**
41
+ - When you find useful information (web search, file reading, research), store it via store_document immediately. Do NOT wait to be asked.
42
+ - When a user expresses an opinion, makes a decision, or shares an insight, store it as doc_type="opinion".
43
+ - When you find factual information from web searches or documents, store it as doc_type="document".
44
+ - Include the full context (conversation, URL content, file content) in the content field.
45
+ - Use source_file="web://url" for web findings, "conversation://session" for conversational insights, "file://path" for local files.
46
+ - Extract the core insight as core_claim, even if it was found casually.
47
+ - Always provide a reason explaining why this knowledge is worth storing.
47
48
 
48
49
  9. **Search result interpretation:**
49
50
  - disputed_by present → present both perspectives
package/setup.ps1 ADDED
@@ -0,0 +1,116 @@
1
+ # taru MCP setup script for Windows
2
+ # Usage:
3
+ # irm https://raw.githubusercontent.com/arupa-inc/taru-mcp/main/setup.ps1 | iex
4
+
5
+ $ErrorActionPreference = "Stop"
6
+ $URL = "https://taru-api.arupa.io"
7
+
8
+ Write-Host ""
9
+ Write-Host " 🌳 taru MCP Setup" -ForegroundColor Green
10
+ Write-Host ""
11
+
12
+ # 1. Ask project folder name
13
+ $Folder = Read-Host "Project folder name"
14
+ if (-not $Folder) {
15
+ Write-Host "Error: folder name is required" -ForegroundColor Red
16
+ exit 1
17
+ }
18
+
19
+ if (Test-Path $Folder) {
20
+ Write-Host "==> Directory '$Folder' already exists, using it."
21
+ } else {
22
+ New-Item -ItemType Directory -Path $Folder | Out-Null
23
+ Write-Host "==> Created '$Folder'"
24
+ }
25
+ Set-Location $Folder
26
+
27
+ # 2. Ask client type
28
+ Write-Host ""
29
+ Write-Host "Which AI client do you use?"
30
+ Write-Host " 1) Claude Code"
31
+ Write-Host " 2) Codex"
32
+ Write-Host " 3) Not sure (copies both CLAUDE.md and AGENTS.md)"
33
+ Write-Host ""
34
+ $ClientChoice = Read-Host "Choose [1/2/3]"
35
+
36
+ switch ($ClientChoice) {
37
+ "1" { $Client = "claude" }
38
+ "2" { $Client = "codex" }
39
+ default { $Client = "both" }
40
+ }
41
+
42
+ # 3. Ask token (skippable)
43
+ Write-Host ""
44
+ $Token = Read-Host "Workspace token (xxv_..., press Enter to add later)"
45
+
46
+ # Check npm
47
+ if (-not (Get-Command npm -ErrorAction SilentlyContinue)) {
48
+ Write-Host "Error: 'npm' not found. Install Node.js first." -ForegroundColor Red
49
+ exit 1
50
+ }
51
+
52
+ # Init & install
53
+ if (-not (Test-Path "package.json")) {
54
+ Write-Host "==> Initializing package.json..."
55
+ npm init -y --silent 2>&1 | Out-Null
56
+ }
57
+
58
+ Write-Host "==> Installing taru-mcp..."
59
+ npm install taru-mcp --silent
60
+
61
+ # Copy agent files
62
+ function Copy-AgentFile($File) {
63
+ $src = "node_modules/taru-mcp/samples/$File"
64
+ if (Test-Path $File) {
65
+ Write-Host "==> $File already exists, appending taru instructions..."
66
+ Add-Content -Path $File -Value ""
67
+ Get-Content $src | Add-Content -Path $File
68
+ } else {
69
+ Copy-Item $src -Destination "./$File"
70
+ Write-Host "==> Created $File"
71
+ }
72
+ }
73
+
74
+ if ($Client -eq "claude") {
75
+ Copy-AgentFile "CLAUDE.md"
76
+ } elseif ($Client -eq "codex") {
77
+ Copy-AgentFile "AGENTS.md"
78
+ } else {
79
+ Copy-AgentFile "CLAUDE.md"
80
+ Copy-AgentFile "AGENTS.md"
81
+ }
82
+
83
+ # Register MCP server
84
+ function Register-MCP($Cli) {
85
+ $tokenArgs = ""
86
+ if ($Token) { $tokenArgs = " --token $Token" }
87
+
88
+ if (Get-Command $Cli -ErrorAction SilentlyContinue) {
89
+ Write-Host "==> Registering MCP server with $Cli..."
90
+ $cmd = "$Cli mcp add taru -- npx taru-mcp --url $URL$tokenArgs"
91
+ Invoke-Expression $cmd
92
+ } else {
93
+ Write-Host "==> '$Cli' not found, skipping MCP registration."
94
+ Write-Host " Run this later: $Cli mcp add taru -- npx taru-mcp --url $URL$tokenArgs"
95
+ }
96
+ }
97
+
98
+ if ($Client -eq "claude") {
99
+ Register-MCP "claude"
100
+ } elseif ($Client -eq "codex") {
101
+ Register-MCP "codex"
102
+ } else {
103
+ Register-MCP "claude"
104
+ Register-MCP "codex"
105
+ }
106
+
107
+ Write-Host ""
108
+ Write-Host " ✅ Setup complete!" -ForegroundColor Green
109
+ Write-Host ""
110
+ Write-Host " Project: $(Get-Location)"
111
+ if ($Client -eq "claude" -or $Client -eq "both") { Write-Host " Agent file: ./CLAUDE.md" }
112
+ if ($Client -eq "codex" -or $Client -eq "both") { Write-Host " Agent file: ./AGENTS.md" }
113
+ if ($Token) { Write-Host " Token: configured" } else { Write-Host " Token: not set yet (add via settings)" }
114
+ Write-Host ""
115
+ Write-Host " Open this folder in your AI client to start growing the tree."
116
+ Write-Host ""
package/setup.sh CHANGED
@@ -12,7 +12,7 @@ echo " 🌳 taru MCP Setup"
12
12
  echo ""
13
13
 
14
14
  # 1. Ask project folder name
15
- read -rp "Project folder name: " FOLDER
15
+ read -rp "Project folder name: " FOLDER </dev/tty
16
16
  if [ -z "$FOLDER" ]; then
17
17
  echo "Error: folder name is required"
18
18
  exit 1
@@ -33,7 +33,7 @@ echo " 1) Claude Code"
33
33
  echo " 2) Codex"
34
34
  echo " 3) Not sure (copies both CLAUDE.md and AGENTS.md)"
35
35
  echo ""
36
- read -rp "Choose [1/2/3]: " CLIENT_CHOICE
36
+ read -rp "Choose [1/2/3]: " CLIENT_CHOICE </dev/tty
37
37
 
38
38
  case "$CLIENT_CHOICE" in
39
39
  1) CLIENT="claude" ;;
@@ -43,7 +43,7 @@ esac
43
43
 
44
44
  # 3. Ask token (skippable)
45
45
  echo ""
46
- read -rp "API token (press Enter to skip): " TOKEN
46
+ read -rp "Workspace token (xxv_..., press Enter to add later): " TOKEN </dev/tty
47
47
 
48
48
  # Check npm
49
49
  if ! command -v npm &>/dev/null; then
@@ -108,13 +108,53 @@ else
108
108
  register_mcp "codex"
109
109
  fi
110
110
 
111
+ # Install Claude Code hooks (search taru first, store after web search)
112
+ if [ "$CLIENT" = "claude" ] || [ "$CLIENT" = "both" ]; then
113
+ if [ -d "node_modules/taru-mcp/.claude/hooks" ]; then
114
+ mkdir -p .claude/hooks
115
+ cp node_modules/taru-mcp/.claude/hooks/*.sh .claude/hooks/
116
+ chmod +x .claude/hooks/*.sh
117
+
118
+ # Write hooks config to .claude/settings.json
119
+ mkdir -p .claude
120
+ cat > .claude/settings.json <<'HOOKS'
121
+ {
122
+ "hooks": {
123
+ "PreToolUse": [
124
+ {
125
+ "matcher": "WebSearch",
126
+ "hooks": [
127
+ {
128
+ "type": "command",
129
+ "command": ".claude/hooks/pre-websearch.sh"
130
+ }
131
+ ]
132
+ }
133
+ ],
134
+ "Stop": [
135
+ {
136
+ "hooks": [
137
+ {
138
+ "type": "command",
139
+ "command": ".claude/hooks/post-stop.sh"
140
+ }
141
+ ]
142
+ }
143
+ ]
144
+ }
145
+ }
146
+ HOOKS
147
+ echo "==> Installed taru hooks (search-first + store-after-search)"
148
+ fi
149
+ fi
150
+
111
151
  echo ""
112
152
  echo " ✅ Setup complete!"
113
153
  echo ""
114
154
  echo " Project: $(pwd)"
115
155
  [ "$CLIENT" = "claude" ] || [ "$CLIENT" = "both" ] && echo " Agent file: ./CLAUDE.md"
116
156
  [ "$CLIENT" = "codex" ] || [ "$CLIENT" = "both" ] && echo " Agent file: ./AGENTS.md"
117
- [ -n "$TOKEN" ] && echo " Token: configured" || echo " Token: skipped (add later via settings)"
157
+ [ -n "$TOKEN" ] && echo " Token: configured" || echo " Token: not set yet (add via settings)"
118
158
  echo ""
119
159
  echo " Open this folder in your AI client to start growing the tree."
120
160
  echo ""