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 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.
@@ -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
 
@@ -1,7 +1,10 @@
1
1
  # MCP Public API
2
2
 
3
- Artifacty's MCP stdio server is the primary agent-to-agent integration surface.
4
- The server currently targets MCP protocol `2025-06-18`.
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 local store and browser URL information.
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
- - The MCP server is local stdio only. Remote MCP auth/OAuth is out of scope.
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
@@ -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.
@@ -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 local
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
- - MCP is local stdio only.
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.7.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
  }
@@ -235,6 +235,9 @@ export function buildServerArgs(options, store) {
235
235
  if (options.allowSecrets) {
236
236
  args.push("--allow-secrets");
237
237
  }
238
+ if (options.mcpHttp) {
239
+ args.push("--mcp-http");
240
+ }
238
241
  return args;
239
242
  }
240
243