artifacty 0.8.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,16 @@ 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
+
85
95
  Run diagnostics for the local runtime, store, server, service definitions, and MCP discovery:
86
96
 
87
97
  ```bash
@@ -185,6 +195,7 @@ Run the MCP server:
185
195
 
186
196
  ```bash
187
197
  artifacty-mcp
198
+ ARTIFACTY_MCP_MODE=bridge ARTIFACTY_MCP_URL=http://10.0.0.50:8787/mcp ARTIFACTY_API_TOKEN=... artifacty-mcp
188
199
  ```
189
200
 
190
201
  MCP clients can create artifacts with `artifacty_create`. `artifacty_publish` remains as a backwards-compatible alias.
@@ -296,12 +307,14 @@ Schema and storage:
296
307
  - Copilot/Cursor examples cover PR reviews, screenshots, demo recordings, and visual evidence bundles.
297
308
  - See [docs/artifact-schema-v1.md](docs/artifact-schema-v1.md).
298
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.
299
311
  - See [docs/sarif-csv-artifact-plan.md](docs/sarif-csv-artifact-plan.md) for the SARIF/CSV output artifact roadmap.
300
312
 
301
313
  ## Security Model
302
314
 
303
315
  - The HTTP server binds to `127.0.0.1` by default.
304
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`.
305
318
  - API token checks use timing-safe digest comparison.
306
319
  - Binding outside localhost requires both `ARTIFACTY_SHARE_MODE=lan` or `team` and `ARTIFACTY_API_TOKEN`.
307
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.
@@ -68,6 +68,8 @@ Useful environment variables:
68
68
 
69
69
  - `ARTIFACTY_HOME`: store directory, shared by all agents.
70
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`.
71
73
  - `ARTIFACTY_API_TOKEN`: required token for HTTP API routes when configured. Generate one with `node src/cli.js token --raw`.
72
74
  - `ARTIFACTY_SHARE_MODE`: set to `lan` or `team` before binding outside localhost.
73
75
  - `ARTIFACTY_ALLOW_SECRETS`: set to `true` only when intentionally storing detected secrets.
@@ -86,12 +88,30 @@ node src/cli.js install all
86
88
  node src/cli.js check
87
89
  ```
88
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
+
89
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.
90
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.
91
108
  - Gemini: writes project `.gemini/settings.json` with a 30 second timeout.
92
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.
93
110
  - Cursor: writes project `.cursor/mcp.json` using the Cursor `mcpServers` shape. Pass `--config ~/.cursor/mcp.json` for global Cursor setup.
94
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.
95
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.
96
116
  - `check` starts the local MCP server and verifies required tools, resources, and prompts through MCP discovery methods.
97
117
  - `doctor` combines MCP discovery with runtime, storage, server, and service diagnostics.
@@ -278,6 +298,7 @@ tests.
278
298
  - `GET /import`: browser artifact import form.
279
299
  - `POST /import`: convert and save pasted agent output.
280
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.
281
302
  - `GET /api/artifacts`: list artifacts.
282
303
  - `POST /api/artifacts`: create artifact.
283
304
  - `POST /api/import`: convert and save an agent-produced artifact.
@@ -295,7 +316,7 @@ tests.
295
316
  - `GET /artifacts/:id/diff`: compare two versions.
296
317
  - `GET /artifacts/:id/raw?version=n`: raw content.
297
318
 
298
- 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.
299
320
 
300
321
  Renderer notes:
301
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).
@@ -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.8.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
@@ -68,7 +68,8 @@ async function main() {
68
68
  home: options.home,
69
69
  apiToken: generatedToken?.token || options.apiToken,
70
70
  shareMode: options.shareMode,
71
- allowSecrets: options.allowSecrets
71
+ allowSecrets: options.allowSecrets,
72
+ mcpHttp: options.mcpHttp
72
73
  });
73
74
  process.stderr.write(`Artifacty listening on ${server.url}\n`);
74
75
  process.stderr.write(`Store: ${server.store.home}\n`);
@@ -183,6 +184,9 @@ async function main() {
183
184
  configPath: options.config,
184
185
  serverPath: options.serverPath,
185
186
  url: options.url,
187
+ mcpUrl: options.mcpUrl,
188
+ apiToken: options.apiToken,
189
+ transport: options.transport,
186
190
  home: options.home,
187
191
  dryRun: options.dryRun,
188
192
  trust: options.trust,
@@ -309,6 +313,7 @@ async function main() {
309
313
  apiToken: options.apiToken,
310
314
  shareMode: options.shareMode,
311
315
  allowSecrets: options.allowSecrets,
316
+ mcpHttp: options.mcpHttp,
312
317
  host: options.host,
313
318
  port: options.port,
314
319
  home: options.home,
@@ -346,7 +351,7 @@ function parseArgs(args) {
346
351
  }
347
352
 
348
353
  const key = arg.slice(2);
349
- 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") {
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") {
350
355
  options[toCamelCase(key)] = true;
351
356
  continue;
352
357
  }
@@ -429,15 +434,15 @@ function printHelp() {
429
434
 
430
435
  Usage:
431
436
  artifacty token [--bytes 32] [--raw]
432
- 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]
433
438
  artifacty serve --foreground [--generate-token]
434
- 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]
435
440
  artifacty status [--home ~/.artifacty]
