Install
$ agentstack add skill-bug-ops-zeph-qdrant ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Qdrant Vector Database
Base URL: http://localhost:6333 (default). Override with QDRANT_URL env var.
All examples use curl. Replace localhost:6333 with the actual Qdrant endpoint.
Quick Reference
| Task | Endpoint | |------|----------| | List collections | GET /collections | | Create collection | PUT /collections/{name} | | Delete collection | DELETE /collections/{name} | | Collection info | GET /collections/{name} | | Upsert points | PUT /collections/{name}/points | | Search | POST /collections/{name}/points/search | | Scroll (paginate) | POST /collections/{name}/points/scroll | | Get point | GET /collections/{name}/points/{id} | | Delete points | POST /collections/{name}/points/delete | | Count points | POST /collections/{name}/points/count | | Health check | GET /healthz |
Collections
List all collections
curl -s http://localhost:6333/collections | jq
Create collection
curl -s -X PUT http://localhost:6333/collections/my_collection \
-H "Content-Type: application/json" \
-d '{
"vectors": {
"size": 384,
"distance": "Cosine"
}
}' | jq
Distance metrics: Cosine, Euclid, Dot, Manhattan.
Create collection with named vectors
curl -s -X PUT http://localhost:6333/collections/my_collection \
-H "Content-Type: application/json" \
-d '{
"vectors": {
"content": {"size": 384, "distance": "Cosine"},
"title": {"size": 128, "distance": "Cosine"}
}
}' | jq
Collection info
curl -s http://localhost:6333/collections/my_collection | jq
Key fields: vectors_count, points_count, segments_count, status (green/yellow/red).
Delete collection
curl -s -X DELETE http://localhost:6333/collections/my_collection | jq
Check collection exists
curl -sI http://localhost:6333/collections/my_collection -o /dev/null -w "%{http_code}"
# 200 = exists, 404 = not found
Points
Upsert points (insert or update)
curl -s -X PUT http://localhost:6333/collections/my_collection/points \
-H "Content-Type: application/json" \
-d '{
"points": [
{
"id": 1,
"vector": [0.1, 0.2, 0.3, ...],
"payload": {"title": "Example", "category": "test", "score": 0.95}
},
{
"id": 2,
"vector": [0.4, 0.5, 0.6, ...],
"payload": {"title": "Another", "category": "prod", "score": 0.87}
}
]
}' | jq
Point IDs can be integers or UUIDs.
Upsert with named vectors
curl -s -X PUT http://localhost:6333/collections/my_collection/points \
-H "Content-Type: application/json" \
-d '{
"points": [
{
"id": 1,
"vector": {
"content": [0.1, 0.2, ...],
"title": [0.3, 0.4, ...]
},
"payload": {"title": "Example"}
}
]
}' | jq
Get point by ID
curl -s http://localhost:6333/collections/my_collection/points/1 | jq
Get multiple points
curl -s -X POST http://localhost:6333/collections/my_collection/points \
-H "Content-Type: application/json" \
-d '{"ids": [1, 2, 3]}' | jq
Delete points by ID
curl -s -X POST http://localhost:6333/collections/my_collection/points/delete \
-H "Content-Type: application/json" \
-d '{"points": [1, 2, 3]}' | jq
Delete points by filter
curl -s -X POST http://localhost:6333/collections/my_collection/points/delete \
-H "Content-Type: application/json" \
-d '{
"filter": {
"must": [
{"key": "category", "match": {"value": "obsolete"}}
]
}
}' | jq
Count points
# Total count
curl -s -X POST http://localhost:6333/collections/my_collection/points/count \
-H "Content-Type: application/json" \
-d '{}' | jq '.result.count'
# Count with filter
curl -s -X POST http://localhost:6333/collections/my_collection/points/count \
-H "Content-Type: application/json" \
-d '{
"filter": {
"must": [{"key": "category", "match": {"value": "test"}}]
},
"exact": true
}' | jq '.result.count'
Search
Basic vector search
curl -s -X POST http://localhost:6333/collections/my_collection/points/search \
-H "Content-Type: application/json" \
-d '{
"vector": [0.1, 0.2, 0.3, ...],
"limit": 10,
"with_payload": true,
"with_vector": false
}' | jq
Search with filter
curl -s -X POST http://localhost:6333/collections/my_collection/points/search \
-H "Content-Type: application/json" \
-d '{
"vector": [0.1, 0.2, 0.3, ...],
"limit": 5,
"with_payload": true,
"filter": {
"must": [
{"key": "category", "match": {"value": "prod"}}
],
"must_not": [
{"key": "archived", "match": {"value": true}}
]
}
}' | jq
Search with score threshold
curl -s -X POST http://localhost:6333/collections/my_collection/points/search \
-H "Content-Type: application/json" \
-d '{
"vector": [0.1, 0.2, 0.3, ...],
"limit": 10,
"score_threshold": 0.7,
"with_payload": true
}' | jq
Search with named vector
curl -s -X POST http://localhost:6333/collections/my_collection/points/search \
-H "Content-Type: application/json" \
-d '{
"vector": {
"name": "content",
"vector": [0.1, 0.2, 0.3, ...]
},
"limit": 10,
"with_payload": true
}' | jq
Scroll (paginate through all points)
# First page
curl -s -X POST http://localhost:6333/collections/my_collection/points/scroll \
-H "Content-Type: application/json" \
-d '{
"limit": 100,
"with_payload": true,
"with_vector": false
}' | jq
# Next page (use next_page_offset from previous response)
curl -s -X POST http://localhost:6333/collections/my_collection/points/scroll \
-H "Content-Type: application/json" \
-d '{
"limit": 100,
"offset": NEXT_PAGE_OFFSET,
"with_payload": true
}' | jq
Recommend (find similar to existing points)
curl -s -X POST http://localhost:6333/collections/my_collection/points/recommend \
-H "Content-Type: application/json" \
-d '{
"positive": [1, 2],
"negative": [3],
"limit": 10,
"with_payload": true
}' | jq
Filtering
Filters use must (AND), should (OR), must_not (NOT) clauses.
Condition types
// Exact match
{"key": "city", "match": {"value": "Berlin"}}
// Match any
{"key": "color", "match": {"any": ["red", "blue", "green"]}}
// Match except
{"key": "status", "match": {"except": ["deleted", "archived"]}}
// Range (numeric)
{"key": "price", "range": {"gte": 10.0, "lte": 100.0}}
// Range (dates as strings)
{"key": "created_at", "range": {"gte": "2025-01-01T00:00:00Z"}}
// Geo bounding box
{"key": "location", "geo_bounding_box": {
"top_left": {"lat": 52.52, "lon": 13.38},
"bottom_right": {"lat": 52.50, "lon": 13.42}
}}
// Geo radius
{"key": "location", "geo_radius": {
"center": {"lat": 52.52, "lon": 13.405},
"radius": 1000.0
}}
// Has key (field exists)
{"has_id": [1, 2, 3]}
// Is empty (field missing or null)
{"is_empty": {"key": "optional_field"}}
// Is null
{"is_null": {"key": "nullable_field"}}
// Nested filter
{"nested": {"key": "tags", "filter": {
"must": [{"key": "tags[].name", "match": {"value": "important"}}]
}}}
// Values count
{"values_count": {"key": "tags", "gte": 2}}
Combined filter example
curl -s -X POST http://localhost:6333/collections/my_collection/points/search \
-H "Content-Type: application/json" \
-d '{
"vector": [0.1, 0.2, ...],
"limit": 10,
"filter": {
"must": [
{"key": "status", "match": {"value": "active"}},
{"key": "score", "range": {"gte": 0.5}}
],
"should": [
{"key": "category", "match": {"value": "A"}},
{"key": "category", "match": {"value": "B"}}
],
"must_not": [
{"is_empty": {"key": "embedding"}}
]
}
}' | jq
Payload Indexes
Create indexes on payload fields for faster filtering.
# Create keyword index
curl -s -X PUT http://localhost:6333/collections/my_collection/index \
-H "Content-Type: application/json" \
-d '{"field_name": "category", "field_schema": "keyword"}' | jq
# Create integer index
curl -s -X PUT http://localhost:6333/collections/my_collection/index \
-H "Content-Type: application/json" \
-d '{"field_name": "score", "field_schema": "integer"}' | jq
# Create float index
curl -s -X PUT http://localhost:6333/collections/my_collection/index \
-H "Content-Type: application/json" \
-d '{"field_name": "price", "field_schema": "float"}' | jq
# Delete index
curl -s -X DELETE http://localhost:6333/collections/my_collection/index/category | jq
Index types: keyword, integer, float, bool, geo, datetime, text, uuid.
Payload Operations
Set payload on existing points
curl -s -X POST http://localhost:6333/collections/my_collection/points/payload \
-H "Content-Type: application/json" \
-d '{
"payload": {"new_field": "value", "score": 0.99},
"points": [1, 2, 3]
}' | jq
Delete payload keys
curl -s -X POST http://localhost:6333/collections/my_collection/points/payload/delete \
-H "Content-Type: application/json" \
-d '{
"keys": ["old_field", "deprecated"],
"points": [1, 2, 3]
}' | jq
Snapshots
curl -s http://localhost:6333/collections/my_collection/snapshots | jq # list
curl -s -X POST http://localhost:6333/collections/my_collection/snapshots | jq # create
curl -s -o snap.tar http://localhost:6333/collections/my_collection/snapshots/NAME # download
curl -s -X DELETE http://localhost:6333/collections/my_collection/snapshots/NAME | jq # delete
Aliases
# Create/swap alias (atomic)
curl -s -X POST http://localhost:6333/aliases \
-H "Content-Type: application/json" \
-d '{"actions": [{"create_alias": {"alias_name": "prod", "collection_name": "v2"}}]}' | jq
# List aliases
curl -s http://localhost:6333/aliases | jq
Service & Health
# Health check
curl -s http://localhost:6333/healthz
# Instance info
curl -s http://localhost:6333/ | jq
# Cluster info
curl -s http://localhost:6333/cluster | jq
# Telemetry
curl -s http://localhost:6333/telemetry | jq
# Prometheus metrics
curl -s http://localhost:6333/metrics
Common Workflows
Inspect collection health
# 1. Check collection status
curl -s http://localhost:6333/collections/my_collection | jq '.result.status, .result.points_count, .result.vectors_count'
# 2. Check optimizer status
curl -s http://localhost:6333/collections/my_collection | jq '.result.optimizer_status'
# 3. Check segment count (high count = needs optimization)
curl -s http://localhost:6333/collections/my_collection | jq '.result.segments_count'
Debug search quality
# Search with vectors returned for inspection
curl -s -X POST http://localhost:6333/collections/my_collection/points/search \
-H "Content-Type: application/json" \
-d '{
"vector": [0.1, 0.2, ...],
"limit": 5,
"with_payload": true,
"with_vector": true
}' | jq '.result[] | {id, score, payload}'
Important Notes
- Qdrant default ports: 6333 (HTTP), 6334 (gRPC)
- Point IDs are either unsigned integers or UUIDs (string format)
- Vectors must match the collection's configured dimension exactly
with_payload: truereturns all payload; usewith_payload: ["field1", "field2"]for specific fields- Filters on non-indexed fields cause full scan — create payload indexes for fields used in filters
- Collection status:
green= fully optimized,yellow= optimizing,red= error - Upsert is idempotent — re-upserting a point with the same ID overwrites it
- Scroll with
offset: nullstarts from the beginning - Batch operations are more efficient than individual requests
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: bug-ops
- Source: bug-ops/zeph
- License: MIT
- Homepage: https://bug-ops.github.io/zeph/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.