@dollhousemcp/mcp-server 2.0.15 → 2.0.17

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 (53) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md.backup +18 -0
  3. package/dist/elements/base/BaseElementManager.d.ts.map +1 -1
  4. package/dist/elements/base/BaseElementManager.js +17 -1
  5. package/dist/elements/memories/MemoryManager.d.ts.map +1 -1
  6. package/dist/elements/memories/MemoryManager.js +13 -2
  7. package/dist/generated/version.d.ts +2 -2
  8. package/dist/generated/version.js +3 -3
  9. package/dist/handlers/ElementCRUDHandler.d.ts.map +1 -1
  10. package/dist/handlers/ElementCRUDHandler.js +7 -3
  11. package/dist/handlers/element-crud/createElement.d.ts.map +1 -1
  12. package/dist/handlers/element-crud/createElement.js +6 -2
  13. package/dist/handlers/element-crud/editElement.d.ts.map +1 -1
  14. package/dist/handlers/element-crud/editElement.js +6 -2
  15. package/dist/handlers/element-crud/helpers.d.ts +2 -0
  16. package/dist/handlers/element-crud/helpers.d.ts.map +1 -1
  17. package/dist/handlers/element-crud/helpers.js +21 -2
  18. package/dist/handlers/mcp-aql/IntrospectionResolver.d.ts.map +1 -1
  19. package/dist/handlers/mcp-aql/IntrospectionResolver.js +34 -7
  20. package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts.map +1 -1
  21. package/dist/handlers/mcp-aql/MCPAQLHandler.js +51 -20
  22. package/dist/handlers/mcp-aql/OperationSchema.d.ts.map +1 -1
  23. package/dist/handlers/mcp-aql/OperationSchema.js +6 -4
  24. package/dist/handlers/mcp-aql/evaluatePermission.d.ts +2 -1
  25. package/dist/handlers/mcp-aql/evaluatePermission.d.ts.map +1 -1
  26. package/dist/handlers/mcp-aql/evaluatePermission.js +23 -11
  27. package/dist/handlers/mcp-aql/policies/ElementPolicies.d.ts +8 -0
  28. package/dist/handlers/mcp-aql/policies/ElementPolicies.d.ts.map +1 -1
  29. package/dist/handlers/mcp-aql/policies/ElementPolicies.js +26 -1
  30. package/dist/handlers/strategies/BaseActivationStrategy.d.ts.map +1 -1
  31. package/dist/handlers/strategies/BaseActivationStrategy.js +12 -3
  32. package/dist/handlers/strategies/PersonaActivationStrategy.js +2 -2
  33. package/dist/utils/permissionHooks.d.ts +74 -0
  34. package/dist/utils/permissionHooks.d.ts.map +1 -0
  35. package/dist/utils/permissionHooks.js +771 -0
  36. package/dist/web/public/index.html +12 -6
  37. package/dist/web/public/permissions.css +11 -0
  38. package/dist/web/public/permissions.js +78 -35
  39. package/dist/web/public/setup.css +172 -1
  40. package/dist/web/public/setup.js +644 -38
  41. package/dist/web/routes/permissionRoutes.d.ts.map +1 -1
  42. package/dist/web/routes/permissionRoutes.js +95 -27
  43. package/dist/web/routes/setupRoutes.d.ts +4 -0
  44. package/dist/web/routes/setupRoutes.d.ts.map +1 -1
  45. package/dist/web/routes/setupRoutes.js +122 -39
  46. package/package.json +8 -1
  47. package/scripts/pretooluse-codex.sh +6 -0
  48. package/scripts/pretooluse-cursor.sh +6 -0
  49. package/scripts/pretooluse-dollhouse.sh +110 -0
  50. package/scripts/pretooluse-gemini.sh +6 -0
  51. package/scripts/pretooluse-vscode.sh +163 -0
  52. package/scripts/pretooluse-windsurf.sh +168 -0
  53. package/server.json +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dollhousemcp/mcp-server",
3
- "version": "2.0.15",
3
+ "version": "2.0.17",
4
4
  "description": "DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -133,6 +133,12 @@
133
133
  "dist/**/*.d.ts.map",
134
134
  "dist/web/public/**",
135
135
  "dist/seed-elements/**",
136
+ "scripts/pretooluse-dollhouse.sh",
137
+ "scripts/pretooluse-vscode.sh",
138
+ "scripts/pretooluse-cursor.sh",
139
+ "scripts/pretooluse-windsurf.sh",
140
+ "scripts/pretooluse-gemini.sh",
141
+ "scripts/pretooluse-codex.sh",
136
142
  "data/personas/**/*.md",
