slashvibe-mcp 0.2.3 → 0.2.4
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 +41 -58
- package/analytics.js +107 -0
- package/config.js +5 -2
- package/index.js +60 -51
- package/intelligence/index.js +9 -2
- package/intelligence/interests.js +369 -0
- package/notification-emitter.js +77 -0
- package/package.json +7 -3
- package/store/api.js +109 -4
- package/store/profiles.js +160 -12
- package/tools/_actions.js +230 -17
- package/tools/_discovery.js +119 -26
- package/tools/_shared/index.js +64 -0
- package/tools/_work-context.js +338 -0
- package/tools/_work-context.manual-test.js +199 -0
- package/tools/_work-context.test.js +260 -0
- package/tools/analytics.js +191 -0
- package/tools/approve.js +197 -0
- package/tools/artifact-create.js +14 -3
- package/tools/artifacts-price.js +107 -0
- package/tools/broadcast.js +286 -0
- package/tools/chat.js +202 -0
- package/tools/discover.js +314 -34
- package/tools/dm.js +22 -5
- package/tools/earnings.js +126 -0
- package/tools/feed.js +22 -3
- package/tools/follow.js +224 -0
- package/tools/friends.js +192 -0
- package/tools/gig-browse.js +206 -0
- package/tools/gig-complete.js +139 -0
- package/tools/help.js +2 -2
- package/tools/idea.js +8 -1
- package/tools/inbox.js +248 -105
- package/tools/init.js +7 -1
- package/tools/open.js +42 -5
- package/tools/plan.js +225 -0
- package/tools/proof-of-work.js +139 -0
- package/tools/request.js +16 -2
- package/tools/schedule.js +367 -0
- package/tools/session.js +420 -0
- package/tools/session_price.js +128 -0
- package/tools/settings.js +90 -2
- package/tools/ship.js +8 -2
- package/tools/start.js +96 -3
- package/tools/status.js +53 -6
- package/tools/stuck.js +297 -0
- package/tools/subscribe.js +148 -0
- package/tools/subscriptions.js +134 -0
- package/tools/suggest-tags.js +6 -8
- package/tools/update.js +1 -1
- package/tools/watch.js +157 -0
- package/tools/withdraw.js +145 -0
- package/tools/work-summary.js +96 -0
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -1,87 +1,70 @@
|
|
|
1
|
-
#
|
|
1
|
+
# vibe-mcp
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## What is /vibe?
|
|
6
|
-
|
|
7
|
-
/vibe brings social connection to the terminal. While you're building with Claude Code, /vibe lets you:
|
|
8
|
-
|
|
9
|
-
- **See who's online** - Know when other developers are in flow
|
|
10
|
-
- **Send DMs** - Message fellow builders without leaving your terminal
|
|
11
|
-
- **Share your presence** - Let others know what you're working on
|
|
12
|
-
- **Build reputation** - Your sessions become proof of work
|
|
3
|
+
Social layer for Claude Code. DMs, presence, and connection between AI-assisted developers.
|
|
13
4
|
|
|
14
5
|
## Installation
|
|
15
6
|
|
|
16
7
|
```bash
|
|
17
|
-
|
|
8
|
+
# Install globally
|
|
9
|
+
npm install -g vibe-mcp
|
|
10
|
+
|
|
11
|
+
# Or add to Claude Code MCP config
|
|
12
|
+
claude mcp add vibe-mcp
|
|
18
13
|
```
|
|
19
14
|
|
|
20
|
-
|
|
15
|
+
## Manual Setup
|
|
16
|
+
|
|
17
|
+
Add to `~/.claude.json`:
|
|
21
18
|
|
|
22
19
|
```json
|
|
23
20
|
{
|
|
24
21
|
"mcpServers": {
|
|
25
22
|
"vibe": {
|
|
26
23
|
"command": "npx",
|
|
27
|
-
"args": ["-
|
|
24
|
+
"args": ["vibe-mcp"],
|
|
25
|
+
"env": {
|
|
26
|
+
"VIBE_API_URL": "https://www.slashvibe.dev"
|
|
27
|
+
}
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
##
|
|
34
|
-
|
|
35
|
-
1. Install the MCP server
|
|
36
|
-
2. Authenticate: `vibe_auth` tool will guide you
|
|
37
|
-
3. Check who's online: `vibe_presence`
|
|
38
|
-
4. Send a message: `vibe_dm`
|
|
39
|
-
|
|
40
|
-
## Available Tools
|
|
33
|
+
## Features
|
|
41
34
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
| `vibe_inbox` | Check your messages |
|
|
48
|
-
| `vibe_ship` | Announce what you shipped |
|
|
49
|
-
| `vibe_idea` | Share an idea with the community |
|
|
50
|
-
| `vibe_discover` | Find interesting builders |
|
|
51
|
-
| `vibe_remember` | Save context about a connection |
|
|
52
|
-
| `vibe_recall` | Recall memories about someone |
|
|
35
|
+
- **Presence** - See who's online building with Claude Code
|
|
36
|
+
- **DMs** - Direct messages between developers
|
|
37
|
+
- **Memory** - Remember context about connections
|
|
38
|
+
- **Status** - Share what you're working on
|
|
39
|
+
- **Games** - Play tic-tac-toe while coding
|
|
53
40
|
|
|
54
|
-
##
|
|
41
|
+
## Commands
|
|
55
42
|
|
|
56
|
-
|
|
43
|
+
Once installed, use these in Claude Code:
|
|
57
44
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
45
|
+
| Command | Description |
|
|
46
|
+
|---------|-------------|
|
|
47
|
+
| `vibe` | Check inbox and see who's online |
|
|
48
|
+
| `vibe who` | List online users |
|
|
49
|
+
| `vibe dm @handle "message"` | Send a DM |
|
|
50
|
+
| `vibe status shipping` | Set your status |
|
|
51
|
+
| `vibe remember @handle "note"` | Save a memory |
|
|
52
|
+
| `vibe recall @handle` | Recall memories |
|
|
61
53
|
|
|
62
|
-
##
|
|
54
|
+
## API
|
|
63
55
|
|
|
64
|
-
|
|
56
|
+
The MCP server connects to `slashvibe.dev` for:
|
|
57
|
+
- User presence and discovery
|
|
58
|
+
- Message routing
|
|
59
|
+
- Identity verification
|
|
65
60
|
|
|
66
|
-
|
|
61
|
+
## Related
|
|
67
62
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
- Report bugs via [GitHub Issues](https://github.com/VibeCodingInc/vibe-mcp/issues)
|
|
73
|
-
- Propose features via [Discussions](https://github.com/VibeCodingInc/vibe-mcp/discussions)
|
|
74
|
-
- Submit PRs for review
|
|
63
|
+
- [GitHub](https://github.com/VibeCodingInc/vibe-mcp) - Source code
|
|
64
|
+
- [slashvibe.dev](https://slashvibe.dev) - Web presence
|
|
65
|
+
- [Spirit Protocol](https://spiritprotocol.io) - Parent ecosystem
|
|
66
|
+
- [AIRC](https://airc.chat) - Agent identity protocol
|
|
75
67
|
|
|
76
68
|
## License
|
|
77
69
|
|
|
78
|
-
MIT
|
|
79
|
-
|
|
80
|
-
## Links
|
|
81
|
-
|
|
82
|
-
- [slashvibe.dev](https://slashvibe.dev) - The platform
|
|
83
|
-
- [Twitter](https://twitter.com/slashvibe) - Updates
|
|
84
|
-
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
Built with obsession by [Slash Vibe, Inc.](https://slashvibe.dev)
|
|
70
|
+
MIT
|
package/analytics.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics — Retention event tracking from MCP server
|
|
3
|
+
*
|
|
4
|
+
* Logs events to the /api/analytics/event endpoint for measuring
|
|
5
|
+
* user engagement and retention funnel performance.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* const analytics = require('./analytics');
|
|
9
|
+
* analytics.track('empty_inbox_action', { action: 'discover', source: 'inbox' });
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const config = require('./config');
|
|
13
|
+
|
|
14
|
+
const API_URL = process.env.VIBE_API_URL || 'https://www.slashvibe.dev';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Track an analytics event (fire and forget)
|
|
18
|
+
* @param {string} eventType - Event type (from valid types in api/lib/events.js)
|
|
19
|
+
* @param {object} data - Additional event data
|
|
20
|
+
*/
|
|
21
|
+
async function track(eventType, data = {}) {
|
|
22
|
+
const handle = config.getHandle();
|
|
23
|
+
if (!handle) return; // Skip if not initialized
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
// Fire and forget - don't await or block
|
|
27
|
+
fetch(`${API_URL}/api/analytics/events`, {
|
|
28
|
+
method: 'POST',
|
|
29
|
+
headers: { 'Content-Type': 'application/json' },
|
|
30
|
+
body: JSON.stringify({
|
|
31
|
+
type: eventType,
|
|
32
|
+
handle,
|
|
33
|
+
data: {
|
|
34
|
+
...data,
|
|
35
|
+
client: 'mcp-server',
|
|
36
|
+
timestamp: Date.now()
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
}).catch(() => {}); // Silently ignore errors
|
|
40
|
+
} catch (e) {
|
|
41
|
+
// Analytics should never block or fail user flows
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Track empty inbox interaction
|
|
47
|
+
* @param {string} action - Which action was taken (or 'none' if user closed)
|
|
48
|
+
* @param {object} context - Context about the state (hadOnboardingTask, hadRecentShips, etc.)
|
|
49
|
+
*/
|
|
50
|
+
function trackEmptyInbox(action, context = {}) {
|
|
51
|
+
// Track that user reached empty inbox state
|
|
52
|
+
track('empty_inbox_reached', {
|
|
53
|
+
hadRecentThreads: context.recentThreads?.length > 0,
|
|
54
|
+
hadOnboardingTask: !!context.onboardingTask,
|
|
55
|
+
hadRecentShips: context.recentShips?.length > 0
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// If an action was taken, track it
|
|
59
|
+
if (action && action !== 'none') {
|
|
60
|
+
track('empty_inbox_action', {
|
|
61
|
+
action,
|
|
62
|
+
...context
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Track lurk mode state change
|
|
69
|
+
* @param {boolean} enabled - Whether lurk mode was enabled or disabled
|
|
70
|
+
*/
|
|
71
|
+
function trackLurkMode(enabled) {
|
|
72
|
+
track(enabled ? 'lurk_mode_enabled' : 'lurk_mode_disabled', {});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Track onboarding task completion
|
|
77
|
+
* @param {string} taskId - The task that was completed
|
|
78
|
+
*/
|
|
79
|
+
function trackOnboardingTask(taskId) {
|
|
80
|
+
track('onboarding_task_completed', { taskId });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Track discovery initiation
|
|
85
|
+
* @param {string} source - Where discovery was initiated from (inbox, start, etc.)
|
|
86
|
+
*/
|
|
87
|
+
function trackDiscovery(source) {
|
|
88
|
+
track('discovery_initiated', { source });
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Track session lifecycle
|
|
93
|
+
* @param {string} event - 'started' or 'ended'
|
|
94
|
+
* @param {object} sessionData - Session metrics (duration, actions, etc.)
|
|
95
|
+
*/
|
|
96
|
+
function trackSession(event, sessionData = {}) {
|
|
97
|
+
track(event === 'started' ? 'session_started' : 'session_ended', sessionData);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
module.exports = {
|
|
101
|
+
track,
|
|
102
|
+
trackEmptyInbox,
|
|
103
|
+
trackLurkMode,
|
|
104
|
+
trackOnboardingTask,
|
|
105
|
+
trackDiscovery,
|
|
106
|
+
trackSession
|
|
107
|
+
};
|
package/config.js
CHANGED
|
@@ -243,13 +243,16 @@ function savePrivyToken(token) {
|
|
|
243
243
|
|
|
244
244
|
/**
|
|
245
245
|
* Check if user has Privy auth (vs legacy keypair)
|
|
246
|
+
* Accepts both 'privy' and 'browser' as valid auth methods
|
|
246
247
|
*/
|
|
247
248
|
function hasPrivyAuth() {
|
|
249
|
+
const validAuthMethods = ['privy', 'browser'];
|
|
250
|
+
|
|
248
251
|
const data = getSessionData();
|
|
249
|
-
if (data?.authMethod
|
|
252
|
+
if (validAuthMethods.includes(data?.authMethod) && data?.token) return true;
|
|
250
253
|
|
|
251
254
|
const cfg = load();
|
|
252
|
-
return cfg?.authMethod
|
|
255
|
+
return validAuthMethods.includes(cfg?.authMethod) && cfg?.privyToken;
|
|
253
256
|
}
|
|
254
257
|
|
|
255
258
|
/**
|
package/index.js
CHANGED
|
@@ -11,6 +11,7 @@ const config = require('./config');
|
|
|
11
11
|
const store = require('./store');
|
|
12
12
|
const prompts = require('./prompts');
|
|
13
13
|
const NotificationEmitter = require('./notification-emitter');
|
|
14
|
+
const authStore = require('./auth-store');
|
|
14
15
|
|
|
15
16
|
// Tools that shouldn't show presence footer (would be redundant/noisy)
|
|
16
17
|
const SKIP_FOOTER_TOOLS = ['vibe_init', 'vibe_doctor', 'vibe_test', 'vibe_update', 'vibe_settings', 'vibe_notifications'];
|
|
@@ -36,9 +37,6 @@ function inferPromptFromArgs(toolName, args) {
|
|
|
36
37
|
case 'context': return 'share context';
|
|
37
38
|
case 'summarize': return 'summarize session';
|
|
38
39
|
case 'bye': return 'end session';
|
|
39
|
-
case 'remember': return `remember about ${handle}`;
|
|
40
|
-
case 'recall': return `recall ${handle}`;
|
|
41
|
-
case 'forget': return `forget ${handle}`;
|
|
42
40
|
case 'board': return args.content ? 'post to board' : 'view board';
|
|
43
41
|
case 'observe': return args.content ? 'record observation' : 'view observations';
|
|
44
42
|
case 'invite': return 'generate invite';
|
|
@@ -50,19 +48,19 @@ function inferPromptFromArgs(toolName, args) {
|
|
|
50
48
|
case 'release': return `release ${args.reservation_id || 'reservation'}`;
|
|
51
49
|
case 'reservations': return 'list reservations';
|
|
52
50
|
case 'solo_game': return `play ${args.game || 'game'}`;
|
|
53
|
-
case '
|
|
54
|
-
case 'wordassociation': return args.word ? `word association: ${args.word}` : 'play word association';
|
|
51
|
+
case 'game': return `play ${args.game || 'game'} with ${handle}`;
|
|
55
52
|
case 'multiplayer_game': return `multiplayer ${args.game || 'game'}`;
|
|
56
53
|
case 'drawing': return args.action ? `drawing ${args.action}` : 'collaborative drawing';
|
|
57
54
|
case 'crossword': return `crossword ${args.action || 'daily'}`;
|
|
58
|
-
case 'away': return args.message ? `set away: "${args.message}"` : 'go away';
|
|
59
|
-
case 'back': return 'come back';
|
|
60
55
|
case 'discover': return `discover ${args.command || 'suggest'}`;
|
|
61
56
|
case 'suggest_tags': return `suggest tags ${args.command || 'suggest'}`;
|
|
62
|
-
case '
|
|
63
|
-
case 'workshop_buddy': return `workshop buddy ${args.command || 'find'}`;
|
|
57
|
+
case 'settings': return args.mute ? `mute for ${args.mute}` : 'view settings';
|
|
64
58
|
case 'create_artifact': return `create ${args.template || 'artifact'}: ${args.title || 'untitled'}`;
|
|
65
59
|
case 'view_artifact': return args.slug ? `view artifact ${args.slug}` : `list ${args.list || 'artifacts'}`;
|
|
60
|
+
case 'broadcast': return args.action ? `broadcast ${args.action}` : 'broadcast status';
|
|
61
|
+
case 'watch': return args.target ? `watch ${args.target}` : 'list live broadcasts';
|
|
62
|
+
case 'session': return args.action ? `session ${args.action}` : 'list sessions';
|
|
63
|
+
case 'chat': return args.message ? `chat "${args.message.slice(0, 30)}..."` : 'view chat';
|
|
66
64
|
default: return `${action} ${handle}`.trim() || null;
|
|
67
65
|
}
|
|
68
66
|
}
|
|
@@ -164,8 +162,8 @@ async function getPresenceFooter() {
|
|
|
164
162
|
}
|
|
165
163
|
}
|
|
166
164
|
|
|
167
|
-
// Load
|
|
168
|
-
const
|
|
165
|
+
// Load core tools (always available)
|
|
166
|
+
const coreTools = {
|
|
169
167
|
// Entry point
|
|
170
168
|
vibe_start: require('./tools/start'),
|
|
171
169
|
// Core
|
|
@@ -180,29 +178,22 @@ const tools = {
|
|
|
180
178
|
vibe_open: require('./tools/open'),
|
|
181
179
|
vibe_status: require('./tools/status'),
|
|
182
180
|
vibe_context: require('./tools/context'),
|
|
181
|
+
vibe_work_summary: require('./tools/work-summary'), // Ambient context for composing messages
|
|
183
182
|
vibe_summarize: require('./tools/summarize'),
|
|
184
183
|
vibe_bye: require('./tools/bye'),
|
|
185
184
|
vibe_game: require('./tools/game'),
|
|
186
185
|
vibe_solo_game: require('./tools/solo-game'),
|
|
187
186
|
vibe_party_game: require('./tools/party-game'),
|
|
188
|
-
vibe_tictactoe: require('./tools/tictactoe'),
|
|
189
|
-
vibe_wordassociation: require('./tools/wordassociation'),
|
|
190
187
|
vibe_multiplayer_game: require('./tools/multiplayer-game'),
|
|
191
188
|
vibe_drawing: require('./tools/drawing'),
|
|
192
|
-
// Nostalgia Stack
|
|
193
189
|
vibe_crossword: require('./tools/crossword'),
|
|
194
|
-
vibe_away: require('./tools/away'),
|
|
195
|
-
vibe_back: require('./tools/back'),
|
|
196
190
|
// AIRC Handoff (v1) — context portability
|
|
197
191
|
vibe_handoff: require('./tools/handoff'),
|
|
198
192
|
// File reservations (advisory locks)
|
|
199
193
|
vibe_reserve: require('./tools/reserve'),
|
|
200
194
|
vibe_release: require('./tools/release'),
|
|
201
195
|
vibe_reservations: require('./tools/reservations'),
|
|
202
|
-
// Memory tools
|
|
203
|
-
vibe_remember: require('./tools/remember'),
|
|
204
|
-
vibe_recall: require('./tools/recall'),
|
|
205
|
-
vibe_forget: require('./tools/forget'),
|
|
196
|
+
// Memory tools removed — simplified UX
|
|
206
197
|
// Consent (AIRC compliance)
|
|
207
198
|
vibe_consent: require('./tools/consent'),
|
|
208
199
|
// Trust & Safety
|
|
@@ -220,20 +211,23 @@ const tools = {
|
|
|
220
211
|
vibe_ship: require('./tools/ship'),
|
|
221
212
|
vibe_feed: require('./tools/feed'),
|
|
222
213
|
vibe_insights: require('./tools/insights'),
|
|
214
|
+
// Launch Analytics — Real-time metrics dashboard
|
|
215
|
+
vibe_analytics: require('./tools/analytics'),
|
|
223
216
|
// Artifacts — Just-in-time social objects
|
|
224
217
|
vibe_create_artifact: require('./tools/artifact-create'),
|
|
225
218
|
vibe_view_artifact: require('./tools/artifact-view'),
|
|
219
|
+
// Plans — Async approval workflow
|
|
220
|
+
vibe_plan: require('./tools/plan'),
|
|
221
|
+
vibe_approve: require('./tools/approve'),
|
|
226
222
|
// Discovery & Matchmaking
|
|
227
223
|
vibe_discover: require('./tools/discover'),
|
|
228
224
|
vibe_suggest_tags: require('./tools/suggest-tags'),
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
//
|
|
232
|
-
|
|
233
|
-
//
|
|
234
|
-
|
|
235
|
-
vibe_doctor: require('./tools/doctor'),
|
|
236
|
-
vibe_update: require('./tools/update'),
|
|
225
|
+
// Follow system
|
|
226
|
+
vibe_follow: require('./tools/follow'),
|
|
227
|
+
// GitHub friends import (Plaxo move)
|
|
228
|
+
vibe_friends: require('./tools/friends'),
|
|
229
|
+
// Scheduling
|
|
230
|
+
vibe_schedule: require('./tools/schedule'),
|
|
237
231
|
// @echo feedback agent (by Flynn)
|
|
238
232
|
vibe_echo: require('./tools/echo'),
|
|
239
233
|
// X/Twitter bridge
|
|
@@ -242,29 +236,59 @@ const tools = {
|
|
|
242
236
|
// Unified social inbox (Phase 1a)
|
|
243
237
|
vibe_social_inbox: require('./tools/social-inbox'),
|
|
244
238
|
vibe_social_post: require('./tools/social-post'),
|
|
245
|
-
// Language evolution
|
|
246
|
-
vibe_patterns: require('./tools/patterns'),
|
|
247
239
|
// Settings
|
|
248
240
|
vibe_settings: require('./tools/settings'),
|
|
249
241
|
// External notification channels
|
|
250
242
|
vibe_notifications: require('./tools/notifications'),
|
|
251
243
|
// Background presence agent (Claude Code 2.1)
|
|
252
244
|
vibe_presence_agent: require('./tools/presence-agent'),
|
|
253
|
-
vibe_mute: require('./tools/mute'),
|
|
254
245
|
// Onboarding checklist
|
|
255
246
|
vibe_onboarding: require('./tools/onboarding'),
|
|
256
247
|
// VIBE L2 tools
|
|
257
248
|
vibe_l2: require('./tools/l2'),
|
|
258
249
|
vibe_l2_status: require('./tools/l2-status'),
|
|
259
250
|
vibe_shipback: require('./tools/shipback'),
|
|
260
|
-
vibe_bridge: require('./tools/l2-bridge')
|
|
251
|
+
vibe_bridge: require('./tools/l2-bridge'),
|
|
252
|
+
// Gig Marketplace & Proof-of-Work
|
|
253
|
+
vibe_gig_browse: require('./tools/gig-browse'),
|
|
254
|
+
vibe_gig_complete: require('./tools/gig-complete'),
|
|
255
|
+
vibe_proof_of_work: require('./tools/proof-of-work'),
|
|
256
|
+
vibe_artifacts_price: require('./tools/artifacts-price'),
|
|
257
|
+
// Watch Me Code — Live broadcasting & sessions
|
|
258
|
+
vibe_broadcast: require('./tools/broadcast'),
|
|
259
|
+
vibe_watch: require('./tools/watch'),
|
|
260
|
+
vibe_session: require('./tools/session'),
|
|
261
|
+
vibe_chat: require('./tools/chat'),
|
|
262
|
+
// Help Signal — Symbiosis layer
|
|
263
|
+
vibe_stuck: require('./tools/stuck'),
|
|
264
|
+
// VIBE Economy — Earnings, Withdrawals, Subscriptions
|
|
265
|
+
vibe_earnings: require('./tools/earnings'),
|
|
266
|
+
vibe_withdraw: require('./tools/withdraw'),
|
|
267
|
+
vibe_session_price: require('./tools/session_price'),
|
|
268
|
+
vibe_subscribe: require('./tools/subscribe'),
|
|
269
|
+
vibe_subscriptions: require('./tools/subscriptions')
|
|
261
270
|
};
|
|
262
271
|
|
|
272
|
+
// Admin tools (only loaded when VIBE_ADMIN=true)
|
|
273
|
+
const adminTools = process.env.VIBE_ADMIN === 'true' ? {
|
|
274
|
+
vibe_admin_inbox: require('./tools/admin-inbox'),
|
|
275
|
+
vibe_test: require('./tools/test'),
|
|
276
|
+
vibe_doctor: require('./tools/doctor'),
|
|
277
|
+
vibe_update: require('./tools/update'),
|
|
278
|
+
vibe_patterns: require('./tools/patterns'),
|
|
279
|
+
} : {};
|
|
280
|
+
|
|
281
|
+
// Combine tools
|
|
282
|
+
const tools = { ...coreTools, ...adminTools };
|
|
283
|
+
|
|
263
284
|
/**
|
|
264
285
|
* MCP Protocol Handler
|
|
265
286
|
*/
|
|
266
287
|
class VibeMCPServer {
|
|
267
288
|
constructor() {
|
|
289
|
+
// Hydrate auth state from disk FIRST (before any tools need it)
|
|
290
|
+
authStore.hydrate();
|
|
291
|
+
|
|
268
292
|
// Initialize notification emitter
|
|
269
293
|
this.notifier = new NotificationEmitter(this);
|
|
270
294
|
|
|
@@ -345,9 +369,10 @@ class VibeMCPServer {
|
|
|
345
369
|
// Emit list_changed notification for state-changing tools
|
|
346
370
|
// This triggers Claude to refresh without reconnection
|
|
347
371
|
const stateChangingTools = [
|
|
348
|
-
'vibe_dm', 'vibe_ping', 'vibe_react',
|
|
372
|
+
'vibe_dm', 'vibe_ping', 'vibe_react',
|
|
349
373
|
'vibe_status', 'vibe_context', 'vibe_handoff',
|
|
350
|
-
'vibe_reserve', 'vibe_release'
|
|
374
|
+
'vibe_reserve', 'vibe_release',
|
|
375
|
+
'vibe_broadcast', 'vibe_session', 'vibe_chat'
|
|
351
376
|
];
|
|
352
377
|
if (stateChangingTools.includes(params.name)) {
|
|
353
378
|
// Debounced notification (prevents spam)
|
|
@@ -360,29 +385,13 @@ class VibeMCPServer {
|
|
|
360
385
|
footer = await getPresenceFooter();
|
|
361
386
|
}
|
|
362
387
|
|
|
363
|
-
// Build simplified hint indicator for Claude (human-readable)
|
|
364
|
-
let hintIndicator = '';
|
|
365
|
-
if (result.hint) {
|
|
366
|
-
// Simple format: <!-- vibe: hint_type @handle (count) -->
|
|
367
|
-
const hint = result.hint;
|
|
368
|
-
const handle = result.suggestion?.handle || result.for_handle || '';
|
|
369
|
-
const count = result.unread_count || '';
|
|
370
|
-
|
|
371
|
-
// Build minimal hint string
|
|
372
|
-
let hintParts = [hint];
|
|
373
|
-
if (handle) hintParts.push(`@${handle.replace('@', '')}`);
|
|
374
|
-
if (count) hintParts.push(`(${count})`);
|
|
375
|
-
|
|
376
|
-
hintIndicator = `\n\n<!-- vibe: ${hintParts.join(' ')} -->`;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
388
|
return {
|
|
380
389
|
jsonrpc: '2.0',
|
|
381
390
|
id,
|
|
382
391
|
result: {
|
|
383
392
|
content: [{
|
|
384
393
|
type: 'text',
|
|
385
|
-
text: (result.display || JSON.stringify(result, null, 2)) +
|
|
394
|
+
text: (result.display || JSON.stringify(result, null, 2)) + footer
|
|
386
395
|
}]
|
|
387
396
|
}
|
|
388
397
|
};
|
package/intelligence/index.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Intelligence Module — Ambient Social Awareness
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Five layers of intelligence:
|
|
5
5
|
* 1. Infer — Smart state detection from context signals
|
|
6
6
|
* 2. Serendipity — Surface meaningful coincidences
|
|
7
7
|
* 3. Proactive — Background agent for social moments
|
|
8
8
|
* 4. Patterns — Persistent behavioral memory (work, social, creative)
|
|
9
|
+
* 5. Interests — Live interest inference from context (Phase 2)
|
|
9
10
|
*/
|
|
10
11
|
|
|
11
12
|
const infer = require('./infer');
|
|
12
13
|
const serendipity = require('./serendipity');
|
|
13
14
|
const proactive = require('./proactive');
|
|
14
15
|
const patterns = require('./patterns');
|
|
16
|
+
const interests = require('./interests');
|
|
15
17
|
|
|
16
18
|
module.exports = {
|
|
17
19
|
// Inference
|
|
@@ -34,5 +36,10 @@ module.exports = {
|
|
|
34
36
|
setSessionStart: proactive.setSessionStart,
|
|
35
37
|
|
|
36
38
|
// Patterns (persistent behavioral memory)
|
|
37
|
-
patterns
|
|
39
|
+
patterns,
|
|
40
|
+
|
|
41
|
+
// Interests (live context inference - Phase 2)
|
|
42
|
+
inferLiveInterests: interests.inferLiveInterests,
|
|
43
|
+
mergeInterests: interests.mergeInterests,
|
|
44
|
+
formatLiveInterests: interests.formatLiveInterests
|
|
38
45
|
};
|