Veilfile

io.github.veilfile由 GitHub 帳號 veilfile 發布v1.0.0更新於 Oct 30, 2026

Private, expiring artifact hosting for AI agents. Upload via API or MCP; links die on their own.

已驗證Streamable HTTP可網頁執行雲端與基礎設施檔案與儲存

概覽

AI 產生的概覽

Veilfile 是託管的 MCP 伺服器,提供私密、會過期的產物託管:助理可上傳截圖、日誌或 HAR 檔,並取得無法猜測、到期自動失效的連結。

可以做什麼
  • 上傳產物並取回無法猜測、具有效期限的連結
  • 為不直接傳送的檔案建立預簽章上傳網址
  • 列出工作區中既有的產物
  • 撤銷產物,使其連結立即失效
  • 上傳內容會掃描敏感資訊樣式並標記,呼叫端要求時可直接拒絕
適用情境
適合 CI 或雲端工作階段中的程式代理產出截圖、日誌包或 HAR 檔,需要私密連結供審閱,而不想放進公開儲存庫的情況。也適合把短期檔案交給人工查看,又不想讓它們長期留在網路上。
執行需求
透過 streamable HTTP 連線至 veilfile.com 的遠端端點,無需本機安裝。需要完成電子郵件驗證的帳號,並在儀表板建立 API 金鑰,以 Authorization 標頭攜帶,或使用 OAuth 權杖。有免費方案,更大額度需付費。
安裝前請注意
API 金鑰只顯示一次,可對工作區執行上傳、列出與撤銷,需妥善保存。只有呼叫端明確要求拒絕時,含敏感資訊樣式的上傳才會被攔截,否則僅被標記但仍會儲存。持有連結的任何人都能讀取檔案,因為權杖本身就是憑證。付費方案透過 Stripe 計費。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Veilfile,將其新增到工作區。
  2. 連接 所需的 憑證。它們會被私密儲存,絕不會在公開頁面上展示。
  3. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/io.github.veilfile%2Fveilfile/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。 客戶端會在首次連接時完成 OAuth 登入。

{
  "mcpServers": {
    "veilfile": {
      "type": "http",
      "url": "https://veilfile.com/mcp/"
    }
  }
}

README

Veilfile — private, ephemeral artifact hosting for AI agents

When a coding agent in CI or a cloud session produces a screenshot, log bundle, or HAR file for review, it needs a private URL to put it at — not a public repo. Veilfile is the sanctioned place: upload via API key (or MCP), get back an unguessable, expiring URL. Uploads are scanned for secret shapes and flagged (blocked only when the caller passes on_secret=reject; file contents are never logged).

  • API: POST /api/v1/artifacts (multipart, Authorization: Bearer vlf_…) → {id, url, expires_at, size_bytes, secret_flags[]}. GET /a/<token> serves the file (the 256-bit token is the auth). List (bare JSON array) and revoke endpoints included.
  • MCP: hosted server at POST /mcp (JSON-RPC over HTTP; tools upload_artifact, create_upload_url, list_artifacts, revoke_artifact), authenticated with a vlf_ key or an OAuth token.
  • CLIs: veilfile on PyPI (cli/) and npm (npm/): login (device flow), logout, status, push, pull.
  • Dashboard: signed-in pages at /app/, Django views on the same shell as the rest of the site: Overview (usage vs plan caps), Files (secret-flag notes
    • revoke), Keys (a new key is shown once), Connected apps and Billing (plan switching and the Stripe billing portal).
  • Landing page: / (public). Agent docs: /llms.txt, docs/API.md, /docs/.
  • Agents working on this repo: read AGENTS.md.

See SPEC.md for the product spec.

Plans

PlanPriceUploads/moMax TTLStorageAPI keys
Free$01007 days1 GB1
Team$4/mo2,00090 days25 GB5
Team Plus$6/mo4,00090 days40 GB10
Scale$12/mo10,000365 days100 GBunlimited
Team (yearly)$40/yr2,00090 days25 GB5
Team Plus (yearly)$60/yr4,00090 days40 GB10
Scale (yearly)$120/yr10,000365 days100 GBunlimited

Yearly billing costs ten months' price, so two months are free. A yearly plan has the same limits as the monthly one.

