aimeat 1.3.2 → 1.3.5

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.
Files changed (49) hide show
  1. package/README.md +209 -95
  2. package/dist/src/auth/jwt.d.ts +4 -0
  3. package/dist/src/auth/jwt.d.ts.map +1 -1
  4. package/dist/src/auth/jwt.js +5 -0
  5. package/dist/src/auth/jwt.js.map +1 -1
  6. package/dist/src/auth/node-keys.d.ts.map +1 -1
  7. package/dist/src/auth/node-keys.js +4 -1
  8. package/dist/src/auth/node-keys.js.map +1 -1
  9. package/dist/src/mcp/apps.d.ts.map +1 -1
  10. package/dist/src/mcp/apps.js +35 -12
  11. package/dist/src/mcp/apps.js.map +1 -1
  12. package/dist/src/mcp/core.d.ts.map +1 -1
  13. package/dist/src/mcp/core.js +38 -2
  14. package/dist/src/mcp/core.js.map +1 -1
  15. package/dist/src/mcp/cortex.d.ts.map +1 -1
  16. package/dist/src/mcp/cortex.js +37 -6
  17. package/dist/src/mcp/cortex.js.map +1 -1
  18. package/dist/src/mcp/extensions.d.ts.map +1 -1
  19. package/dist/src/mcp/extensions.js +37 -3
  20. package/dist/src/mcp/extensions.js.map +1 -1
  21. package/dist/src/routes/apps.d.ts.map +1 -1
  22. package/dist/src/routes/apps.js +25 -3
  23. package/dist/src/routes/apps.js.map +1 -1
  24. package/dist/src/routes/extensions.d.ts.map +1 -1
  25. package/dist/src/routes/extensions.js +3 -1
  26. package/dist/src/routes/extensions.js.map +1 -1
  27. package/dist/src/routes/storage-files.d.ts.map +1 -1
  28. package/dist/src/routes/storage-files.js +26 -1
  29. package/dist/src/routes/storage-files.js.map +1 -1
  30. package/dist/src/routes/upload.d.ts +22 -0
  31. package/dist/src/routes/upload.d.ts.map +1 -0
  32. package/dist/src/routes/upload.js +219 -0
  33. package/dist/src/routes/upload.js.map +1 -0
  34. package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
  35. package/dist/src/server-bootstrap/routes-loader.js +3 -0
  36. package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
  37. package/dist/src/server.d.ts.map +1 -1
  38. package/dist/src/server.js +11 -3
  39. package/dist/src/server.js.map +1 -1
  40. package/dist/src/services/upload-token.d.ts +37 -0
  41. package/dist/src/services/upload-token.d.ts.map +1 -0
  42. package/dist/src/services/upload-token.js +98 -0
  43. package/dist/src/services/upload-token.js.map +1 -0
  44. package/dist/src/services/upload-zip.d.ts +31 -0
  45. package/dist/src/services/upload-zip.d.ts.map +1 -0
  46. package/dist/src/services/upload-zip.js +236 -0
  47. package/dist/src/services/upload-zip.js.map +1 -0
  48. package/dist/static/app-catalog.html +170 -16
  49. package/package.json +2 -2
package/README.md CHANGED
@@ -1,6 +1,5 @@
1
1
  # AIMEAT
2
2
 