436
441
  artifacty stop [--home ~/.artifacty] [--timeout 30000] [--force]
437
442
  artifacty doctor [--home ~/.artifacty] [--skip-mcp] [--timeout 5000]
438
443
  artifacty publish --title <title> (--file <path> | --content <text>) [--format html|markdown|text|json|code|svg|mermaid|react] [--source agent] [--tag tag]
439
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]
440
- 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]
441
446
  artifacty check [--server-path <path>] [--timeout 5000]
442
447
  artifacty update <id> (--file <path> | --content <text>) [--title <title>] [--format html|markdown|text|json|code|svg|mermaid|react]
443
448
  artifacty archive <id>
@@ -448,13 +453,15 @@ Usage:
448
453
  artifacty export --file <path>
449
454
  artifacty backup [--file <path>]
450
455
  artifacty import-store --file <path>
451
- 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]
452
457
  artifacty list [--query text] [--tag tag] [--source agent] [--limit 50] [--offset 0] [--include-archived]
453
458
  artifacty show <id> [--version n] [--raw]
454
459
 
455
460
  Environment:
456
461
  ARTIFACTY_HOME Storage directory. Defaults to ~/.artifacty
457
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
458
465
  ARTIFACTY_API_TOKEN Required token for HTTP API and LAN mode
459
466
  ARTIFACTY_SHARE_MODE Use lan or team before binding outside localhost
460
467
  ARTIFACTY_ALLOW_SECRETS Set true only to intentionally store detected secrets
@@ -485,6 +492,7 @@ function serverOptions(options) {
485
492
  allowSecrets: options.allowSecrets,
486
493
  generateToken: options.generateToken,
487
494
  bytes: options.bytes,
495
+ mcpHttp: options.mcpHttp,
488
496
  timeout: options.timeout
489
497
  };
490
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
 
@@ -48,6 +48,17 @@ export function createMcpServerConfig(options = {}) {
48
48
  env.ARTIFACTY_URL = options.url || process.env.ARTIFACTY_URL;
49
49
  }
50
50
 
51
+ if (options.mcpUrl || process.env.ARTIFACTY_MCP_URL) {
52
+ env.ARTIFACTY_MCP_MODE = normalizeMcpMode(options.transport || "bridge");
53
+ env.ARTIFACTY_MCP_URL = normalizeMcpEndpoint(options.mcpUrl || process.env.ARTIFACTY_MCP_URL);
54
+ } else if (options.transport || process.env.ARTIFACTY_MCP_MODE) {
55
+ env.ARTIFACTY_MCP_MODE = normalizeMcpMode(options.transport || process.env.ARTIFACTY_MCP_MODE);
56
+ }
57
+
58
+ if (options.apiToken || process.env.ARTIFACTY_API_TOKEN) {
59
+ env.ARTIFACTY_API_TOKEN = options.apiToken || process.env.ARTIFACTY_API_TOKEN;
60
+ }
61
+
51
62
  if (options.home || process.env.ARTIFACTY_HOME) {
52
63
  env.ARTIFACTY_HOME = path.resolve(options.home || process.env.ARTIFACTY_HOME);
53
64
  }
@@ -241,6 +252,26 @@ function normalizeTimeoutMs(value) {
241
252
  return Number.isFinite(timeout) && timeout > 0 ? timeout : DEFAULT_MCP_TIMEOUT_MS;
242
253
  }
243
254
 
255
+ function normalizeMcpMode(value) {
256
+ const mode = String(value || "bridge").trim().toLowerCase();
257
+ if (mode === "remote") {
258
+ return "bridge";
259
+ }
260
+ if (!["local", "bridge"].includes(mode)) {
261
+ throw new Error("MCP transport must be local or bridge");
262
+ }
263
+ return mode;
264
+ }
265
+
266
+ function normalizeMcpEndpoint(value) {
267
+ const parsed = new URL(value);
268
+ const pathname = parsed.pathname.replace(/\/+$/, "");
269
+ parsed.pathname = pathname || "/mcp";
270
+ parsed.search = "";
271
+ parsed.hash = "";
272
+ return parsed.toString();
273
+ }
274
+
244
275
  function quoteTomlString(value) {
245
276
  return JSON.stringify(String(value));
246
277
  }