artifacty 0.7.0 → 0.9.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/README.md +21 -0
- package/docs/central-team-deployment-design.md +208 -0
- package/docs/integrations.md +32 -1
- package/docs/mcp-public-api.md +13 -4
- package/docs/network-sharing.md +13 -0
- package/docs/release-checklist.md +7 -0
- package/docs/threat-model.md +20 -6
- package/package.json +2 -1
- package/src/cli.js +37 -6
- package/src/lib/background.js +3 -0
- package/src/lib/doctor.js +214 -0
- package/src/lib/installer.js +31 -0
- package/src/lib/render.js +250 -1
- package/src/lib/security.js +4 -0
- package/src/lib/service.js +4 -0
- package/src/lib/storage.js +332 -1
- package/src/mcp-server.js +225 -81
- package/src/server.js +317 -13
package/README.md
CHANGED
|
@@ -82,6 +82,23 @@ artifacty install all
|
|
|
82
82
|
artifacty check
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
+
For a central internal server, enable the HTTP MCP endpoint on the server and
|
|
86
|
+
let users issue personal MCP/API tokens from the account page:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
ARTIFACTY_BOOTSTRAP_TOKEN="$(artifacty token --raw)"
|
|
90
|
+
artifacty serve --host 10.0.0.50 --share-mode team --api-token "$ARTIFACTY_BOOTSTRAP_TOKEN" --mcp-http --foreground
|
|
91
|
+
# Open http://10.0.0.50:8787/login, create the first admin, then create a personal token at /account.
|
|
92
|
+
artifacty install all --mcp-url http://10.0.0.50:8787/mcp --api-token "$ARTIFACTY_PERSONAL_TOKEN"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Run diagnostics for the local runtime, store, server, service definitions, and MCP discovery:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
artifacty doctor
|
|
99
|
+
artifacty doctor --skip-mcp
|
|
100
|
+
```
|
|
101
|
+
|
|
85
102
|
Use `artifacty install codex --timeout 30000` or
|
|
86
103
|
`artifacty install gemini --timeout 30000` to tune supported MCP client timeouts.
|
|
87
104
|
|
|
@@ -178,6 +195,7 @@ Run the MCP server:
|
|
|
178
195
|
|
|
179
196
|
```bash
|
|
180
197
|
artifacty-mcp
|
|
198
|
+
ARTIFACTY_MCP_MODE=bridge ARTIFACTY_MCP_URL=http://10.0.0.50:8787/mcp ARTIFACTY_API_TOKEN=... artifacty-mcp
|
|
181
199
|
```
|
|
182
200
|
|
|
183
201
|
MCP clients can create artifacts with `artifacty_create`. `artifacty_publish` remains as a backwards-compatible alias.
|
|
@@ -190,6 +208,7 @@ Operational commands:
|
|
|
190
208
|
|
|
191
209
|
```bash
|
|
192
210
|
artifacty audit --limit 20
|
|
211
|
+
artifacty doctor
|
|
193
212
|
artifacty index rebuild
|
|
194
213
|
artifacty integrity
|
|
195
214
|
artifacty backup
|
|
@@ -288,12 +307,14 @@ Schema and storage:
|
|
|
288
307
|
- Copilot/Cursor examples cover PR reviews, screenshots, demo recordings, and visual evidence bundles.
|
|
289
308
|
- See [docs/artifact-schema-v1.md](docs/artifact-schema-v1.md).
|
|
290
309
|
- See [docs/mcp-public-api.md](docs/mcp-public-api.md) for MCP tools, resources, prompts, and compatibility notes.
|
|
310
|
+
- See [docs/central-team-deployment-design.md](docs/central-team-deployment-design.md) for central team deployment.
|
|
291
311
|
- See [docs/sarif-csv-artifact-plan.md](docs/sarif-csv-artifact-plan.md) for the SARIF/CSV output artifact roadmap.
|
|
292
312
|
|
|
293
313
|
## Security Model
|
|
294
314
|
|
|
295
315
|
- The HTTP server binds to `127.0.0.1` by default.
|
|
296
316
|
- If `ARTIFACTY_API_TOKEN` is set, HTTP API routes require `Authorization: Bearer <token>` or `x-artifacty-token`; scripts should prefer headers over `?token=...` URLs.
|
|
317
|
+
- When users exist, personal API tokens issued from `/account` also authenticate HTTP API and MCP requests, and audit logs record the token owner's email as `actor`.
|
|
297
318
|
- API token checks use timing-safe digest comparison.
|
|
298
319
|
- Binding outside localhost requires both `ARTIFACTY_SHARE_MODE=lan` or `team` and `ARTIFACTY_API_TOKEN`.
|
|
299
320
|
- Non-local sharing is intended for trusted LAN or VPN sessions. Prefer a specific interface IP over `0.0.0.0`, keep React rendering disabled, and see [docs/network-sharing.md](docs/network-sharing.md).
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# Central Team Deployment Design
|
|
2
|
+
|
|
3
|
+
This document defines the design for running Artifacty as a shared internal
|
|
4
|
+
service, where many users connect Claude Code, Codex, Gemini, GitHub Copilot,
|
|
5
|
+
Cursor, or another MCP client to one central Artifacty server.
|
|
6
|
+
|
|
7
|
+
## Problem
|
|
8
|
+
|
|
9
|
+
Artifacty is local-first by default. The HTTP server can listen on a LAN
|
|
10
|
+
address, and the MCP server can either read and write the local `ARTIFACTY_HOME`
|
|
11
|
+
store directly or run as a stdio bridge to a central `/mcp` endpoint. The
|
|
12
|
+
installer `--url` option only controls the browser URL returned in MCP
|
|
13
|
+
responses; central MCP mode is selected with `--mcp-url`.
|
|
14
|
+
|
|
15
|
+
For a central deployment, every MCP client must write through the central
|
|
16
|
+
service instead of touching local SQLite or shared network files. The preferred
|
|
17
|
+
central surface is the native HTTP `/mcp` endpoint. A local stdio bridge remains
|
|
18
|
+
the default installer path for broad client compatibility.
|
|
19
|
+
|
|
20
|
+
## Goals
|
|
21
|
+
|
|
22
|
+
- One central Artifacty store per internal deployment.
|
|
23
|
+
- Native central MCP over Streamable HTTP for clients that support remote MCP.
|
|
24
|
+
- Per-user local stdio bridge compatibility for clients that only support local
|
|
25
|
+
stdio MCP configuration.
|
|
26
|
+
- Stable install commands that can target a central server.
|
|
27
|
+
- Token-authenticated HTTP writes with no token leakage through query strings.
|
|
28
|
+
- Clear audit attribution for user, agent, host, and client surface.
|
|
29
|
+
- Safe defaults for LAN/team operation without weakening local-first behavior.
|
|
30
|
+
|
|
31
|
+
## Non-Goals
|
|
32
|
+
|
|
33
|
+
- Public internet hosting without a reverse proxy, TLS, and stronger auth.
|
|
34
|
+
- SQLite access over NFS or SMB as the recommended sharing model.
|
|
35
|
+
- Relaxing browser-origin checks to make remote browser writes easier.
|
|
36
|
+
- Removing the local stdio MCP path for single-user or legacy clients.
|
|
37
|
+
|
|
38
|
+
## Target Architecture
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
MCP client with remote transport support
|
|
42
|
+
-> https://artifacty.internal/mcp
|
|
43
|
+
-> central Artifacty MCP handler
|
|
44
|
+
-> central SQLite store and immutable version files
|
|
45
|
+
-> browser dashboard at the same central URL
|
|
46
|
+
|
|
47
|
+
MCP client with stdio-only support
|
|
48
|
+
-> local Artifacty stdio bridge
|
|
49
|
+
-> https://artifacty.internal/mcp
|
|
50
|
+
-> same central MCP handler
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The central MCP handler is the canonical team integration surface. HTTP JSON API
|
|
54
|
+
routes remain useful for scripts, browser workflows, and compatibility, but MCP
|
|
55
|
+
tool semantics should not be reimplemented separately in a REST-only bridge.
|
|
56
|
+
Both stdio and Streamable HTTP should share the same tool/resource/prompt
|
|
57
|
+
dispatcher.
|
|
58
|
+
|
|
59
|
+
## Runtime Modes
|
|
60
|
+
|
|
61
|
+
Artifacty supports these explicit MCP operation modes:
|
|
62
|
+
|
|
63
|
+
- `local`: default mode; MCP reads and writes the local store directly.
|
|
64
|
+
- `streamable-http`: a central `/mcp` endpoint serves MCP over HTTP when
|
|
65
|
+
`--mcp-http` or `ARTIFACTY_MCP_HTTP=true` is enabled.
|
|
66
|
+
- `bridge`: local stdio process forwards MCP JSON-RPC to a remote `/mcp`
|
|
67
|
+
endpoint for clients that cannot connect to remote MCP directly.
|
|
68
|
+
|
|
69
|
+
Mode selection should be explicit. `ARTIFACTY_URL` must remain the public
|
|
70
|
+
browser URL override for backwards compatibility. New variables should define
|
|
71
|
+
remote MCP behavior:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
ARTIFACTY_MCP_MODE=bridge
|
|
75
|
+
ARTIFACTY_MCP_URL=https://artifacty.internal/mcp
|
|
76
|
+
ARTIFACTY_API_TOKEN=...
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`ARTIFACTY_URL` may default to the central browser URL when not set, but browser
|
|
80
|
+
links and MCP transport URLs should stay separate in the code and documentation.
|
|
81
|
+
|
|
82
|
+
## Installer UX
|
|
83
|
+
|
|
84
|
+
The installer exposes central-server options for every supported client:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
artifacty install codex \
|
|
88
|
+
--mcp-url https://artifacty.internal/mcp \
|
|
89
|
+
--api-token "$ARTIFACTY_API_TOKEN"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Equivalent commands work for `claude`, `gemini`, `copilot`, `cursor`, and `all`.
|
|
93
|
+
|
|
94
|
+
The current installer generates a local bridge entry for every supported client:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"ARTIFACTY_MCP_MODE": "bridge",
|
|
99
|
+
"ARTIFACTY_MCP_URL": "https://artifacty.internal/mcp",
|
|
100
|
+
"ARTIFACTY_API_TOKEN": "..."
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The installer should continue to support `--url` for link-only overrides.
|
|
105
|
+
`--mcp-url` should imply central MCP behavior; `--url` should not.
|
|
106
|
+
|
|
107
|
+
## Central Server Operation
|
|
108
|
+
|
|
109
|
+
A minimal LAN deployment should bind to a specific internal interface and require
|
|
110
|
+
token auth:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
ARTIFACTY_API_TOKEN="$(artifacty token --raw)"
|
|
114
|
+
ARTIFACTY_SHARE_MODE=team \
|
|
115
|
+
artifacty serve \
|
|
116
|
+
--host 10.0.0.50 \
|
|
117
|
+
--port 8787 \
|
|
118
|
+
--api-token "$ARTIFACTY_API_TOKEN" \
|
|
119
|
+
--mcp-http
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Open `/login` after the server starts. If no users exist, the first successful
|
|
123
|
+
login form creates an administrator. Administrators can create users from
|
|
124
|
+
`/admin/users`, and every user can create or revoke personal API tokens from
|
|
125
|
+
`/account`. Use those personal tokens for `artifacty install ... --api-token`
|
|
126
|
+
so MCP and API audit logs record the user's email as `actor`.
|
|
127
|
+
|
|
128
|
+
Production-like internal deployments should run Artifacty behind a TLS reverse
|
|
129
|
+
proxy, keep `ARTIFACTY_ENABLE_REACT_RENDERER` disabled unless the team trusts
|
|
130
|
+
all artifact authors, and store `ARTIFACTY_HOME` on local server disk with
|
|
131
|
+
regular backups.
|
|
132
|
+
|
|
133
|
+
The central server exposes `/mcp` only when explicitly enabled. This keeps the
|
|
134
|
+
local browser/API server behavior unchanged while making team MCP exposure an
|
|
135
|
+
intentional operating mode.
|
|
136
|
+
|
|
137
|
+
## MCP Requirements
|
|
138
|
+
|
|
139
|
+
Remote MCP mode needs complete parity with local MCP tools:
|
|
140
|
+
|
|
141
|
+
- create/import/list/get/update/archive/restore/audit/info
|
|
142
|
+
- resources: recent artifact list, artifact by ID, schema
|
|
143
|
+
- prompts: handoff, review, test report, visual QA, release notes
|
|
144
|
+
|
|
145
|
+
The stdio server and `/mcp` HTTP endpoint call the same dispatcher so tool
|
|
146
|
+
schemas, resources, prompts, validation, and audit behavior cannot drift.
|
|
147
|
+
|
|
148
|
+
All remote MCP requests must send `Authorization: Bearer` or an equivalent
|
|
149
|
+
header accepted by the central endpoint. Remote MCP should never place tokens in
|
|
150
|
+
URLs.
|
|
151
|
+
|
|
152
|
+
## Audit and Identity
|
|
153
|
+
|
|
154
|
+
Remote MCP requests should include headers such as:
|
|
155
|
+
|
|
156
|
+
```text
|
|
157
|
+
x-artifacty-client: codex
|
|
158
|
+
x-artifacty-actor: user@example.com
|
|
159
|
+
x-artifacty-host: IRAE-MACBOOK
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The server records the authenticated user's email as the audit `actor` when a
|
|
163
|
+
personal token is used. The `x-artifacty-actor` header remains a compatibility
|
|
164
|
+
fallback for the bootstrap/global token path.
|
|
165
|
+
|
|
166
|
+
## Security Model
|
|
167
|
+
|
|
168
|
+
Central mode increases the trust boundary from one machine to a team network.
|
|
169
|
+
Required safeguards:
|
|
170
|
+
|
|
171
|
+
- non-loopback binding still requires `ARTIFACTY_SHARE_MODE=lan|team`
|
|
172
|
+
- central API always requires `ARTIFACTY_API_TOKEN`
|
|
173
|
+
- remote MCP uses header auth only
|
|
174
|
+
- shared instances should prefer TLS through a reverse proxy
|
|
175
|
+
- browser-origin protections remain in place
|
|
176
|
+
- artifact renderers continue treating stored content as untrusted
|
|
177
|
+
|
|
178
|
+
For larger organizations, the next step after personal tokens is scoped tokens,
|
|
179
|
+
token rotation policy, and SSO/OIDC.
|
|
180
|
+
|
|
181
|
+
## Current Implementation
|
|
182
|
+
|
|
183
|
+
- `artifacty serve --mcp-http` exposes `POST /mcp`.
|
|
184
|
+
- `ARTIFACTY_MCP_MODE=bridge` forwards stdio JSON-RPC to `ARTIFACTY_MCP_URL`.
|
|
185
|
+
- `artifacty install <agent> --mcp-url ... --api-token ...` writes bridge env
|
|
186
|
+
config for Claude, Codex, Gemini, GitHub Copilot, and Cursor.
|
|
187
|
+
- `/login`, `/account`, and `/admin/users` provide server-side user management,
|
|
188
|
+
administrator/user roles, and personal token issue/revoke flows.
|
|
189
|
+
- Remote MCP requests use header auth and never put tokens in URLs.
|
|
190
|
+
- Tests cover direct HTTP MCP calls and stdio bridge calls to a token-protected
|
|
191
|
+
central server.
|
|
192
|
+
|
|
193
|
+
## Remaining Work
|
|
194
|
+
|
|
195
|
+
- Client-specific direct remote MCP config generation where the client supports
|
|
196
|
+
it.
|
|
197
|
+
- Scoped tokens, token rotation policy, and stronger audit identity.
|
|
198
|
+
- Optional reverse proxy examples for TLS termination.
|
|
199
|
+
|
|
200
|
+
## Acceptance Criteria
|
|
201
|
+
|
|
202
|
+
- A user can install Artifacty MCP against a central `/mcp` endpoint without
|
|
203
|
+
sharing a filesystem.
|
|
204
|
+
- Artifacts created from any supported MCP client appear in the central
|
|
205
|
+
dashboard and are visible to other clients.
|
|
206
|
+
- Local MCP behavior remains unchanged when remote mode is not configured.
|
|
207
|
+
- Tokens are sent only in headers.
|
|
208
|
+
- CI covers remote MCP parity against the HTTP API.
|
package/docs/integrations.md
CHANGED
|
@@ -37,6 +37,15 @@ The lifecycle commands are intended to be cross-platform:
|
|
|
37
37
|
- Windows: `start` hides the child console window, and `stop` uses `taskkill /PID <pid> /T`, falling back to `/F` when Windows requires forceful termination. `--force` uses `/F` immediately.
|
|
38
38
|
- All platforms: `status` combines the managed pid file with the HTTP `/health` endpoint, so a stale pid alone is not reported as healthy.
|
|
39
39
|
|
|
40
|
+
Run diagnostics when setup behaves unexpectedly:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
node src/cli.js doctor
|
|
44
|
+
node src/cli.js doctor --skip-mcp
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`doctor` checks Node version support, local exposure settings, store integrity, managed server health, service definition rendering, and MCP discovery. A stopped server is reported as a warning, not a failure.
|
|
48
|
+
|
|
40
49
|
For login/startup persistence, use the operating system's service manager. Artifacty's `service` command can generate macOS LaunchAgent, Linux systemd user-unit, and Windows Task Scheduler definitions.
|
|
41
50
|
|
|
42
51
|
Create artifacts directly in the browser at `http://127.0.0.1:8787/new`.
|
|
@@ -59,6 +68,8 @@ Useful environment variables:
|
|
|
59
68
|
|
|
60
69
|
- `ARTIFACTY_HOME`: store directory, shared by all agents.
|
|
61
70
|
- `ARTIFACTY_URL`: optional browser URL override. Leave it unset to let MCP read the last running server URL from `server.json`.
|
|
71
|
+
- `ARTIFACTY_MCP_MODE`: `local` by default, or `bridge` to forward stdio MCP to a central HTTP MCP endpoint.
|
|
72
|
+
- `ARTIFACTY_MCP_URL`: central MCP endpoint used by bridge mode, for example `http://10.0.0.50:8787/mcp`.
|
|
62
73
|
- `ARTIFACTY_API_TOKEN`: required token for HTTP API routes when configured. Generate one with `node src/cli.js token --raw`.
|
|
63
74
|
- `ARTIFACTY_SHARE_MODE`: set to `lan` or `team` before binding outside localhost.
|
|
64
75
|
- `ARTIFACTY_ALLOW_SECRETS`: set to `true` only when intentionally storing detected secrets.
|
|
@@ -77,14 +88,33 @@ node src/cli.js install all
|
|
|
77
88
|
node src/cli.js check
|
|
78
89
|
```
|
|
79
90
|
|
|
91
|
+
Central team server setup:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
ARTIFACTY_BOOTSTRAP_TOKEN="$(node src/cli.js token --raw)"
|
|
95
|
+
node src/cli.js serve --foreground \
|
|
96
|
+
--host 10.0.0.50 \
|
|
97
|
+
--share-mode team \
|
|
98
|
+
--api-token "$ARTIFACTY_BOOTSTRAP_TOKEN" \
|
|
99
|
+
--mcp-http
|
|
100
|
+
# Open http://10.0.0.50:8787/login, create the first admin, then create a personal token at /account.
|
|
101
|
+
node src/cli.js install all \
|
|
102
|
+
--mcp-url http://10.0.0.50:8787/mcp \
|
|
103
|
+
--api-token "$ARTIFACTY_PERSONAL_TOKEN"
|
|
104
|
+
```
|
|
105
|
+
|
|
80
106
|
- Claude: writes project `.mcp.json`. Claude Code's startup timeout is controlled by the parent `MCP_TIMEOUT` environment variable and defaults to 30 seconds, so Artifacty does not add a per-server `.mcp.json` `timeout` field.
|
|
81
107
|
- Codex: writes or replaces the `[mcp_servers.artifacty]` block in `~/.codex/config.toml` unless `--config` is provided. The generated block uses a 30 second startup timeout so slower Windows or cold-start environments can load the MCP server reliably.
|
|
82
108
|
- Gemini: writes project `.gemini/settings.json` with a 30 second timeout.
|
|
83
109
|
- GitHub Copilot in VS Code: writes workspace `.vscode/mcp.json` using the VS Code `servers` shape. Pass `--config` to target a user-profile `mcp.json` instead.
|
|
84
110
|
- Cursor: writes project `.cursor/mcp.json` using the Cursor `mcpServers` shape. Pass `--config ~/.cursor/mcp.json` for global Cursor setup.
|
|
85
111
|
- `--dry-run` returns the generated config without writing it.
|
|
112
|
+
- `--mcp-url <url>` installs stdio bridge mode for central Artifacty. If the URL has no path, `/mcp` is appended.
|
|
113
|
+
- `--api-token <token>` is written into the generated MCP environment for bridge mode. For central servers, prefer a personal token issued from `/account`.
|
|
114
|
+
- `--url <url>` remains a browser-link override and does not enable central MCP by itself.
|
|
86
115
|
- `--timeout <ms>` adjusts Codex `startup_timeout_sec` and Gemini `timeout`. It does not change Claude Code startup behavior; set `MCP_TIMEOUT` before launching Claude Code if you need a larger value there.
|
|
87
116
|
- `check` starts the local MCP server and verifies required tools, resources, and prompts through MCP discovery methods.
|
|
117
|
+
- `doctor` combines MCP discovery with runtime, storage, server, and service diagnostics.
|
|
88
118
|
|
|
89
119
|
## Client Compatibility Matrix
|
|
90
120
|
|
|
@@ -268,6 +298,7 @@ tests.
|
|
|
268
298
|
- `GET /import`: browser artifact import form.
|
|
269
299
|
- `POST /import`: convert and save pasted agent output.
|
|
270
300
|
- `GET /health`: health check.
|
|
301
|
+
- `POST /mcp`: token-protected MCP Streamable HTTP JSON-RPC endpoint when `--mcp-http` or `ARTIFACTY_MCP_HTTP=true` is enabled.
|
|
271
302
|
- `GET /api/artifacts`: list artifacts.
|
|
272
303
|
- `POST /api/artifacts`: create artifact.
|
|
273
304
|
- `POST /api/import`: convert and save an agent-produced artifact.
|
|
@@ -285,7 +316,7 @@ tests.
|
|
|
285
316
|
- `GET /artifacts/:id/diff`: compare two versions.
|
|
286
317
|
- `GET /artifacts/:id/raw?version=n`: raw content.
|
|
287
318
|
|
|
288
|
-
When `ARTIFACTY_API_TOKEN` is configured, `/api/*` routes require either `Authorization: Bearer <token>` or `x-artifacty-token: <token>`. Browser forms can also carry `?token=<token>` in the URL, which is copied to hidden form fields for local team workflows.
|
|
319
|
+
When `ARTIFACTY_API_TOKEN` is configured, `/api/*` routes require either `Authorization: Bearer <token>` or `x-artifacty-token: <token>`. When users exist, personal tokens issued from `/account` also authenticate API and MCP requests and are mapped to the token owner's email in audit logs. Browser forms can also carry `?token=<token>` in the URL, which is copied to hidden form fields for local team workflows.
|
|
289
320
|
|
|
290
321
|
Renderer notes:
|
|
291
322
|
|
package/docs/mcp-public-api.md
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# MCP Public API
|
|
2
2
|
|
|
3
|
-
Artifacty's MCP
|
|
4
|
-
|
|
3
|
+
Artifacty's MCP server is the primary agent-to-agent integration surface. It
|
|
4
|
+
supports local stdio MCP by default, a token-protected HTTP `/mcp` endpoint when
|
|
5
|
+
enabled on the browser server, and stdio bridge mode for clients that need local
|
|
6
|
+
stdio config but should write to a central Artifacty server. The server
|
|
7
|
+
currently targets MCP protocol `2025-06-18`.
|
|
5
8
|
|
|
6
9
|
## Capabilities
|
|
7
10
|
|
|
@@ -23,7 +26,7 @@ Stable tool names:
|
|
|
23
26
|
- `artifacty_update`: append an immutable version.
|
|
24
27
|
- `artifacty_archive` / `artifacty_restore`: toggle archive state.
|
|
25
28
|
- `artifacty_audit`: list audit events.
|
|
26
|
-
- `artifacty_info`: return
|
|
29
|
+
- `artifacty_info`: return store, browser URL, transport, and protocol information.
|
|
27
30
|
|
|
28
31
|
Tool schemas use Artifacty schema v1 formats and artifact types. New optional
|
|
29
32
|
properties may be added during 0.x releases; existing names should not be
|
|
@@ -60,7 +63,13 @@ Prompts accept optional context arguments such as `artifactId`, `goal`, `scope`,
|
|
|
60
63
|
|
|
61
64
|
## Compatibility Notes
|
|
62
65
|
|
|
63
|
-
-
|
|
66
|
+
- Local stdio remains the default. Enable the central HTTP endpoint with
|
|
67
|
+
`artifacty serve --mcp-http` and install bridge mode with
|
|
68
|
+
`artifacty install <agent> --mcp-url http://host:8787/mcp --api-token <token>`.
|
|
69
|
+
- On central servers, use a personal token from `/account` so audit logs record
|
|
70
|
+
the token owner's email as the artifact actor.
|
|
71
|
+
- Remote MCP currently uses bearer/header token auth. OAuth and per-user scoped
|
|
72
|
+
tokens are future hardening work.
|
|
64
73
|
- Binary media resources return stored base64 text through MCP; browser `/raw`
|
|
65
74
|
decodes first-class `image` and `video` artifacts into bytes.
|
|
66
75
|
- Clients may display resources and prompts differently. Tools remain the most
|
package/docs/network-sharing.md
CHANGED
|
@@ -16,6 +16,16 @@ If another device on a trusted LAN or private VPN needs read access, prefer bind
|
|
|
16
16
|
artifacty serve --host 192.168.1.20 --share-mode lan --generate-token
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
For a central internal MCP server, enable `/mcp` explicitly and install clients
|
|
20
|
+
with `--mcp-url` and a personal token from `/account`:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
ARTIFACTY_BOOTSTRAP_TOKEN="$(artifacty token --raw)"
|
|
24
|
+
artifacty serve --host 10.0.0.50 --share-mode team --api-token "$ARTIFACTY_BOOTSTRAP_TOKEN" --mcp-http --foreground
|
|
25
|
+
# Open /login to create the first admin, then /account to issue a personal token.
|
|
26
|
+
artifacty install all --mcp-url http://10.0.0.50:8787/mcp --api-token "$ARTIFACTY_PERSONAL_TOKEN"
|
|
27
|
+
```
|
|
28
|
+
|
|
19
29
|
Use `0.0.0.0` only when you intentionally want Artifacty to listen on every network interface:
|
|
20
30
|
|
|
21
31
|
```bash
|
|
@@ -43,3 +53,6 @@ Do not relax the origin check just to make remote browser writes easier. A futur
|
|
|
43
53
|
Artifact content is untrusted. HTML, SVG, Mermaid, and React artifacts are rendered with sandboxing and CSP controls, but shared viewing still means content reaches another user's browser. Keep `ARTIFACTY_ENABLE_REACT_RENDERER` disabled for LAN sessions unless every viewer trusts the artifact source.
|
|
44
54
|
|
|
45
55
|
See [threat-model.md](threat-model.md) for the full trust-boundary summary.
|
|
56
|
+
|
|
57
|
+
For a durable internal deployment where many MCP clients share one central
|
|
58
|
+
Artifacty instance, see [central-team-deployment-design.md](central-team-deployment-design.md).
|
|
@@ -10,6 +10,12 @@ npm run release:check
|
|
|
10
10
|
|
|
11
11
|
This runs syntax checks, the full Node test suite, and a local smoke test that starts the HTTP server with token auth enabled, creates an artifact, verifies secret blocking, reads audit logs, writes a backup, and checks MCP tool/resource/prompt discovery.
|
|
12
12
|
|
|
13
|
+
Run the local diagnostics pass:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
artifacty doctor
|
|
17
|
+
```
|
|
18
|
+
|
|
13
19
|
## Packaging
|
|
14
20
|
|
|
15
21
|
- Confirm `package.json` `version` and `files` are intentional.
|
|
@@ -47,4 +53,5 @@ This runs syntax checks, the full Node test suite, and a local smoke test that s
|
|
|
47
53
|
|
|
48
54
|
- Export a backup before upgrades: `artifacty backup`.
|
|
49
55
|
- Confirm `artifacty audit --limit 20` shows recent create/update/read/archive events.
|
|
56
|
+
- Confirm `artifacty doctor` reports no failures. A stopped server warning is acceptable when intentionally checking an offline store.
|
|
50
57
|
- For background service installs, dry-run first: `artifacty service install --dry-run`. Use `--platform macos|linux|windows` to review another OS definition.
|
package/docs/threat-model.md
CHANGED
|
@@ -8,6 +8,7 @@ operator, one local store, and trusted local MCP clients by default.
|
|
|
8
8
|
- Artifact content, including generated code, reports, screenshots, and media.
|
|
9
9
|
- Artifact metadata, tags, audit records, and version history.
|
|
10
10
|
- API tokens and generated startup tokens.
|
|
11
|
+
- User accounts, password hashes, browser sessions, and personal API tokens.
|
|
11
12
|
- Local MCP client configuration files.
|
|
12
13
|
- The Artifacty SQLite database and immutable version files.
|
|
13
14
|
|
|
@@ -16,7 +17,11 @@ operator, one local store, and trusted local MCP clients by default.
|
|
|
16
17
|
- **HTTP browser server**: local by default, optionally reachable on LAN/team
|
|
17
18
|
networks when explicitly configured.
|
|
18
19
|
- **MCP stdio server**: local process launched by an MCP client. It inherits the
|
|
19
|
-
local user account's filesystem permissions.
|
|
20
|
+
local user account's filesystem permissions. In bridge mode, it forwards
|
|
21
|
+
JSON-RPC to a configured central `/mcp` endpoint instead of touching local
|
|
22
|
+
storage.
|
|
23
|
+
- **HTTP MCP endpoint**: optional `POST /mcp` endpoint exposed only when
|
|
24
|
+
`--mcp-http` or `ARTIFACTY_MCP_HTTP=true` is configured.
|
|
20
25
|
- **Artifact renderers**: untrusted content is rendered inside browser sandbox
|
|
21
26
|
boundaries where practical.
|
|
22
27
|
- **Storage**: Artifacty stores content under `ARTIFACTY_HOME`; anyone with
|
|
@@ -50,6 +55,8 @@ Controls:
|
|
|
50
55
|
- Scripts should use `x-artifacty-token` or `Authorization: Bearer <token>`.
|
|
51
56
|
- Browser form token URLs exist only for local convenience.
|
|
52
57
|
- Token comparisons use timing-safe digest comparison.
|
|
58
|
+
- Personal API tokens are stored only as hashes.
|
|
59
|
+
- Browser sessions use `HttpOnly` and `SameSite=Lax` cookies.
|
|
53
60
|
|
|
54
61
|
Guidance: rotate tokens after sharing sessions, prefer header-based tokens for
|
|
55
62
|
scripts, and use generated startup tokens only for temporary interactive shares.
|
|
@@ -98,22 +105,29 @@ of sensitive data.
|
|
|
98
105
|
|
|
99
106
|
### MCP Tool Abuse
|
|
100
107
|
|
|
101
|
-
Risk: an MCP client can create, update, import, archive, restore, and read
|
|
102
|
-
artifacts through stdio.
|
|
108
|
+
Risk: an MCP client can create, update, import, archive, restore, and read
|
|
109
|
+
artifacts through local stdio or the central HTTP MCP endpoint.
|
|
103
110
|
|
|
104
111
|
Controls:
|
|
105
112
|
|
|
106
|
-
-
|
|
113
|
+
- Local stdio remains the default.
|
|
114
|
+
- The HTTP MCP endpoint is disabled unless explicitly enabled.
|
|
115
|
+
- Remote MCP requests require the configured API token.
|
|
116
|
+
- Stdio bridge mode sends tokens in headers, not URLs.
|
|
117
|
+
- Personal tokens map requests to a server-side user record for audit actor
|
|
118
|
+
attribution.
|
|
107
119
|
- MCP writes go through the same secret scan and audit paths as CLI/HTTP writes.
|
|
108
120
|
- MCP resources are read-only.
|
|
109
121
|
|
|
110
|
-
Guidance: install Artifacty MCP only in clients and workspaces you trust.
|
|
122
|
+
Guidance: install Artifacty MCP only in clients and workspaces you trust. For
|
|
123
|
+
central deployments, prefer TLS through a reverse proxy and rotate shared tokens
|
|
124
|
+
after team changes.
|
|
111
125
|
|
|
112
126
|
## Out of Scope
|
|
113
127
|
|
|
114
128
|
- Public internet hosting without a separate TLS/auth proxy.
|
|
115
129
|
- Multi-user browser write access.
|
|
116
|
-
- OAuth or remote MCP authorization.
|
|
130
|
+
- OAuth, scoped tokens, or per-user remote MCP authorization.
|
|
117
131
|
- Per-artifact ACLs.
|
|
118
132
|
- Encrypted-at-rest storage.
|
|
119
133
|
- Malware analysis of arbitrary artifact content.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "artifacty",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Local artifact exchange for heterogeneous LLM agents via HTTP and MCP.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"src",
|
|
37
37
|
"docs/artifact-schema-v1.md",
|
|
38
38
|
"docs/assets/artifacty.png",
|
|
39
|
+
"docs/central-team-deployment-design.md",
|
|
39
40
|
"docs/integrations.md",
|
|
40
41
|
"docs/mcp-public-api.md",
|
|
41
42
|
"docs/network-sharing.md",
|
package/src/cli.js
CHANGED
|
@@ -22,6 +22,7 @@ import { serviceCommand } from "./lib/service.js";
|
|
|
22
22
|
import { backgroundStatus, startBackgroundServer, stopBackgroundServer } from "./lib/background.js";
|
|
23
23
|
import { resolvePublicBaseUrl } from "./lib/server-state.js";
|
|
24
24
|
import { generateToken } from "./lib/token.js";
|
|
25
|
+
import { runDoctor } from "./lib/doctor.js";
|
|
25
26
|
import { startServer } from "./server.js";
|
|
26
27
|
|
|
27
28
|
const PACKAGE_ROOT = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
|
|
@@ -67,7 +68,8 @@ async function main() {
|
|
|
67
68
|
home: options.home,
|
|
68
69
|
apiToken: generatedToken?.token || options.apiToken,
|
|
69
70
|
shareMode: options.shareMode,
|
|
70
|
-
allowSecrets: options.allowSecrets
|
|
71
|
+
allowSecrets: options.allowSecrets,
|
|
72
|
+
mcpHttp: options.mcpHttp
|
|
71
73
|
});
|
|
72
74
|
process.stderr.write(`Artifacty listening on ${server.url}\n`);
|
|
73
75
|
process.stderr.write(`Store: ${server.store.home}\n`);
|
|
@@ -105,6 +107,27 @@ async function main() {
|
|
|
105
107
|
return;
|
|
106
108
|
}
|
|
107
109
|
|
|
110
|
+
if (command === "doctor") {
|
|
111
|
+
const result = await runDoctor({
|
|
112
|
+
packageRoot: PACKAGE_ROOT,
|
|
113
|
+
serverPath: options.serverPath,
|
|
114
|
+
url: options.url,
|
|
115
|
+
home: options.home,
|
|
116
|
+
host: options.host,
|
|
117
|
+
port: options.port,
|
|
118
|
+
apiToken: options.apiToken,
|
|
119
|
+
shareMode: options.shareMode,
|
|
120
|
+
allowSecrets: options.allowSecrets,
|
|
121
|
+
timeout: options.timeout,
|
|
122
|
+
skipMcp: options.skipMcp
|
|
123
|
+
});
|
|
124
|
+
printJson(result);
|
|
125
|
+
if (!result.ok) {
|
|
126
|
+
process.exitCode = 1;
|
|
127
|
+
}
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
108
131
|
if (command === "publish") {
|
|
109
132
|
const content = await readContent(options);
|
|
110
133
|
const artifact = await createArtifact(store, {
|
|
@@ -161,6 +184,9 @@ async function main() {
|
|
|
161
184
|
configPath: options.config,
|
|
162
185
|
serverPath: options.serverPath,
|
|
163
186
|
url: options.url,
|
|
187
|
+
mcpUrl: options.mcpUrl,
|
|
188
|
+
apiToken: options.apiToken,
|
|
189
|
+
transport: options.transport,
|
|
164
190
|
home: options.home,
|
|
165
191
|
dryRun: options.dryRun,
|
|
166
192
|
trust: options.trust,
|
|
@@ -287,6 +313,7 @@ async function main() {
|
|
|
287
313
|
apiToken: options.apiToken,
|
|
288
314
|
shareMode: options.shareMode,
|
|
289
315
|
allowSecrets: options.allowSecrets,
|
|
316
|
+
mcpHttp: options.mcpHttp,
|
|
290
317
|
host: options.host,
|
|
291
318
|
port: options.port,
|
|
292
319
|
home: options.home,
|
|
@@ -324,7 +351,7 @@ function parseArgs(args) {
|
|
|
324
351
|
}
|
|
325
352
|
|
|
326
353
|
const key = arg.slice(2);
|
|
327
|
-
if (key === "raw" || key === "dry-run" || key === "trust" || key === "include-archived" || key === "allow-secrets" || key === "generate-token" || key === "detach" || key === "foreground" || key === "force") {
|
|
354
|
+
if (key === "raw" || key === "dry-run" || key === "trust" || key === "include-archived" || key === "allow-secrets" || key === "generate-token" || key === "detach" || key === "foreground" || key === "force" || key === "skip-mcp" || key === "mcp-http") {
|
|
328
355
|
options[toCamelCase(key)] = true;
|
|
329
356
|
continue;
|
|
330
357
|
}
|
|
@@ -407,14 +434,15 @@ function printHelp() {
|
|
|
407
434
|
|
|
408
435
|
Usage:
|
|
409
436
|
artifacty token [--bytes 32] [--raw]
|
|
410
|
-
artifacty serve [--host 127.0.0.1] [--port 8787] [--home ~/.artifacty] [--api-token token] [--generate-token] [--bytes 32] [--foreground]
|
|
437
|
+
artifacty serve [--host 127.0.0.1] [--port 8787] [--home ~/.artifacty] [--api-token token] [--generate-token] [--bytes 32] [--mcp-http] [--foreground]
|
|
411
438
|
artifacty serve --foreground [--generate-token]
|
|
412
|
-
artifacty start [--host 127.0.0.1] [--port 8787] [--home ~/.artifacty] [--api-token token] [--generate-token] [--timeout 30000]
|
|
439
|
+
artifacty start [--host 127.0.0.1] [--port 8787] [--home ~/.artifacty] [--api-token token] [--generate-token] [--mcp-http] [--timeout 30000]
|
|
413
440
|
artifacty status [--home ~/.artifacty]
|
|
414
441
|
artifacty stop [--home ~/.artifacty] [--timeout 30000] [--force]
|
|
442
|
+
artifacty doctor [--home ~/.artifacty] [--skip-mcp] [--timeout 5000]
|
|
415
443
|
artifacty publish --title <title> (--file <path> | --content <text>) [--format html|markdown|text|json|code|svg|mermaid|react] [--source agent] [--tag tag]
|
|
416
444
|
artifacty import --agent claude|codex|gemini|copilot|cursor|auto (--file <path> | --content <text>) [--title <title>] [--format html|markdown|text|json|code|svg|mermaid|react] [--tag tag]
|
|
417
|
-
artifacty install claude|codex|gemini|copilot|cursor|all [--dry-run] [--config <path>] [--server-path <path>] [--url http://127.0.0.1:8787] [--timeout 30000]
|
|
445
|
+
artifacty install claude|codex|gemini|copilot|cursor|all [--dry-run] [--config <path>] [--server-path <path>] [--url http://127.0.0.1:8787] [--mcp-url http://127.0.0.1:8787/mcp] [--api-token token] [--transport local|bridge] [--timeout 30000]
|
|
418
446
|
artifacty check [--server-path <path>] [--timeout 5000]
|
|
419
447
|
artifacty update <id> (--file <path> | --content <text>) [--title <title>] [--format html|markdown|text|json|code|svg|mermaid|react]
|
|
420
448
|
artifacty archive <id>
|
|
@@ -425,13 +453,15 @@ Usage:
|
|
|
425
453
|
artifacty export --file <path>
|
|
426
454
|
artifacty backup [--file <path>]
|
|
427
455
|
artifacty import-store --file <path>
|
|
428
|
-
artifacty service plist|unit|task|install|uninstall [--platform macos|linux|windows] [--dry-run] [--path <path>]
|
|
456
|
+
artifacty service plist|unit|task|install|uninstall [--platform macos|linux|windows] [--dry-run] [--path <path>] [--mcp-http]
|
|
429
457
|
artifacty list [--query text] [--tag tag] [--source agent] [--limit 50] [--offset 0] [--include-archived]
|
|
430
458
|
artifacty show <id> [--version n] [--raw]
|
|
431
459
|
|
|
432
460
|
Environment:
|
|
433
461
|
ARTIFACTY_HOME Storage directory. Defaults to ~/.artifacty
|
|
434
462
|
ARTIFACTY_URL Public URL override. Otherwise CLI/MCP read the last running server URL
|
|
463
|
+
ARTIFACTY_MCP_URL Central MCP HTTP endpoint used by bridge mode
|
|
464
|
+
ARTIFACTY_MCP_MODE local or bridge. bridge forwards stdio MCP to ARTIFACTY_MCP_URL
|
|
435
465
|
ARTIFACTY_API_TOKEN Required token for HTTP API and LAN mode
|
|
436
466
|
ARTIFACTY_SHARE_MODE Use lan or team before binding outside localhost
|
|
437
467
|
ARTIFACTY_ALLOW_SECRETS Set true only to intentionally store detected secrets
|
|
@@ -462,6 +492,7 @@ function serverOptions(options) {
|
|
|
462
492
|
allowSecrets: options.allowSecrets,
|
|
463
493
|
generateToken: options.generateToken,
|
|
464
494
|
bytes: options.bytes,
|
|
495
|
+
mcpHttp: options.mcpHttp,
|
|
465
496
|
timeout: options.timeout
|
|
466
497
|
};
|
|
467
498
|
}
|