alora-mcp 0.6.0 → 0.7.1

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 CHANGED
@@ -26,13 +26,15 @@ Or in any MCP client's JSON config:
26
26
  }
27
27
  ```
28
28
 
29
- ## Connect (once, takes a minute)
29
+ ## Connect (one email, one click)
30
30
 
31
- 1. Create a free account at [alora.build/register](https://alora.build/register) — $0.50 of credit included, no card.
32
- 2. Run `npx alora-cli connect` in your terminal — it prints a code.
33
- 3. Paste the code at [alora.build/activate](https://alora.build/activate).
31
+ Just ask your agent to set you up. It asks for your email and calls the `account_create_and_connect` tool you get **a single email, and one click** creates your account ($0.50 of free credit included, no card), verifies it, and authorizes the agent. No password to invent; you log into the panel later with a magic link.
34
32
 
35
- The token lands in `~/.alora/config.json`, and from then on your agent takes it from here. Full playbook for agents: [alora.build/llms.txt](https://alora.build/llms.txt).
33
+ Already have an account? The same flow sends you an authorize link instead one click never creates or touches an existing account without you signing in.
34
+
35
+ Prefer the classic way? Create an account at [alora.build/register](https://alora.build/register), run `npx alora-cli connect`, and paste the code at [alora.build/activate](https://alora.build/activate).
36
+
37
+ Either way the token lands in `~/.alora/config.json`, and from then on your agent takes it from here. Full playbook for agents: [alora.build/llms.txt](https://alora.build/llms.txt).
36
38
 
37
39
  ## What your agent can do (45 tools)
38
40
 
@@ -45,6 +47,7 @@ The token lands in `~/.alora/config.json`, and from then on your agent takes it
45
47
  | **Configure** | `secrets_set` (encrypted, injected as env) · `domain_connect` · `egress_ip_allocate` (static egress IP) |
46
48
  | **Use AI inside the app** | `ai_enable` — the deployed app runs `claude -p` with the owner's own Claude account |
47
49
  | **Buy domains** | `domain_search` · `domain_buy` — always gated on the owner's approval by email |
50
+ | **Be an MCP server** | your deployed app can expose its own `/mcp` endpoint, with per-customer tokens (`token_create`) and identity headers — an [MCP-first SaaS in one deploy](https://alora.build/blog/host-mcp-server) |
48
51
  | **Know what's happening** | `analytics_summary` · `analytics_users` · `wallet_balance` · `changelog` |
49
52
 
50
53
  ## How it behaves
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "alora-mcp",
3
- "version": "0.6.0",
4
- "description": "MCP server for Alora, the cloud where your agent works deploy, preview, share and run the apps your agent writes. Claude Code, Codex, Cursor and any MCP client.",
3
+ "version": "0.7.1",
4
+ "description": "MCP server for Alora, the cloud where your agent works \u2014 deploy, preview, share and run the apps your agent writes. Claude Code, Codex, Cursor and any MCP client.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "alora-mcp": "src/index.js"
8
8
  },
9
9
  "dependencies": {
10
- "alora-sdk": "^0.6.0",
10
+ "alora-sdk": "^0.7.0",
11
11
  "@modelcontextprotocol/sdk": "^1.12.0",
12
12
  "tar": "^7.4.3",
13
13
  "zod": "^3.24.0"
package/src/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
5
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
6
  import { z } from 'zod';
7
- import { readFileSync, rmSync } from 'node:fs';
7
+ import { readFileSync, rmSync, writeFileSync, mkdirSync } from 'node:fs';
8
8
  import { homedir, tmpdir } from 'node:os';
9
9
  import path from 'node:path';
10
10
  import * as tar from 'tar';
@@ -18,7 +18,7 @@ function client() {
18
18
  return new AloraClient({ api: cfg.api || 'https://api.alora.build', token: cfg.token });
19
19
  }
20
20
 
21
- const server = new McpServer({ name: 'alora', version: '0.6.0' });
21
+ const server = new McpServer({ name: 'alora', version: '0.7.0' });
22
22
 
23
23
  const ok = (data) => ({ content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] });
24
24
  const asError = (e) => ({
@@ -43,6 +43,30 @@ server.registerTool('whoami', {
43
43
  inputSchema: {},
44
44
  }, wrap(() => client().whoami()));
45
45
 
46
+ // --- alta iniciada por el agente: el usuario solo toca UN email ---
47
+ server.registerTool('account_create_and_connect', {
48
+ description: 'SIN cuenta de Alora todavía: preguntale al usuario su email EN EL CHAT y llamá esta tool. Le llega UN email; con un click se crea la cuenta (si no existe), se verifica, se activan sus US$0.50 gratis y este agente queda autorizado. Después llamá account_connect_poll con el device_code hasta que apruebe (el link vence en 15 min). NUNCA inventes un email ni uses uno descartable — tiene que ser el inbox real del usuario. Si el email ya tiene cuenta, le llega un pedido de autorización al flujo normal (login + Authorize).',
49
+ inputSchema: {
50
+ email: z.string().describe('El email que el usuario te dio en el chat'),
51
+ agent_name: z.string().optional().describe('Cómo se llama este agente, ej: "Claude de Ana"'),
52
+ },
53
+ }, wrap(({ email, agent_name }) => client().signupStart(email, agent_name || 'agente MCP')));
54
+
55
+ server.registerTool('account_connect_poll', {
56
+ description: 'Después de account_create_and_connect: llamá esto cada ~5s con el device_code. Cuando el usuario toque el email devuelve approved y GUARDA el token automáticamente — desde ahí todas las demás tools funcionan. expired = el link venció sin click: pedile al usuario que revise el inbox y volvé a empezar.',
57
+ inputSchema: { device_code: z.string() },
58
+ }, wrap(async ({ device_code }) => {
59
+ const res = await client().devicePoll(device_code);
60
+ if (res.status === 'approved' && res.token) {
61
+ let cfg = {};
62
+ try { cfg = JSON.parse(readFileSync(CONFIG_FILE, 'utf8')); } catch {}
63
+ mkdirSync(path.dirname(CONFIG_FILE), { recursive: true });
64
+ writeFileSync(CONFIG_FILE, JSON.stringify({ ...cfg, api: cfg.api || 'https://api.alora.build', token: res.token }, null, 2));
65
+ return { status: 'approved', note: 'Token guardado — ya podés usar todas las tools (probá whoami).' };
66
+ }
67
+ return res;
68
+ }));
69
+
46
70
  server.registerTool('list_projects', {
47
71
  description: 'Lista los proyectos del workspace con URL, versión activa y estado.',
48
72
  inputSchema: {},