pointguard-mcp 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pointguard_mcp-0.1.0/.github/workflows/publish.yml +83 -0
- pointguard_mcp-0.1.0/.gitignore +29 -0
- pointguard_mcp-0.1.0/PKG-INFO +158 -0
- pointguard_mcp-0.1.0/README.md +140 -0
- pointguard_mcp-0.1.0/pyproject.toml +36 -0
- pointguard_mcp-0.1.0/src/pointguard_mcp/__init__.py +2 -0
- pointguard_mcp-0.1.0/src/pointguard_mcp/client.py +262 -0
- pointguard_mcp-0.1.0/src/pointguard_mcp/server.py +746 -0
- pointguard_mcp-0.1.0/src/pointguard_mcp/tools/__init__.py +2 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
environment: Pypi # pulls CM_API_USER, CM_API_PASS, POINTGUARD_BASE_URL from GitHub environment
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.10"
|
|
20
|
+
|
|
21
|
+
- name: Install package and dependencies
|
|
22
|
+
run: pip install -e ".[dev]" || pip install -e .
|
|
23
|
+
|
|
24
|
+
- name: Smoke test — server starts and lists tools
|
|
25
|
+
# Secrets are injected as env vars here but never written into any build artifact
|
|
26
|
+
env:
|
|
27
|
+
CM_API_USER: ${{ secrets.CM_API_USER }}
|
|
28
|
+
CM_API_PASS: ${{ secrets.CM_API_PASS }}
|
|
29
|
+
POINTGUARD_BASE_URL: ${{ secrets.POINTGUARD_BASE_URL }}
|
|
30
|
+
run: |
|
|
31
|
+
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
|
|
32
|
+
| timeout 5 pointguard-mcp || true
|
|
33
|
+
|
|
34
|
+
- name: Verify CM product details API is reachable
|
|
35
|
+
env:
|
|
36
|
+
CM_API_USER: ${{ secrets.CM_API_USER }}
|
|
37
|
+
CM_API_PASS: ${{ secrets.CM_API_PASS }}
|
|
38
|
+
run: |
|
|
39
|
+
python - <<'EOF'
|
|
40
|
+
import os, httpx
|
|
41
|
+
resp = httpx.get(
|
|
42
|
+
"https://creativemarket.com/api/external/newsletter/product-details/7375489",
|
|
43
|
+
headers={"Accept": "application/json"},
|
|
44
|
+
auth=(os.environ["CM_API_USER"], os.environ["CM_API_PASS"]),
|
|
45
|
+
follow_redirects=True,
|
|
46
|
+
timeout=10,
|
|
47
|
+
)
|
|
48
|
+
resp.raise_for_status()
|
|
49
|
+
data = resp.json()
|
|
50
|
+
assert data.get("products"), "No products returned — check credentials"
|
|
51
|
+
print(f"✓ API reachable — got product: {data['products'][0]['title']}")
|
|
52
|
+
EOF
|
|
53
|
+
|
|
54
|
+
publish:
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
needs: test # only publish if tests pass
|
|
57
|
+
environment: Pypi
|
|
58
|
+
permissions:
|
|
59
|
+
contents: read
|
|
60
|
+
id-token: write # required for PyPI trusted publishing — no API token needed
|
|
61
|
+
|
|
62
|
+
steps:
|
|
63
|
+
- uses: actions/checkout@v4
|
|
64
|
+
|
|
65
|
+
- uses: actions/setup-python@v5
|
|
66
|
+
with:
|
|
67
|
+
python-version: "3.10"
|
|
68
|
+
|
|
69
|
+
- name: Install build tools
|
|
70
|
+
run: pip install hatchling build
|
|
71
|
+
|
|
72
|
+
- name: Build package
|
|
73
|
+
# No secrets are passed here — the wheel contains only source code
|
|
74
|
+
run: python -m build
|
|
75
|
+
|
|
76
|
+
- name: Verify no secrets in built package
|
|
77
|
+
run: |
|
|
78
|
+
unzip -p dist/*.whl '*.py' | grep -i "CM_API_PASS\s*=\s*\"[^\"]\+" && \
|
|
79
|
+
echo "ERROR: hardcoded secret found in wheel" && exit 1 || \
|
|
80
|
+
echo "✓ No hardcoded secrets in built package"
|
|
81
|
+
|
|
82
|
+
- name: Publish to PyPI
|
|
83
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.pyo
|
|
5
|
+
*.pyd
|
|
6
|
+
*.egg
|
|
7
|
+
*.egg-info/
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
.eggs/
|
|
11
|
+
*.whl
|
|
12
|
+
|
|
13
|
+
# Virtual environments
|
|
14
|
+
.venv/
|
|
15
|
+
venv/
|
|
16
|
+
env/
|
|
17
|
+
|
|
18
|
+
# Environment / secrets
|
|
19
|
+
.env
|
|
20
|
+
.env.*
|
|
21
|
+
|
|
22
|
+
# IDE
|
|
23
|
+
.idea/
|
|
24
|
+
.vscode/
|
|
25
|
+
*.swp
|
|
26
|
+
|
|
27
|
+
# OS
|
|
28
|
+
.DS_Store
|
|
29
|
+
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pointguard-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server for Creative Market's Pointguard search platform — discover fonts, graphics, and creative assets through natural conversation.
|
|
5
|
+
Project-URL: Homepage, https://github.com/creativemarket/pointguard-mcp
|
|
6
|
+
Project-URL: Repository, https://github.com/creativemarket/pointguard-mcp
|
|
7
|
+
Author: Creative Market
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: ai,creative-market,fonts,mcp,search
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Requires-Dist: httpx>=0.27
|
|
15
|
+
Requires-Dist: mcp>=1.0
|
|
16
|
+
Requires-Dist: pydantic>=2.0
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# Pointguard MCP Server
|
|
20
|
+
|
|
21
|
+
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that exposes Creative Market's Pointguard search platform to AI assistants. Discover fonts, graphics, templates, and creative assets through natural conversation.
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
| Tool | Description |
|
|
26
|
+
|------|-------------|
|
|
27
|
+
| `search_products` | Search by style, mood, subject, or keyword with natural language |
|
|
28
|
+
| `get_product` | Get full product details — pricing, category, file types, availability |
|
|
29
|
+
| `browse_category` | Explore products by classification (Fonts, Graphics, Photos, etc.) |
|
|
30
|
+
| `browse_shop` | Browse a designer or studio's full catalog |
|
|
31
|
+
| `find_similar` | Find visually/stylistically similar products using embeddings |
|
|
32
|
+
| `autocomplete` | Get search suggestions from partial input |
|
|
33
|
+
| `suggested_searches` | Discover related searches and trending terms |
|
|
34
|
+
|
|
35
|
+
## Example Queries
|
|
36
|
+
|
|
37
|
+
Once connected to an MCP-compatible client (Claude, Cursor, etc.), you can ask:
|
|
38
|
+
|
|
39
|
+
- *"Find me a condensed sans-serif for a sports brand logo."*
|
|
40
|
+
- *"Show me retro display fonts for a vinyl record label."*
|
|
41
|
+
- *"I need textures and grunge graphics for a concert poster."*
|
|
42
|
+
- *"Find script fonts under $30 that work for wedding stationery."*
|
|
43
|
+
- *"Show me font alternatives to Futura."* (uses `find_similar`)
|
|
44
|
+
- *"What's trending in the Fonts category?"*
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
cd pointguard-mcp
|
|
50
|
+
pip install -e .
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Configuration
|
|
54
|
+
|
|
55
|
+
Set environment variables:
|
|
56
|
+
|
|
57
|
+
| Variable | Default | Description |
|
|
58
|
+
|----------|---------|-------------|
|
|
59
|
+
| `POINTGUARD_BASE_URL` | `http://localhost:5000` | Pointguard API base URL |
|
|
60
|
+
| `POINTGUARD_TIMEOUT` | `30` | Request timeout in seconds |
|
|
61
|
+
|
|
62
|
+
For production:
|
|
63
|
+
```bash
|
|
64
|
+
export POINTGUARD_BASE_URL=https://pointguard-public.cm-ops.com
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Usage
|
|
68
|
+
|
|
69
|
+
### Standalone (stdio)
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pointguard-mcp
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### With Claude Desktop
|
|
76
|
+
|
|
77
|
+
Add to your `claude_desktop_config.json`:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"mcpServers": {
|
|
82
|
+
"pointguard": {
|
|
83
|
+
"command": "pointguard-mcp",
|
|
84
|
+
"env": {
|
|
85
|
+
"POINTGUARD_BASE_URL": "https://pointguard-public.cm-ops.com"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### With Cursor
|
|
93
|
+
|
|
94
|
+
Add to `.cursor/mcp.json` in your project:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"mcpServers": {
|
|
99
|
+
"pointguard": {
|
|
100
|
+
"command": "pointguard-mcp",
|
|
101
|
+
"env": {
|
|
102
|
+
"POINTGUARD_BASE_URL": "https://pointguard-public.cm-ops.com"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Category Reference
|
|
110
|
+
|
|
111
|
+
| ID | Category |
|
|
112
|
+
|----|----------|
|
|
113
|
+
| 1 | Fonts |
|
|
114
|
+
| 2 | Graphics |
|
|
115
|
+
| 3 | Templates |
|
|
116
|
+
| 4 | Themes |
|
|
117
|
+
| 5 | 3D |
|
|
118
|
+
| 6 | Photos |
|
|
119
|
+
| 8 | Video |
|
|
120
|
+
| 9 | Add-ons |
|
|
121
|
+
|
|
122
|
+
## Development
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Install in development mode
|
|
126
|
+
pip install -e .
|
|
127
|
+
|
|
128
|
+
# Run directly
|
|
129
|
+
python -m pointguard_mcp.server
|
|
130
|
+
|
|
131
|
+
# Test with MCP inspector
|
|
132
|
+
npx @modelcontextprotocol/inspector pointguard-mcp
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Architecture
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
┌─────────────────┐ stdio ┌──────────────────┐ HTTP/JSON ┌─────────────────┐
|
|
139
|
+
│ AI Assistant │◄──────────────►│ pointguard-mcp │◄────────────────►│ Pointguard API │
|
|
140
|
+
│ (Claude, etc.) │ │ (MCP Server) │ │ (Flask + ES) │
|
|
141
|
+
└─────────────────┘ └──────────────────┘ └─────────────────┘
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The MCP server is a thin translation layer:
|
|
145
|
+
1. Receives structured tool calls from the AI assistant via MCP protocol
|
|
146
|
+
2. Maps them to Pointguard API HTTP requests
|
|
147
|
+
3. Formats responses back as readable text for the LLM
|
|
148
|
+
|
|
149
|
+
## Autocomplete Endpoint
|
|
150
|
+
|
|
151
|
+
The `autocomplete` tool requires a completion suggest endpoint on the Pointguard API:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
GET /creative-market/completions/suggest?prefix=mono&size=10
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
If this endpoint doesn't exist yet, add it to the Pointguard Flask app (see `pointguard/api/creative_market/resources/`).
|
|
158
|
+
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Pointguard MCP Server
|
|
2
|
+
|
|
3
|
+
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that exposes Creative Market's Pointguard search platform to AI assistants. Discover fonts, graphics, templates, and creative assets through natural conversation.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
| Tool | Description |
|
|
8
|
+
|------|-------------|
|
|
9
|
+
| `search_products` | Search by style, mood, subject, or keyword with natural language |
|
|
10
|
+
| `get_product` | Get full product details — pricing, category, file types, availability |
|
|
11
|
+
| `browse_category` | Explore products by classification (Fonts, Graphics, Photos, etc.) |
|
|
12
|
+
| `browse_shop` | Browse a designer or studio's full catalog |
|
|
13
|
+
| `find_similar` | Find visually/stylistically similar products using embeddings |
|
|
14
|
+
| `autocomplete` | Get search suggestions from partial input |
|
|
15
|
+
| `suggested_searches` | Discover related searches and trending terms |
|
|
16
|
+
|
|
17
|
+
## Example Queries
|
|
18
|
+
|
|
19
|
+
Once connected to an MCP-compatible client (Claude, Cursor, etc.), you can ask:
|
|
20
|
+
|
|
21
|
+
- *"Find me a condensed sans-serif for a sports brand logo."*
|
|
22
|
+
- *"Show me retro display fonts for a vinyl record label."*
|
|
23
|
+
- *"I need textures and grunge graphics for a concert poster."*
|
|
24
|
+
- *"Find script fonts under $30 that work for wedding stationery."*
|
|
25
|
+
- *"Show me font alternatives to Futura."* (uses `find_similar`)
|
|
26
|
+
- *"What's trending in the Fonts category?"*
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
cd pointguard-mcp
|
|
32
|
+
pip install -e .
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Configuration
|
|
36
|
+
|
|
37
|
+
Set environment variables:
|
|
38
|
+
|
|
39
|
+
| Variable | Default | Description |
|
|
40
|
+
|----------|---------|-------------|
|
|
41
|
+
| `POINTGUARD_BASE_URL` | `http://localhost:5000` | Pointguard API base URL |
|
|
42
|
+
| `POINTGUARD_TIMEOUT` | `30` | Request timeout in seconds |
|
|
43
|
+
|
|
44
|
+
For production:
|
|
45
|
+
```bash
|
|
46
|
+
export POINTGUARD_BASE_URL=https://pointguard-public.cm-ops.com
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
### Standalone (stdio)
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pointguard-mcp
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### With Claude Desktop
|
|
58
|
+
|
|
59
|
+
Add to your `claude_desktop_config.json`:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"mcpServers": {
|
|
64
|
+
"pointguard": {
|
|
65
|
+
"command": "pointguard-mcp",
|
|
66
|
+
"env": {
|
|
67
|
+
"POINTGUARD_BASE_URL": "https://pointguard-public.cm-ops.com"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### With Cursor
|
|
75
|
+
|
|
76
|
+
Add to `.cursor/mcp.json` in your project:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"mcpServers": {
|
|
81
|
+
"pointguard": {
|
|
82
|
+
"command": "pointguard-mcp",
|
|
83
|
+
"env": {
|
|
84
|
+
"POINTGUARD_BASE_URL": "https://pointguard-public.cm-ops.com"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Category Reference
|
|
92
|
+
|
|
93
|
+
| ID | Category |
|
|
94
|
+
|----|----------|
|
|
95
|
+
| 1 | Fonts |
|
|
96
|
+
| 2 | Graphics |
|
|
97
|
+
| 3 | Templates |
|
|
98
|
+
| 4 | Themes |
|
|
99
|
+
| 5 | 3D |
|
|
100
|
+
| 6 | Photos |
|
|
101
|
+
| 8 | Video |
|
|
102
|
+
| 9 | Add-ons |
|
|
103
|
+
|
|
104
|
+
## Development
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Install in development mode
|
|
108
|
+
pip install -e .
|
|
109
|
+
|
|
110
|
+
# Run directly
|
|
111
|
+
python -m pointguard_mcp.server
|
|
112
|
+
|
|
113
|
+
# Test with MCP inspector
|
|
114
|
+
npx @modelcontextprotocol/inspector pointguard-mcp
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Architecture
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
┌─────────────────┐ stdio ┌──────────────────┐ HTTP/JSON ┌─────────────────┐
|
|
121
|
+
│ AI Assistant │◄──────────────►│ pointguard-mcp │◄────────────────►│ Pointguard API │
|
|
122
|
+
│ (Claude, etc.) │ │ (MCP Server) │ │ (Flask + ES) │
|
|
123
|
+
└─────────────────┘ └──────────────────┘ └─────────────────┘
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The MCP server is a thin translation layer:
|
|
127
|
+
1. Receives structured tool calls from the AI assistant via MCP protocol
|
|
128
|
+
2. Maps them to Pointguard API HTTP requests
|
|
129
|
+
3. Formats responses back as readable text for the LLM
|
|
130
|
+
|
|
131
|
+
## Autocomplete Endpoint
|
|
132
|
+
|
|
133
|
+
The `autocomplete` tool requires a completion suggest endpoint on the Pointguard API:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
GET /creative-market/completions/suggest?prefix=mono&size=10
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
If this endpoint doesn't exist yet, add it to the Pointguard Flask app (see `pointguard/api/creative_market/resources/`).
|
|
140
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pointguard-mcp"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "MCP server for Creative Market's Pointguard search platform — discover fonts, graphics, and creative assets through natural conversation."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
license = { text = "MIT" }
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "Creative Market" }
|
|
10
|
+
]
|
|
11
|
+
keywords = ["mcp", "creative-market", "fonts", "search", "ai"]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Programming Language :: Python :: 3",
|
|
14
|
+
"License :: OSI Approved :: MIT License",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
]
|
|
17
|
+
dependencies = [
|
|
18
|
+
"mcp>=1.0",
|
|
19
|
+
"httpx>=0.27",
|
|
20
|
+
"pydantic>=2.0",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://github.com/creativemarket/pointguard-mcp"
|
|
25
|
+
Repository = "https://github.com/creativemarket/pointguard-mcp"
|
|
26
|
+
|
|
27
|
+
[project.scripts]
|
|
28
|
+
pointguard-mcp = "pointguard_mcp.server:main"
|
|
29
|
+
|
|
30
|
+
[build-system]
|
|
31
|
+
requires = ["hatchling"]
|
|
32
|
+
build-backend = "hatchling.build"
|
|
33
|
+
|
|
34
|
+
[tool.hatch.build.targets.wheel]
|
|
35
|
+
packages = ["src/pointguard_mcp"]
|
|
36
|
+
|