slashvibe-mcp 0.3.20 → 0.3.21
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 +47 -252
- package/analytics.js +107 -0
- package/auth-store.js +148 -0
- package/auto-update.js +130 -0
- package/bridges/bridge-monitor.js +388 -0
- package/bridges/discord-bot.js +431 -0
- package/bridges/farcaster.js +299 -0
- package/bridges/telegram.js +261 -0
- package/bridges/webhook-health.js +420 -0
- package/bridges/webhook-server.js +437 -0
- package/bridges/whatsapp.js +441 -0
- package/bridges/x-webhook.js +423 -0
- package/config.js +27 -15
- package/games/arcade.js +406 -0
- package/games/chess.js +451 -0
- package/games/colorguess.js +343 -0
- package/games/crossword-words.js +171 -0
- package/games/crossword.js +461 -0
- package/games/drawing.js +347 -0
- package/games/gameroulette.js +300 -0
- package/games/gamerouter.js +336 -0
- package/games/gamestatus.js +337 -0
- package/games/guessnumber.js +209 -0
- package/games/hangman.js +279 -0
- package/games/memory.js +338 -0
- package/games/multiplayer-tictactoe.js +389 -0
- package/games/pixelart.js +399 -0
- package/games/quickduel.js +354 -0
- package/games/riddle.js +371 -0
- package/games/rockpaperscissors.js +291 -0
- package/games/snake.js +406 -0
- package/games/storybuilder.js +343 -0
- package/games/tictactoe.js +345 -0
- package/games/twentyquestions.js +286 -0
- package/games/twotruths.js +207 -0
- package/games/werewolf.js +508 -0
- package/games/wordassociation.js +247 -0
- package/games/wordchain.js +135 -0
- package/index.js +116 -159
- package/intelligence/index.js +9 -2
- package/intelligence/interests.js +369 -0
- package/notification-emitter.js +77 -0
- package/notify.js +5 -1
- package/package.json +21 -16
- package/prompts.js +1 -1
- package/protocol/index.js +73 -0
- package/setup.js +480 -0
- package/smart-inbox.js +276 -0
- package/store/api.js +536 -215
- package/store/profiles.js +160 -12
- package/tools/_actions.js +362 -21
- package/tools/_discovery.js +119 -26
- package/tools/_shared/index.js +64 -0
- package/tools/_shared.js +234 -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/activity.js +220 -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/available.js +120 -0
- package/tools/broadcast.js +325 -0
- package/tools/chat.js +202 -0
- package/tools/collaborative-drawing.js +1 -1
- package/tools/connection-status.js +178 -0
- package/tools/discover.js +350 -34
- package/tools/dm.js +80 -8
- package/tools/earnings.js +126 -0
- package/tools/feed.js +35 -4
- package/tools/follow.js +224 -0
- package/tools/friends.js +207 -0
- package/tools/gig-browse.js +206 -0
- package/tools/gig-complete.js +144 -0
- package/tools/health.js +87 -0
- package/tools/help.js +3 -3
- package/tools/idea.js +9 -2
- package/tools/inbox.js +289 -105
- package/tools/init.js +131 -34
- package/tools/invite.js +15 -4
- package/tools/leaderboard.js +117 -0
- package/tools/lib/git-apply.js +206 -0
- package/tools/lib/git-bundle.js +407 -0
- package/tools/migrate.js +3 -3
- package/tools/multiplayer-game.js +1 -1
- package/tools/onboarding.js +7 -7
- package/tools/open.js +143 -12
- package/tools/party-game.js +1 -1
- package/tools/plan.js +225 -0
- package/tools/proof-of-work.js +144 -0
- package/tools/reply.js +166 -0
- package/tools/report.js +1 -1
- package/tools/request.js +17 -3
- package/tools/schedule.js +367 -0
- package/tools/search-messages.js +123 -0
- package/tools/session.js +467 -0
- package/tools/session_price.js +128 -0
- package/tools/settings.js +90 -2
- package/tools/ship.js +30 -7
- package/tools/smart-check.js +201 -0
- package/tools/start.js +147 -12
- package/tools/status.js +53 -6
- package/tools/streak.js +147 -0
- 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/tag-suggestions.js +1 -1
- package/tools/tip.js +150 -77
- package/tools/token.js +4 -4
- package/tools/update.js +1 -1
- package/tools/wallet.js +221 -79
- package/tools/watch.js +157 -0
- package/tools/who.js +30 -1
- package/tools/withdraw.js +145 -0
- package/tools/work-summary.js +96 -0
- package/version.json +10 -8
- package/LICENSE +0 -21
- package/store/sqlite.js +0 -347
- /package/tools/{auto-suggest-connections.js → _deprecated/auto-suggest-connections.js} +0 -0
- /package/tools/{away.js → _deprecated/away.js} +0 -0
- /package/tools/{back.js → _deprecated/back.js} +0 -0
- /package/tools/{bootstrap-skills.js → _deprecated/bootstrap-skills.js} +0 -0
- /package/tools/{bridge-dashboard.js → _deprecated/bridge-dashboard.js} +0 -0
- /package/tools/{bridge-health.js → _deprecated/bridge-health.js} +0 -0
- /package/tools/{bridge-live.js → _deprecated/bridge-live.js} +0 -0
- /package/tools/{bridges.js → _deprecated/bridges.js} +0 -0
- /package/tools/{colorguess.js → _deprecated/colorguess.js} +0 -0
- /package/tools/{discover-insights.js → _deprecated/discover-insights.js} +0 -0
- /package/tools/{discover-momentum.js → _deprecated/discover-momentum.js} +0 -0
- /package/tools/{discovery-analytics.js → _deprecated/discovery-analytics.js} +0 -0
- /package/tools/{discovery-auto-suggest.js → _deprecated/discovery-auto-suggest.js} +0 -0
- /package/tools/{discovery-bootstrap.js → _deprecated/discovery-bootstrap.js} +0 -0
- /package/tools/{discovery-daily.js → _deprecated/discovery-daily.js} +0 -0
- /package/tools/{discovery-dashboard.js → _deprecated/discovery-dashboard.js} +0 -0
- /package/tools/{discovery-digest.js → _deprecated/discovery-digest.js} +0 -0
- /package/tools/{discovery-hub.js → _deprecated/discovery-hub.js} +0 -0
- /package/tools/{discovery-insights.js → _deprecated/discovery-insights.js} +0 -0
- /package/tools/{discovery-momentum.js → _deprecated/discovery-momentum.js} +0 -0
- /package/tools/{discovery-monitor.js → _deprecated/discovery-monitor.js} +0 -0
- /package/tools/{discovery-proactive.js → _deprecated/discovery-proactive.js} +0 -0
- /package/tools/{draw.js → _deprecated/draw.js} +0 -0
- /package/tools/{farcaster.js → _deprecated/farcaster.js} +0 -0
- /package/tools/{forget.js → _deprecated/forget.js} +0 -0
- /package/tools/{games-catalog.js → _deprecated/games-catalog.js} +0 -0
- /package/tools/{games.js → _deprecated/games.js} +0 -0
- /package/tools/{guessnumber.js → _deprecated/guessnumber.js} +0 -0
- /package/tools/{hangman.js → _deprecated/hangman.js} +0 -0
- /package/tools/{multiplayer-tictactoe.js → _deprecated/multiplayer-tictactoe.js} +0 -0
- /package/tools/{mute.js → _deprecated/mute.js} +0 -0
- /package/tools/{recall.js → _deprecated/recall.js} +0 -0
- /package/tools/{remember.js → _deprecated/remember.js} +0 -0
- /package/tools/{riddle.js → _deprecated/riddle.js} +0 -0
- /package/tools/{run-bootstrap.js → _deprecated/run-bootstrap.js} +0 -0
- /package/tools/{skills-analytics.js → _deprecated/skills-analytics.js} +0 -0
- /package/tools/{skills-bootstrap.js → _deprecated/skills-bootstrap.js} +0 -0
- /package/tools/{skills-dashboard.js → _deprecated/skills-dashboard.js} +0 -0
- /package/tools/{skills-exchange.js → _deprecated/skills-exchange.js} +0 -0
- /package/tools/{skills.js → _deprecated/skills.js} +0 -0
- /package/tools/{smart-intro.js → _deprecated/smart-intro.js} +0 -0
- /package/tools/{storybuilder.js → _deprecated/storybuilder.js} +0 -0
- /package/tools/{telegram-bot.js → _deprecated/telegram-bot.js} +0 -0
- /package/tools/{telegram-setup.js → _deprecated/telegram-setup.js} +0 -0
- /package/tools/{tictactoe.js → _deprecated/tictactoe.js} +0 -0
- /package/tools/{twentyquestions.js → _deprecated/twentyquestions.js} +0 -0
- /package/tools/{wordassociation.js → _deprecated/wordassociation.js} +0 -0
package/README.md
CHANGED
|
@@ -1,288 +1,83 @@
|
|
|
1
|
-
#
|
|
1
|
+
# vibe-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Social layer for AI-assisted coding. DMs, presence, and connection between developers.
|
|
4
4
|
|
|
5
|
-
Works
|
|
5
|
+
**Works in:** Claude Code • Cursor • Any MCP-compatible IDE
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Quick Start
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<details open>
|
|
12
|
-
<summary><strong>Claude Code</strong></summary>
|
|
13
|
-
|
|
14
|
-
Add to `~/.claude.json`:
|
|
15
|
-
```json
|
|
16
|
-
{
|
|
17
|
-
"mcpServers": {
|
|
18
|
-
"vibe": {
|
|
19
|
-
"command": "npx",
|
|
20
|
-
"args": ["-y", "slashvibe-mcp"]
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Or via CLI:
|
|
9
|
+
**Claude Code:**
|
|
27
10
|
```bash
|
|
28
|
-
|
|
11
|
+
npx slashvibe-mcp setup
|
|
29
12
|
```
|
|
30
|
-
</details>
|
|
31
13
|
|
|
32
|
-
|
|
33
|
-
<summary><strong>Cursor</strong></summary>
|
|
14
|
+
**Cursor:** See [Cursor Setup Guide](docs/CURSOR_SETUP.md)
|
|
34
15
|
|
|
35
|
-
|
|
36
|
-
```json
|
|
37
|
-
{
|
|
38
|
-
"mcpServers": {
|
|
39
|
-
"vibe": {
|
|
40
|
-
"command": "npx",
|
|
41
|
-
"args": ["-y", "slashvibe-mcp"]
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
```
|
|
46
|
-
</details>
|
|
16
|
+
**Other IDEs:** Any editor supporting MCP protocol can use the manual config below.
|
|
47
17
|
|
|
48
|
-
|
|
49
|
-
<summary><strong>VS Code (GitHub Copilot)</strong></summary>
|
|
18
|
+
## Installation
|
|
50
19
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"servers": {
|
|
55
|
-
"vibe": {
|
|
56
|
-
"command": "npx",
|
|
57
|
-
"args": ["-y", "slashvibe-mcp"]
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
```
|
|
20
|
+
```bash
|
|
21
|
+
# Install globally
|
|
22
|
+
npm install -g vibe-mcp
|
|
62
23
|
|
|
63
|
-
Or add to
|
|
64
|
-
|
|
65
|
-
{
|
|
66
|
-
"mcp": {
|
|
67
|
-
"servers": {
|
|
68
|
-
"vibe": {
|
|
69
|
-
"command": "npx",
|
|
70
|
-
"args": ["-y", "slashvibe-mcp"]
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
24
|
+
# Or add to Claude Code MCP config
|
|
25
|
+
claude mcp add vibe-mcp
|
|
75
26
|
```
|
|
76
|
-
</details>
|
|
77
|
-
|
|
78
|
-
<details>
|
|
79
|
-
<summary><strong>Windsurf</strong></summary>
|
|
80
27
|
|
|
81
|
-
|
|
82
|
-
```json
|
|
83
|
-
{
|
|
84
|
-
"mcpServers": {
|
|
85
|
-
"vibe": {
|
|
86
|
-
"command": "npx",
|
|
87
|
-
"args": ["-y", "slashvibe-mcp"]
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
```
|
|
92
|
-
</details>
|
|
28
|
+
## Manual Setup
|
|
93
29
|
|
|
94
|
-
|
|
95
|
-
<summary><strong>Cline (VS Code)</strong></summary>
|
|
30
|
+
Add to `~/.claude.json`:
|
|
96
31
|
|
|
97
|
-
Open Cline > MCP Servers icon > Configure > Edit JSON, then add:
|
|
98
32
|
```json
|
|
99
33
|
{
|
|
100
34
|
"mcpServers": {
|
|
101
35
|
"vibe": {
|
|
102
36
|
"command": "npx",
|
|
103
|
-
"args": ["-
|
|
37
|
+
"args": ["vibe-mcp"],
|
|
38
|
+
"env": {
|
|
39
|
+
"VIBE_API_URL": "https://www.slashvibe.dev"
|
|
40
|
+
}
|
|
104
41
|
}
|
|
105
42
|
}
|
|
106
43
|
}
|
|
107
44
|
```
|
|
108
|
-
</details>
|
|
109
|
-
|
|
110
|
-
<details>
|
|
111
|
-
<summary><strong>Continue.dev</strong></summary>
|
|
112
|
-
|
|
113
|
-
Create `.continue/mcpServers/vibe.json`:
|
|
114
|
-
```json
|
|
115
|
-
{
|
|
116
|
-
"command": "npx",
|
|
117
|
-
"args": ["-y", "slashvibe-mcp"]
|
|
118
|
-
}
|
|
119
|
-
```
|
|
120
|
-
</details>
|
|
121
|
-
|
|
122
|
-
<details>
|
|
123
|
-
<summary><strong>JetBrains (IntelliJ, WebStorm, etc.)</strong></summary>
|
|
124
|
-
|
|
125
|
-
Go to **Settings > Tools > AI Assistant > Model Context Protocol (MCP)** and add a new server:
|
|
126
|
-
- **Command:** `npx`
|
|
127
|
-
- **Arguments:** `-y slashvibe-mcp`
|
|
128
|
-
|
|
129
|
-
Or import from your Claude Code config if you already have one.
|
|
130
|
-
</details>
|
|
131
|
-
|
|
132
|
-
## Getting Started
|
|
133
|
-
|
|
134
|
-
Once installed, tell Claude:
|
|
135
|
-
|
|
136
|
-
```
|
|
137
|
-
"let's vibe"
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
That's it. Claude will authenticate you via GitHub, show who's online, and check your inbox.
|
|
141
|
-
|
|
142
|
-
If you prefer step-by-step:
|
|
143
|
-
|
|
144
|
-
1. **Authenticate** — `vibe init` opens GitHub OAuth in your browser. Takes 30 seconds.
|
|
145
|
-
2. **See who's around** — `vibe who` shows online builders and what they're working on.
|
|
146
|
-
3. **Check messages** — `vibe inbox` shows unread DMs.
|
|
147
|
-
4. **Send your first message** — `vibe dm @seth hey, just set up /vibe!`
|
|
148
|
-
|
|
149
|
-
## Tools
|
|
150
|
-
|
|
151
|
-
### Core — Messaging & Presence
|
|
152
|
-
|
|
153
|
-
| Tool | What it does |
|
|
154
|
-
|------|-------------|
|
|
155
|
-
| `vibe_start` | Entry point — authenticates, shows who's online, checks inbox |
|
|
156
|
-
| `vibe_init` | Set up your identity via GitHub OAuth |
|
|
157
|
-
| `vibe_who` | See who's online and what they're building |
|
|
158
|
-
| `vibe_dm` | Send a direct message |
|
|
159
|
-
| `vibe_inbox` | Check your unread messages |
|
|
160
|
-
| `vibe_open` | Open a conversation thread with someone |
|
|
161
|
-
| `vibe_ping` | Send a quick wave to someone |
|
|
162
|
-
| `vibe_react` | React to a message |
|
|
163
|
-
| `vibe_status` | Set your mood or what you're working on |
|
|
164
|
-
| `vibe_away` / `vibe_back` | Set yourself away or return |
|
|
165
|
-
| `vibe_bye` | End your session |
|
|
166
|
-
|
|
167
|
-
### Discovery — Find Your People
|
|
168
|
-
|
|
169
|
-
| Tool | What it does |
|
|
170
|
-
|------|-------------|
|
|
171
|
-
| `vibe_discover` | Find builders by interests, projects, or activity |
|
|
172
|
-
| `vibe_suggest_tags` | Get tag suggestions for your profile |
|
|
173
|
-
| `vibe_skills_exchange` | Browse and offer skills |
|
|
174
|
-
| `vibe_workshop_buddy` | Find a learning partner |
|
|
175
|
-
| `vibe_invite` | Generate an invite link |
|
|
176
|
-
|
|
177
|
-
### Creative — Ship & Share
|
|
178
|
-
|
|
179
|
-
| Tool | What it does |
|
|
180
|
-
|------|-------------|
|
|
181
|
-
| `vibe_ship` | Announce what you shipped |
|
|
182
|
-
| `vibe_idea` | Share an idea with the community |
|
|
183
|
-
| `vibe_request` | Ask the community for help |
|
|
184
|
-
| `vibe_feed` | See what people are shipping and sharing |
|
|
185
|
-
| `vibe_create_artifact` | Create a shareable guide, workspace, or learning |
|
|
186
|
-
| `vibe_view_artifact` | View shared artifacts |
|
|
187
|
-
|
|
188
|
-
### Memory — Context That Persists
|
|
189
|
-
|
|
190
|
-
| Tool | What it does |
|
|
191
|
-
|------|-------------|
|
|
192
|
-
| `vibe_remember` | Save a note about someone for next time |
|
|
193
|
-
| `vibe_recall` | Pull up everything you know about someone |
|
|
194
|
-
| `vibe_forget` | Delete a memory |
|
|
195
|
-
| `vibe_handoff` | Create an AIRC context handoff for another tool |
|
|
196
|
-
|
|
197
|
-
### Games — 27 Multiplayer & Solo Games
|
|
198
|
-
|
|
199
|
-
| Tool | What it does |
|
|
200
|
-
|------|-------------|
|
|
201
|
-
| `vibe_game` | Start a multiplayer game with someone |
|
|
202
|
-
| `vibe_solo_game` | Play a solo game (riddles, hangman, number guess) |
|
|
203
|
-
| `vibe_tictactoe` | Challenge someone to tic-tac-toe |
|
|
204
|
-
| `vibe_crossword` | Collaborative crossword puzzle |
|
|
205
|
-
| `vibe_drawing` | Collaborative ASCII drawing |
|
|
206
|
-
| `vibe_party_game` | Start a party game for 3+ players |
|
|
207
|
-
|
|
208
|
-
### Bridges — Cross-Platform Social
|
|
209
|
-
|
|
210
|
-
| Tool | What it does |
|
|
211
|
-
|------|-------------|
|
|
212
|
-
| `vibe_x_mentions` | Check your X/Twitter mentions |
|
|
213
|
-
| `vibe_x_reply` | Reply on X from the terminal |
|
|
214
|
-
| `vibe_social_inbox` | Unified inbox across platforms |
|
|
215
|
-
| `vibe_social_post` | Post to multiple networks at once |
|
|
216
|
-
|
|
217
|
-
### Diagnostics
|
|
218
|
-
|
|
219
|
-
| Tool | What it does |
|
|
220
|
-
|------|-------------|
|
|
221
|
-
| `vibe_doctor` | Full health check — API, auth, storage, presence |
|
|
222
|
-
| `vibe_test` | Quick connection and identity test |
|
|
223
|
-
| `vibe_help` | Show available commands |
|
|
224
|
-
| `vibe_update` | Check for and apply updates |
|
|
225
|
-
| `vibe_settings` | Configure preferences |
|
|
226
|
-
|
|
227
|
-
## How It Works
|
|
228
|
-
|
|
229
|
-
/vibe is an MCP server that connects your editor to [slashvibe.dev](https://slashvibe.dev). Messages sync via a Postgres backend with local SQLite persistence for offline-first speed. Everyone using /vibe is on the same network — regardless of which editor they use.
|
|
230
|
-
|
|
231
|
-
```
|
|
232
|
-
Your Editor ←→ /vibe MCP (stdio) ←→ slashvibe.dev API ←→ Other users
|
|
233
|
-
↕
|
|
234
|
-
Local SQLite DB
|
|
235
|
-
(~/.vibecodings/sessions.db)
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
- **Identity** persists via GitHub OAuth — your handle follows you across sessions
|
|
239
|
-
- **Messages** are stored locally first, then synced to the server (optimistic send)
|
|
240
|
-
- **Presence** broadcasts via heartbeat — others see you in real time
|
|
241
|
-
- **Memory** is local — notes you save about people stay on your machine
|
|
242
|
-
|
|
243
|
-
## Troubleshooting
|
|
244
45
|
|
|
245
|
-
|
|
246
|
-
- Make sure you restarted Claude Code after adding the MCP config
|
|
247
|
-
- Check your config file: `~/.claude.json` or `~/.config/claude-code/mcp.json`
|
|
248
|
-
- Run `vibe doctor` to diagnose issues
|
|
46
|
+
## Features
|
|
249
47
|
|
|
250
|
-
**
|
|
251
|
-
-
|
|
252
|
-
-
|
|
253
|
-
-
|
|
48
|
+
- **Presence** - See who's online building with Claude Code
|
|
49
|
+
- **DMs** - Direct messages between developers
|
|
50
|
+
- **Memory** - Remember context about connections
|
|
51
|
+
- **Status** - Share what you're working on
|
|
52
|
+
- **Games** - Play tic-tac-toe while coding
|
|
254
53
|
|
|
255
|
-
|
|
256
|
-
- Run `vibe doctor` to check API connectivity
|
|
257
|
-
- Check your internet connection
|
|
258
|
-
- Messages are saved locally even if the API is down — they'll sync when you reconnect
|
|
54
|
+
## Commands
|
|
259
55
|
|
|
260
|
-
|
|
261
|
-
- You may be running an older version. Run `vibe update` or reinstall: `npm install -g slashvibe-mcp`
|
|
56
|
+
Once installed, use these in Claude Code:
|
|
262
57
|
|
|
263
|
-
|
|
58
|
+
| Command | Description |
|
|
59
|
+
|---------|-------------|
|
|
60
|
+
| `vibe` | Check inbox and see who's online |
|
|
61
|
+
| `vibe who` | List online users |
|
|
62
|
+
| `vibe dm @handle "message"` | Send a DM |
|
|
63
|
+
| `vibe status shipping` | Set your status |
|
|
64
|
+
| `vibe remember @handle "note"` | Save a memory |
|
|
65
|
+
| `vibe recall @handle` | Recall memories |
|
|
264
66
|
|
|
265
|
-
|
|
67
|
+
## API
|
|
266
68
|
|
|
267
|
-
|
|
69
|
+
The MCP server connects to `slashvibe.dev` for:
|
|
70
|
+
- User presence and discovery
|
|
71
|
+
- Message routing
|
|
72
|
+
- Identity verification
|
|
268
73
|
|
|
269
|
-
##
|
|
74
|
+
## Related
|
|
270
75
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
-
|
|
274
|
-
-
|
|
76
|
+
- [GitHub](https://github.com/VibeCodingInc/vibe-mcp) - Source code
|
|
77
|
+
- [slashvibe.dev](https://slashvibe.dev) - Web presence
|
|
78
|
+
- [Spirit Protocol](https://spiritprotocol.io) - Parent ecosystem
|
|
79
|
+
- [AIRC](https://airc.chat) - Agent identity protocol
|
|
275
80
|
|
|
276
81
|
## License
|
|
277
82
|
|
|
278
|
-
MIT
|
|
279
|
-
|
|
280
|
-
## Links
|
|
281
|
-
|
|
282
|
-
- [slashvibe.dev](https://slashvibe.dev) — The platform
|
|
283
|
-
- [Vibe Terminal](https://github.com/VibeCodingInc/vibe-terminal) — Desktop app
|
|
284
|
-
- [@slashvibe on X](https://twitter.com/slashvibe) — Updates
|
|
285
|
-
|
|
286
|
-
---
|
|
287
|
-
|
|
288
|
-
Built by [Slash Vibe, Inc.](https://slashvibe.dev)
|
|
83
|
+
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/auth-store.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Store - In-memory singleton for authentication state
|
|
3
|
+
*
|
|
4
|
+
* This is the SOURCE OF TRUTH for auth during MCP runtime.
|
|
5
|
+
* File persistence (config.json) is only for durability across restarts.
|
|
6
|
+
*
|
|
7
|
+
* Why this exists:
|
|
8
|
+
* - OAuth callback and API calls happen in the same MCP process
|
|
9
|
+
* - File-based auth was unreliable due to per-PID session files and caching
|
|
10
|
+
* - In-memory state is immediate and deterministic
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* - Startup: authStore.hydrate() loads from disk once
|
|
14
|
+
* - OAuth: authStore.setToken(token) updates immediately
|
|
15
|
+
* - API calls: authStore.getToken() returns current token (no file I/O)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// In-memory state - the single source of truth during runtime
|
|
19
|
+
let _token = null;
|
|
20
|
+
let _handle = null;
|
|
21
|
+
let _oneLiner = null;
|
|
22
|
+
let _hydrated = false;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Hydrate auth state from disk (call once at MCP startup)
|
|
26
|
+
* This loads persisted state from config.json
|
|
27
|
+
*/
|
|
28
|
+
function hydrate() {
|
|
29
|
+
if (_hydrated) return; // Only hydrate once
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
const config = require('./config');
|
|
33
|
+
const cfg = config.load();
|
|
34
|
+
|
|
35
|
+
_token = cfg.authToken || cfg.privyToken || null;
|
|
36
|
+
_handle = cfg.handle || cfg.username || null;
|
|
37
|
+
_oneLiner = cfg.one_liner || cfg.workingOn || null;
|
|
38
|
+
_hydrated = true;
|
|
39
|
+
|
|
40
|
+
if (_token) {
|
|
41
|
+
console.error('[auth-store] Hydrated from disk: @' + _handle);
|
|
42
|
+
} else {
|
|
43
|
+
console.error('[auth-store] Hydrated from disk: no token');
|
|
44
|
+
}
|
|
45
|
+
} catch (e) {
|
|
46
|
+
console.error('[auth-store] Hydration failed:', e.message);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Set auth token (call after OAuth completes)
|
|
52
|
+
* @param {string} token - JWT token
|
|
53
|
+
*/
|
|
54
|
+
function setToken(token) {
|
|
55
|
+
const hadToken = !!_token;
|
|
56
|
+
_token = token;
|
|
57
|
+
|
|
58
|
+
if (!hadToken && token) {
|
|
59
|
+
console.error('[auth-store] Token set (was empty)');
|
|
60
|
+
} else if (hadToken && token && token !== _token) {
|
|
61
|
+
console.error('[auth-store] Token updated');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get current auth token
|
|
67
|
+
* @returns {string|null} Current token or null
|
|
68
|
+
*/
|
|
69
|
+
function getToken() {
|
|
70
|
+
return _token;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Set user handle
|
|
75
|
+
* @param {string} handle - User handle (without @)
|
|
76
|
+
*/
|
|
77
|
+
function setHandle(handle) {
|
|
78
|
+
_handle = handle;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get current handle
|
|
83
|
+
* @returns {string|null} Current handle or null
|
|
84
|
+
*/
|
|
85
|
+
function getHandle() {
|
|
86
|
+
return _handle;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Set one-liner (what user is building)
|
|
91
|
+
* @param {string} oneLiner - One-liner description
|
|
92
|
+
*/
|
|
93
|
+
function setOneLiner(oneLiner) {
|
|
94
|
+
_oneLiner = oneLiner;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Get current one-liner
|
|
99
|
+
* @returns {string|null} Current one-liner or null
|
|
100
|
+
*/
|
|
101
|
+
function getOneLiner() {
|
|
102
|
+
return _oneLiner;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Check if user is authenticated
|
|
107
|
+
* @returns {boolean} True if token exists
|
|
108
|
+
*/
|
|
109
|
+
function isAuthenticated() {
|
|
110
|
+
return !!_token;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Clear all auth state (for logout/reset)
|
|
115
|
+
*/
|
|
116
|
+
function clear() {
|
|
117
|
+
_token = null;
|
|
118
|
+
_handle = null;
|
|
119
|
+
_oneLiner = null;
|
|
120
|
+
console.error('[auth-store] Cleared');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Get full auth state (for debugging)
|
|
125
|
+
* @returns {object} Current auth state
|
|
126
|
+
*/
|
|
127
|
+
function getState() {
|
|
128
|
+
return {
|
|
129
|
+
token: _token ? _token.substring(0, 20) + '...' : null,
|
|
130
|
+
handle: _handle,
|
|
131
|
+
oneLiner: _oneLiner,
|
|
132
|
+
hydrated: _hydrated,
|
|
133
|
+
isAuthenticated: !!_token
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
module.exports = {
|
|
138
|
+
hydrate,
|
|
139
|
+
setToken,
|
|
140
|
+
getToken,
|
|
141
|
+
setHandle,
|
|
142
|
+
getHandle,
|
|
143
|
+
setOneLiner,
|
|
144
|
+
getOneLiner,
|
|
145
|
+
isAuthenticated,
|
|
146
|
+
clear,
|
|
147
|
+
getState
|
|
148
|
+
};
|