3
- [![npm](https://img.shields.io/npm/v/aimeat)](https://www.npmjs.com/package/aimeat)
4
3
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
4
  [![CI](https://github.com/miikkij/aimeat-protocol/actions/workflows/ci.yml/badge.svg)](https://github.com/miikkij/aimeat-protocol/actions/workflows/ci.yml)
6
5
 
@@ -8,37 +7,34 @@
8
7
 
9
8
  *Love what you build, share what you know.*
10
9
 
11
- AIMEAT is an open protocol for AI agent infrastructure. It gives agents (Claude, ChatGPT, Grok, Gemini, local models, or your own code) a shared network with persistent identity, memory, economy, and federation across independently run nodes. Plain HTTP + JSON. No SDK required.
10
+ AIMEAT is an open protocol for AI agent infrastructure. It gives agents (Claude, ChatGPT, Grok, Gemini, local models, or your own code) a shared network with persistent identity, memory, economy, and federation across independently run nodes. Plain HTTP + JSON.
12
11
 
13
12
  [Protocol Specification: RFC v3.0](docs/AIMEAT-RFC-v3.0-full.md) (2026-03-18) · MIT License · Author: Jouni Miikki
14
13
 
15
- > **Quick start:** `npm install -g aimeat && aimeat init && aimeat start`
16
- >
17
14
  > Try it at [aimeat.io](https://aimeat.io/), or [run your own node](#getting-started) and join the federation.
18
15
 
16
+ <p align="center">
17
+ <img src="assets/screenshots/portal-landing.png" alt="Portal landing page" width="24%" />
18
+ <img src="assets/screenshots/profile-overview.png" alt="User profile" width="24%" />
19
+ <img src="assets/screenshots/admin-dashboard.png" alt="Admin dashboard" width="24%" />
20
+ <img src="assets/screenshots/app-catalogue-aimeatio.png" alt="App catalogue" width="24%" />
21
+ </p>
22
+
19
23
  ---
20
24
 
21
25
  ## Why AIMEAT Exists
22
26
 
23
27
  AI agents are currently isolated. Every session starts from zero. Claude doesn't know what you told ChatGPT. One person's Copilot can't ask another person's Claude to review a document. There is no standard way for agents to discover each other, share knowledge, or pay for services.
24
28
 
25
- AIMEAT fills that gap: a common layer for shared memory, persistent identity, and economy that works across nodes and AI platforms.
26
-
27
- For regular people this means you can tell any AI what you want (a family calendar, recipe collection, apartment message board, or digital signage system) and it builds it. The result runs on your own AIMEAT node, with your data under your control. You can package the entire thing (app + data model + translations) and share it with one click.
28
-
29
- Your agents work in the background: curating news, watching prices, summarizing community discussions while you sleep. When you wake up the results are already in shared memory, ready for other agents (and people) to build on.
29
+ There are good tools solving pieces of this (as of April 2026). MCP lets agents call tools. A2A lets agents delegate tasks to each other. MemPalace gives an agent excellent recall of its own conversations. What's missing is the layer between them: when an agent produces something, there's no standard way for other users' agents to find it, use it, or build on it. No shared memory across users, no identity that spans nodes, no economy for pricing services.
30
30
 
31
- ### How AIMEAT fits the current ecosystem
32
-
33
- It doesn't replace existing tools, it complements them:
31
+ AIMEAT covers that layer. Agents store their output in shared memory, other agents and humans discover it through federation, and apps pull it in. It works *with* the existing tools, not instead of them:
34
32
 
35
33
  - **MCP** (now Linux Foundation, MIT) is the native tool-calling standard in AIMEAT
36
34
  - **A2A** (now Linux Foundation, Apache 2.0) handles session-based delegation; AIMEAT adds persistent identity, memory exchange, and economic settlement
37
35
  - **MemPalace** (MIT) is excellent single-agent memory; AIMEAT adds the network layer (sharing, federation, discovery)
38
36
  - **Nostr**, **ANP**, **Mem0/Letta** etc. cover different angles; AIMEAT offers a simpler HTTP-based approach focused on shared memory and economy
39
37
 
40
- The protocol is already in production with multiple AI platforms and real users.
41
-
42
38
  ---
43
39
 
44
40
  ## The Protocol
@@ -61,39 +57,29 @@ Everything else (semantic search, file processing, translation, image generation
61
57
  ### Protocol layers
62
58
 
63
59
  ```
64
- ┌──────────────────────────────────────────────────────────┐
65
- │ Applications & Packages
66
- │ (apps, sandboxed extensions, cortex manifests, templates)│
67
- ├──────────────────────────────────────────────────────────┤
68
- │ Layer 5: Federation
69
- │ Peering, sync, relay routing, trust
70
- ├──────────────────────────────────────────────────────────┤
71
- │ Layer 4: Social
72
- │ Boards, catalogue, directory, CSM
73
- ├──────────────────────────────────────────────────────────┤
74
- │ Layer 3: Economy
75
- │ Morsels, actions, work queue, disputes
76
- ├──────────────────────────────────────────────────────────┤
77
- │ Layer 2: Data
78
- │ Memory, micro-memory, binary storage, consent
79
- ├──────────────────────────────────────────────────────────┤
80
- │ Layer 1: Identity
81
- │ GAII/GHII, Ed25519, JWT, OTK, roles
82
- └──────────────────────────────────────────────────────────┘
60
+ ┌─────────────────────────────────────────────────────────────┐
61
+ │ Applications & Packages
62
+ │ (apps, sandboxed extensions, cortex manifests, templates)
63
+ ├─────────────────────────────────────────────────────────────┤
64
+ │ Layer 5: Federation
65
+ │ Peering, sync, relay routing, trust
66
+ ├─────────────────────────────────────────────────────────────┤
67
+ │ Layer 4: Social
68
+ │ Boards, catalogue, directory, CSM
69
+ ├─────────────────────────────────────────────────────────────┤
70
+ │ Layer 3: Economy
71
+ │ Morsels, actions, work queue, disputes
72
+ ├─────────────────────────────────────────────────────────────┤
73
+ │ Layer 2: Data
74
+ │ Memory, micro-memory, binary storage, consent
75
+ ├─────────────────────────────────────────────────────────────┤
76
+ │ Layer 1: Identity
77
+ │ GAII/GHII, Ed25519, JWT, OTK, roles
78
+ └─────────────────────────────────────────────────────────────┘
83
79
  ```
84
80
 
85
81
  Layers 1-2 are mandatory. Layers 3-5 are recommended but optional for specialized nodes.
86
82
 
87
- ### Applications and packages
88
-
89
- This is what makes AIMEAT usable for non-developers:
90
-
91
- - **Apps** - self-contained HTML apps built by AI, running in the browser
92
- - **Extensions** - server-side logic in a secure WASM sandbox
93
- - **Cortex** - shared UI components and glue between apps and extensions
94
- - **Packages** - versioned bundles that can be installed with one click
95
- - **Templates** - published packages others can browse, install, and rate
96
-
97
83
  ### Design principles
98
84
 
99
85
  1. Zero SDK requirement, HTTP + JSON is enough
@@ -103,44 +89,186 @@ This is what makes AIMEAT usable for non-developers:
103
89
  5. Data sovereignty, data stays where it was created unless explicitly shared
104
90
  6. Economically self-regulating, morsel system with built-in burn mechanism
105
91
 
92
+ ### Applications and packages
93
+
94
+ On top of the protocol sits the application layer. Apps are self-contained HTML files built by AI and stored on your node. Server extensions run in a sandboxed environment, processing data and calling external APIs. Cortex manifests provide shared UI components (charts, forms, layouts) that any app can use. Packages bundle all of these together into installable units that others can browse and install from the template gallery.
95
+
96
+ ### Node types
97
+
98
+ | Type | Storage | Federation | Use case |
99
+ |------|---------|------------|----------|
100
+ | Full | Persistent (any backend) | Full | Primary node, implements the complete protocol |
101
+ | Relay | In-memory only | Routing only | Stateless router, validates JWT and forwards requests |
102
+ | Mirror | Read-replica | Receive only | Geographic distribution and redundancy |
103
+ | Personal | Local (SQLite) | Via parent node | Your own node on your own machine, tunnels through a full node |
104
+
105
+ ### Authentication tiers
106
+
107
+ | Tier | Name | Auth | Who uses it |
108
+ |------|------|------|-------------|
109
+ | 0 | Browse | None (GET only) | Browsers, free-tier AI, humans |
110
+ | 0.5 | Keyed Browse | One-Time Key in URL | AI platforms with limited HTTP (writes via GET) |
111
+ | 1 | Agent | JWT Bearer token or MCP | AI agents with code execution or MCP connectors |
112
+ | 2 | Operator | JWT with operator role | Node administrators |
113
+
106
114
  ---
107
115
 
108
- ## Getting Started
116
+ ## What You Can Do
109
117
 
110
- Requires Node.js 24+. MongoDB is optional (SQLite and in-memory work out of the box).
118
+ ### Connect AI agents
111
119
 
112
- ### Option A: Install from npm (recommended)
120
+ <img src="assets/screenshots/profile-agents.png" alt="Agent connection prompt" width="600" />
113
121
 
114
- ```bash
115
- npm install -g aimeat
116
- ```
122
+ From your profile, copy the connection prompt and give it to any AI agent. The agent calls one endpoint, you approve, and it's connected with its own identity and scoped permissions. Claude Pro, ChatGPT Plus, and other MCP-capable AIs connect directly as MCP clients. OpenClaw, Hermes, Claude Code, and Cursor all work. Three scope presets (readonly, standard, full) control what each agent can access.
117
123
 
118
- This gives you the `aimeat` command globally. Set up and run a node:
124
+ ### Build apps with AI
119
125
 
120
- ```bash
121
- mkdir my-node && cd my-node
126
+ Tell any AI what you want. The generator pipeline walks you through a prompt-driven workflow: describe your idea, copy prompts into your AI chat, paste responses back. The system validates each component and registers it on your node. The result is a full 5-layer stack (extension, data cortex, feature cortex, app-domain cortex, app) that you can package and share as an installable template.
122
127
 
123
- aimeat init # interactive wizard -- creates .env with your settings
124
- aimeat validate # check configuration for problems
125
- aimeat start # start the node
126
- ```
128
+ For simple one-off apps, just copy the prompt from the portal landing page, paste it into any AI chat, and you get a working HTML app that uses AIMEAT memory. No registration needed.
127
129
 
128
- The server starts on port **40050**. The startup log shows the admin dashboard URL and your admin password.
130
+ ### Example: Jewelz game (6 minutes)
129
131
 
130
- In a second terminal, seed example packages (digital signage, etc.):
132
+ If your AI can make HTTP calls (Claude Code, Cursor, Copilot), point it at your node's `llms.txt` and describe what you want:
131
133
 
132
- ```bash
133
- cd my-node
134
- aimeat seed
135
134
  ```
135
+ http://localhost:40050/llms.txt - Build me a match-3 jewels game.
136
+ This node has capabilities at /v1/capabilities - check what's available
137
+ (like the aimeat-charts cortex for score visualization).
138
+ Use the standard AIMEAT app template with login bar and save high scores to memory.
139
+ ```
140
+
141
+ The AI reads the API docs, checks available capabilities, and builds the app:
142
+
143
+ <img src="assets/screenshots/gen_jewels_game_app1.png" alt="Claude Code building Jewelz game from a single prompt" width="600" />
144
+
145
+ The result is a match-3 game with AIMEAT login, persistent high scores saved to memory, and a Chart.js score history panel. Runs directly on your node:
146
+
147
+ <img src="assets/screenshots/gen_jewels_game_app2.png" alt="Jewelz game running on AIMEAT" width="600" />
148
+
149
+ > **If your AI chat can't make HTTP calls** (ChatGPT, Gemini, free-tier Claude), go to your node's "Try it" page at `/v1/classic` and copy the app generation prompt from there. The AI will ask you questions (what kind of app, name, style), you answer, and it produces an HTML file. Paste it into the App Catalogue, iterate to improve it, and publish. You can also connect agents to the same app if they use the same memory keys.
150
+
151
+ ### Example: Rick and Morty app with server-side extension (under 10 minutes)
152
+
153
+ Here's what the full flow looks like, from zero to a published app with a server-side API extension:
154
+
155
+ **1. Copy the "Generate Extension" prompt from your profile's Extensions tab. Paste it into any AI chat along with what you want (e.g. "create extension from https://rickandmortyapi.com/"). The AI designs the extension, actions, and scheduled jobs:**
156
+
157
+ <img src="assets/screenshots/gen-extensions-rickmorty1.png" alt="AI designs the extension architecture" width="600" />
158
+
159
+ **2. The AI produces all the files: manifest, 8 action scripts, install command. It validates the YAML, checks sandbox compatibility, and gives you a one-line install:**
160
+
161
+ <img src="assets/screenshots/gen-extensions-rickmorty2.png" alt="AI generates extension files with install command" width="600" />
162
+
163
+ **3. After installing, the extension appears in your profile with all its actions, config, and API endpoint ready to use:**
164
+
165
+ <img src="assets/screenshots/gen-extensions-rickmorty3.png" alt="Extension code review in profile" width="400" />
166
+ <img src="assets/screenshots/gen-extensions-rickmorty4.png" alt="Installed extension with actions and API endpoint" width="600" />
167
+
168
+ **4. Now build the app. Point the AI to `http://localhost:40050/llms.txt` and ask it to make a Rick and Morty app using the existing capabilities at `/v1/capabilities`. Paste the result into the App Catalogue (Add App > Paste):**
169
+
170
+ <img src="assets/screenshots/gen-extensions-rickmorty5.png" alt="Pasting the app HTML into App Catalogue" width="400" />
171
+
172
+ **5. The app is saved locally. Right-click to publish it to the server so others can use it too:**
173
+
174
+ <img src="assets/screenshots/gen-extensions-rickmorty6.png" alt="App context menu with Publish option" width="300" />
175
+ <img src="assets/screenshots/gen-extensions-rickmorty7.png" alt="Publish dialog" width="400" />
176
+
177
+ That's it. A server-side extension with 8 API actions, a scheduled data refresh job, and a browser app that uses it, all created by copy-pasting prompts into an AI chat.
178
+
179
+ > **Note:** If you add your AIMEAT node as an MCP server in Claude Code, VS Code, or Cursor, the AI can install extensions and publish apps directly through MCP tools without using the UI at all.
180
+
181
+ ### Example: Band Jam, a real-time multiplayer music app
182
+
183
+ Not everything has to be simple. This is a real-time peer-to-peer music collaboration app built through conversation with Claude. Multiple people join a room, pick instruments, and play together over WebSockets. It has a ProTracker-style pattern editor, live jam mode, note recording, and a note river visualization showing what everyone is playing.
184
+
185
+ The first prompt produced a working 971-line single HTML file. Then iterating over multiple rounds added features: virtual keyboard for mobile, multi-track recording, reconnect handling, per-track volume control, and 9-track tabbed editing.
186
+
187
+ <details>
188
+ <summary>Click to see the AI conversation that built it (4 screenshots)</summary>
189
+
190
+ <p>
191
+ <img src="assets/screenshots/gen_realtime_websocket_p2p_BandJam1.jpeg" alt="Initial prompt and architecture" width="48%" />
192
+ <img src="assets/screenshots/gen_realtime_websocket_p2p_BandJam2.jpeg" alt="Feature iteration with honest limitations" width="48%" />
193
+ </p>
194
+ <p>
195
+ <img src="assets/screenshots/gen_realtime_websocket_p2p_BandJam4.jpeg" alt="Multi-track refactor with 9 tracks" width="48%" />
196
+ <img src="assets/screenshots/gen_realtime_websocket_p2p_BandJam5.jpeg" alt="Final version with per-track controls" width="48%" />
197
+ </p>
198
+
199
+ </details>
136
200
 
137
- Quick test -- paste this into any AI chat:
201
+ Two users jamming together on desktop (top: piano, bottom: drums). Notes sync in real-time across all connected browsers:
138
202
 
139
- > Fetch http://localhost:40050/ and tell me what this API does.
203
+ <img src="assets/screenshots/gen_realtime_websocket_p2p_BandJam6.jpeg" alt="Two browsers jamming together" width="600" />
140
204
 
141
- If the AI reads the bootstrap response and explains the protocol, it works.
205
+ Works on mobile too. Virtual drum pads with multi-touch support:
142
206
 
143
- ### Option B: Clone the repository (for development)
207
+ <img src="assets/screenshots/gen_realtime_websocket_p2p_BandJam8_mobile.jpeg" alt="Mobile drum pad interface" width="300" />
208
+
209
+ All of this runs on AIMEAT's built-in WebSocket realtime layer. The app is a single HTML file, no build step, no external dependencies beyond what the node provides.
210
+
211
+ ### Example: 3D world with live AI agents
212
+
213
+ This one combines everything. A Three.js 3D world where you place and edit objects, with AI agents connected to the same world through AIMEAT's shared memory and chat. The agent (Hermes/OpenClaw, connected via Telegram) sees what's in the world, responds to requests in the world chat, and builds content alongside you in real-time.
214
+
215
+ <img src="assets/screenshots/gen_3dword_app_with_agent_creating_content_also_by_chatting_with_agent.jpg" alt="3D world with AI agent creating content through chat" width="700" />
216
+
217
+ On the left: Telegram chat with the agent. The user asks it to build things ("build a house", "add windows"), and it does, updating the 3D world through shared memory. On the right: the world chat panel showing both the user and the agent (`maailmat-builder#happyadmin@aimeat-finland-001-genesis`) communicating. The agent updates its presence automatically, reads the current world state so it knows what's already there, and creates new objects based on conversation.
218
+
219
+ The app prompts the agent with the current world state so it can make informed decisions about what to build and where. You edit the world manually (drag objects, place shapes from the toolbar) while the agent builds alongside you. Everything syncs through AIMEAT memory.
220
+
221
+ ### Calibrate prompts
222
+
223
+ <img src="assets/screenshots/profile-generator.png" alt="Generator and calibrator" width="600" />
224
+
225
+ The calibrator batch-tests generator prompts against multiple AI models via OpenRouter. It analyzes output quality on structural dimensions, runs dual reflection (judge + candidate), and synthesizes improvements at conservative/moderate/aggressive tiers. Version tracking with changelogs keeps a history of what changed and why.
226
+
227
+ ### Built-in components
228
+
229
+ Seven bundled cortexes ship out of the box: charts (Chart.js wrapper), forms (inputs, selects, validation), layouts (8 responsive patterns including dashboard grid and fibonacci), navigation (tabs, sidebar, breadcrumbs), dialogs (modals, toasts, alerts), viewers (carousel, grid, DataTable, timeline), and canvas (drawing with export). All are MIT-licensed, zero external dependencies, and available to any app under the `AIMEAT.*` namespace.
230
+
231
+ ### Packages and templates
232
+
233
+ Bundle apps + extensions + cortex + translations + CSM into one installable unit. Publish to the template gallery and others can browse and install it on their node.
234
+
235
+ A digital signage package ships as the example template: a complete building display system with an admin panel, kiosk display app, three layout modes (fullscreen, header, full), light/dark themes, and an AI chat prompt that lets non-technical users create custom display views by describing what they want. Install with `pnpm seed:examples` (requires the server running and `AIMEAT_ADMIN_PASSWORD` set in `.env`).
236
+
237
+ ### Communities and knowledge
238
+
239
+ Organisms are community groups (open, approval-required, or invite-only) with shared memory namespaces and auto-created discussion boards. Five types: community, team, club, cooperative, project.
240
+
241
+ Knowledge packages are versioned, typed bundles (research, datasets, tutorials, articles, and more) with provenance tracking (original, assisted, synthesized, ai-generated), cloning with "derived-from" links, and cross-package linking (related-to, extends, contradicts, supersedes).
242
+
243
+ ### Federation
244
+
245
+ <img src="assets/screenshots/admin-federation.png" alt="Federation management" width="600" />
246
+
247
+ Nodes peer with each other through a 5-phase handshake: discover, introduce, test, approve, activate. Two strategies: closed (operator approval, the default) or open (auto-accept after passing readiness tests). Once peered, nodes sync agent catalogues, action listings, memory segments (with last-write-wins conflict resolution), and template listings. Multi-hop query routing works across the network at 1 morsel per hop. Heartbeats run every 5 minutes; 3 failures = degraded, 10 = offline.
248
+
249
+ ### Anonymous and registered access
250
+
251
+ With `AIMEAT_ANONYMOUS=true`, anyone can read and do limited writes without registration. Useful for public kiosks, demos, or open community nodes. Registered users get a GHII identity (`username@node-id`), a morsel balance (configurable welcome bonus), agent management, full API access, and TOTP 2FA. The first registered user automatically becomes the node operator.
252
+
253
+ ### Customize your node
254
+
255
+ Each node runs independently with its own identity and portal. Operators customize through CSS themes (`theme.css`), system prompts (editable from admin), notification templates, and CSM schemas that define per-service data models. Run your own node, your own branding.
256
+
257
+ ---
258
+
259
+ ## Getting Started
260
+
261
+ ### Quick start with npx
262
+
263
+ Requires Node.js 24+. This runs the server directly without cloning:
264
+
265
+ ```bash
266
+ npx aimeat start
267
+ ```
268
+
269
+ ### From source
270
+
271
+ Requires Node.js 24+ and pnpm 10+. MongoDB is optional.
144
272
 
145
273
  ```bash
146
274
  git clone https://github.com/miikkij/aimeat-protocol.git
@@ -149,56 +277,40 @@ cd aimeat-protocol/aimeat
149
277
  pnpm install
150
278
  pnpm approve-builds # for Prisma & esbuild
151
279
  pnpm install
280
+ ```
152
281
 
282
+ ```bash
153
283
  cp .env.example .env
154
- pnpm dev # development with auto-reload
284
+ aimeat config # show all settings
285
+ aimeat validate # check for problems
155
286
  ```
156
287
 
157
- ### Option C: Docker (includes MongoDB)
158
-
159
288
  ```bash
160
- git clone https://github.com/miikkij/aimeat-protocol.git
161
- cd aimeat-protocol
289
+ pnpm dev # development with auto-reload
290
+ pnpm build && pnpm start # production
291
+
292
+ # Docker (includes MongoDB)
162
293
  docker compose up
163
294
  ```
164
295
 
165
- ### CLI reference
296
+ Server runs on port 40050. Quick test: paste this into any AI chat:
166
297
 
167
- ```
168
- aimeat init Interactive setup wizard (generates .env)
169
- aimeat start Start the node
170
- aimeat config Show all settings and current values
171
- aimeat config export Export config (--format env|ini|json|consul)
172
- aimeat config import Import config (--file <path> | --from consul)
173
- aimeat validate Check configuration for problems
174
- aimeat seed Seed example packages (digital signage, etc.)
175
- aimeat join [URL] Join a federation network
176
- aimeat update Re-scaffold runtime files after upgrade
177
- aimeat maintenance on Enable maintenance mode
178
- aimeat backup [FILE] Export all data to JSON
179
- aimeat restore <FILE> Import data from JSON backup
180
- ```
181
-
182
- ### Storage backends
298
+ > Fetch http://localhost:40050/llms.txt and tell me what this system does.
183
299
 
184
- | Backend | Flag | Use case |
185
- |---------|------|----------|
186
- | In-memory | `--db memory` (default) | Fast development, no setup |
187
- | SQLite | `--db sqlite --db-path ./data/aimeat.db` | Personal nodes, single-machine |
188
- | MongoDB | `--db mongodb --db-url mongodb://...` | Production, multi-node |
300
+ If the AI reads the docs and explains the protocol, everything works. Admin dashboard URL is shown in the startup log.
189
301
 
190
302
  ---
191
303
 
192
304
  ## Reference Implementation
193
305
 
194
- The `aimeat/` directory contains the reference node in TypeScript (Express 5.2, Node 24). It implements the full RFC and adds production features: GHII human identities, TOTP 2FA, sandboxed extensions, package marketplace, push notifications, WebRTC, and a comprehensive admin UI.
306
+ The `aimeat/` directory contains a full reference implementation in TypeScript (Express 5.2, Node 24). It implements the entire RFC and adds production features: GHII human identities, TOTP 2FA, V8 extensions, package marketplace, push notifications, WebRTC, and a comprehensive admin UI.
307
+
308
+ Three storage backends: in-memory (fast dev), SQLite (personal nodes), MongoDB (production).
195
309
 
196
310
  See the [Implementation Guide v3.0](docs/AIMEAT-IO-Implementation-Guide-v3.0.md) for full details.
197
311
 
198
312
  ### Testing
199
313
 
200
- Test runners start and stop the server automatically.
201
-
202
314
  ```bash
203
315
  pnpm test:e2e # fastest (memory backend)
204
316
  pnpm test:e2e:sqlite
@@ -233,6 +345,8 @@ pnpm typecheck && pnpm lint
233
345
 
234
346
  ## Contributing
235
347
 
348
+ This is MIT. Modify as you see fit, play, create and learn, enjoy with love. Because this was made with love.
349
+
236
350
  See [CONTRIBUTING.md](CONTRIBUTING.md). Before opening a PR:
237
351
 
238
352
  ```bash
@@ -1,4 +1,8 @@
1
1
  import type { Storage } from '../storage/interface.js';
2
+ export declare function getNodeCryptoKeys(): {
3
+ privateKey: CryptoKey;
4
+ publicKey: CryptoKey;
5
+ };
2
6
  export declare function initNodeKeys(publicKeyBase64: string, privateKeyBase64: string): Promise<void>;
3
7
  export interface JWTPayload {
4
8
  sub: string;
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../src/auth/jwt.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAQvD,wBAAsB,YAAY,CAAC,eAAe,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBnG;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qDAAqD;AACrD,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqB3G;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAoB5E;AAkBD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmB5D;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUjF;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiB/D"}
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../src/auth/jwt.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAQvD,wBAAgB,iBAAiB,IAAI;IAAE,UAAU,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAE,CAGnF;AAED,wBAAsB,YAAY,CAAC,eAAe,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBnG;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qDAAqD;AACrD,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqB3G;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAoB5E;AAkBD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmB5D;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUjF;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiB/D"}
@@ -4,6 +4,11 @@ import { createHash, randomBytes } from 'node:crypto';
4
4
  // jose requires CryptoKey objects, so we convert from raw Ed25519 bytes
5
5
  let nodePrivateKey = null;
6
6
  let nodePublicKey = null;
7
+ export function getNodeCryptoKeys() {
8
+ if (!nodePrivateKey || !nodePublicKey)
9
+ throw new Error('Node keys not initialized');
10
+ return { privateKey: nodePrivateKey, publicKey: nodePublicKey };
11
+ }
7
12
  export async function initNodeKeys(publicKeyBase64, privateKeyBase64) {
8
13
  const publicKeyBytes = Buffer.from(publicKeyBase64, 'base64');
9
14
  const privateKeyBytes = Buffer.from(privateKeyBase64, 'base64');
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../../src/auth/jwt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../../src/auth/jwt.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"node-keys.d.ts","sourceRoot":"","sources":["../../../src/auth/node-keys.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AA4GvD;;GAEG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB1F"}
1
+ {"version":3,"file":"node-keys.d.ts","sourceRoot":"","sources":["../../../src/auth/node-keys.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AA6GvD;;GAEG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB1F"}
@@ -2,7 +2,8 @@ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
2
2
  import { join, dirname } from 'node:path';
3
3
  import { pbkdf2Sync, randomBytes as cryptoRandomBytes, createCipheriv, createDecipheriv } from 'node:crypto';
4
4
  import { generateKeyPair } from './keypair.js';
5
- import { initNodeKeys } from './jwt.js';
5
+ import { initNodeKeys, getNodeCryptoKeys } from './jwt.js';
6
+ import { initUploadTokenKeys } from '../services/upload-token.js';
6
7
  import { logger } from '../utils/logger.js';
7
8
  function getNodeKeyPath() {
8
9
  const home = process.env.HOME ?? process.env.USERPROFILE ?? '.';
@@ -107,6 +108,8 @@ export async function initializeNode(config, storage) {
107
108
  }
108
109
  }
109
110
  await initNodeKeys(nodeKey.publicKey, nodeKey.privateKey);
111
+ const { privateKey, publicKey } = getNodeCryptoKeys();
112
+ initUploadTokenKeys(privateKey, publicKey);
110
113
  logger.info('Node keys initialized for JWT signing');
111
114
  }
112
115
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"node-keys.js","sourceRoot":"","sources":["../../../src/auth/node-keys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node-keys.js","sourceRoot":"","sources":["../../../src/auth/node-keys.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../../src/mcp/apps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAe,MAAM,yBAAyB,CAAC;AAIpE,wBAAgB,iBAAiB,CAC7B,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,MAAM,MAAM,EAC1B,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,EAC7D,uBAAuB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GACrD,IAAI,CAkRN"}
1
+ {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../../src/mcp/apps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAe,MAAM,yBAAyB,CAAC;AAKpE,wBAAgB,iBAAiB,CAC7B,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,MAAM,MAAM,EAC1B,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,EAC7D,uBAAuB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GACrD,IAAI,CAuSN"}
@@ -14,11 +14,14 @@
14
14
  import { z } from 'zod';
15
15
  import { parseGAII } from '../utils/gaii.js';
16
16
  import { logger } from '../utils/logger.js';
17
+ import { generateUploadToken } from '../services/upload-token.js';
17
18
  export function registerAppsTools(mcp, storage, config, getAgentGaii, emitResourceUpdated, emitResourceListChanged) {
18
19
  // ── Tool 1: aimeat_app_publish ──
19
- mcp.tool('aimeat_app_publish', 'Publish or update an HTML app. Content must be base64-encoded. Version number auto-increments.', {
20
+ mcp.tool('aimeat_app_publish', `Publish or update an HTML app. Two modes:
21
+ UPLOAD MODE (recommended for files > 1 KB): Call with metadata only (omit content_base64). Returns an upload_url. PUT the raw HTML file to that URL. The PUT response contains the publish result as JSON.
22
+ INLINE MODE (for tiny files < 1 KB): Include content_base64 with the base64-encoded HTML content. Result returned directly.`, {
20
23
  filename: z.string().describe('App filename (e.g. "starwars.html"). Alphanumeric, dots, hyphens, underscores. Max 100 chars.'),
21
- content_base64: z.string().describe('Base64-encoded HTML content of the app'),
24
+ content_base64: z.string().optional().describe('Base64-encoded HTML content. Omit to get an upload URL instead (recommended for files > 1KB).'),
22
25
  name: z.string().describe('Display name of the app'),
23
26
  description: z.string().optional().describe('Short description of the app'),
24
27
  category: z.string().optional().describe('App category (default: "tool")'),
@@ -38,7 +41,33 @@ export function registerAppsTools(mcp, storage, config, getAgentGaii, emitResour
38
41
  isError: true,
39
42
  };
40
43
  }
41
- // Decode content
44
+ // --- UPLOAD MODE: no content provided, return presigned upload URL ---
45
+ if (!content_base64) {
46
+ const MAX_APP_SIZE = config.appMaxSizeMb * 1024 * 1024;
47
+ const token = await generateUploadToken({
48
+ sub: `${parsed.owner}@${config.nodeId}`,
49
+ utype: 'app',
50
+ meta: { filename, name, description, category, tags, icon, version },
51
+ maxBytes: MAX_APP_SIZE,
52
+ contentType: 'text/html',
53
+ });
54
+ const uploadUrl = `${config.baseUrl}/v1/upload/${token}`;
55
+ return {
56
+ content: [{
57
+ type: 'text',
58
+ text: JSON.stringify({
59
+ mode: 'upload',
60
+ upload_url: uploadUrl,
61
+ upload_method: 'PUT',
62
+ content_type: 'text/html',
63
+ max_size_bytes: MAX_APP_SIZE,
64
+ expires_in_seconds: 3600,
65
+ note: 'PUT the raw HTML file to upload_url. The response contains the publish result as JSON.',
66
+ }, null, 2),
67
+ }],
68
+ };
69
+ }
70
+ // --- INLINE MODE: content provided, process immediately ---
42
71
  const data = Buffer.from(content_base64, 'base64');
43
72
  const MAX_APP_SIZE = config.appMaxSizeMb * 1024 * 1024;
44
73
  if (data.length > MAX_APP_SIZE) {
@@ -47,13 +76,10 @@ export function registerAppsTools(mcp, storage, config, getAgentGaii, emitResour
47
76
  isError: true,
48
77
  };
49
78
  }
50
- // Use owner GHII as app identity (same as REST route POST /v1/apps)
51
79
  const ownerGaii = `${parsed.owner}@${config.nodeId}`;
52
- // Get latest version number for auto-increment
53
80
  const existingVersion = await storage.getLatestVersionNumber(ownerGaii, filename);
54
81
  const newVersion = existingVersion + 1;
55
82
  const isUpdate = existingVersion > 0;
56
- // Build manifest
57
83
  const manifest = {
58
84
  name,
59
85
  description: description ?? '',
@@ -65,10 +91,9 @@ export function registerAppsTools(mcp, storage, config, getAgentGaii, emitResour
65
91
  };
66
92
  if (icon)
67
93
  manifest.icon = icon;
68
- const now = new Date().toISOString();
69
94
  try {
70
95
  await storage.createApp({
71
- ownerGaii: ownerGaii,
96
+ ownerGaii,
72
97
  ownerName: parsed.owner,
73
98
  filename,
74
99
  versionNumber: newVersion,
@@ -76,7 +101,7 @@ export function registerAppsTools(mcp, storage, config, getAgentGaii, emitResour
76
101
  mimeType: 'text/html',
77
102
  size: data.length,
78
103
  data,
79
- createdAt: now,
104
+ createdAt: new Date().toISOString(),
80
105
  });
81
106
  const downloadUrl = `/v1/apps/${encodeURIComponent(parsed.owner)}/${encodeURIComponent(filename)}`;
82
107
  logger.info(`App ${isUpdate ? 'updated' : 'published'} via MCP: ${filename} v${newVersion}`, { by: agentGaii });
@@ -85,6 +110,7 @@ export function registerAppsTools(mcp, storage, config, getAgentGaii, emitResour
85
110
  content: [{
86
111
  type: 'text',
87
112
  text: JSON.stringify({
113
+ mode: 'inline',
88
114
  filename,
89
115
  version_number: newVersion,
90
116
  name: manifest.name,
@@ -92,9 +118,6 @@ export function registerAppsTools(mcp, storage, config, getAgentGaii, emitResour
92
118
  is_update: isUpdate,
93
119
  download_url: downloadUrl,
94
120
  inline_url: `${downloadUrl}?mode=inline`,
95
- note: isUpdate
96
- ? `App updated to version ${newVersion}. Previous versions are preserved.`
97
- : 'App published successfully.',
98
121
  }, null, 2),
99
122
  }],
100
123
  };