137
143
  "data/skills/**/*.md",
138
144
  "data/templates/**/*.md",
@@ -174,6 +180,7 @@
174
180
  "otpauth": "^9.5.0",
175
181
  "posthog-node": "^5.24.17",
176
182
  "qrcode": "^1.5.4",
183
+ "smol-toml": "^1.6.1",
177
184
  "uuid": "^11.1.0",
178
185
  "zod": "^4.3.6"
179
186
  },
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+ # pretooluse-codex.sh — Manual Codex hook wrapper for DollhouseMCP
3
+
4
+ export DOLLHOUSE_HOOK_PLATFORM="codex"
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ exec bash "$SCRIPT_DIR/pretooluse-dollhouse.sh"
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+ # pretooluse-cursor.sh — Manual Cursor hook wrapper for DollhouseMCP
3
+
4
+ export DOLLHOUSE_HOOK_PLATFORM="cursor"
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ exec bash "$SCRIPT_DIR/pretooluse-dollhouse.sh"
@@ -0,0 +1,110 @@
1
+ #!/bin/bash
2
+ # pretooluse-dollhouse.sh — PreToolUse hook for DollhouseMCP permission evaluation
3
+ #
4
+ # Routes permission checks through DollhouseMCP's evaluate_permission endpoint.
5
+ # The DollhouseMCP web server runs alongside the MCP stdio server on a dynamic port.
6
+ # Port discovery via ~/.dollhouse/run/permission-server.port
7
+ #
8
+ # Input: JSON on stdin. Claude Code uses { tool_name, tool_input }.
9
+ # Other clients may expose { toolName, toolInput } or { tool, input }.
10
+ # Output: JSON on stdout (platform-specific hook response; Claude Code expects
11
+ # hookSpecificOutput.permissionDecision for PreToolUse)
12
+ #
13
+ # Fail-open: if the server is unreachable or returns an error, the hook allows
14
+ # the action rather than blocking the user.
15
+ #
16
+ # Set DOLLHOUSE_HOOK_DEBUG=1 for debug logging to stderr.
17
+ # Set DOLLHOUSE_HOOK_PLATFORM to override the platform sent to the server.
18
+
19
+ PORT_FILE="$HOME/.dollhouse/run/permission-server.port"
20
+ MAX_RETRIES=2
21
+ INITIAL_TIMEOUT=5
22
+ HOOK_PLATFORM="${DOLLHOUSE_HOOK_PLATFORM:-claude_code}"
23
+
24
+ # Debug logging helper — writes to stderr so it doesn't pollute stdout
25
+ debug() {
26
+ if [[ "${DOLLHOUSE_HOOK_DEBUG:-0}" == "1" ]]; then
27
+ echo "[pretooluse] $*" >&2
28
+ fi
29
+ return 0
30
+ }
31
+
32
+ # Discover the port from the port file
33
+ if [[ -f "$PORT_FILE" ]]; then
34
+ PORT=$(cat "$PORT_FILE" 2>/dev/null)
35
+ debug "Port file found: $PORT"
36
+ else
37
+ debug "No port file at $PORT_FILE — fail open"
38
+ exit 0
39
+ fi
40
+
41
+ # Validate port is a number
42
+ if ! [[ "$PORT" =~ ^[0-9]+$ ]]; then
43
+ debug "Invalid port value: $PORT — fail open"
44
+ exit 0
45
+ fi
46
+
47
+ ENDPOINT="http://127.0.0.1:${PORT}/api/evaluate_permission"
48
+ debug "Endpoint: $ENDPOINT"
49
+
50
+ # Read the hook input from stdin
51
+ INPUT=$(cat)
52
+
53
+ # Extract tool_name and tool_input from the hook payload
54
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // .toolName // .tool // .name // empty' 2>/dev/null)
55
+ TOOL_INPUT=$(echo "$INPUT" | jq -c '.tool_input // .toolInput // .input // {}' 2>/dev/null)
56
+
57
+ # If we can't parse the input, fail open
58
+ if [[ -z "$TOOL_NAME" ]]; then
59
+ debug "Could not parse tool_name from input — fail open"
60
+ exit 0
61
+ fi
62
+
63
+ debug "Evaluating: $TOOL_NAME"
64
+ debug "Platform: $HOOK_PLATFORM"
65
+
66
+ if [[ -n "${DOLLHOUSE_SESSION_ID:-}" ]]; then
67
+ debug "Using DOLLHOUSE_SESSION_ID=${DOLLHOUSE_SESSION_ID}"
68
+ fi
69
+
70
+ PAYLOAD=$(jq -cn \
71
+ --arg tool_name "$TOOL_NAME" \
72
+ --arg platform "$HOOK_PLATFORM" \
73
+ --arg session_id "${DOLLHOUSE_SESSION_ID:-}" \
74
+ --argjson input "$TOOL_INPUT" \
75
+ '{
76
+ tool_name: $tool_name,
77
+ input: $input,
78
+ platform: $platform
79
+ } + (if ($session_id | length) > 0 then { session_id: $session_id } else {} end)')
80
+
81
+ # Call the DollhouseMCP permission evaluation endpoint with exponential backoff.
82
+ # Retry on transient failures (connection refused, timeout) but not on HTTP errors.
83
+ ATTEMPT=0
84
+ TIMEOUT=$INITIAL_TIMEOUT
85
+
86
+ while [[ $ATTEMPT -le $MAX_RETRIES ]]; do
87
+ RESPONSE=$(curl -s --max-time "$TIMEOUT" -X POST "$ENDPOINT" \
88
+ -H "Content-Type: application/json" \
89
+ -d "$PAYLOAD" \
90
+ 2>/dev/null)
91
+ CURL_EXIT=$?
92
+
93
+ if [[ $CURL_EXIT -eq 0 ]] && [[ -n "$RESPONSE" ]]; then
94
+ debug "Response (attempt $((ATTEMPT+1))): $RESPONSE"
95
+ echo "$RESPONSE"
96
+ exit 0
97
+ fi
98
+
99
+ ATTEMPT=$((ATTEMPT + 1))
100
+ if [[ $ATTEMPT -le $MAX_RETRIES ]]; then
101
+ BACKOFF=$((TIMEOUT * ATTEMPT))
102
+ debug "Attempt $ATTEMPT failed (curl exit $CURL_EXIT) — retrying in ${BACKOFF}s (timeout ${TIMEOUT}s → $((TIMEOUT * 2))s)"
103
+ sleep "$BACKOFF"
104
+ TIMEOUT=$((TIMEOUT * 2))
105
+ fi
106
+ done
107
+
108
+ # All retries exhausted — fail open
109
+ debug "All $((MAX_RETRIES + 1)) attempts failed — fail open"
110
+ exit 0
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+ # pretooluse-gemini.sh — Manual Gemini CLI hook wrapper for DollhouseMCP
3
+
4
+ export DOLLHOUSE_HOOK_PLATFORM="gemini"
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ exec bash "$SCRIPT_DIR/pretooluse-dollhouse.sh"
@@ -0,0 +1,163 @@
1
+ #!/bin/bash
2
+ # pretooluse-vscode.sh — VS Code / Copilot hook wrapper for DollhouseMCP
3
+ #
4
+ # VS Code supports Claude-compatible PreToolUse hooks, but its tool names and
5
+ # tool_input field names differ from Claude Code. This adapter normalizes the
6
+ # most relevant built-in tool names into Dollhouse's existing permission model.
7
+
8
+ PORT_FILE="$HOME/.dollhouse/run/permission-server.port"
9
+ MAX_RETRIES=2
10
+ INITIAL_TIMEOUT=5
11
+ HOOK_PLATFORM="vscode"
12
+
13
+ debug() {
14
+ if [[ "${DOLLHOUSE_HOOK_DEBUG:-0}" == "1" ]]; then
15
+ echo "[pretooluse-vscode] $*" >&2
16
+ fi
17
+ return 0
18
+ }
19
+
20
+ if [[ -f "$PORT_FILE" ]]; then
21
+ PORT=$(cat "$PORT_FILE" 2>/dev/null)
22
+ else
23
+ debug "No port file at $PORT_FILE — fail open"
24
+ exit 0
25
+ fi
26
+
27
+ if ! [[ "$PORT" =~ ^[0-9]+$ ]]; then
28
+ debug "Invalid port value: $PORT — fail open"
29
+ exit 0
30
+ fi
31
+
32
+ ENDPOINT="http://127.0.0.1:${PORT}/api/evaluate_permission"
33
+ INPUT=$(cat)
34
+
35
+ RAW_TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // .toolName // .tool // .name // empty' 2>/dev/null)
36
+ TOOL_NAME="$RAW_TOOL_NAME"
37
+ TOOL_INPUT=$(echo "$INPUT" | jq -c '.tool_input // .toolInput // .input // {}' 2>/dev/null)
38
+
39
+ case "$RAW_TOOL_NAME" in
40
+ runTerminalCommand|run_terminal_command|run_in_terminal|terminal_command)
41
+ TOOL_NAME='Bash'
42
+ TOOL_INPUT=$(echo "$INPUT" | jq -c '
43
+ . as $root
44
+ | {
45
+ command: (
46
+ $root.tool_input.command
47
+ // $root.tool_input.commandLine
48
+ // $root.toolInput.command
49
+ // $root.toolInput.commandLine
50
+ // $root.input.command
51
+ // $root.input.commandLine
52
+ // ""
53
+ )
54
+ }
55
+ | if ($root.cwd // $root.working_directory // $root.workingDirectory) != null
56
+ then . + { cwd: ($root.cwd // $root.working_directory // $root.workingDirectory) }
57
+ else .
58
+ end
59
+ ' 2>/dev/null)
60
+ ;;
61
+ createFile|create_file|writeFile|write_file)
62
+ TOOL_NAME='Write'
63
+ ;;
64
+ editFile|edit_file|editFiles|replace_string_in_file|multi_edit)
65
+ TOOL_NAME='Edit'
66
+ ;;
67
+ readFile|read_file|openFile|open_file)
68
+ TOOL_NAME='Read'
69
+ ;;
70
+ findFiles|find_files|glob_search)
71
+ TOOL_NAME='Glob'
72
+ ;;
73
+ searchWorkspace|search_workspace|searchInFiles|grep_search)
74
+ TOOL_NAME='Grep'
75
+ ;;
76
+ fetchWebPage|fetch_web_page|fetch_webpage)
77
+ TOOL_NAME='WebFetch'
78
+ ;;
79
+ searchWeb|search_web)
80
+ TOOL_NAME='WebSearch'
81
+ ;;
82
+ *)
83
+ ;;
84
+ esac
85
+
86
+ if [[ -z "$TOOL_NAME" ]]; then
87
+ debug "Could not parse VS Code tool name — fail open"
88
+ exit 0
89
+ fi
90
+
91
+ if [[ -z "$TOOL_INPUT" ]]; then
92
+ TOOL_INPUT='{}'
93
+ fi
94
+
95
+ PAYLOAD=$(jq -cn \
96
+ --arg tool_name "$TOOL_NAME" \
97
+ --arg platform "$HOOK_PLATFORM" \
98
+ --arg session_id "${DOLLHOUSE_SESSION_ID:-}" \
99
+ --argjson input "$TOOL_INPUT" \
100
+ '{
101
+ tool_name: $tool_name,
102
+ input: $input,
103
+ platform: $platform
104
+ } + (if ($session_id | length) > 0 then { session_id: $session_id } else {} end)')
105
+
106
+ ATTEMPT=0
107
+ TIMEOUT=$INITIAL_TIMEOUT
108
+
109
+ while [[ $ATTEMPT -le $MAX_RETRIES ]]; do
110
+ RESPONSE=$(curl -s --max-time "$TIMEOUT" -X POST "$ENDPOINT" \
111
+ -H "Content-Type: application/json" \
112
+ -d "$PAYLOAD" \
113
+ 2>/dev/null)
114
+ CURL_EXIT=$?
115
+
116
+ if [[ $CURL_EXIT -eq 0 ]] && [[ -n "$RESPONSE" ]]; then
117
+ HOOK_RESPONSE=$(echo "$RESPONSE" | jq -c '
118
+ def decision_from_response:
119
+ if (.hookSpecificOutput.permissionDecision? | type) == "string" then .hookSpecificOutput.permissionDecision
120
+ elif (.decision? | type) == "string" then .decision
121
+ elif (.allowed? == true) then "allow"
122
+ elif (.allowed? == false) then "deny"
123
+ else empty
124
+ end;
125
+ def reason_from_response:
126
+ .hookSpecificOutput.permissionDecisionReason
127
+ // .reason
128
+ // .hookSpecificOutput.reason
129
+ // empty;
130
+
131
+ (decision_from_response) as $decision
132
+ | if ($decision | type) == "string" and ($decision | length) > 0 then
133
+ {
134
+ hookSpecificOutput:
135
+ ({
136
+ hookEventName: "PreToolUse",
137
+ permissionDecision: $decision
138
+ } + (if (reason_from_response | type) == "string" and (reason_from_response | length) > 0
139
+ then { permissionDecisionReason: reason_from_response }
140
+ else {}
141
+ end))
142
+ }
143
+ else empty
144
+ end
145
+ ' 2>/dev/null)
146
+
147
+ if [[ -n "$HOOK_RESPONSE" ]]; then
148
+ echo "$HOOK_RESPONSE"
149
+ else
150
+ debug "Permission evaluation returned an unrecognized response — fail open"
151
+ fi
152
+ exit 0
153
+ fi
154
+
155
+ ATTEMPT=$((ATTEMPT + 1))
156
+ if [[ $ATTEMPT -le $MAX_RETRIES ]]; then
157
+ sleep $((TIMEOUT * ATTEMPT))
158
+ TIMEOUT=$((TIMEOUT * 2))
159
+ fi
160
+ done
161
+
162
+ debug "Permission evaluation failed — fail open"
163
+ exit 0
@@ -0,0 +1,168 @@
1
+ #!/bin/bash
2
+ # pretooluse-windsurf.sh — Windsurf hook wrapper for DollhouseMCP
3
+ #
4
+ # Windsurf pre-hooks are binary: exit 0 to allow, exit 2 to block.
5
+ # This wrapper translates Windsurf hook events into Dollhouse permission
6
+ # evaluations and then maps the response back to Windsurf exit codes.
7
+
8
+ PORT_FILE="$HOME/.dollhouse/run/permission-server.port"
9
+ MAX_RETRIES=2
10
+ INITIAL_TIMEOUT=5
11
+ HOOK_PLATFORM="windsurf"
12
+
13
+ debug() {
14
+ if [[ "${DOLLHOUSE_HOOK_DEBUG:-0}" == "1" ]]; then
15
+ echo "[pretooluse-windsurf] $*" >&2
16
+ fi
17
+ return 0
18
+ }
19
+
20
+ if [[ -f "$PORT_FILE" ]]; then
21
+ PORT=$(cat "$PORT_FILE" 2>/dev/null)
22
+ else
23
+ debug "No port file at $PORT_FILE — fail open"
24
+ exit 0
25
+ fi
26
+
27
+ if ! [[ "$PORT" =~ ^[0-9]+$ ]]; then
28
+ debug "Invalid port value: $PORT — fail open"
29
+ exit 0
30
+ fi
31
+
32
+ ENDPOINT="http://127.0.0.1:${PORT}/api/evaluate_permission"
33
+ INPUT=$(cat)
34
+
35
+ EVENT_NAME=$(echo "$INPUT" | jq -r '
36
+ .hook_event_name
37
+ // .hookEventName
38
+ // .event_name
39
+ // .eventName
40
+ // .event
41
+ // empty
42
+ ' 2>/dev/null)
43
+
44
+ TOOL_NAME=''
45
+ TOOL_INPUT='{}'
46
+
47
+ case "$EVENT_NAME" in
48
+ pre_run_command)
49
+ TOOL_NAME='Bash'
50
+ TOOL_INPUT=$(echo "$INPUT" | jq -c '
51
+ . as $root
52
+ | {
53
+ command: (
54
+ $root.tool_info.command_line
55
+ // $root.toolInfo.commandLine
56
+ // $root.command_line
57
+ // $root.commandLine
58
+ // $root.command
59
+ // $root.input.command
60
+ // $root.tool_input.command
61
+ // ""
62
+ )
63
+ }
64
+ | if ($root.cwd // $root.working_directory // $root.workingDirectory // $root.tool_info.cwd // $root.toolInfo.cwd) != null
65
+ then . + { cwd: ($root.cwd // $root.working_directory // $root.workingDirectory // $root.tool_info.cwd // $root.toolInfo.cwd) }
66
+ else .
67
+ end
68
+ ' 2>/dev/null)
69
+ ;;
70
+ pre_mcp_tool_use)
71
+ TOOL_NAME=$(echo "$INPUT" | jq -r '
72
+ .tool_name
73
+ // .toolName
74
+ // .tool.name
75
+ // .tool_info.name
76
+ // .toolInfo.name
77
+ // .name
78
+ // .mcp_tool_name
79
+ // empty
80
+ ' 2>/dev/null)
81
+ TOOL_INPUT=$(echo "$INPUT" | jq -c '
82
+ . as $root
83
+ | (
84
+ $root.tool_arguments
85
+ // $root.toolArgs
86
+ // $root.input.arguments
87
+ // $root.arguments
88
+ // $root.tool_input
89
+ // $root.input
90
+ // {}
91
+ )
92
+ | if ($root.server_name // $root.serverName // $root.mcp_server_name) != null
93
+ then . + { server_name: ($root.server_name // $root.serverName // $root.mcp_server_name) }
94
+ else .
95
+ end
96
+ ' 2>/dev/null)
97
+ ;;
98
+ *)
99
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // .toolName // .tool // .name // empty' 2>/dev/null)
100
+ TOOL_INPUT=$(echo "$INPUT" | jq -c '.tool_input // .toolInput // .input // {}' 2>/dev/null)
101
+ ;;
102
+ esac
103
+
104
+ if [[ -z "$TOOL_NAME" ]]; then
105
+ debug "Could not parse Windsurf tool name — fail open"
106
+ exit 0
107
+ fi
108
+
109
+ PAYLOAD=$(jq -cn \
110
+ --arg tool_name "$TOOL_NAME" \
111
+ --arg platform "$HOOK_PLATFORM" \
112
+ --arg session_id "${DOLLHOUSE_SESSION_ID:-}" \
113
+ --argjson input "$TOOL_INPUT" \
114
+ '{
115
+ tool_name: $tool_name,
116
+ input: $input,
117
+ platform: $platform
118
+ } + (if ($session_id | length) > 0 then { session_id: $session_id } else {} end)')
119
+
120
+ ATTEMPT=0
121
+ TIMEOUT=$INITIAL_TIMEOUT
122
+
123
+ while [[ $ATTEMPT -le $MAX_RETRIES ]]; do
124
+ RESPONSE=$(curl -s --max-time "$TIMEOUT" -X POST "$ENDPOINT" \
125
+ -H "Content-Type: application/json" \
126
+ -d "$PAYLOAD" \
127
+ 2>/dev/null)
128
+ CURL_EXIT=$?
129
+
130
+ if [[ $CURL_EXIT -eq 0 ]] && [[ -n "$RESPONSE" ]]; then
131
+ ALLOWED=$(echo "$RESPONSE" | jq -r '
132
+ if .allowed == true then "true"
133
+ elif .allowed == false then "false"
134
+ elif .decision == "allow" then "true"
135
+ elif .decision == "deny" or .decision == "ask" then "false"
136
+ elif .hookSpecificOutput.permissionDecision == "allow" then "true"
137
+ elif .hookSpecificOutput.permissionDecision == "deny" or .hookSpecificOutput.permissionDecision == "ask" then "false"
138
+ else "unknown"
139
+ end
140
+ ' 2>/dev/null)
141
+
142
+ if [[ "$ALLOWED" == "true" ]]; then
143
+ exit 0
144
+ fi
145
+
146
+ if [[ "$ALLOWED" == "false" ]]; then
147
+ REASON=$(echo "$RESPONSE" | jq -r '
148
+ .reason
149
+ // .hookSpecificOutput.reason
150
+ // .hookSpecificOutput.permissionDecisionReason
151
+ // empty
152
+ ' 2>/dev/null)
153
+ if [[ -n "$REASON" ]]; then
154
+ echo "$REASON" >&2
155
+ fi
156
+ exit 2
157
+ fi
158
+ fi
159
+
160
+ ATTEMPT=$((ATTEMPT + 1))
161
+ if [[ $ATTEMPT -le $MAX_RETRIES ]]; then
162
+ sleep $((TIMEOUT * ATTEMPT))
163
+ TIMEOUT=$((TIMEOUT * 2))
164
+ fi
165
+ done
166
+
167
+ debug "Permission evaluation failed — fail open"
168
+ exit 0
package/server.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "io.github.DollhouseMCP/mcp-server",
4
4
  "title": "DollhouseMCP",
5
5
  "description": "OSS to create Personas, Skills, Templates, Agents, and Memories to customize your AI experience.",
6
- "version": "2.0.15",
6
+ "version": "2.0.17",
7
7
  "homepage": "https://dollhousemcp.com",
8
8
  "repository": {
9
9
  "type": "git",
@@ -29,7 +29,7 @@
29
29
  {
30
30
  "registryType": "npm",
31
31
  "identifier": "@dollhousemcp/mcp-server",
32
- "version": "2.0.15",
32
+ "version": "2.0.17",
33
33
  "transport": {
34
34
  "type": "stdio"
35
35
  }