The source of truth is backend/drop_core/plans.py (PLANS, and ANNUAL_PRICE_USD for the yearly prices; Stripe prices live in Stripe and the STRIPE_PRICE_* variables). backend/drop_core/tests_fix_docs.py fails when a doc or template states a different price or cap.

Quickstart (local dev)

bash
# Backendpython3 -m venv venv && ./venv/bin/pip install -r backend/requirements.txtexport DJANGO_DEBUG=True DJANGO_SECRET_KEY=dev-only-key./venv/bin/python backend/manage.py migrate./venv/bin/python backend/manage.py createsuperuser   # dashboard login./venv/bin/python backend/manage.py runserver          # :8000

Sign up at http://localhost:8000/accounts/signup/ (or log in), open /app/, create an API key, then:

bash
curl -H "Authorization: Bearer vlf_..." \     -F "[email protected]" \     http://localhost:8000/api/v1/artifacts/

Environment variables

No secrets are committed to this repo. Copy the names below into a local .env (gitignored) or your host's env config. Billing is live in production (sk_live_..., live price IDs, Stripe Managed Payments); use a Stripe sandbox/test key only on a local or staging copy.

VariableRequiredDefaultNotes
DJANGO_SECRET_KEYprod—Required when DJANGO_DEBUG is false
DJANGO_DEBUGnoFalseSet True for local dev and for tests
DJANGO_ALLOWED_HOSTSprod—Comma-separated, e.g. veilfile.com
DJANGO_CSRF_TRUSTED_ORIGINSnoderived from DJANGO_ALLOWED_HOSTSComma-separated origins
DATABASE_URLprodsqlite (dev only)Postgres URL. Production refuses to start without it, or with a sqlite:// URL, unless DJANGO_ALLOW_SQLITE=True. User, password and name are percent-decoded; ?sslmode=... is passed to the driver
DJANGO_ALLOW_SQLITEno—True lets production mode run on SQLite on purpose (local docker run, image build)
DJANGO_CONN_MAX_AGEno60Persistent DB connection lifetime (seconds)
DROP_BASE_URLprodhttp://localhost:8000Public URL; artifact links are built from it
DROP_STORAGEnolocallocal (dev) or s3 (prod)
DROP_LOCAL_DIRnobackend/media/artifactsLocal storage root
AWS_S3_ENDPOINT_URLprod (s3)—R2 endpoint, e.g. https://<acct>.r2.cloudflarestorage.com
AWS_S3_BUCKETprod (s3)—R2 bucket name
AWS_ACCESS_KEY_IDprod (s3)—R2 API token (access key)
AWS_SECRET_ACCESS_KEYprod (s3)—R2 API token (secret)
STRIPE_SECRET_KEYbilling—Live secret key (sk_live_…) in production
STRIPE_WEBHOOK_SECRETbilling—Signing secret (whsec_…) from the same Stripe account and mode as the secret key
STRIPE_PRICE_TEAMbilling—Price ID for the $4/mo Team plan (tax-inclusive)
STRIPE_PRICE_TEAMPLUSbilling—Price ID for the $6/mo Team Plus plan (tax-inclusive). The name has no underscore between TEAM and PLUS
STRIPE_PRICE_SCALEbilling—Price ID for the $12/mo Scale plan (tax-inclusive)
STRIPE_PRICE_TEAM_ANNUALbilling—Price ID for yearly Team billing, $40/yr (tax-inclusive)
STRIPE_PRICE_TEAMPLUS_ANNUALbilling—Price ID for yearly Team Plus billing, $60/yr (tax-inclusive). No underscore between TEAM and PLUS, as in STRIPE_PRICE_TEAMPLUS
STRIPE_PRICE_SCALE_ANNUALbilling—Price ID for yearly Scale billing, $120/yr (tax-inclusive)
EMAIL_BACKENDprodconsoleSet django.core.mail.backends.smtp.EmailBackend; without SMTP no new user can verify their email, mint keys or approve CLI logins (veilfile.W001)
EMAIL_HOST, EMAIL_PORT, EMAIL_USE_TLS, EMAIL_HOST_USER, EMAIL_HOST_PASSWORDprod—SMTP settings (the live service uses Gmail SMTP)
DEFAULT_FROM_EMAILprod—From address, e.g. [email protected]
EMAIL_TIMEOUTno10SMTP timeout (seconds)
VEILFILE_SAFETY_MODEnooffoff, log or enforce: SHA-256 blocklist screening of uploads. Unset is reported as veilfile.W002
VEILFILE_CLIENT_IP_HEADERnoCF-Connecting-IPHeader carrying the visitor IP, set (and overwritten) by Cloudflare. Used for rate limits when it holds a valid IP and the request came from a Cloudflare edge address; otherwise the X-Forwarded-For hop logic below applies. Empty disables it
VEILFILE_TRUSTED_PROXY_HOPSno2Trusted public proxy hops in front of the app. The client IP used for rate limits is the X-Forwarded-For entry that many positions from the right, after trailing private-network hops are skipped, when the last of them is a Cloudflare edge address. A request without one did not come through Cloudflare, and the last entry (the one the platform's proxy appended) is used. Confirm against real traffic before changing
DJANGO_SECURE_HSTS_SECONDSno31536000HSTS max-age on HTTPS responses
DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS, DJANGO_SECURE_HSTS_PRELOADnoFalseTurn on only after every subdomain serves HTTPS
PORTno8000Set by the host (Render); the entrypoint falls back to 8000
WEB_CONCURRENCYno1gunicorn workers (gthread)
GUNICORN_THREADSno4Threads per worker. Each in-flight upload is held in memory; lower this on small instances
GUNICORN_TIMEOUT, GUNICORN_GRACEFUL_TIMEOUTno120, 30gunicorn timeouts (seconds)
SKIP_MIGRATEnounset1 skips migrate at boot (use with a Render pre-deploy command)
VEILFILE_FUNNEL_RETENTION_DAYSno365How long prune_funnel_events keeps funnel rows
VEILFILE_ALERT_DIRnounsetDirectory where CRITICAL safety alerts are also written as files, for an external alert bus; they always go to the log
DJANGO_TEST_ALLOW_REMOTE_DBno—Lets manage.py test run against a non-local database server (CI with a service container)

Without Stripe vars, checkout/switch/portal return 503 billing_not_configured and the dashboard shows a friendly note; everything else works.

Tests

Tests need DJANGO_DEBUG=True (the test runner refuses False) and a local database; it also forces local storage and strips STRIPE_*/AWS_*.

bash
# Backend (the count changes; run it rather than trusting a number here)cd backend && DJANGO_DEBUG=True DJANGO_SECRET_KEY=dev-only-key \  ../venv/bin/python manage.py test../venv/bin/python manage.py makemigrations --check --dry-run   # must report no changes
# CLIscd npm && node --testcd cli && ../venv/bin/python -m unittest discover -s tests -t .

CI (.github/workflows/ci.yml) runs all of the above plus manage.py check --deploy, a production-settings collectstatic, and the browser checks in site-tests/ (jobs site, site-cloth, site-ink, site-reading, site-phone, site-forms, site-catalog and site-dashboard; see AGENTS.md, "Site checks") on every pull request to main (the browser checks skip a pull request that changes no page), and the backend and CLI checks on every push to it. It runs on GitHub-hosted runners, one machine for each job, with the jobs side by side (AGENTS.md, "Where CI runs").

Ops

  • Deploy: Render Docker web service (serves veilfile.com), auto-deploys every commit to main after its CI checks pass, with a paid Postgres. render.yaml mirrors it. The container runs as a non-root user. Boot sequence (backend/entrypoint.sh): migrate --noinput (skipped when SKIP_MIGRATE=1), createcachetable, a background daily housekeeping loop, then gunicorn.
  • Health check: GET /healthz returns 200 {"status":"ok"} after a SELECT 1, or 503. Set it as the Render Health Check Path.
  • Daily housekeeping: the entrypoint loop runs sweep_expired, clearsessions, cleartokens, prune_funnel_events, prune_email_ips (clears send-log IPs after 90 days) and purge_expired_cache once a day. No separate cron job is needed. Uploads also trigger a small lazy sweep.
  • TTL sweeper: python backend/manage.py sweep_expired deletes expired artifacts (files + rows). Idempotent. Prints swept=N bytes=N failed=N and exits non-zero when any storage delete failed (those rows are kept for the next run); --limit N / --time-budget SECONDS bound a run.
  • Orphaned files: python backend/manage.py reconcile_storage lists stored objects with no artifact row; --delete removes them. Run it by hand, dry run first: --delete refuses when the database looks wrong (empty artifact table, more than 20% orphans, or R2 storage without PostgreSQL) unless you pass --force after checking the db= / storage= it prints.
  • Billing resync: python backend/manage.py sync_stripe_billing (dry run; --apply to write) rebuilds workspace plans from Stripe. The Stripe setup steps are in the private ops repository.
  • Deploy checks: manage.py check --deploy reports veilfile.W001-W006 misconfigurations (also logged at ERROR by every worker at boot).
  • Local container: docker run needs DATABASE_URL=sqlite:////tmp/db.sqlite3 together with DJANGO_ALLOW_SQLITE=True (production mode otherwise refuses SQLite); /app/backend is read-only to the non-root user.
  • Storage: Render's disk is ephemeral. Production must use DROP_STORAGE=s3 (Cloudflare R2).
  • MCP registries: launch checklist in docs/REGISTRIES.md.

Project layout

backend/  config/          Django settings/URLs (env-driven)  drop_core/       Workspace, APIKey (vlf_), Artifact, plans, storage,                   secret scan, agent API, key mgmt, device login, OAuth                   glue, sweeper  drop_billing/    Stripe checkout/switch/portal/status/webhook (live,                   tax-inclusive, Managed Payments)  drop_mcp/        MCP server (POST /mcp)  blog/, docs/     Markdown-rendered Journal posts (and their feed) and Docs pages  legal/           Terms, privacy policy, abuse reporting (Markdown)  pages/           public-page registry, sitemap, component catalog, content checks  static/          the new shell's CSS, JS, fonts and images  dashboard/       the signed-in dashboard at /app/ (views, URLs, tests)  templates/       shell.html, layouts/, chapters/ and components/, the Journal, Docs and legal pages, the form pages (sign in, device, OAuth), the dashboard and the error pagescli/, npm/         Python and Node `veilfile` command-line clientsplugin/            Claude Code plugin (share-artifact skill)docs/              API.md, llms.txt (served at /llms.txt), REGISTRIES.md,                   superpowers/ (design specs and build plans)site-tests/        browser checks for the new shell (CI jobs `site`, `site-cloth`, `site-ink`, `site-reading`, `site-phone`, `site-forms`, `site-catalog`, `site-dashboard`)tools/             one-off font and image generators, run by handDockerfile         one Python stage, WhiteNoise + gunicorn (the site has no build step)render.yaml        Render deploy blueprint (mirrors the live service)AGENTS.md          Rules and commands for agents working on this repo

License and contributions

The code is published so that anyone can read it and check what Veilfile does. All rights are reserved (LICENSE), except for the command-line clients in cli/ and npm/, which are under the MIT License. This repository does not accept pull requests from outside contributors. Issues are welcome, and a security problem should be reported privately with "Report a vulnerability" on the repository's Security tab.

Launch checklist

  1. Create Cloudflare R2 bucket + API token (S3-compatible).
  2. Create Stripe products/prices (Team $4, Team Plus $6, Scale $12, tax-inclusive) with product tax codes; note the price IDs.
  3. Deploy on Render (see render.yaml); set env vars incl. DROP_BASE_URL, DATABASE_URL and the EMAIL_* SMTP settings; set the Health Check Path to /healthz.
  4. Point the Stripe webhook at https://<host>/api/v1/billing/webhook; set STRIPE_WEBHOOK_SECRET.
  5. Decide VEILFILE_SAFETY_MODE (log or enforce).
  6. List the MCP server per docs/REGISTRIES.md.

Expired artifacts are swept daily by the entrypoint loop; no cron job is needed.

來源:README.md,提交 5a19640

工具

0
該伺服器需要登入,因此 SourceWeft 無法在沒有帳號的情況下讀取其工具,也未收錄。已連接帳號所能看到的內容可能因帳號及其權限而異。

版本歷史

1
  1. v1.0.0最新Oct 29, 2026

評分

已滿足適用檢查項的 75%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分

    請在儲存庫或註冊中心條目中宣告授權條款。