Pointguard MCP Server
An MCP (Model Context Protocol) server that exposes Creative Market's Pointguard search platform to AI assistants. Discover fonts, graphics, templates, and creative assets through natural conversation.
Quick Start — Cursor
1. Install from PyPI:
pip install pointguard-mcp
2. Find where it was installed:
which pointguard-mcp
Copy the full path (e.g. /usr/local/bin/pointguard-mcp or /Users/you/miniforge3/envs/myenv/bin/pointguard-mcp).
3. Add to Cursor:
Go to Cursor → Settings → Features → MCP → Add new global MCP server, or create/edit ~/.cursor/mcp.json:
{
"mcpServers": {
"pointguard": {
"command": "/full/path/to/pointguard-mcp",
"env": {
"POINTGUARD_BASE_URL": "https://your-pointguard-api-host.com",
"CM_API_USER": "your-cm-api-user",
"CM_API_PASS": "your-cm-api-pass"
}
}
}
}
4. Restart Cursor (or go to Settings → Features → MCP and click the ↺ refresh icon next to pointguard).
5. Open a chat and try it:
"Find me a condensed sans-serif for a sports brand logo"
Features
| Tool | Description |
|---|---|
search_products |
Search by style, mood, subject, or keyword with natural language |
get_product |
Internal Pointguard index metadata for agent reasoning — numeric shop ID, category IDs, file type IDs, visibility, staff pick flag |
browse_category |
Explore products by classification using the full CM category taxonomy |
browse_shop |
Browse a designer or studio's full catalog by shop ID |
find_similar |
Find visually/stylistically similar products using embeddings |
autocomplete |
Get search suggestions from partial input |
suggested_searches |
Discover related searches and trending terms |
get_product_details |
Display-ready product data from the CM API — title, URL, full image gallery, description, shop name, formatted price. Accepts up to 50 IDs |
Example Queries
Once connected to an MCP-compatible client (Claude, Cursor, etc.), you can ask:
- "Find me a condensed sans-serif for a sports brand logo."
- "Show me retro display fonts for a vinyl record label."
- "I need textures and grunge graphics for a concert poster."
- "Find script fonts under $30 that work for wedding stationery."
- "Show me font alternatives to Filson Pro Font Family (16 fonts)." (uses
find_similar) - "What's trending in the Fonts category?"
- "Show me everything by Loudoun Design Co." (uses
browse_shop) - "Browse sans-serif fonts." (uses
browse_categorywith ID 81)
Installation
pip install pointguard-mcp
Or in development mode:
cd pointguard-mcp
pip install -e .
Configuration
Set environment variables before running:
| Variable | Default | Description |
|---|---|---|
POINTGUARD_BASE_URL |
http://localhost:5000 |
Pointguard API base URL |
POINTGUARD_TIMEOUT |
30 |
Request timeout in seconds |
CM_API_USER |
(required) | Creative Market API basic auth username |
CM_API_PASS |
(required) | Creative Market API basic auth password |
Usage
Standalone (stdio)
pointguard-mcp
With Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"pointguard": {
"command": "pointguard-mcp",
"env": {
"POINTGUARD_BASE_URL": "https://your-api-host.com",
"CM_API_USER": "your-cm-api-user",
"CM_API_PASS": "your-cm-api-pass"
}
}
}
}
With Cursor
Add to .cursor/mcp.json in your project:
{
"mcpServers": {
"pointguard": {
"command": "pointguard-mcp",
"env": {
"POINTGUARD_BASE_URL": "https://your-api-host.com",
"CM_API_USER": "your-cm-api-user",
"CM_API_PASS": "your-cm-api-pass"
}
}
}
}
Agent Guide (Full Project Map)
This section is a practical guide for coding agents and maintainers working on the full MCP project.
Repository Layout
src/pointguard_mcp/server.py: MCP server entrypoint, tool schemas, tool dispatch, HTTP/SSE transport routes.src/pointguard_mcp/client.py: Async HTTP client for Pointguard API and Creative Market detail API.pyproject.toml: Package metadata and CLI entrypoint (pointguard-mcp = pointguard_mcp.server:main).terraform/: AWS infra for ECR + ECS Fargate + ALB deployment.Dockerfile: Container image used for remote deployment.
Runtime Modes
- Default mode is stdio (for Claude Desktop, Cursor command-based config, and local agent use).
- Set
MCP_HTTP=1to run as an HTTP server with:GET/POST/DELETE /mcpfor Streamable HTTP transportGET /sse+POST /messages/for legacy SSE transport
Transport and Auth Behavior
- If
MCP_API_KEYis set, HTTP calls to/mcpand/ssemust include headerx-api-key. - In stdio mode, no HTTP auth is involved because transport is local process pipes.
- For remote clients:
- Streamable HTTP clients should use
/mcp. - SSE clients should use
/sse.
- Streamable HTTP clients should use
Tooling Contract
- Search and discovery tools (
search_products,browse_category,browse_shop,find_similar) return Pointguard index-oriented results. get_productreturns internal metadata useful for agent planning (shop/category/file-type IDs, flags).get_product_detailsreturns display-ready Creative Market data (title, URL, description, images, shop).
Typical Agent Flow
- Run
search_productswith natural language query. - Use
get_productwhen internal metadata is needed for reasoning/filtering. - Use
browse_shoporbrowse_categoryfor expansion. - Use
get_product_detailsto produce user-facing final answers.
Deployment Notes for Agents
- ECS/ALB deployment lives in
terraform/. - ALB TLS now depends on
acm_certificate_arn:- empty value: HTTP-only listener on port 80
- non-empty value: HTTPS listener on 443 + HTTP 301 redirect to HTTPS
- Cloudflare setup for custom domain usually needs:
- ACM validation CNAME (DNS only)
- service CNAME
mcp-> ALB DNS name (typically proxied)
Local Validation Checklist
# package and imports
pip install -e .
# stdio server starts
python -m pointguard_mcp.server
# HTTP server starts
MCP_HTTP=1 MCP_PORT=8080 python -m pointguard_mcp.server
# health check
curl -i http://localhost:8080/health
Common Failure Modes
301 Moved Permanentlyfrom internal API host: use HTTPS base URL or allow redirects.- TLS hostname mismatch on internal ELB: certificate does not match host; use a valid host/cert path for production.
- Remote client
Invalid URL: missing scheme (must behttps://..., not bare host). - Remote client
ECONNREFUSEDonhttps://...: no HTTPS listener configured on origin ALB or DNS/proxy mismatch.
Deployment Runbook (GitHub Actions + Terraform)
Use this runbook when shipping code or infrastructure changes for the MCP service.
A) Application Deploy via GitHub Actions
This repo includes workflows under .github/workflows/:
build.yml: builds and pushes Docker images to ECR (onmainpushes, releases, or manual dispatch)publish.yml: package publishing flow
Recommended flow for runtime changes:
- Merge code changes to
main. - Confirm
Build and Push Containersucceeds in GitHub Actions. - Record the image tag from workflow output (
sha-xxxxxxxon push, release tag on release event). - Trigger infrastructure rollout using Terraform (next section).
Required GitHub environment secrets (as used by current workflows):
ECS_ADMIN_DEPLOY_KEY(forbuild.yml)ECS_ADMIN_DEPLOY_SECRET(forbuild.yml)
Recommended additional CI checks before merge:
- Run
python -m pointguard_mcp.server(stdio smoke test). - Run
MCP_HTTP=1 MCP_PORT=8080 python -m pointguard_mcp.serverand verify/health. - Confirm no tool schema regressions in
server.py.
B) Infrastructure Deploy via Terraform (ECS/ALB path)
Terraform config is in terraform/ and is intended for ECS + ALB deployments.
Recommended Terraform workflow:
- Update Terraform code in
terraform/. - Run plan in Terraform Cloud (or local CLI) and review listener/DNS/cert diffs carefully.
- Apply in the target workspace.
- Validate outputs and ALB listeners.
Important variables for HTTPS custom domain setup:
acm_certificate_arn: when set, enables ALB HTTPS listener:443and HTTP:80redirect to HTTPSpointguard_base_urlcm_api_usercm_api_passmcp_api_key
Post-apply validation checklist:
- ALB listener
443/HTTPSexists and uses expected ACM cert. - ALB listener
80/HTTPredirects to443. - Cloudflare DNS includes:
- ACM validation CNAME (DNS only)
mcpCNAME to ALB (proxied, unless your network policy requires DNS-only)
- Health endpoint is reachable:
curl -i https://mcp.creativemarket.com/health
C) End-to-end Release Order (safe sequence)
- Merge and let
build.ymlpush a fresh image to ECR. - Apply Terraform changes (or run ECS force-new-deployment if only code changed and task definition already references latest image).
- Verify ALB listeners and health endpoint.
- Verify MCP transport in Inspector, then in client apps.
PyPI Release Process
This repo uses GitHub Trusted Publishing for PyPI via .github/workflows/publish.yml.
Publishing is triggered by creating a GitHub Release with status published.
1) Bump package version
Update version in pyproject.toml (must be higher than current PyPI version).
2) Merge to main
Open/merge a PR with the version bump and release changes.
3) Create GitHub release
In GitHub UI:
- Go to Releases -> Draft a new release.
- Create tag
vX.Y.Zmatching the version inpyproject.toml. - Publish the release.
This triggers publish.yml which:
- Runs smoke tests.
- Builds wheel/sdist.
- Publishes to PyPI with OIDC trusted publishing.
4) Verify publish
python -m pip index versions pointguard-mcp
You should see the new version listed as latest.
Notes
- Re-publishing the same version will fail on PyPI.
- If publish fails, check GitHub Action logs for
publish.ymlfirst (test stage or trusted publishing permissions).
MCP Inspector UI Debugging Guide
Use MCP Inspector to isolate transport/auth issues before testing in Claude or Cursor.
1) Open Inspector
npx @modelcontextprotocol/inspector
2) Test Streamable HTTP endpoint
- Transport:
Streamable HTTP - URL:
https://mcp.creativemarket.com/mcp - Header:
x-api-key: <MCP_API_KEY>(if API key protection is enabled)
Expected result:
- Connect succeeds
- Tools list loads
- You can call
search_products
3) If Streamable HTTP fails, test SSE endpoint
- Transport:
SSE - URL:
https://mcp.creativemarket.com/sse - Header:
x-api-key: <MCP_API_KEY>
4) Error-to-cause quick map
Invalid URL: URL missing scheme (https://)ECONNREFUSED: origin not accepting requested protocol/port (often no ALB HTTPS listener)401 Unauthorized: wrong or missingx-api-key301 redirect loops/unexpected redirects: mismatch between client endpoint and listener redirect policy
Operational Notes
- Keep
MCP_API_KEYin secret stores only; do not hardcode in repo files. - For internal Pointguard APIs, prefer
https://base URLs to avoid redirect overhead. - If using internal ELB hostnames with cert mismatch, use proper cert/hostname pairing for production-grade security.
- When troubleshooting client startup, inspect local logs first (for Claude Desktop:
~/Library/Logs/Claude/mcp.log).
Category Reference
Top-level Categories
| ID | Category |
|---|---|
| 1 | Graphics |
| 2 | Templates |
| 3 | Fonts |
| 4 | Add-ons (Brushes & More) |
| 6 | Photos |
| 7 | 3D |
| 8 | Stock Video / Footage |
| 23 | Illustrations |
| 26 | Icons |
| 1800 | Mockups |
Font Subcategories
| ID | Subcategory |
|---|---|
| 80 | Serif |
| 81 | Sans Serif |
| 82 | Script |
| 84 | Symbols |
| 85 | Blackletter |
| 86 | Slab Serif |
| 88 | Handwritten |
Template Subcategories
| ID | Subcategory |
|---|---|
| 50 | Logos |
| 19 | Posters |
| 42 | Flyers |
| 46 | Invitations |
| 45 | Business Cards |
| 49 | Presentations |
| 52 | Social Media |
| 44 | Stationery |
| 41 | Brochures |
| 43 | Resumes |
Other Notable Subcategories
| ID | Subcategory |
|---|---|
| 27 | Textures (Graphics) |
| 28 | Patterns (Graphics) |
| 24 | Objects (Graphics) |
| 131 | Nature (Photos) |
| 132 | People (Photos) |
| 127 | Food & Drink (Photos) |
| 21 | Product Mockups |
| 1801 | Device Mockups |
| 1805 | Apparel Mockups |
| 2601 | Solid Icons |
| 2602 | Outline Icons |
| 2603 | Duotone Icons |
See CATEGORY_MAP in server.py for the full list of 170+ category and subcategory mappings.
Development
# Install in development mode
pip install -e .
# Run directly (stdio)
python -m pointguard_mcp.server
# Run as HTTP/SSE server locally
MCP_HTTP=1 MCP_API_KEY=secret python -m pointguard_mcp.server
# Test with MCP inspector (browser UI)
npx @modelcontextprotocol/inspector pointguard-mcp
Deploying to AWS (HTTP/SSE mode)
The server supports HTTP/SSE transport for remote deployment. Set MCP_HTTP=1 to switch from stdio to HTTP.
Environment Variables (HTTP mode)
| Variable | Default | Description |
|---|---|---|
MCP_HTTP |
0 |
Set to 1 to enable HTTP/SSE transport |
MCP_HOST |
0.0.0.0 |
Host to bind to |
MCP_PORT |
8080 |
Port to listen on |
MCP_API_KEY |
(optional) | If set, all SSE connections must include X-API-Key: <value> |
ECS + ALB Deployment (production)
This repository deploys to AWS ECS Fargate behind an ALB using the Terraform in terraform/.
1) Build and publish image to ECR
Use GitHub Actions build.yml (recommended), or build manually:
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-east-1.amazonaws.com
docker build -t pointguard-mcp .
docker tag pointguard-mcp:latest <account-id>.dkr.ecr.us-east-1.amazonaws.com/pointguard-mcp:latest
docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/pointguard-mcp:latest
2) Apply Terraform infrastructure and service configuration
Ensure workspace variables are set (or defaults are correct):
acm_certificate_arn(for HTTPS listener on 443)pointguard_base_urlcm_api_usercm_api_passmcp_api_key
Then run Terraform plan/apply in terraform/.
3) Force ECS service rollout when needed
If only image tag/state changed and you need immediate recycle:
aws ecs update-service \
--region us-east-1 \
--cluster pointguard-mcp \
--service pointguard-mcp \
--force-new-deployment
Optional wait:
aws ecs wait services-stable \
--region us-east-1 \
--cluster pointguard-mcp \
--services pointguard-mcp
4) DNS and TLS
For mcp.creativemarket.com:
- Keep ACM validation CNAME record as DNS-only in Cloudflare.
- Point
mcpCNAME to the ALB DNS name. - Keep
mcprecord proxied unless your network policy requires direct origin access.
5) Smoke tests
curl -i https://mcp.creativemarket.com/health
curl -i -H "x-api-key: <MCP_API_KEY>" https://mcp.creativemarket.com/mcp
Remote Client Setup Example (mcp.creativemarket.com/mcp)
For clients with native remote Streamable HTTP support:
{
"mcpServers": {
"pointguard-public": {
"type": "http",
"url": "https://mcp.creativemarket.com/mcp",
"headers": {
"x-api-key": "<MCP_API_KEY>"
}
}
}
}
For Claude Desktop, if direct remote transport is skipped in your build, use an mcp-remote bridge:
{
"mcpServers": {
"pointguard-public": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://mcp.creativemarket.com/mcp",
"--transport",
"http-only",
"--header",
"x-api-key:${POINTGUARD_PUBLIC_API_KEY}"
],
"env": {
"POINTGUARD_PUBLIC_API_KEY": "<MCP_API_KEY>"
}
}
}
}
Architecture
┌─────────────────┐ stdio ┌──────────────────┐ HTTP/JSON ┌──────────────────────┐
│ AI Assistant │◄──────────────►│ pointguard-mcp │◄────────────────►│ Pointguard API │
│ (Claude, etc.) │ │ (MCP Server) │ │ (Flask + ES) │
└─────────────────┘ └──────────────────┘ └──────────────────────┘
│
│ HTTPS
▼
┌──────────────────┐
│ creativemarket │
│ .com (search + │
│ product detail) │
└──────────────────┘
The MCP server has two data sources:
- Pointguard API (
POINTGUARD_BASE_URL) — powerssearch_products,get_product,browse_category,browse_shop,find_similar,autocomplete,suggested_searches - creativemarket.com API — powers
get_product_details(full image gallery, descriptions, licenses via authenticated API)
Endpoints Used
| Tool | Endpoint | Returns |
|---|---|---|
search_products |
POST /creative-market/products/search |
Product IDs + relevance tokens |
get_product |
GET /creative-market/product/{id} |
Internal metadata — shop ID, category IDs, file types, flags |
browse_category |
POST /creative-market/products/category |
Product IDs |
browse_shop |
POST /creative-market/products/shop |
Product IDs |
find_similar |
POST /creative-market/product/{id}/similar |
Product IDs |
autocomplete |
GET /creative-market/completions/suggest |
Suggestion strings |
suggested_searches |
POST /creative-market/suggested-searches |
Related search terms |
get_product_details |
GET https://creativemarket.com/api/external/newsletter/product-details/{ids} |
Display-ready detail (title, URL, images, description, shop URL) |
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pointguard_mcp-0.3.1.tar.gz.
File metadata
- Download URL: pointguard_mcp-0.3.1.tar.gz
- Upload date:
- Size: 23.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ce2d3a47d673342917b5e2d4724aa001214ed956494b18b91560bc303f33886
|
|
| MD5 |
a6b9bc80a3a9e487ecf44c279af7d2c7
|
|
| BLAKE2b-256 |
9e9e81d1f331ea78aa9c8252846f41e8e8c4da4baa6ff8512c5066b466ae1d8f
|
Provenance
The following attestation bundles were made for pointguard_mcp-0.3.1.tar.gz:
Publisher:
publish.yml on creativemarket/pointguard-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pointguard_mcp-0.3.1.tar.gz -
Subject digest:
4ce2d3a47d673342917b5e2d4724aa001214ed956494b18b91560bc303f33886 - Sigstore transparency entry: 1854325885
- Sigstore integration time:
-
Permalink:
creativemarket/pointguard-mcp@0decbd6bc9333c33abcc8c6d3e76df846c4e5b77 -
Branch / Tag:
refs/tags/v0.3.2 - Owner: https://github.com/creativemarket
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0decbd6bc9333c33abcc8c6d3e76df846c4e5b77 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pointguard_mcp-0.3.1-py3-none-any.whl.
File metadata
- Download URL: pointguard_mcp-0.3.1-py3-none-any.whl
- Upload date:
- Size: 18.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
83c71fe01716f304e8151ed100c267acfa559be2b450fd555ea065a545b443d2
|
|
| MD5 |
230d1cfadfc873a980bc28d52cbcc458
|
|
| BLAKE2b-256 |
d1971c6100ff9bed3d6dfa946ef028922dee56b169f00ce8db51ab19ce863685
|
Provenance
The following attestation bundles were made for pointguard_mcp-0.3.1-py3-none-any.whl:
Publisher:
publish.yml on creativemarket/pointguard-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pointguard_mcp-0.3.1-py3-none-any.whl -
Subject digest:
83c71fe01716f304e8151ed100c267acfa559be2b450fd555ea065a545b443d2 - Sigstore transparency entry: 1854325915
- Sigstore integration time:
-
Permalink:
creativemarket/pointguard-mcp@0decbd6bc9333c33abcc8c6d3e76df846c4e5b77 -
Branch / Tag:
refs/tags/v0.3.2 - Owner: https://github.com/creativemarket
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0decbd6bc9333c33abcc8c6d3e76df846c4e5b77 -
Trigger Event:
release
-
Statement type: