mcp-voice-hooks 1.0.30 → 1.0.31

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,13 @@
1
+ {
2
+ "name": "mcp-voice-hooks-marketplace",
3
+ "owner": {
4
+ "name": "John Matthew Tennant"
5
+ },
6
+ "plugins": [
7
+ {
8
+ "name": "mcp-voice-hooks-plugin",
9
+ "source": "./plugin",
10
+ "description": "Real-time voice interaction for Claude Code. Speak naturally while Claude works - interrupt, redirect, or provide continuous feedback without stopping."
11
+ }
12
+ ]
13
+ }
package/README.md CHANGED
@@ -16,17 +16,28 @@ Voice recognition and text-to-speech are handled by the browser, so there is not
16
16
 
17
17
  ## Installation
18
18
 
19
- Installation is easy.
19
+ There are two ways to install Voice Mode for Claude Code:
20
20
 
21
- ### 1. Install Claude Code
21
+ ### Method 1: Plugin Installation (Recommended)
22
+
23
+ The easiest way to install is using Claude Code's plugin system:
22
24
 
23
25
  ```bash
24
- npm install -g @anthropic-ai/claude-code
26
+ # Add the marketplace
27
+ claude plugin marketplace add johnmatthewtennant/mcp-voice-hooks
28
+
29
+ # Install the plugin
30
+ claude plugin install mcp-voice-hooks@mcp-voice-hooks
25
31
  ```
26
32
 
27
- ### 2. Install Voice Mode
33
+ That's it! The plugin automatically configures both the MCP server and hooks.
34
+
35
+ ### Method 2: Manual Installation (Legacy)
36
+
37
+ If you prefer manual installation or need more control:
28
38
 
29
39
  ```bash
40
+ # Install hooks and configure MCP server
30
41
  npx mcp-voice-hooks@latest install-hooks
31
42
  claude mcp add voice-hooks npx mcp-voice-hooks@latest
32
43
  ```
@@ -96,20 +107,23 @@ This will configure your project's `.claude/settings.local.json` with the necess
96
107
 
97
108
  ## Uninstallation
98
109
 
99
- To completely remove MCP Voice Hooks:
110
+ ### If installed via Plugin (Method 1)
100
111
 
101
112
  ```bash
102
- # Remove from Claude MCP servers
103
- claude mcp remove voice-hooks
113
+ claude plugin uninstall mcp-voice-hooks@mcp-voice-hooks
104
114
  ```
105
115
 
116
+ ### If installed manually (Method 2)
117
+
106
118
  ```bash
119
+ # Remove from Claude MCP servers
120
+ claude mcp remove voice-hooks
121
+
107
122
  # Also remove hooks and settings
108
123
  npx mcp-voice-hooks uninstall
109
124
  ```
110
125
 
111
- This will:
112
-
126
+ Both methods will:
113
127
  - Clean up voice hooks from your project's `.claude/settings.local.json`
114
128
  - Preserve any custom hooks you've added
115
129
 
@@ -142,6 +156,21 @@ claude
142
156
  - For changes to **browser files** (`public/*`), just restart Claude Code
143
157
  - Then restart Claude Code to use the updated code
144
158
 
159
+ ### Plugin Directory Structure
160
+
161
+ ```
162
+ mcp-voice-hooks/
163
+ ├── .claude-plugin/
164
+ │ └── marketplace.json # Points to ./plugin
165
+ ├── .mcp.json # Local dev (no @latest, works with npm link)
166
+ └── plugin/ # Plugin distribution
167
+ ├── .claude-plugin/
168
+ │ └── plugin.json # Plugin manifest
169
+ ├── hooks/
170
+ │ └── hooks.json # Single source of truth for hooks
171
+ └── .mcp.json # Plugin users (with @latest)
172
+ ```
173
+
145
174
  ### Configuration
146
175
 
147
176
  #### Port Configuration
