Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Commonlands Optics: M12 Lens and C-Mount Lens Finder + Field-of-View Calculator

БесплатноНе проверен

M12 lens and C-mount lens finder with image-sensor matching and field-of-view calculator.

GitHubEmbed

Описание

M12 lens and C-mount lens finder with image-sensor matching and field-of-view calculator.

README

Public MCP server for Commonlands precision optics. Use it to choose M12/C-mount lenses, calculate field of view, verify live Shopify product truth, and hand buyers to Shopify-owned carts safely.

Connect

Copy-paste agent instruction

Use Commonlands MCP at https://mcp.commonlands.com/mcp for lens selection. Start with tools/list. Catalog EFL, image circle, max FoV/FOV@image-circle, and distortion display fields are insufficient to compute FoV on a specific sensor; do not interpolate or estimate sensor FoV from those fields. Use calculate_field_of_view for one lens/sensor pair, match_lens_to_sensor for sensor/target-FoV selection, search_lens_catalog for broad catalog discovery, and get_lens_distortion_profile for distortion status. Preserve the returned method, distortion_model, coverage_ok, image_circle_mm, sensor_diagonal_mm, and rectilinear_comparison. Call read_shopify_products before stating live price, availability, Product/Variant GIDs, URL, SKU, media, metafields, inventory, or cart payload. Only call create_cart/update_cart after the buyer confirms exact live Variant GIDs and quantities. Checkout tools are not live unless they appear in tools/list. Never ask for card data or perform Shopify catalog/inventory/order/customer writes.

Agent workflow

  1. Call tools/list and trust the live list over docs.
  2. For sensor-specific lens finding, call match_lens_to_sensor first, then call calculate_field_of_view for final candidate lens/sensor FoV claims.
  3. Use search_lens_catalog only for broad SKU/title/mount/lens-type discovery. It does not replace per-sensor FoV calculation.
  4. Get per-object grounding with resources/read for commonlands://sensors/{part} or commonlands://lenses/{sku} when needed.
  5. Use get_lens_distortion_profile for distortion/model/status questions. Do not invent polynomial coefficients or claim measured correction when the response says source-display-only.
  6. Use prompts/list / prompts/get with select_lens_for_sensor_fov_working_distance when a client surfaces MCP prompts.
  7. Verify purchasable truth with read_shopify_products before quoting final SKU, URL, price, availability, Shopify IDs, or cart payloads.
  8. Create/update a Shopify cart only after explicit buyer confirmation of line items and quantities.
  9. Send the buyer to Shopify's returned cart/checkout URL. Do not claim Checkout MCP is live until checkout tools appear in tools/list.

FoV rule

Catalog EFL, image circle, max FoV/FOV@image-circle, and distortion display fields are insufficient to compute field of view on a specific sensor. Agents must not interpolate interior-sensor FoV or substitute their own calculations. Use calculate_field_of_view, then preserve returned hfov_deg, vfov_deg, dfov_deg, method, distortion_model, coverage_ok, image_circle_mm, sensor_diagonal_mm, rectilinear_comparison, and provenance/source metadata in the answer.

Truth hierarchy

  1. read_shopify_products = live Shopify product truth.
  2. calculate_field_of_view / match_lens_to_sensor = live FoV backend (AWS Lambda + DynamoDB lens catalog) when configured. Sensor inputs resolve through the live DynamoDB sensor catalog with fixture fallback. These are the routed public optics tools.
  3. Compatibility aliases (compute_fov, compute_fov_catalog, match_lenses_to_sensor) still dispatch where practical, but new clients should route through the intent-named tools above.
  4. Ranking tools (match_lens_to_sensor, recommend_lenses_for_application, compare_lenses) rank against live FoV-backend specs and field of view when the live backend is enabled, so they use real per-SKU specs (EFL, mount, image circle, FoV). They still exclude live Shopify stock/price/variant IDs; use read_shopify_products for purchasable truth. If the live backend is unconfigured they fall back to fixture scaffold.
  5. The remaining fixture catalog/product-page tools = useful engineering context, not final commerce truth. If the live backend is ever unconfigured, FoV tools fail closed and sensor lookups fall back to a small reference fixture.

If fixture data conflicts with read_shopify_products or the live FoV/sensor backends, use the live truth.

Data sources

  • Sensors (commonlands://sensors/{part} and the sensor used by calculate_field_of_view / match_lens_to_sensor): read from the Commonlands DynamoDB sensor table by part number when configured, with fixture fallback. Pixel pitch and pixel counts come straight from that table; active-area mm is derived as pixels x pitch.
  • Lenses (commonlands://lenses/{sku}, calculate_field_of_view, match_lens_to_sensor, search_lens_catalog): the FoV Lambda reads lens optical parameters from its DynamoDB lens table when configured. Catalog-wide matching covers the full lens table when backend scanning is enabled.
  • Distortion coefficients are computed server-side inside the Lambda and are never returned to clients. If the live backend only returns a display distortion string, MCP returns an honest distortion_model / distortion_status and does not claim measured polynomial correction.

Current live surface

The production surface currently exposes 20 tools across catalog/search, FoV, Shopify read-only, cart, UCP catalog, and purchase-handoff. Checkout tools, cancel_cart, and read_shopify_metaobjects are not exposed. Always trust the live tools/list over any doc.

Key tools:

  • Public optics routing: calculate_field_of_view, match_lens_to_sensor, search_lens_catalog, get_lens_distortion_profile.
  • Catalog/context (in tools/list): search_catalog, lookup_catalog, get_product, get_product_page_details, compare_lenses, recommend_lenses_for_application.
  • Legacy hidden aliases (still dispatch for old clients, not listed in tools/list): compute_fov, compute_fov_catalog, match_lenses_to_sensor, search_lenses, get_lens_details.
  • Resources/prompts: commonlands://sensors/{part}, commonlands://lenses/{sku}, commonlands://catalog/sensors, commonlands://catalog/lenses, and prompt select_lens_for_sensor_fov_working_distance.
  • Live Shopify read-only truth: read_shopify_products, get_shopify_readonly_config_status.
  • Buyer-confirmed Shopify cart handoff: create_cart, get_cart, update_cart when visible in tools/list.
  • RFQ / question handoff: submit_rfq forwards a buyer quote request or question to the fixed Commonlands engineering inbox (SendGrid). The agent cannot choose the recipient; it sends an inquiry only (no order, payment, or Shopify write) and stays inert (routes to the contact page) until SENDGRID_API_KEY + RFQ_TO_EMAIL + RFQ_FROM_EMAIL are configured.
  • Diagnostics/readiness: get_catalog_snapshot_status, get_shopify_ucp_readiness, prepare_shopify_purchase_handoff, get_purchase_route_options.

Public-data scope (Shopify reads)

The endpoint is public and unauthenticated, so read_shopify_products returns only data that is already public on commonlands.com (enforced server-side in src/shopify-read-adapter.ts, see PUBLIC_DATA_POLICY):

  • Active products only. DRAFT and ARCHIVED products are filtered out and the internal status field is never returned.
  • No exact inventory. Variants carry a coarse availability signal (in_stock / low_stock / out_of_stock / untracked); raw counts and inventory item IDs are never returned.
  • Metafields are opt-in and allowlisted. includeMetafields defaults to false; when enabled, only the custom.* display fields rendered on public product pages are returned. App/private namespaces and non-allowlisted keys (including custom.docsend_page) are always dropped.
  • read_shopify_metaobjects was removed from the public surface (2026-07): Admin metaobject definitions can hold non-public store content. Calls return an actionable error pointing to read_shopify_products.
  • The requested Admin scopes were narrowed to the read scopes the surface actually needs (no metaobject, marketing, payment-terms, or shipping scopes).

Abuse controls (cart and endpoint)

Cart tools are deliberately reachable without authentication — the same trust model as Shopify's own public Storefront cart — but they are bounded:

  • Per-IP rate limits (Workers Rate Limiting API, wrangler.toml): 120 requests/min per IP across /mcp, and 10 cart mutations/min per IP for create_cart/update_cart. Exceeding either returns HTTP 429 with retry-after: 60.
  • Strict payloads: 1–25 line items per cart, quantity 1–999 per line, and item IDs must be live Shopify ProductVariant GIDs — fixture IDs, SKUs, and numeric IDs are rejected before any Shopify call.
  • Carts are Shopify-owned and expire. The Worker is a stateless proxy; cart state, TTL, and expiry (expiryAuthority: shopify_cart_ttl_expires_at) belong to Shopify, which prunes abandoned carts automatically. No cart, session, customer, or payment state is ever stored in the Worker.
  • No checkout surface: checkout/cancel tools are hidden; the server cannot take payment, create orders or customers, apply discounts, or write inventory, so an abusive caller cannot mutate anything durable.

Safety boundaries

  • Do not use fixture prices, availability, product URLs, SKU variants, or IDs as final commerce truth.
  • Do not create or update carts unless the buyer has confirmed live Variant GIDs and quantities.
  • Do not use Checkout MCP yet; checkout endpoints will be enabled later after validation and approval.
  • Do not ask for or transmit card numbers, CVV/CVC, payment tokens, passwords, or customer account credentials.
  • Do not perform Shopify product, variant, collection, tag, metafield, inventory, order, customer, discount, RFQ, Acumatica, or database writes.
  • Do not expose gated datasheet URLs or backend secrets.
  • For live FoV, call Commonlands MCP only. Do not call the AWS Lambda/API Gateway backend directly.

Good prompts

  • Find M12 lenses for IMX477 around 50° horizontal FoV. Use match_lens_to_sensor, calculate_field_of_view, then verify the final purchasable SKU with read_shopify_products.
  • Compare CIL078 and CIL250 on IMX477. Preserve rectilinear_comparison and label fixture-backed context separately from live Shopify truth.
  • Find the live Shopify Product and Variant GID for CIL250. Return URL, SKU, price, inventory signal, and cart path, but do not create a cart.
  • Create a Shopify cart for two units of this live Variant GID: <gid>. The buyer has confirmed quantity 2.
  • List Commonlands MCP tools and classify each as fixture context, live FoV, live Shopify read-only, or Shopify cart.

Observability

The Worker can write privacy-safe request/tool telemetry when a Cloudflare Analytics Engine binding named MCP_ANALYTICS is configured. Telemetry records only method, path, MCP method, tool name, status, client label, environment/version, HTTP status, and duration. It does not record request arguments, Shopify payloads, customer data, product IDs, cart IDs, secrets, or response bodies.

Example binding:

[[analytics_engine_datasets]]
binding = "MCP_ANALYTICS"
dataset = "commonlands_mcp_events"

After deploy, verify that telemetry is live:

curl https://mcp.commonlands.com/healthz
curl -X POST https://mcp.commonlands.com/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -H 'mcp-client-name: telemetry-smoke' \
  -d '{"jsonrpc":"2.0","id":"telemetry-smoke","method":"tools/list","params":{}}'

/healthz should report "telemetry":{"analyticsEngine":"configured"}. Then query the commonlands_mcp_events Analytics Engine dataset. Column order is blob1=request method, blob2=path, blob3=MCP method, blob4=tool, blob5=status, blob6=client, blob7=environment, blob8=version, double1=HTTP status, and double2=duration ms.

Tool usage rollup:

curl "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/analytics_engine/sql" \
  -H "Authorization: Bearer $CLOUDFLARE_ANALYTICS_READ_TOKEN" \
  --data "SELECT blob4 AS tool, blob5 AS status, SUM(_sample_interval) AS calls, SUM(_sample_interval * double2) / SUM(_sample_interval) AS avg_duration_ms FROM commonlands_mcp_events WHERE timestamp >= NOW() - INTERVAL '7' DAY AND blob3 = 'tools/call' GROUP BY tool, status ORDER BY calls DESC LIMIT 50 FORMAT JSON"

Client/tool rollup:

curl "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/analytics_engine/sql" \
  -H "Authorization: Bearer $CLOUDFLARE_ANALYTICS_READ_TOKEN" \
  --data "SELECT blob6 AS client, blob4 AS tool, SUM(_sample_interval) AS calls, SUM(_sample_interval * double2) / SUM(_sample_interval) AS avg_duration_ms FROM commonlands_mcp_events WHERE timestamp >= NOW() - INTERVAL '7' DAY AND blob3 = 'tools/call' AND blob5 = 'ok' GROUP BY client, tool ORDER BY calls DESC LIMIT 100 FORMAT JSON"

Use blob4 to see which MCP tools agents actually call. High-call/high-success tools are candidates for deeper investment; low-call or repeated-error tools are candidates for better descriptions, consolidation, or deprecation. Keep Cloudflare invocation logs enabled for request/response metadata, but use Analytics Engine for tool-level decisions because it captures the JSON-RPC method and tool name without storing request arguments.

Quick client setup

Codex

[mcp_servers.commonlands]
url = "https://mcp.commonlands.com/mcp"
tool_timeout_sec = 60

Claude Desktop / Claude Code via mcp-remote

{
  "mcpServers": {
    "commonlands": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.commonlands.com/mcp"]
    }
  }
}

Cursor

{
  "mcpServers": {
    "commonlands": {
      "url": "https://mcp.commonlands.com/mcp"
    }
  }
}

Configuration

Non-secret config lives in wrangler.toml [vars]; credentials are Worker secrets set via the Cloudflare dashboard or wrangler secret put (never committed).

Setting Where Purpose
account_id wrangler.toml Pins the Cloudflare account so deploys do not call /memberships (which an account-scoped API token cannot access, surfacing as auth error 9106).
FOV_LIVE_BACKEND_ENABLED [vars] "true" routes FoV through the live Lambda backend.
FOV_LAMBDA_ENDPOINT [vars] Allowlisted FoV Lambda/API Gateway URL.
FOV_BACKEND_SCANS_FULL_CATALOG [vars] "true" makes compute_fov_catalog omit partNums so the Lambda scans its full DynamoDB lens table. Requires ALLOW_LENS_SCAN=true on the Lambda. When "false", the Worker sends fixture SKUs as a fallback.
SENSOR_DDB_TABLE [vars] DynamoDB sensor table name.
SENSOR_DDB_REGION [vars] DynamoDB sensor table region.
FOV_API_KEY secret Shared key the Worker sends to the FoV Lambda (x-api-key); must match the Lambda's FOV_API_KEY exactly (byte-for-byte, no trailing newline).
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY secret Read-only IAM user credentials the Worker uses to read the sensor DynamoDB table (SigV4).
CLOUDFLARE_API_TOKEN GitHub Actions secret Token with Workers Scripts: Edit used by the Deploy workflow.

AWS / DynamoDB notes

  • The Worker reads the sensor table directly with a read-only IAM user (only dynamodb:Scan/Query/GetItem/DescribeTable on that table ARN). No write actions exist in the code path.
  • The FoV Lambda reads the lens table with its own read-only execution role. For compute_fov_catalog full-catalog coverage the Lambda needs ALLOW_LENS_SCAN=true and dynamodb:Scan on the lens table.
  • Sensor table partition key is the part number (id); attributes used: sensormfg, sensorhpix, sensorvpix, sensorpitch, sensortype (shutter type).
  • Lens table partition key is the SKU; the Lambda's LENS_PK must be set accordingly.

Local development

Requirements: Node.js 22+.

npm install
npm run verify
npm run dev

Local smoke test:

curl http://localhost:8787/healthz
curl -X POST http://localhost:8787/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

Deploy

Run verification first, then deploy through CI so /healthz receives production build metadata (ENVIRONMENT=production, package VERSION, and GIT_SHA=$GITHUB_SHA). The source wrangler.toml intentionally does not define deployable local metadata placeholders.

npm run verify
npm run deploy:ci

For an approved manual deploy, npm run deploy runs scripts/deploy.mjs, which deploys with --keep-vars and injects the same production build metadata. npm run deploy:raw is the unwrapped Wrangler deploy command.

from github.com/CommonlandsAbbe/commonlands-mcp

Установка Commonlands Optics: M12 Lens and C-Mount Lens Finder + Field-of-View Calculator

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/CommonlandsAbbe/commonlands-mcp

FAQ

Commonlands Optics: M12 Lens and C-Mount Lens Finder + Field-of-View Calculator MCP бесплатный?

Да, Commonlands Optics: M12 Lens and C-Mount Lens Finder + Field-of-View Calculator MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Commonlands Optics: M12 Lens and C-Mount Lens Finder + Field-of-View Calculator?

Нет, Commonlands Optics: M12 Lens and C-Mount Lens Finder + Field-of-View Calculator работает без API-ключей и переменных окружения.

Commonlands Optics: M12 Lens and C-Mount Lens Finder + Field-of-View Calculator — hosted или self-hosted?

Доступен hosted-вариант: Unyly запускает сервер в облаке, локальная установка не обязательна.

Как установить Commonlands Optics: M12 Lens and C-Mount Lens Finder + Field-of-View Calculator в Claude Desktop, Claude Code или Cursor?

Открой Commonlands Optics: M12 Lens and C-Mount Lens Finder + Field-of-View Calculator на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Commonlands Optics: M12 Lens and C-Mount Lens Finder + Field-of-View Calculator with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории media