@dollhousemcp/mcp-server 2.0.16 → 2.0.18
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/CHANGELOG.md +12 -0
- package/README.md.backup +18 -0
- package/dist/elements/BaseElement.d.ts +1 -0
- package/dist/elements/BaseElement.d.ts.map +1 -1
- package/dist/elements/BaseElement.js +7 -1
- package/dist/elements/agents/AgentManager.js +2 -2
- package/dist/elements/base/BaseElementManager.d.ts.map +1 -1
- package/dist/elements/base/BaseElementManager.js +17 -1
- package/dist/elements/base/ElementFileOperations.js +2 -2
- package/dist/elements/ensembles/EnsembleManager.js +3 -3
- package/dist/elements/memories/MemoryManager.d.ts.map +1 -1
- package/dist/elements/memories/MemoryManager.js +14 -3
- package/dist/elements/skills/SkillManager.js +2 -2
- package/dist/elements/templates/TemplateManager.js +2 -2
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.js +3 -3
- package/dist/handlers/ElementCRUDHandler.d.ts.map +1 -1
- package/dist/handlers/ElementCRUDHandler.js +3 -2
- package/dist/handlers/element-crud/createElement.d.ts.map +1 -1
- package/dist/handlers/element-crud/createElement.js +6 -2
- package/dist/handlers/element-crud/editElement.d.ts.map +1 -1
- package/dist/handlers/element-crud/editElement.js +6 -2
- package/dist/handlers/element-crud/helpers.d.ts +2 -0
- package/dist/handlers/element-crud/helpers.d.ts.map +1 -1
- package/dist/handlers/element-crud/helpers.js +21 -2
- package/dist/handlers/mcp-aql/IntrospectionResolver.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/IntrospectionResolver.js +34 -7
- package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts +1 -0
- package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/MCPAQLHandler.js +50 -14
- package/dist/handlers/mcp-aql/OperationSchema.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/OperationSchema.js +3 -2
- package/dist/handlers/mcp-aql/evaluatePermission.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/evaluatePermission.js +2 -1
- package/dist/handlers/mcp-aql/policies/ElementPolicies.d.ts +17 -1
- package/dist/handlers/mcp-aql/policies/ElementPolicies.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/ElementPolicies.js +88 -4
- package/dist/handlers/strategies/AgentActivationStrategy.d.ts.map +1 -1
- package/dist/handlers/strategies/AgentActivationStrategy.js +5 -1
- package/dist/handlers/strategies/BaseActivationStrategy.d.ts +1 -0
- package/dist/handlers/strategies/BaseActivationStrategy.d.ts.map +1 -1
- package/dist/handlers/strategies/BaseActivationStrategy.js +15 -1
- package/dist/handlers/strategies/EnsembleActivationStrategy.d.ts.map +1 -1
- package/dist/handlers/strategies/EnsembleActivationStrategy.js +5 -1
- package/dist/handlers/strategies/MemoryActivationStrategy.d.ts.map +1 -1
- package/dist/handlers/strategies/MemoryActivationStrategy.js +5 -1
- package/dist/handlers/strategies/PersonaActivationStrategy.d.ts.map +1 -1
- package/dist/handlers/strategies/PersonaActivationStrategy.js +5 -1
- package/dist/handlers/strategies/SkillActivationStrategy.d.ts.map +1 -1
- package/dist/handlers/strategies/SkillActivationStrategy.js +5 -1
- package/dist/handlers/strategies/TemplateActivationStrategy.d.ts.map +1 -1
- package/dist/handlers/strategies/TemplateActivationStrategy.js +7 -2
- package/dist/persona/PersonaElement.js +2 -2
- package/dist/services/SerializationService.d.ts.map +1 -1
- package/dist/services/SerializationService.js +7 -1
- package/dist/types/elements/IElement.d.ts +9 -0
- package/dist/types/elements/IElement.d.ts.map +1 -1
- package/dist/types/elements/IElement.js +1 -1
- package/dist/utils/permissionHooks.d.ts +39 -3
- package/dist/utils/permissionHooks.d.ts.map +1 -1
- package/dist/utils/permissionHooks.js +651 -74
- package/dist/web/public/permissions.css +190 -2
- package/dist/web/public/permissions.js +209 -56
- package/dist/web/public/setup.js +452 -108
- package/dist/web/routes/permissionRoutes.d.ts.map +1 -1
- package/dist/web/routes/permissionRoutes.js +108 -17
- package/dist/web/routes/setupRoutes.d.ts +1 -0
- package/dist/web/routes/setupRoutes.d.ts.map +1 -1
- package/dist/web/routes/setupRoutes.js +128 -42
- package/package.json +3 -1
- package/scripts/pretooluse-dollhouse.sh +39 -1
- package/scripts/pretooluse-vscode.sh +163 -0
- package/scripts/pretooluse-windsurf.sh +166 -4
- 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.
|
|
3
|
+
"version": "2.0.18",
|
|
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",
|
|
@@ -134,6 +134,7 @@
|
|
|
134
134
|
"dist/web/public/**",
|
|
135
135
|
"dist/seed-elements/**",
|
|
136
136
|
"scripts/pretooluse-dollhouse.sh",
|
|
137
|
+
"scripts/pretooluse-vscode.sh",
|
|
137
138
|
"scripts/pretooluse-cursor.sh",
|
|
138
139
|
"scripts/pretooluse-windsurf.sh",
|
|
139
140
|
"scripts/pretooluse-gemini.sh",
|
|
@@ -179,6 +180,7 @@
|
|
|
179
180
|
"otpauth": "^9.5.0",
|
|
180
181
|
"posthog-node": "^5.24.17",
|
|
181
182
|
"qrcode": "^1.5.4",
|
|
183
|
+
"smol-toml": "^1.6.1",
|
|
182
184
|
"uuid": "^11.1.0",
|
|
183
185
|
"zod": "^4.3.6"
|
|
184
186
|
},
|
|
@@ -29,6 +29,35 @@ debug() {
|
|
|
29
29
|
return 0
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
normalize_response() {
|
|
33
|
+
local response="$1"
|
|
34
|
+
|
|
35
|
+
case "$HOOK_PLATFORM" in
|
|
36
|
+
claude_code)
|
|
37
|
+
echo "$response" | jq -c '
|
|
38
|
+
if (.hookSpecificOutput.permissionDecision? | type) == "string" then
|
|
39
|
+
.
|
|
40
|
+
elif (.decision? | type) == "string" and (.decision | IN("allow", "deny", "ask")) then
|
|
41
|
+
{
|
|
42
|
+
hookSpecificOutput: {
|
|
43
|
+
hookEventName: "PreToolUse",
|
|
44
|
+
permissionDecision: .decision,
|
|
45
|
+
permissionDecisionReason: (.reason // .message // "")
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else
|
|
49
|
+
empty
|
|
50
|
+
end
|
|
51
|
+
' 2>/dev/null
|
|
52
|
+
;;
|
|
53
|
+
*)
|
|
54
|
+
echo "$response"
|
|
55
|
+
;;
|
|
56
|
+
esac
|
|
57
|
+
|
|
58
|
+
return 0
|
|
59
|
+
}
|
|
60
|
+
|
|
32
61
|
# Discover the port from the port file
|
|
33
62
|
if [[ -f "$PORT_FILE" ]]; then
|
|
34
63
|
PORT=$(cat "$PORT_FILE" 2>/dev/null)
|
|
@@ -92,7 +121,16 @@ while [[ $ATTEMPT -le $MAX_RETRIES ]]; do
|
|
|
92
121
|
|
|
93
122
|
if [[ $CURL_EXIT -eq 0 ]] && [[ -n "$RESPONSE" ]]; then
|
|
94
123
|
debug "Response (attempt $((ATTEMPT+1))): $RESPONSE"
|
|
95
|
-
echo "$RESPONSE"
|
|
124
|
+
if ! echo "$RESPONSE" | jq -e . >/dev/null 2>&1; then
|
|
125
|
+
debug "Non-JSON response for platform $HOOK_PLATFORM — fail open"
|
|
126
|
+
exit 0
|
|
127
|
+
fi
|
|
128
|
+
NORMALIZED_RESPONSE=$(normalize_response "$RESPONSE")
|
|
129
|
+
if [[ -n "$NORMALIZED_RESPONSE" ]]; then
|
|
130
|
+
echo "$NORMALIZED_RESPONSE"
|
|
131
|
+
else
|
|
132
|
+
debug "Malformed response for platform $HOOK_PLATFORM — fail open"
|
|
133
|
+
fi
|
|
96
134
|
exit 0
|
|
97
135
|
fi
|
|
98
136
|
|
|
@@ -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
|
|
@@ -1,6 +1,168 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# pretooluse-windsurf.sh —
|
|
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.
|
|
3
7
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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.
|
|
6
|
+
"version": "2.0.18",
|
|
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.
|
|
32
|
+
"version": "2.0.18",
|
|
33
33
|
"transport": {
|
|
34
34
|
"type": "stdio"
|
|
35
35
|
}
|