package/bin/cli.js CHANGED
@@ -35,8 +35,14 @@ async function main() {
35
35
  // Default behavior: ensure hooks are installed/updated, then run the MCP server
36
36
  console.log('🎤 MCP Voice Hooks - Starting server...');
37
37
 
38
- // Auto-install/update hooks on every startup
39
- await ensureHooksInstalled();
38
+ // Skip hook installation if --skip-hooks flag is present (used by plugin mode)
39
+ const skipHooks = args.includes('--skip-hooks');
40
+ if (!skipHooks) {
41
+ // Auto-install/update hooks on every startup
42
+ await ensureHooksInstalled();
43
+ } else {
44
+ console.log('ℹ️ Skipping hook installation (plugin mode)');
45
+ }
40
46
 
41
47
  console.log('');
42
48
  await runMCPServer();
@@ -102,51 +108,10 @@ async function configureClaudeCodeSettings() {
102
108
  }
103
109
  }
104
110
 
105
- // Add hook configuration with inline commands
106
- const hookConfig = {
107
- "Stop": [
108
- {
109
- "matcher": "",
110
- "hooks": [
111
- {
112
- "type": "command",
113
- "command": "curl -s -X POST \"http://localhost:${MCP_VOICE_HOOKS_PORT:-5111}/api/hooks/stop\" || echo '{\"decision\": \"approve\", \"reason\": \"voice-hooks unavailable\"}'"
114
- }
115
- ]
116
- }
117
- ],
118
- "PreToolUse": [
119
- {
120
- "matcher": "^mcp__voice-hooks__speak$",
121
- "hooks": [
122
- {
123
- "type": "command",
124
- "command": "curl -s -X POST \"http://localhost:${MCP_VOICE_HOOKS_PORT:-5111}/api/hooks/pre-speak\" || echo '{\"decision\": \"approve\", \"reason\": \"voice-hooks unavailable\"}'"
125
- }
126
- ]
127
- },
128
- {
129
- "matcher": "^mcp__voice-hooks__wait_for_utterance$",
130
- "hooks": [
131
- {
132
- "type": "command",
133
- "command": "curl -s -X POST \"http://localhost:${MCP_VOICE_HOOKS_PORT:-5111}/api/hooks/pre-wait\" || echo '{\"decision\": \"approve\", \"reason\": \"voice-hooks unavailable\"}'"
134
- }
135
- ]
136
- }
137
- ],
138
- "PostToolUse": [
139
- {
140
- "matcher": "^(?!mcp__voice-hooks__).*",
141
- "hooks": [
142
- {
143
- "type": "command",
144
- "command": "curl -s -X POST \"http://localhost:${MCP_VOICE_HOOKS_PORT:-5111}/api/hooks/post-tool\" || echo '{}'"
145
- }
146
- ]
147
- }
148
- ]
149
- };
111
+ // Load hook configuration from plugin/hooks/hooks.json
112
+ const hooksJsonPath = path.join(__dirname, '..', 'plugin', 'hooks', 'hooks.json');
113
+ const hooksJson = JSON.parse(fs.readFileSync(hooksJsonPath, 'utf8'));
114
+ const hookConfig = hooksJson.hooks;
150
115
 
151
116
  // Replace voice hooks intelligently
152
117
  const updatedHooks = replaceVoiceHooks(settings.hooks || {}, hookConfig);
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "mcp-voice-hooks-dev-marketplace",
3
+ "owner": {
4
+ "name": "Local Dev"
5
+ },
6
+ "plugins": [
7
+ {
8
+ "name": "mcp-voice-hooks-dev-plugin",
9
+ "source": "./dev-plugin",
10
+ "description": "Development version of mcp-voice-hooks plugin (uses npm link)"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "mcp-voice-hooks-dev-plugin",
3
+ "version": "1.0.30",
4
+ "description": "Development version of mcp-voice-hooks (uses npm link)",
5
+ "author": {
6
+ "name": "John Matthew Tennant",
7
+ "url": "https://github.com/johnmatthewtennant"
8
+ }
9
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "mcpServers": {
3
+ "voice-hooks": {
4
+ "command": "npx",
5
+ "args": [
6
+ "mcp-voice-hooks",
7
+ "--skip-hooks"
8
+ ],
9
+ "env": {}
10
+ }
11
+ }
12
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-voice-hooks",
3
- "version": "1.0.30",
3
+ "version": "1.0.31",
4
4
  "main": "dist/index.js",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "mcp-voice-hooks-plugin",
3
+ "version": "1.0.30",
4
+ "description": "Real-time voice interaction for Claude Code. Speak naturally while Claude works - interrupt, redirect, or provide continuous feedback without stopping.",
5
+ "author": {
6
+ "name": "John Matthew Tennant",
7
+ "url": "https://github.com/johnmatthewtennant"
8
+ },
9
+ "homepage": "https://github.com/johnmatthewtennant/mcp-voice-hooks#readme",
10
+ "repository": "https://github.com/johnmatthewtennant/mcp-voice-hooks",
11
+ "license": "UNLICENSED",
12
+ "keywords": [
13
+ "voice",
14
+ "speech-recognition",
15
+ "mcp",
16
+ "claude-code",
17
+ "voice-control",
18
+ "dictation",
19
+ "speech-to-text"
20
+ ]
21
+ }
@@ -4,7 +4,8 @@
4
4
  "type": "stdio",
5
5
  "command": "npx",
6
6
  "args": [
7
- "mcp-voice-hooks"
7
+ "mcp-voice-hooks",
8
+ "--skip-hooks"
8
9
  ],
9
10
  "env": {}
10
11
  }
@@ -0,0 +1,46 @@
1
+ {
2
+ "hooks": {
3
+ "Stop": [
4
+ {
5
+ "matcher": "",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "curl -s -X POST \"http://localhost:${MCP_VOICE_HOOKS_PORT:-5111}/api/hooks/stop\" || echo '{\"decision\": \"approve\", \"reason\": \"voice-hooks not running\"}'"
10
+ }
11
+ ]
12
+ }
13
+ ],
14
+ "PreToolUse": [
15
+ {
16
+ "matcher": "^(mcp__voice-hooks__speak|mcp__plugin_mcp-voice-hooks_voice-hooks__speak)$",
17
+ "hooks": [
18
+ {
19
+ "type": "command",
20
+ "command": "curl -s -X POST \"http://localhost:${MCP_VOICE_HOOKS_PORT:-5111}/api/hooks/pre-speak\" || echo '{\"decision\": \"approve\", \"reason\": \"voice-hooks not running\"}'"
21
+ }
22
+ ]
23
+ },
24
+ {
25
+ "matcher": "^(mcp__voice-hooks__wait_for_utterance|mcp__plugin_mcp-voice-hooks_voice-hooks__wait_for_utterance)$",
26
+ "hooks": [
27
+ {
28
+ "type": "command",
29
+ "command": "curl -s -X POST \"http://localhost:${MCP_VOICE_HOOKS_PORT:-5111}/api/hooks/pre-wait\" || echo '{\"decision\": \"approve\", \"reason\": \"voice-hooks not running\"}'"
30
+ }
31
+ ]
32
+ }
33
+ ],
34
+ "PostToolUse": [
35
+ {
36
+ "matcher": "^(?!mcp__voice-hooks__|mcp__plugin_mcp-voice-hooks_voice-hooks__).*",
37
+ "hooks": [
38
+ {
39
+ "type": "command",
40
+ "command": "curl -s -X POST \"http://localhost:${MCP_VOICE_HOOKS_PORT:-5111}/api/hooks/post-tool\" || echo '{}'"
41
+ }
42
+ ]
43
+ }
44
+ ]
45
+ }
46
+ }