@autopo/mcp 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +119 -2
- package/dist/api.d.ts +51 -0
- package/dist/api.js +107 -0
- package/dist/api.js.map +1 -0
- package/dist/apps.d.ts +10 -0
- package/dist/apps.js +146 -0
- package/dist/apps.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +63 -0
- package/dist/cli.js.map +1 -0
- package/dist/guides.d.ts +3 -0
- package/dist/guides.js +52 -0
- package/dist/guides.js.map +1 -0
- package/dist/http.d.ts +20 -0
- package/dist/http.js +119 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/kit.d.ts +149 -0
- package/dist/kit.js +206 -0
- package/dist/kit.js.map +1 -0
- package/dist/prompts.d.ts +3 -0
- package/dist/prompts.js +44 -0
- package/dist/prompts.js.map +1 -0
- package/dist/resources.d.ts +4 -0
- package/dist/resources.js +40 -0
- package/dist/resources.js.map +1 -0
- package/dist/server.d.ts +24 -0
- package/dist/server.js +40 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/company.d.ts +4 -0
- package/dist/tools/company.js +431 -0
- package/dist/tools/company.js.map +1 -0
- package/dist/tools/marketing.d.ts +4 -0
- package/dist/tools/marketing.js +214 -0
- package/dist/tools/marketing.js.map +1 -0
- package/dist/tools/studio.d.ts +9 -0
- package/dist/tools/studio.js +363 -0
- package/dist/tools/studio.js.map +1 -0
- package/dist/ui/gallery.html +124 -0
- package/dist/ui/home.html +124 -0
- package/dist/ui/inbox.html +124 -0
- package/dist/ui/money.html +124 -0
- package/dist/ui/storyboard.html +124 -0
- package/package.json +71 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Autopoiesis
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,120 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://autopoiesis.app/favicon.svg" width="56" alt="" />
|
|
3
|
+
</p>
|
|
4
|
+
<h1 align="center">Autopoiesis MCP</h1>
|
|
5
|
+
<p align="center">Run your AI-run company from Claude Code, Codex, Cursor, Claude Desktop or ChatGPT.<br/>
|
|
6
|
+
Briefings, the Board inbox, tasks, the team, the Studio, marketing, money: as you, with your permissions.</p>
|
|
2
7
|
|
|
3
|
-
|
|
8
|
+
<p align="center">
|
|
9
|
+
<a href="https://www.npmjs.com/package/@autopo/mcp"><img src="https://img.shields.io/npm/v/%40autopo%2Fmcp?color=B8F36B&label=npm" alt="npm" /></a>
|
|
10
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-black" alt="MIT" /></a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
you › make a 20-second teaser for our launch
|
|
15
|
+
› brand_brain · create_video · ask_agent creative · video_keyframes (confirm $0.09) · critique_video
|
|
16
|
+
› make_video_media (confirm $1.20) · wait_for_video · render_video · open_in_app
|
|
17
|
+
you › approve the hosting card and tell Kaveh to go
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Connect in a minute
|
|
21
|
+
|
|
22
|
+
1. In the app: **Connectors → MCP → Make the token**. Copy it; it is shown once.
|
|
23
|
+
2. Paste one line into your tool.
|
|
24
|
+
|
|
25
|
+
**Claude Code**
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
claude mcp add --transport http autopoiesis https://autopoiesis-api-267405155162.us-west1.run.app/mcp --header "Authorization: Bearer apk_…"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Codex** (`~/.codex/config.toml`, then `export AUTOPOIESIS_TOKEN=apk_…`)
|
|
32
|
+
|
|
33
|
+
```toml
|
|
34
|
+
[mcp_servers.autopoiesis]
|
|
35
|
+
url = "https://autopoiesis-api-267405155162.us-west1.run.app/mcp"
|
|
36
|
+
bearer_token_env_var = "AUTOPOIESIS_TOKEN"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Cursor** (`~/.cursor/mcp.json`, or the *Add to Cursor* button on the Connectors page)
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{ "mcpServers": { "autopoiesis": { "url": "https://autopoiesis-api-267405155162.us-west1.run.app/mcp", "headers": { "Authorization": "Bearer apk_…" } } } }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Claude Desktop** (`claude_desktop_config.json`): inline views render here.
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{ "mcpServers": { "autopoiesis": { "command": "npx", "args": ["-y", "@autopo/mcp"], "env": { "AUTOPOIESIS_TOKEN": "apk_…" } } } }
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Prefer to run the server on your machine with any tool? `npx -y @autopo/mcp` with `AUTOPOIESIS_TOKEN` set is the whole install.
|
|
52
|
+
|
|
53
|
+
## What it does
|
|
54
|
+
|
|
55
|
+
| | |
|
|
56
|
+
|---|---|
|
|
57
|
+
| **63 tools** | the company at a glance, briefings, the inbox, tasks, the team's chats, runs, knowledge, the Studio, marketing, money, and `api_request` for every other endpoint of the REST API with `api_reference` as the manual |
|
|
58
|
+
| **Asks before it spends** | anything that spends credits or cannot be undone opens a confirmation dialog in your tool, with the cost: generate media, keyframes, clips, decide a card, post, cancel, delete |
|
|
59
|
+
| **Inline views** | the inbox, a video's storyboard, the media library, your home and the money page render inside Cursor, Claude Desktop and ChatGPT ([MCP Apps](https://modelcontextprotocol.io/extensions/apps/overview)); Claude Code and Codex CLI get the same results as text |
|
|
60
|
+
| **Docs** | [docs.autopoiesis.app](https://docs.autopoiesis.app): quickstart per client, guides, the tool reference, the REST API |
|
|
61
|
+
| **Prompts** | `/autopoiesis:make_a_teaser`, `morning_review`, `decide_inbox`, `studio_status`, `weekly_marketing` |
|
|
62
|
+
| **Resources** | the Studio guide, the teaser guide, a company's home and brand brain, the API's OpenAPI document |
|
|
63
|
+
| **Both protocol eras** | the stateless 2026-07-28 revision and the 2025 `initialize` handshake today's clients speak, from one endpoint |
|
|
64
|
+
|
|
65
|
+
Everything happens as you: your permissions, member access areas, limits and billing hold exactly as in the app, and it all shows in the app as you did it. A token can be scoped to one company and revoked at any time; it can never make tokens, delete the account or hand a company over.
|
|
66
|
+
|
|
67
|
+
## The teaser loop
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
brand_brain → create_video {title, brief, seconds: 20}
|
|
71
|
+
→ get_video → ask_agent {agent: "creative", production: <id>, message: "tighten the shots"} → apply_chat_action
|
|
72
|
+
→ studio_overview → update_video {style: {models}} (only if the defaults don't fit)
|
|
73
|
+
→ video_keyframes (you confirm the cents) → wait_for_video → critique_video {stage: "keyframes"}
|
|
74
|
+
→ make_video_media (you confirm the cost) → wait_for_video → critique_video {stage: "clips"}
|
|
75
|
+
→ render_video (free) → wait_for_video → the render link, or open_in_app {what: "video", id}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The `make_a_teaser` prompt runs this for you, step by step, stopping at every dialog.
|
|
79
|
+
|
|
80
|
+
## Run it yourself
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
npx -y @autopo/mcp # stdio, for a tool on this machine (AUTOPOIESIS_TOKEN)
|
|
84
|
+
npx -y @autopo/mcp --http # Streamable HTTP on PORT, one token per request (Authorization: Bearer)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
| Variable | What it is |
|
|
88
|
+
|---|---|
|
|
89
|
+
| `AUTOPOIESIS_TOKEN` | your personal access token (stdio only; HTTP takes it per request) |
|
|
90
|
+
| `AUTOPOIESIS_API_URL` | the platform API (default: the production API) |
|
|
91
|
+
| `AUTOPOIESIS_APP_URL` | the web app, for links (default `https://app.autopoiesis.app`) |
|
|
92
|
+
| `AUTOPOIESIS_MCP_URL` | this server's public address when hosted (names the Claude sandbox domain for the views) |
|
|
93
|
+
| `AUTOPOIESIS_MEDIA_DOMAINS` | extra origins the views may load media from, comma separated |
|
|
94
|
+
|
|
95
|
+
A `Dockerfile` builds the hosted server (Cloud Run: `PORT` is set for you; turn on session affinity so 2025-era clients keep their session on one instance).
|
|
96
|
+
|
|
97
|
+
## Develop
|
|
98
|
+
|
|
99
|
+
The source lives in Autopoiesis' repository; this package ships the built server and views.
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
npm install
|
|
103
|
+
npm run typecheck # server + views
|
|
104
|
+
npm test # the server against an in-memory API, both protocol eras
|
|
105
|
+
npm run build # dist/ (server) and dist/ui/*.html (the views, one file each)
|
|
106
|
+
npm run docs:tools # docs/tools/*.mdx from the server's own tool list
|
|
107
|
+
npm run dev # the stdio server from source (tsx)
|
|
108
|
+
npx @modelcontextprotocol/inspector node dist/cli.js
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Layout: `src/tools/*` (the tools, grouped the way the app is), `src/kit.ts` (sessions, elicitation, the `define()` wrapper), `src/apps.ts` (the inline views' resources and the app-only tools their buttons call), `src/http.ts` (the hosted server, both protocol legs), `ui/*` (the views, React, built to one HTML file each), `docs/` (the documentation site, Mintlify), `test/` (an in-memory API and the end-to-end tests).
|
|
112
|
+
|
|
113
|
+
## Security
|
|
114
|
+
|
|
115
|
+
- The token is a hashed secret the platform checks on every call; this server forwards it and never stores it.
|
|
116
|
+
- Every tool is a thin wrapper over the public REST API, so nothing here can do what you could not do in the app.
|
|
117
|
+
- Confirmations are host-enforced dialogs (MCP elicitation), not instructions the model may skip. Hosts that cannot show them get a refusal, never a silent spend.
|
|
118
|
+
- Report a vulnerability to security@autopoiesis.app.
|
|
119
|
+
|
|
120
|
+
MIT © Autopoiesis. Questions: support@autopoiesis.app
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The platform's REST API, called as the person whose token this is. Every MCP tool is a thin wrapper over these
|
|
3
|
+
* endpoints, so permissions, member access areas, limits, billing and the user action log hold exactly as in the app:
|
|
4
|
+
* the server never sees anything the person could not do themselves.
|
|
5
|
+
*/
|
|
6
|
+
export interface ApiErrorBody {
|
|
7
|
+
error?: {
|
|
8
|
+
code?: string;
|
|
9
|
+
message?: string;
|
|
10
|
+
fields?: Record<string, string[]>;
|
|
11
|
+
};
|
|
12
|
+
raw?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class ApiError extends Error {
|
|
15
|
+
readonly status: number;
|
|
16
|
+
readonly code: string | undefined;
|
|
17
|
+
readonly body: ApiErrorBody;
|
|
18
|
+
constructor(status: number, body: ApiErrorBody);
|
|
19
|
+
}
|
|
20
|
+
export type Query = Record<string, string | number | boolean | null | undefined>;
|
|
21
|
+
export interface ApiOptions {
|
|
22
|
+
/** The API's origin, e.g. https://api.example.com (no trailing slash). */
|
|
23
|
+
baseUrl: string;
|
|
24
|
+
/** The person's token: a personal access token (apk_…) made on the Connectors page, or the app's own JWT. */
|
|
25
|
+
token: string;
|
|
26
|
+
fetch?: typeof fetch;
|
|
27
|
+
userAgent?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare class Api {
|
|
30
|
+
readonly baseUrl: string;
|
|
31
|
+
private readonly token;
|
|
32
|
+
private readonly fetchImpl;
|
|
33
|
+
private readonly userAgent;
|
|
34
|
+
constructor(options: ApiOptions);
|
|
35
|
+
request<T = unknown>(method: string, path: string, body?: unknown, query?: Query): Promise<T>;
|
|
36
|
+
get<T = unknown>(path: string, query?: Query): Promise<T>;
|
|
37
|
+
post<T = unknown>(path: string, body?: unknown, query?: Query): Promise<T>;
|
|
38
|
+
patch<T = unknown>(path: string, body: unknown): Promise<T>;
|
|
39
|
+
put<T = unknown>(path: string, body: unknown): Promise<T>;
|
|
40
|
+
delete<T = unknown>(path: string): Promise<T>;
|
|
41
|
+
}
|
|
42
|
+
/** A list endpoint's rows, whether it paginates (`{results, count, next}`) or returns a bare list. */
|
|
43
|
+
export declare function rows<T = Record<string, unknown>>(data: unknown): T[];
|
|
44
|
+
/** Trim a list result so it never floods the model: `count` and `more` say what was left out. */
|
|
45
|
+
export declare function trimmed<T = Record<string, unknown>>(data: unknown, limit?: number): {
|
|
46
|
+
results: T[];
|
|
47
|
+
count: number;
|
|
48
|
+
more: boolean;
|
|
49
|
+
};
|
|
50
|
+
/** Keep only some keys of an object (for the brief forms of rows). */
|
|
51
|
+
export declare function pick<T extends Record<string, unknown>>(row: T, keys: readonly string[]): Record<string, unknown>;
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The platform's REST API, called as the person whose token this is. Every MCP tool is a thin wrapper over these
|
|
3
|
+
* endpoints, so permissions, member access areas, limits, billing and the user action log hold exactly as in the app:
|
|
4
|
+
* the server never sees anything the person could not do themselves.
|
|
5
|
+
*/
|
|
6
|
+
export class ApiError extends Error {
|
|
7
|
+
status;
|
|
8
|
+
code;
|
|
9
|
+
body;
|
|
10
|
+
constructor(status, body) {
|
|
11
|
+
const message = body.error?.message ?? (status === 401 ? 'The token is unknown or revoked.' : `HTTP ${status}`);
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = 'ApiError';
|
|
14
|
+
this.status = status;
|
|
15
|
+
this.code = body.error?.code;
|
|
16
|
+
this.body = body;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class Api {
|
|
20
|
+
baseUrl;
|
|
21
|
+
token;
|
|
22
|
+
fetchImpl;
|
|
23
|
+
userAgent;
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, '');
|
|
26
|
+
this.token = options.token;
|
|
27
|
+
this.fetchImpl = options.fetch ?? globalThis.fetch;
|
|
28
|
+
this.userAgent = options.userAgent ?? 'autopoiesis-mcp';
|
|
29
|
+
}
|
|
30
|
+
async request(method, path, body, query) {
|
|
31
|
+
if (!path.startsWith('/api/')) {
|
|
32
|
+
throw new ApiError(400, { error: { code: 'validation_error', message: 'Paths start with /api/ (see the API reference).' } });
|
|
33
|
+
}
|
|
34
|
+
const url = new URL(this.baseUrl + path);
|
|
35
|
+
for (const [key, value] of Object.entries(query ?? {})) {
|
|
36
|
+
if (value === undefined || value === null || value === '')
|
|
37
|
+
continue;
|
|
38
|
+
url.searchParams.set(key, String(value));
|
|
39
|
+
}
|
|
40
|
+
const headers = {
|
|
41
|
+
Authorization: `Bearer ${this.token}`,
|
|
42
|
+
Accept: 'application/json',
|
|
43
|
+
'User-Agent': this.userAgent,
|
|
44
|
+
'X-Client': 'mcp',
|
|
45
|
+
};
|
|
46
|
+
if (body !== undefined)
|
|
47
|
+
headers['Content-Type'] = 'application/json';
|
|
48
|
+
const init = { method, headers };
|
|
49
|
+
if (body !== undefined)
|
|
50
|
+
init.body = JSON.stringify(body);
|
|
51
|
+
const response = await this.fetchImpl(url, init);
|
|
52
|
+
const text = await response.text();
|
|
53
|
+
let data = null;
|
|
54
|
+
if (text) {
|
|
55
|
+
try {
|
|
56
|
+
data = JSON.parse(text);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
data = { raw: text.slice(0, 2000) };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
const errorBody = data && typeof data === 'object' && !Array.isArray(data) ? data : { error: { message: String(data).slice(0, 300) } };
|
|
64
|
+
throw new ApiError(response.status, errorBody);
|
|
65
|
+
}
|
|
66
|
+
return data;
|
|
67
|
+
}
|
|
68
|
+
get(path, query) {
|
|
69
|
+
return this.request('GET', path, undefined, query);
|
|
70
|
+
}
|
|
71
|
+
post(path, body = {}, query) {
|
|
72
|
+
return this.request('POST', path, body, query);
|
|
73
|
+
}
|
|
74
|
+
patch(path, body) {
|
|
75
|
+
return this.request('PATCH', path, body);
|
|
76
|
+
}
|
|
77
|
+
put(path, body) {
|
|
78
|
+
return this.request('PUT', path, body);
|
|
79
|
+
}
|
|
80
|
+
delete(path) {
|
|
81
|
+
return this.request('DELETE', path);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** A list endpoint's rows, whether it paginates (`{results, count, next}`) or returns a bare list. */
|
|
85
|
+
export function rows(data) {
|
|
86
|
+
if (Array.isArray(data))
|
|
87
|
+
return data;
|
|
88
|
+
if (data && typeof data === 'object' && Array.isArray(data.results))
|
|
89
|
+
return data.results;
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
/** Trim a list result so it never floods the model: `count` and `more` say what was left out. */
|
|
93
|
+
export function trimmed(data, limit = 50) {
|
|
94
|
+
const all = rows(data);
|
|
95
|
+
const count = data && typeof data === 'object' && typeof data.count === 'number' ? data.count : all.length;
|
|
96
|
+
const next = Boolean(data && typeof data === 'object' && data.next);
|
|
97
|
+
return { results: all.slice(0, limit), count, more: all.length > limit || next };
|
|
98
|
+
}
|
|
99
|
+
/** Keep only some keys of an object (for the brief forms of rows). */
|
|
100
|
+
export function pick(row, keys) {
|
|
101
|
+
const out = {};
|
|
102
|
+
for (const key of keys)
|
|
103
|
+
if (key in row)
|
|
104
|
+
out[key] = row[key];
|
|
105
|
+
return out;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/apps.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
|
+
import type { Session } from './kit.js';
|
|
3
|
+
export declare const VIEWS: readonly ['inbox', 'storyboard', 'gallery', 'home', 'money'];
|
|
4
|
+
export type View = (typeof VIEWS)[number];
|
|
5
|
+
export declare const viewUri: (view: View) => string;
|
|
6
|
+
/** The built HTML of a view, wherever this module runs from (dist/, or src/ under tsx). */
|
|
7
|
+
export declare function viewHtml(view: View): string | null;
|
|
8
|
+
/** Claude's sandbox origin for a hosted server: the first 32 hex characters of the SHA-256 of the server URL. */
|
|
9
|
+
export declare function claudeDomain(publicUrl: string | undefined): string | undefined;
|
|
10
|
+
export declare function registerApps(server: McpServer, s: Session): void;
|
package/dist/apps.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Apps (the `io.modelcontextprotocol/ui` extension): views a host renders inline for some tools' results. Each view
|
|
3
|
+
* is one self-contained HTML file built from ui/<name>/ into dist/ui/<name>.html. Hosts that don't render apps (Claude
|
|
4
|
+
* Code, Codex CLI) still get the full text result: the views are an extra, never the only answer.
|
|
5
|
+
*
|
|
6
|
+
* Buttons in a view call app-only tools (hidden from the model): the click is the person's confirmation, so those skip
|
|
7
|
+
* the elicitation their model-facing twins ask for.
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
10
|
+
import { createHash } from 'node:crypto';
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
import { dirname, join } from 'node:path';
|
|
13
|
+
import { RESOURCE_MIME_TYPE, registerAppResource, registerAppTool } from '@modelcontextprotocol/ext-apps/server';
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
export const VIEWS = ['inbox', 'storyboard', 'gallery', 'home', 'money'];
|
|
16
|
+
export const viewUri = (view) => `ui://autopoiesis/${view}.html`;
|
|
17
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
18
|
+
/** The built HTML of a view, wherever this module runs from (dist/, or src/ under tsx). */
|
|
19
|
+
export function viewHtml(view) {
|
|
20
|
+
for (const dir of [join(here, 'ui'), join(here, '..', 'dist', 'ui')]) {
|
|
21
|
+
const file = join(dir, `${view}.html`);
|
|
22
|
+
if (existsSync(file))
|
|
23
|
+
return readFileSync(file, 'utf8');
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
/** Claude's sandbox origin for a hosted server: the first 32 hex characters of the SHA-256 of the server URL. */
|
|
28
|
+
export function claudeDomain(publicUrl) {
|
|
29
|
+
if (!publicUrl)
|
|
30
|
+
return undefined;
|
|
31
|
+
return `${createHash('sha256').update(publicUrl).digest('hex').slice(0, 32)}.claudemcpcontent.com`;
|
|
32
|
+
}
|
|
33
|
+
export function registerApps(server, s) {
|
|
34
|
+
const apiOrigin = new URL(s.api.baseUrl).origin;
|
|
35
|
+
const resourceDomains = Array.from(new Set([apiOrigin, s.appUrl, 'https://fonts.googleapis.com', 'https://fonts.gstatic.com', ...s.mediaDomains]));
|
|
36
|
+
const domain = claudeDomain(s.publicUrl);
|
|
37
|
+
for (const view of VIEWS) {
|
|
38
|
+
const html = viewHtml(view);
|
|
39
|
+
if (!html)
|
|
40
|
+
continue; // not built (tests, a source checkout): the tools still work, without the view
|
|
41
|
+
const uri = viewUri(view);
|
|
42
|
+
registerAppResource(server, `${view}-view`, uri, {
|
|
43
|
+
title: `${view[0].toUpperCase()}${view.slice(1)} view`,
|
|
44
|
+
description: `The ${view} as an inline view.`,
|
|
45
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
46
|
+
_meta: { ui: { prefersBorder: false } },
|
|
47
|
+
}, async () => ({
|
|
48
|
+
contents: [{
|
|
49
|
+
uri,
|
|
50
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
51
|
+
text: html,
|
|
52
|
+
_meta: {
|
|
53
|
+
ui: {
|
|
54
|
+
csp: { connectDomains: [], resourceDomains, frameDomains: [], baseUriDomains: [] },
|
|
55
|
+
prefersBorder: false,
|
|
56
|
+
permissions: { clipboardWrite: {} },
|
|
57
|
+
...(domain ? { domain } : {}),
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
}],
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
// --- app-only tools: what the buttons call -------------------------------------------------------------------------
|
|
64
|
+
const appOnly = { visibility: ['app'] };
|
|
65
|
+
registerAppTool(server, 'app_decide', {
|
|
66
|
+
title: 'Decide (from the inbox view)',
|
|
67
|
+
description: 'Decide a card from the inbox view. Hidden from the model: the click is the confirmation.',
|
|
68
|
+
inputSchema: z.object({ decision: z.string(), choice: z.enum(['approve', 'reject', 'cancel']), note: z.string().optional(), answer: z.unknown().optional() }),
|
|
69
|
+
annotations: { destructiveHint: true },
|
|
70
|
+
_meta: { ui: { resourceUri: viewUri('inbox'), ...appOnly } },
|
|
71
|
+
}, async ({ decision, choice, note, answer }) => {
|
|
72
|
+
try {
|
|
73
|
+
const body = { decision: choice };
|
|
74
|
+
if (note)
|
|
75
|
+
body.note = note;
|
|
76
|
+
if (answer !== undefined)
|
|
77
|
+
body.answer = answer;
|
|
78
|
+
const out = (await s.api.post(`/api/approvals/${decision}/decide`, body));
|
|
79
|
+
return { content: [{ type: 'text', text: `${choice} ${decision}` }], structuredContent: out };
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
return { isError: true, content: [{ type: 'text', text: error.message }] };
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
registerAppTool(server, 'app_refresh_inbox', {
|
|
86
|
+
title: 'Refresh the inbox view',
|
|
87
|
+
description: 'Reload the pending cards for the inbox view.',
|
|
88
|
+
inputSchema: z.object({ company: z.string(), status: z.string().optional() }),
|
|
89
|
+
annotations: { readOnlyHint: true },
|
|
90
|
+
_meta: { ui: { resourceUri: viewUri('inbox'), ...appOnly } },
|
|
91
|
+
}, async ({ company, status }) => {
|
|
92
|
+
const data = (await s.api.get(`/api/companies/${company}/approvals`, { status: status ?? 'pending' }));
|
|
93
|
+
const results = Array.isArray(data) ? data : (data.results ?? []);
|
|
94
|
+
return { content: [{ type: 'text', text: `${results.length} cards` }], structuredContent: { company, results, count: results.length, more: false } };
|
|
95
|
+
});
|
|
96
|
+
registerAppTool(server, 'app_video', {
|
|
97
|
+
title: 'Video (from the storyboard view)',
|
|
98
|
+
description: 'Reload a video, or act on it: keyframes, make media, critique, render. The click is the confirmation.',
|
|
99
|
+
inputSchema: z.object({ video: z.string(), action: z.enum(['refresh', 'keyframes', 'make', 'critique_keyframes', 'critique_clips', 'render']).optional() }),
|
|
100
|
+
annotations: { destructiveHint: false },
|
|
101
|
+
_meta: { ui: { resourceUri: viewUri('storyboard'), ...appOnly } },
|
|
102
|
+
}, async ({ video, action }) => {
|
|
103
|
+
try {
|
|
104
|
+
if (action === 'keyframes')
|
|
105
|
+
await s.api.post(`/api/studio/productions/${video}/keyframes`, {});
|
|
106
|
+
else if (action === 'make')
|
|
107
|
+
await s.api.post(`/api/studio/productions/${video}/generate`, { what: 'all' });
|
|
108
|
+
else if (action === 'critique_keyframes')
|
|
109
|
+
await s.api.post(`/api/studio/productions/${video}/critique`, { stage: 'keyframes' });
|
|
110
|
+
else if (action === 'critique_clips')
|
|
111
|
+
await s.api.post(`/api/studio/productions/${video}/critique`, { stage: 'clips' });
|
|
112
|
+
else if (action === 'render')
|
|
113
|
+
await s.api.post(`/api/studio/productions/${video}/render`);
|
|
114
|
+
const fresh = (await s.api.get(`/api/studio/productions/${video}`));
|
|
115
|
+
return { content: [{ type: 'text', text: `${action ?? 'refresh'} ${video}` }], structuredContent: fresh };
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
return { isError: true, content: [{ type: 'text', text: error.message }] };
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
registerAppTool(server, 'app_media', {
|
|
122
|
+
title: 'Media (from the gallery view)',
|
|
123
|
+
description: 'Star, retry or reload media from the gallery view.',
|
|
124
|
+
inputSchema: z.object({ company: z.string().optional(), media: z.string().optional(), action: z.enum(['refresh', 'star', 'unstar', 'retry']).optional(), kind: z.string().optional() }),
|
|
125
|
+
annotations: { destructiveHint: false },
|
|
126
|
+
_meta: { ui: { resourceUri: viewUri('gallery'), ...appOnly } },
|
|
127
|
+
}, async ({ company, media, action, kind }) => {
|
|
128
|
+
try {
|
|
129
|
+
if (media && action === 'star')
|
|
130
|
+
await s.api.patch(`/api/studio/media/${media}`, { starred: true });
|
|
131
|
+
if (media && action === 'unstar')
|
|
132
|
+
await s.api.patch(`/api/studio/media/${media}`, { starred: false });
|
|
133
|
+
if (media && action === 'retry')
|
|
134
|
+
await s.api.post(`/api/studio/media/${media}/retry`);
|
|
135
|
+
if (!company)
|
|
136
|
+
return { content: [{ type: 'text', text: 'ok' }], structuredContent: { ok: true } };
|
|
137
|
+
const data = (await s.api.get(`/api/companies/${company}/studio/media`, { kind }));
|
|
138
|
+
const results = Array.isArray(data) ? data : (data.results ?? []);
|
|
139
|
+
return { content: [{ type: 'text', text: `${results.length} media` }], structuredContent: { company, results: results.slice(0, 60), count: results.length, more: results.length > 60 } };
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
return { isError: true, content: [{ type: 'text', text: error.message }] };
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=apps.js.map
|
package/dist/apps.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apps.js","sourceRoot":"","sources":["../src/apps.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `autopoiesis-mcp`: the server on stdio for a tool on this machine (Claude Code, Codex, Cursor, Claude Desktop), or
|
|
4
|
+
* `--http` to host it. The token comes from AUTOPOIESIS_TOKEN (or --token); make one on Connectors → MCP in the app.
|
|
5
|
+
*/
|
|
6
|
+
import { serveStdio } from '@modelcontextprotocol/server/stdio';
|
|
7
|
+
import { createServer, DEFAULT_API_URL, DEFAULT_APP_URL, VERSION } from './server.js';
|
|
8
|
+
import { serveHttp } from './http.js';
|
|
9
|
+
const HELP = `autopoiesis-mcp ${VERSION}
|
|
10
|
+
|
|
11
|
+
Run your Autopoiesis company from your own AI tool, over MCP.
|
|
12
|
+
|
|
13
|
+
Usage
|
|
14
|
+
autopoiesis-mcp stdio server (what Claude Code, Codex, Cursor and Claude Desktop launch)
|
|
15
|
+
autopoiesis-mcp --http Streamable HTTP server on PORT (default 8080), one token per request
|
|
16
|
+
|
|
17
|
+
Options
|
|
18
|
+
--token <apk_…> your personal access token (or AUTOPOIESIS_TOKEN)
|
|
19
|
+
--api-url <url> the platform API (or AUTOPOIESIS_API_URL; default ${DEFAULT_API_URL})
|
|
20
|
+
--app-url <url> the web app, for links (or AUTOPOIESIS_APP_URL; default ${DEFAULT_APP_URL})
|
|
21
|
+
--public-url <url> this server's public address when hosted (or AUTOPOIESIS_MCP_URL)
|
|
22
|
+
--port <n> --http only (or PORT)
|
|
23
|
+
--host <addr> --http only (default 0.0.0.0)
|
|
24
|
+
--version, --help
|
|
25
|
+
|
|
26
|
+
Get a token: open the app → Connectors → MCP → Make the token. Docs: https://docs.autopoiesis.app
|
|
27
|
+
`;
|
|
28
|
+
function arg(name) {
|
|
29
|
+
const i = process.argv.indexOf(name);
|
|
30
|
+
return i >= 0 ? process.argv[i + 1] : undefined;
|
|
31
|
+
}
|
|
32
|
+
const env = process.env;
|
|
33
|
+
const apiUrl = arg('--api-url') ?? env.AUTOPOIESIS_API_URL ?? DEFAULT_API_URL;
|
|
34
|
+
const appUrl = arg('--app-url') ?? env.AUTOPOIESIS_APP_URL ?? DEFAULT_APP_URL;
|
|
35
|
+
const publicUrl = arg('--public-url') ?? env.AUTOPOIESIS_MCP_URL;
|
|
36
|
+
const mediaDomains = (env.AUTOPOIESIS_MEDIA_DOMAINS ?? '').split(',').map((d) => d.trim()).filter(Boolean);
|
|
37
|
+
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
38
|
+
process.stdout.write(HELP);
|
|
39
|
+
}
|
|
40
|
+
else if (process.argv.includes('--version') || process.argv.includes('-v')) {
|
|
41
|
+
process.stdout.write(`${VERSION}\n`);
|
|
42
|
+
}
|
|
43
|
+
else if (process.argv.includes('--http')) {
|
|
44
|
+
const port = Number(arg('--port') ?? env.PORT ?? 8080);
|
|
45
|
+
const host = arg('--host') ?? env.HOST ?? '0.0.0.0';
|
|
46
|
+
serveHttp({ port, host, apiUrl, appUrl, ...(publicUrl ? { publicUrl } : {}), mediaDomains });
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const token = arg('--token') ?? env.AUTOPOIESIS_TOKEN;
|
|
50
|
+
if (!token) {
|
|
51
|
+
process.stderr.write('autopoiesis-mcp: no token. Set AUTOPOIESIS_TOKEN (make one in the app: Connectors → MCP) or pass --token.\n');
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
const handle = serveStdio(() => createServer({ token, apiUrl, appUrl, mediaDomains, ...(publicUrl ? { publicUrl } : {}) }), {
|
|
55
|
+
legacy: 'serve',
|
|
56
|
+
onerror: (error) => process.stderr.write(`autopoiesis-mcp: ${error.message}\n`),
|
|
57
|
+
});
|
|
58
|
+
process.stderr.write(`autopoiesis-mcp ${VERSION} on stdio → ${apiUrl}\n`);
|
|
59
|
+
const stop = () => void handle.close().then(() => process.exit(0));
|
|
60
|
+
process.on('SIGINT', stop);
|
|
61
|
+
process.on('SIGTERM', stop);
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/guides.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Guides served as resources and read by the prompts: short, in plain words, the way the platform writes. */
|
|
2
|
+
export declare const STUDIO_GUIDE = "# The Studio, in short\n\nThe Studio makes images, clips, voice lines and music, and cuts them into videos. A video is a storyboard: shots in\norder, each with a picture (generated, footage you have, a title card, or a presenter), a line of voice-over, text on\nscreen, a length in seconds, and direction for the critic.\n\n## Who does what\n- **You** say what the video is for and how it should feel. One paragraph is enough: who it is for, what it must show,\n the one thing to feel.\n- **The platform** drafts the storyboard from that brief for free (create_video with draft on).\n- **Rose, the Creative Director** (ask_agent creative, with production set to the video id) tightens shots, writes\n better lines, picks looks and models, and proposes changes you apply with apply_chat_action.\n- **The critic** (critique_video) judges takes against each shot's direction and keeps the best.\n\n## Models and money\nstudio_overview lists every model the company can run with its price per image, per second of clip, per voice line or\nper track. update_video {style: {models: {clip, keyframe, voice, music}}} picks them for one video; studio_settings\nsets the defaults. Keyframes (one still per shot) cost cents and lock the look before clips, which cost the most. Every\ntool that spends asks you first, through your tool's own dialog, with the amount.\n\n## The order that works\n1. create_video \u2192 2. get_video, read the shots \u2192 3. ask_agent creative to tighten \u2192 4. update_video models if needed \u2192\n5. video_keyframes \u2192 wait_for_video \u2192 critique_video keyframes \u2192 6. make_video_media all \u2192 wait_for_video \u2192\ncritique_video clips \u2192 7. render_video \u2192 wait_for_video \u2192 the render link, or open_in_app video.\n\n## Shapes and lengths\n16:9 for the web and decks, 9:16 for Reels, Shorts and TikTok, 1:1 and 4:5 for feeds. Teasers run 15 to 30 seconds;\na product walkthrough 60 to 90. Fewer, longer shots read better than many short ones.\n\n## When something is missing\nget_video and wait_for_video list what still blocks a render: a shot without media, a voice line not made, music not\ncomposed. make_video_media takes a `what` (visuals, voice, music or all) to fill only that gap. A failed generation can\nbe retried with update_media {action: retry}.\n";
|
|
3
|
+
export declare const TEASER_GUIDE = "# Making a teaser from a terminal\n\nThe loop, tool by tool (the make_a_teaser prompt runs it for you):\n\n1. brand_brain: the voice, the audience, the enemy.\n2. create_video {title, brief, aspect_ratio, seconds: 20}: a storyboard is drafted for free.\n3. get_video: read the shots. ask_agent {agent: \"creative\", production: <video id>, message: ...}: Rose tightens them;\n apply_chat_action on her proposals, or set_video_shots to write them yourself.\n4. studio_overview, then update_video {style: {models}} only if the defaults don't fit.\n5. video_keyframes: cents per shot, you confirm. wait_for_video. critique_video {stage: \"keyframes\"}.\n6. make_video_media {what: \"all\"}: the clips and voice lines, you confirm the cost. wait_for_video until nothing is\n generating. critique_video {stage: \"clips\"}.\n7. render_video (free). wait_for_video. The render link is in the result; open_in_app {what: \"video\", id} shows it.\n\nNothing is spent without the dialog. wait_for_video returns what is still missing when it cannot go on.\n";
|
package/dist/guides.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** Guides served as resources and read by the prompts: short, in plain words, the way the platform writes. */
|
|
2
|
+
export const STUDIO_GUIDE = `# The Studio, in short
|
|
3
|
+
|
|
4
|
+
The Studio makes images, clips, voice lines and music, and cuts them into videos. A video is a storyboard: shots in
|
|
5
|
+
order, each with a picture (generated, footage you have, a title card, or a presenter), a line of voice-over, text on
|
|
6
|
+
screen, a length in seconds, and direction for the critic.
|
|
7
|
+
|
|
8
|
+
## Who does what
|
|
9
|
+
- **You** say what the video is for and how it should feel. One paragraph is enough: who it is for, what it must show,
|
|
10
|
+
the one thing to feel.
|
|
11
|
+
- **The platform** drafts the storyboard from that brief for free (create_video with draft on).
|
|
12
|
+
- **Rose, the Creative Director** (ask_agent creative, with production set to the video id) tightens shots, writes
|
|
13
|
+
better lines, picks looks and models, and proposes changes you apply with apply_chat_action.
|
|
14
|
+
- **The critic** (critique_video) judges takes against each shot's direction and keeps the best.
|
|
15
|
+
|
|
16
|
+
## Models and money
|
|
17
|
+
studio_overview lists every model the company can run with its price per image, per second of clip, per voice line or
|
|
18
|
+
per track. update_video {style: {models: {clip, keyframe, voice, music}}} picks them for one video; studio_settings
|
|
19
|
+
sets the defaults. Keyframes (one still per shot) cost cents and lock the look before clips, which cost the most. Every
|
|
20
|
+
tool that spends asks you first, through your tool's own dialog, with the amount.
|
|
21
|
+
|
|
22
|
+
## The order that works
|
|
23
|
+
1. create_video → 2. get_video, read the shots → 3. ask_agent creative to tighten → 4. update_video models if needed →
|
|
24
|
+
5. video_keyframes → wait_for_video → critique_video keyframes → 6. make_video_media all → wait_for_video →
|
|
25
|
+
critique_video clips → 7. render_video → wait_for_video → the render link, or open_in_app video.
|
|
26
|
+
|
|
27
|
+
## Shapes and lengths
|
|
28
|
+
16:9 for the web and decks, 9:16 for Reels, Shorts and TikTok, 1:1 and 4:5 for feeds. Teasers run 15 to 30 seconds;
|
|
29
|
+
a product walkthrough 60 to 90. Fewer, longer shots read better than many short ones.
|
|
30
|
+
|
|
31
|
+
## When something is missing
|
|
32
|
+
get_video and wait_for_video list what still blocks a render: a shot without media, a voice line not made, music not
|
|
33
|
+
composed. make_video_media takes a \`what\` (visuals, voice, music or all) to fill only that gap. A failed generation can
|
|
34
|
+
be retried with update_media {action: retry}.
|
|
35
|
+
`;
|
|
36
|
+
export const TEASER_GUIDE = `# Making a teaser from a terminal
|
|
37
|
+
|
|
38
|
+
The loop, tool by tool (the make_a_teaser prompt runs it for you):
|
|
39
|
+
|
|
40
|
+
1. brand_brain: the voice, the audience, the enemy.
|
|
41
|
+
2. create_video {title, brief, aspect_ratio, seconds: 20}: a storyboard is drafted for free.
|
|
42
|
+
3. get_video: read the shots. ask_agent {agent: "creative", production: <video id>, message: ...}: Rose tightens them;
|
|
43
|
+
apply_chat_action on her proposals, or set_video_shots to write them yourself.
|
|
44
|
+
4. studio_overview, then update_video {style: {models}} only if the defaults don't fit.
|
|
45
|
+
5. video_keyframes: cents per shot, you confirm. wait_for_video. critique_video {stage: "keyframes"}.
|
|
46
|
+
6. make_video_media {what: "all"}: the clips and voice lines, you confirm the cost. wait_for_video until nothing is
|
|
47
|
+
generating. critique_video {stage: "clips"}.
|
|
48
|
+
7. render_video (free). wait_for_video. The render link is in the result; open_in_app {what: "video", id} shows it.
|
|
49
|
+
|
|
50
|
+
Nothing is spent without the dialog. wait_for_video returns what is still missing when it cannot go on.
|
|
51
|
+
`;
|
|
52
|
+
//# sourceMappingURL=guides.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guides.js","sourceRoot":"","sources":["../src/guides.ts"],"names":[],"mappings":"AAAA,8GAA8G;AAE9G,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiC3B,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;CAe3B,CAAA"}
|