Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
제작자가 쓴 설명(영어 원문)
Private, expiring artifact hosting for AI agents. Upload via API or MCP; links die on their own.
이 세 가지는 절대 하나의 점수로 합치지 않아요. 의견, 측정, 인기는 서로 다른 것이니까요.
이 서버는 아직 쉬운 말로 된 요약을 쓰지 못했어요. 아래는 레지스트리에서 읽어 온 사실이에요.
쓰고 있는 AI 앱을 고른 다음 설정을 복사하세요.
Authorization비밀로 표시된 값은 내 계정의 열쇠예요. 절대 다른 사람과 공유하거나 채팅에 붙여 넣지 마세요.
필요한 것
어떤 앱을 쓰세요?
위에서 앱을 고르세요. 기억해 두었다가 다음부터는 버튼에 “…에 설치”라고 표시해요.
이 주소는 요청 header에 키가 필요한데, 커넥터 추가 메뉴에서는 넣을 수 없어요. 대신 Claude Code, Cursor, VS Code를 쓰세요.
터미널에서 이 명령어를 실행하세요
claude mcp add --transport http veilfile https://veilfile.com/mcp/ --header 'Authorization: your-value'실행하기 전에 빈 값을 채워 주세요.
프로젝트의 .cursor/mcp.json 또는 ~/.cursor/mcp.json에 붙여 넣으세요
{
"mcpServers": {
"veilfile": {
"url": "https://veilfile.com/mcp/",
"headers": {
"Authorization": "your-value"
}
}
}
}브라우저가 앱을 열지 물어본 다음, 앱이 설정을 보여 주고 확인을 요청해요. 키 값은 비워 두니 직접 입력하세요.
프로젝트의 .vscode/mcp.json에 붙여 넣으세요
{
"servers": {
"veilfile": {
"type": "http",
"url": "https://veilfile.com/mcp/",
"headers": {
"Authorization": "your-value"
}
}
}
}브라우저가 앱을 열지 물어본 다음, 앱이 설정을 보여 주고 확인을 요청해요. 키 값은 비워 두니 직접 입력하세요.
이 주소는 요청 header에 키가 필요한데, 커넥터 추가 메뉴에서는 넣을 수 없어요. 대신 Claude Code, Cursor, VS Code를 쓰세요.
선택한 앱은 이 기기의 쿠키에만 저장돼요. 계정은 필요 없어요.
Authorization 비밀 필수 HTTP header이 설정은 제작자의 레지스트리 정보로 만들었어요. README와 다르면 README를 따르세요.
아직 이 서버의 도구 목록을 읽지 않았어요. 엔드포인트는 차례대로 돌아가며 점검해요.
누구나 볼 수 있는 정보를 점검했고, 코드는 읽지 않았어요. 해당하지 않는 항목은 개수에서 뺐어요. · 2026년 11월 6일 점검
레지스트리 이름이 GitHub 계정 veilfile 기준으로 확인되었고, 이 계정이 저장소를 소유하고 있어요
아직 GitHub에서 이 저장소를 읽어 오지 않았어요
아직 GitHub에서 이 저장소를 읽어 오지 않았어요
아직 점검하지 않았어요. 엔드포인트는 차례대로 돌아가며 점검해요
아직 점검하지 않았어요. 엔드포인트는 차례대로 돌아가며 점검해요
아직 점검하지 않았어요. 엔드포인트를 점검할 때 도구 목록을 읽어요
레지스트리에서 이 카테고리의 활성 서버 전체와 비교했어요. 스타는 게시자가 저장소를 소유한 경우에만 세요.
해당하는 기본 점검 1개 중 1개를 통과했어요. 코드는 읽지 않았어요. 키나 토큰을 넣기 전에 서버가 어떤 권한을 요구하는지 확인하고, 꼭 필요한 권한만 있는 키를 쓰세요.
입력해야 할 값: Authorization
제작자의 클라우드에서 실행돼요. 설치 없이 인터넷으로 연결하지만, 보내는 내용은 제작자의 서버를 거쳐요.
GitHub 저장소는 마지막으로 – 변경됐고, 최신 버전(1.0.0)은 10일 전 레지스트리에 올라왔어요.
Claude Desktop, Claude Code, Cursor, VS Code처럼 MCP를 지원하는 앱에서 쓸 수 있어요. URL로 연결되기 때문에, 원격 MCP 서버를 지원하는 앱(예: 개발자 모드의 ChatGPT)에서도 쓸 수 있어요.
같은 카테고리에는: Spec Driven Development, Remote Desktop Commander, LickityClick
같은 카테고리에서 다른 제작자가 만든 서버예요. 스타 순으로 정렬했어요.
카드 보는 법:★ GitHub 스타i세 기둥: 리뷰 · 점검 · 사용 정도i업데이트 = 최신 버전을 레지스트리에 공개한 날i
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Create, edit and track LickityClick short links, campaigns and click stats from your AI assistant.
제작자의 저장소에서 쓰인 그대로 가져왔어요. PopNx MCP가 검토하거나 보증한 내용이 아니에요. HTML, 이미지, 스크립트는 제거했어요. 링크를 누르면 이 사이트를 벗어나요.
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).
POST /api/v1/artifacts (multipart, Authorization: Bearer vlf_…) → {id, url, expires_at, size_bytes, secret_flags[]}. GET /a/ serves the file (the 256-bit token *is* the auth). List (bare JSON array) and revoke endpoints included.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.veilfile on PyPI (cli/) and npm (npm/): login (device flow), logout, status, push, pull./app/, Django views on the same shell as the rest of the site: Overview (usage vs plan caps), Files (secret-flag notes/ (public). Agent docs: /llms.txt, docs/API.md, /docs/.See SPEC.md for the product spec.
| Plan | Price | Uploads/mo | Max TTL | Storage | API keys |
|---|---|---|---|---|---|
| Free | $0 | 100 | 7 days | 1 GB | 1 |
| Team | $4/mo | 2,000 | 90 days | 25 GB | 5 |
| Team Plus | $6/mo | 4,000 | 90 days | 40 GB | 10 |
| Scale | $12/mo | 10,000 | 365 days | 100 GB | unlimited |
| Team (yearly) | $40/yr | 2,000 | 90 days | 25 GB | 5 |
| Team Plus (yearly) | $60/yr | 4,000 | 90 days | 40 GB | 10 |
| Scale (yearly) | $120/yr | 10,000 | 365 days | 100 GB | unlimited |
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.
# Backend
python3 -m venv venv && ./venv/bin/pip install -r backend/requirements.txt export 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:
curl -H "Authorization: Bearer vlf_..." \
-F "file=@screenshot.png" \ http://localhost:8000/api/v1/artifacts/
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.
| Variable | Required | Default | Notes |
|---|---|---|---|
DJANGO_SECRET_KEY | prod | — | Required when DJANGO_DEBUG is false |
DJANGO_DEBUG | no | False | Set True for local dev and for tests |
DJANGO_ALLOWED_HOSTS | prod | — | Comma-separated, e.g. veilfile.com |
DJANGO_CSRF_TRUSTED_ORIGINS | no | derived from DJANGO_ALLOWED_HOSTS | Comma-separated origins |
DATABASE_URL | prod | sqlite (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_SQLITE | no | — | True lets production mode run on SQLite on purpose (local docker run, image build) |
DJANGO_CONN_MAX_AGE | no | 60 | Persistent DB connection lifetime (seconds) |
DROP_BASE_URL | prod | http://localhost:8000 | Public URL; artifact links are built from it |
DROP_STORAGE | no | local | local (dev) or s3 (prod) |
DROP_LOCAL_DIR | no | backend/media/artifacts | Local storage root |
AWS_S3_ENDPOINT_URL | prod (s3) | — | R2 endpoint, e.g. https:// .r2.cloudflarestorage.com |
AWS_S3_BUCKET | prod (s3) | — | R2 bucket name |
AWS_ACCESS_KEY_ID | prod (s3) | — | R2 API token (access key) |
AWS_SECRET_ACCESS_KEY | prod (s3) | — | R2 API token (secret) |
STRIPE_SECRET_KEY | billing | — | Live secret key (sk_live_…) in production |
STRIPE_WEBHOOK_SECRET | billing | — | Signing secret (whsec_…) from the same Stripe account and mode as the secret key |
STRIPE_PRICE_TEAM | billing | — | Price ID for the $4/mo Team plan (tax-inclusive) |
STRIPE_PRICE_TEAMPLUS | billing | — | Price ID for the $6/mo Team Plus plan (tax-inclusive). The name has no underscore between TEAM and PLUS |
STRIPE_PRICE_SCALE | billing | — | Price ID for the $12/mo Scale plan (tax-inclusive) |
STRIPE_PRICE_TEAM_ANNUAL | billing | — | Price ID for yearly Team billing, $40/yr (tax-inclusive) |
STRIPE_PRICE_TEAMPLUS_ANNUAL | billing | — | 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_ANNUAL | billing | — | Price ID for yearly Scale billing, $120/yr (tax-inclusive) |
EMAIL_BACKEND | prod | console | Set 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_PASSWORD | prod | — | SMTP settings (the live service uses Gmail SMTP) |
DEFAULT_FROM_EMAIL | prod | — | From address, e.g. support@veilfile.com |
EMAIL_TIMEOUT | no | 10 | SMTP timeout (seconds) |
VEILFILE_SAFETY_MODE | no | off | off, log or enforce: SHA-256 blocklist screening of uploads. Unset is reported as veilfile.W002 |
VEILFILE_CLIENT_IP_HEADER | no | CF-Connecting-IP | Header 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_HOPS | no | 2 | Trusted 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_SECONDS | no | 31536000 | HSTS max-age on HTTPS responses |
DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS, DJANGO_SECURE_HSTS_PRELOAD | no | False | Turn on only after every subdomain serves HTTPS |
PORT | no | 8000 | Set by the host (Render); the entrypoint falls back to 8000 |
WEB_CONCURRENCY | no | 1 | gunicorn workers (gthread) |
GUNICORN_THREADS | no | 4 | Threads per worker. Each in-flight upload is held in memory; lower this on small instances |
GUNICORN_TIMEOUT, GUNICORN_GRACEFUL_TIMEOUT | no | 120, 30 | gunicorn timeouts (seconds) |
SKIP_MIGRATE | no | unset | 1 skips migrate at boot (use with a Render pre-deploy command) |
VEILFILE_FUNNEL_RETENTION_DAYS | no | 365 | How long prune_funnel_events keeps funnel rows |
VEILFILE_ALERT_DIR | no | unset | Directory where CRITICAL safety alerts are also written as files, for an external alert bus; they always go to the log |
DJANGO_TEST_ALLOW_REMOTE_DB | no | — | 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 need DJANGO_DEBUG=True (the test runner refuses False) and a local database; it also forces local storage and strips STRIPE_*/AWS_*.
# 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
cd npm && node --test cd 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").
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.GET /healthz returns 200 {"status":"ok"} after a SELECT 1, or 503. Set it as the Render Health Check Path.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.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.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.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.manage.py check --deploy reports veilfile.W001-W006 misconfigurations (also logged at ERROR by every worker at boot).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.docs/REGISTRIES.md.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,
앞부분만 보여 드려요. 나머지는 저장소에서 읽어 보세요