{
  "markdown": "# PrintYourDuck MCP\n\n[![CI](https://github.com/printyourduck/printyourduck-mcp/actions/workflows/checks.yml/badge.svg)](https://github.com/printyourduck/printyourduck-mcp/actions/workflows/checks.yml)\n[![Security](https://github.com/printyourduck/printyourduck-mcp/actions/workflows/security.yml/badge.svg)](https://github.com/printyourduck/printyourduck-mcp/actions/workflows/security.yml)\n[![MCP](https://img.shields.io/badge/MCP-com.printyourduck%2Fquote-blue)](https://printyourduck.com/server.json)\n[![Node.js >=20](https://img.shields.io/badge/node-%3E%3D20-339933)](package.json)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\nMCP server for sending local 3D print files to PrintYourDuck manual quote\nreview. It is built for coding-agent workflows where the user has generated or\nselected a local `.stl`, `.step`, `.stp`, `.3mf`, `.obj`, or `.zip` file and\nwants help preparing a quote request.\n\nThe server is preconfigured for `https://printyourduck.com`. Users do not need\nto supply an API URL, API key, or shop routing configuration.\n\n<!-- mcp-name: com.printyourduck/quote -->\n\n## Status\n\n| Surface | Status |\n| --- | --- |\n| Remote MCP | Live at `https://printyourduck.com/api/mcp` |\n| Local stdio package | Available via npm as `@printyourduck/mcp` |\n| npm package | Public: `@printyourduck/mcp` |\n| OCI image | Release target: `ghcr.io/printyourduck/printyourduck-mcp:<version>` |\n| MCP Registry | Live as `com.printyourduck/quote` |\n\n`npx` is the primary install path today. Use Docker only after verifying the\nGHCR image is publicly pullable for the target version.\n\n## Why This Exists\n\n3D-print quote workflows are easy to get wrong when a user is coming from code,\nCAD generation, or rapid prototyping. This MCP server gives agents a narrow,\nauditable workflow:\n\n1. Read the public quote requirements.\n2. Find recent printable files in the current project.\n3. Ask the user to choose one file and confirm the required safety statements.\n4. Upload that file through PrintYourDuck's private upload flow.\n5. Submit the manual quote request.\n6. Check public-safe quote status by quote ID and customer email.\n\nIt does not calculate instant pricing, collect payment at upload, automate\ncheckout, or expose private operational details.\n\n## Install\n\nUse this now:\n\n```bash\nnpx -y @printyourduck/mcp\n```\n\nFor team-shared or reproducible client configs, pin a package version:\n\n```bash\nnpx -y @printyourduck/mcp@<version>\n```\n\n## Client Setup\n\nMCP client configuration files are not identical across clients. Use the shape\nexpected by your client, then restart or refresh that client so it reloads the\nserver.\n\nClaude Code, local user setup:\n\n```bash\nclaude mcp add --transport stdio printyourduck -- npx -y @printyourduck/mcp\n```\n\nClaude Code, project-shared `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"printyourduck\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@printyourduck/mcp\"]\n    }\n  }\n}\n```\n\nUse project-shared `.mcp.json` only when a repository should intentionally\noffer PrintYourDuck tools to everyone opening that project. Claude Code prompts\nfor approval before using project-scoped MCP servers.\n\nVS Code workspace setup in `.vscode/mcp.json`:\n\n```json\n{\n  \"servers\": {\n    \"printyourduck\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@printyourduck/mcp\"]\n    }\n  }\n}\n```\n\nClients that use the common `mcpServers` shape can use the Claude Code project\nsnippet above.\n\nTest the local server with MCP Inspector:\n\n```bash\nnpx -y @modelcontextprotocol/inspector npx -y @printyourduck/mcp\n```\n\nDocker, after verifying the GHCR image is public:\n\n```bash\ndocker run --rm -i ghcr.io/printyourduck/printyourduck-mcp:<version>\n```\n\nRemote-capable MCP clients can connect today:\n\n```text\nhttps://printyourduck.com/api/mcp\n```\n\nClaude Code remote HTTP setup:\n\n```bash\nclaude mcp add --transport http printyourduck https://printyourduck.com/api/mcp\n```\n\n## Tools\n\n| Tool | Purpose | Network/File Access |\n| --- | --- | --- |\n| `get_printyourduck_quote_requirements` | Returns accepted file types, material choices, required confirmations, and safety boundaries. | No local file access. No network. |\n| `find_recent_printable_files` | Finds recent printable files under an allowed local project directory. | Read-only local file metadata. |\n| `submit_local_file_for_quote` | Uploads one user-approved local file and creates a manual quote request. | Reads one allowed local file, uploads privately, then submits to PrintYourDuck. |\n| `get_quote_status` | Looks up public-safe quote status with quote ID and matching email. | Network request to PrintYourDuck only. |\n\nLocal file discovery and upload are limited to the current working directory by\ndefault. Set `PRINTYOURDUCK_MCP_ALLOWED_ROOTS` to a path-delimited allowlist when\nthe MCP client should access additional project directories.\n\n`submit_local_file_for_quote` derives a stable `submissionId` from the selected\nfile and quote details unless the caller provides one. Reuse that ID on retry to\navoid duplicate manual quote requests. The helper also caches the uploaded\nprivate file key locally by `submissionId` and file hash so retries can reuse the\nsame uploaded file reference when the upload service returns a generated Blob\nkey.\n\n## Guardrails\n\nThis server preserves the PrintYourDuck manual-quote boundary:\n\n- no instant pricing today;\n- no payment at upload;\n- no checkout automation;\n- no local-production, Canadian-made-production, or guaranteed-delivery claims;\n- no supplier locations, fulfilment routes, carrier strategy, supplier costs,\n  margin logic, private file references, or customer data in public responses.\n\nPrice ranges or instant estimates are a valid future capability only when they\nare explicitly scoped, tested, publicly documented, and clearly separated from\ncheckout or payment collection.\n\n## Development\n\n```bash\npnpm install\npnpm check:release\n```\n\nUseful checks:\n\n```bash\npnpm check          # lint, tests, typecheck\npnpm check:security # audit, gitleaks, trufflehog\npnpm check:mcp      # stdio initialize, tool list, fixture discovery, path guard\npnpm check:pack     # npm tarball allowlist\n```\n\n`pnpm check:mcp` builds the server, starts it over stdio, verifies initialize and\ntool metadata, creates a temporary `.stl` fixture, verifies local discovery, and\nverifies files outside allowed roots are rejected before upload.\n\nRun the live production smoke only when you intentionally want to create a real\nquote request:\n\n```bash\nPRINTYOURDUCK_MCP_LIVE_SMOKE=1 \\\nPRINTYOURDUCK_MCP_SMOKE_EMAIL=operator@example.com \\\npnpm smoke:live\n```\n\nThe live smoke uploads a tiny fixture through `https://printyourduck.com`,\nsubmits one manual quote request, and verifies `get_quote_status` returns.\n\n## Release Checklist\n\nOnly claim npm local-helper installability after all of these pass:\n\n```bash\npnpm check:release\nnpm view @printyourduck/mcp version\nVERSION=\"$(npm view @printyourduck/mcp version)\"\ngh release view \"mcp-v${VERSION}\"\nPRINTYOURDUCK_MCP_LIVE_SMOKE=1 PRINTYOURDUCK_MCP_SMOKE_EMAIL=operator@example.com pnpm smoke:live\n```\n\nRelease npm package changes from this dedicated MCP repository, not from the\nwebsite repository.\n\nFor each tagged release, verify the npm package was published from the tagged\ncommit:\n\n```bash\nVERSION=\"$(node -p \"require('./package.json').version\")\"\ntest \"$(npm view \"@printyourduck/mcp@${VERSION}\" gitHead)\" = \"$(git rev-parse HEAD)\"\nnpm view \"@printyourduck/mcp@${VERSION}\" dist.tarball dist.integrity\n```\n\nThe MCP Registry name is `com.printyourduck/quote`, so publication uses\ndomain-based HTTP authentication for `printyourduck.com`. Serve the public\n`v=MCPv1; ...` record from `https://printyourduck.com/.well-known/mcp-registry-auth`\nand keep the matching private key only in the `MCP_REGISTRY_PRIVATE_KEY` GitHub\nActions secret for this repository.\n\nOnly claim MCP Registry publication after this passes:\n\n```bash\ncurl -f \"https://registry.modelcontextprotocol.io/v0/servers/com.printyourduck%2Fquote/versions\"\n```\n\nBefore tagging a release, make the GHCR package public in GitHub's package\nsettings. The release workflow fails before publishing npm if\n`ghcr.io/printyourduck/printyourduck-mcp` is still private, because the public\nrelease must be anonymously pullable.\n\nOnly claim OCI/container installability after making package visibility public\nand running:\n\n```bash\nVERSION=\"$(node -p \"require('./package.json').version\")\"\nDOCKER_CONFIG=\"$(mktemp -d)\" docker manifest inspect \"ghcr.io/printyourduck/printyourduck-mcp:${VERSION}\"\n```\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md). Good first areas include client setup\ndocs, path-safety hardening, MCP metadata safety, package release checks, and\npublic-safe examples.\n\nFor security issues, see [SECURITY.md](SECURITY.md). Do not include secrets,\ncustomer files, private file references, supplier/cost/margin details, or\ndashboard screenshots in public issues.\n",
  "bytes": 8906,
  "sha": "58a80de4150c616879e163a2b1a08d67db46feb430316893871154b53b357d95",
  "repo_slug": "printyourduck/printyourduck-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_com_printyourduck_quote_a97f80a0/readme"
}