moeba-claude-channel 0.0.5 → 0.0.7

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 ADDED
@@ -0,0 +1,98 @@
1
+ # moeba-claude-channel
2
+
3
+ Claude Code channel for [Moeba](https://moeba.co.za) — chat with Claude Code from the Moeba mobile app.
4
+
5
+ ## What it does
6
+
7
+ Bridges your Claude Code session to the Moeba app. Send messages from your phone, Claude Code processes them and replies back.
8
+
9
+ ```
10
+ Moeba App → Moeba Server → SSE → Local MCP Channel → Claude Code
11
+ ← HTTP reply ← moeba_reply tool ←
12
+ ```
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install -g moeba-claude-channel
18
+ ```
19
+
20
+ ## Setup
21
+
22
+ Add to `~/.claude.json`:
23
+
24
+ ```json
25
+ {
26
+ "mcpServers": {
27
+ "moeba": {
28
+ "command": "moeba-claude-channel",
29
+ "args": ["--login"],
30
+ "autoApprove": ["moeba_reply", "moeba_progress"]
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ ### First run
37
+
38
+ 1. Start Claude Code — the channel starts automatically
39
+ 2. Browser opens for Google/Apple sign-in (same account as your Moeba app)
40
+ 3. Credentials cached at `~/.moeba/channel-<project>.json`
41
+ 4. A **"Claude Code — \<project\>"** agent appears in your Moeba app
42
+
43
+ ### Headless mode (SSH, CI, or setting up for another user)
44
+
45
+ No browser needed — pass an API key and email via env vars:
46
+
47
+ ```json
48
+ {
49
+ "mcpServers": {
50
+ "moeba": {
51
+ "command": "moeba-claude-channel",
52
+ "args": ["--login"],
53
+ "env": {
54
+ "MOEBA_API_KEY": "mba_your_key_here",
55
+ "MOEBA_EMAIL": "user@example.com"
56
+ },
57
+ "autoApprove": ["moeba_reply", "moeba_progress"]
58
+ }
59
+ }
60
+ }
61
+ ```
62
+
63
+ ## Multi-project support
64
+
65
+ Each project directory gets its own agent in the Moeba app:
66
+
67
+ - `Claude Code — kepler`
68
+ - `Claude Code — moeba`
69
+ - `Claude Code — roxy`
70
+
71
+ The project name is detected from the git repo. Override with `MOEBA_PROJECT` env var.
72
+
73
+ ## Tools
74
+
75
+ | Tool | Description |
76
+ |------|-------------|
77
+ | `moeba_reply` | Send a reply back to the Moeba user |
78
+ | `moeba_progress` | Show a typing indicator while working |
79
+
80
+ ## Channel notifications
81
+
82
+ To enable Claude Code to auto-respond to incoming messages:
83
+
84
+ ```bash
85
+ claude --dangerously-load-development-channels server:moeba
86
+ ```
87
+
88
+ ## Requirements
89
+
90
+ - [Claude Code](https://claude.ai/code) v2.1.80+
91
+ - [Moeba](https://moeba.co.za) account (free)
92
+ - Node.js 20+
93
+
94
+ ## Links
95
+
96
+ - [Moeba App (iOS)](https://apps.apple.com/za/app/moeba/id6758993423)
97
+ - [Moeba App (Android)](https://play.google.com/store/apps/details?id=za.co.moeba.app)
98
+ - [Moeba Web](https://web.moeba.co.za)
@@ -237,11 +237,47 @@ function connectSSE(c, mcp) {
237
237
  // Main — authenticate first, then connect MCP
238
238
  // ---------------------------------------------------------------------------
239
239
  async function main() {
240
- // 1. Load cached credentials never open browser automatically
241
- // User must run `npx moeba-claude-channel --login` to authenticate new projects
240
+ // 1. Authenticatethree modes:
241
+ // a. Cached credentials (fastest, no network)
242
+ // b. API key + email env vars (headless — SSH, CI, inviting others)
243
+ // c. Browser OAuth (--login flag)
242
244
  const loginMode = process.argv.includes('--login');
245
+ const envApiKey = process.env.MOEBA_API_KEY;
246
+ const envEmail = process.env.MOEBA_EMAIL;
243
247
  let creds = loadCredentials();
244
- if (!creds && loginMode) {
248
+ if (!creds && envApiKey && envEmail) {
249
+ // Mode B: headless auth via API key + email
250
+ console.error(`Authenticating as ${envEmail} via API key...`);
251
+ try {
252
+ const response = await fetch(`${MOEBA_API_URL}/channel/auth`, {
253
+ method: 'POST',
254
+ headers: { 'Content-Type': 'application/json' },
255
+ body: JSON.stringify({ apiKey: envApiKey, email: envEmail, projectName: PROJECT_NAME }),
256
+ });
257
+ if (!response.ok) {
258
+ const err = await response.text();
259
+ console.error(`API key auth failed: ${err}`);
260
+ }
261
+ else {
262
+ const data = (await response.json());
263
+ creds = {
264
+ token: data.token,
265
+ email: data.email,
266
+ businessId: data.businessId,
267
+ agentId: data.agentId,
268
+ connectionId: data.connectionId,
269
+ agentApiKey: data.agentApiKey,
270
+ projectName: PROJECT_NAME,
271
+ };
272
+ saveCredentials(creds);
273
+ }
274
+ }
275
+ catch (err) {
276
+ console.error(`API key auth error: ${err.message}`);
277
+ }
278
+ }
279
+ else if (!creds && loginMode) {
280
+ // Mode C: browser OAuth
245
281
  console.error('No Moeba credentials found — opening browser to sign in...');
246
282
  creds = await authenticate();
247
283
  }
@@ -249,7 +285,7 @@ async function main() {
249
285
  console.error(`Authenticated as ${creds.email} (project: ${PROJECT_NAME})`);
250
286
  }
251
287
  else {
252
- console.error(`Moeba channel: no credentials for project "${PROJECT_NAME}" — run with --login to authenticate`);
288
+ console.error(`Moeba channel: no credentials for project "${PROJECT_NAME}" — run with --login or set MOEBA_API_KEY + MOEBA_EMAIL`);
253
289
  }
254
290
  // 2. Create MCP channel server
255
291
  const mcp = new Server({ name: 'moeba', version: '0.0.1' }, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moeba-claude-channel",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "Claude Code channel for Moeba — chat with Claude Code from the Moeba app",
5
5
  "type": "module",
6
6
  "main": "dist/moeba-channel.js",
@@ -8,7 +8,8 @@
8
8
  "moeba-claude-channel": "dist/moeba-channel.js"
9
9
  },
10
10
  "files": [
11
- "dist"
11
+ "dist",
12
+ "README.md"
12
13
  ],
13
14
  "scripts": {
14
15
  "build": "tsc",