- Python 96.8%
- Shell 2.6%
- Dockerfile 0.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .grok/agents | ||
| docs | ||
| scripts | ||
| src/sa_mcp | ||
| tests | ||
| .env.example | ||
| .gitignore | ||
| .python-version | ||
| AGENTS.md | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| LICENSE | ||
| pyproject.toml | ||
| README.md | ||
| VERSION | ||
sa-mcp
MCP server for Stash — full content lifecycle access for AI agents.
sa-mcp connects any Model Context Protocol host (Claude Desktop, Cursor, Grok, custom agents) to a running Stash instance via its GraphQL API. Unlike analysis-only Stash MCP projects, this server covers content-related operations: find, create, update, merge, destroy, scrape, identify, and metadata jobs.
Current version: root VERSION. Tool reference: docs/tools.md.
What you get
| Capability | Examples |
|---|---|
| Library browse | Scenes, images, galleries, performers, studios, tags, groups, markers, files |
| Metadata CRUD | Create/update/bulk/merge/destroy for content entities |
| Activity | Play counts, O-counter, resume time, screenshots |
| Scrapers | List scrapers; scrape scenes/performers/etc. by query or URL |
| Jobs | Scan, generate, auto-tag, clean, identify; queue inspection & stop |
| Stash-box | Fingerprint submit, drafts, batch tagging (via Stash) |
| Safety | Read-only mode, confirm flags on destructive ops, pagination defaults |
| Deploy | stdio for local hosts; Streamable HTTP for Docker Compose |
Out of scope: Stash setup/migration, UI/config mutation, DLNA, raw SQL, plugin package management. See docs/tools.md.
How it fits
┌─────────────────┐ MCP (stdio or ┌─────────────┐ GraphQL ┌──────────────┐
│ MCP host / AI │ streamable-http) │ sa-mcp │ ApiKey header │ Stash │
│ agent │ ───────────────────► │ container │ ───────────────►│ :9999/graphql│
└─────────────────┘ └─────────────┘ └──────────────┘
sa-mcp does not store media. It is a thin, agent-friendly façade over Stash.
Requirements
- A running Stash instance (v0.27+ recommended; schema aligned with develop / ~v0.31)
- Stash API key: Settings → Security → Authentication
- For local run: Python 3.12+, uv
- For container run: Docker / Docker Compose
Configuration (summary)
| Variable | Default | Description |
|---|---|---|
STASH_URL |
http://localhost:9999 |
Stash base URL (no trailing slash) |
STASH_API_KEY |
(empty) | API key header value |
STASH_TIMEOUT |
30 |
HTTP timeout (seconds) |
STASH_MCP_READ_ONLY |
false |
Block all mutations when true |
STASH_MCP_ALLOW_RAW_GQL |
false |
Enable stash_graphql escape hatch |
MCP_TRANSPORT |
stdio |
stdio or streamable-http |
MCP_HOST |
127.0.0.1 |
HTTP bind host (0.0.0.0 in Docker) |
MCP_PORT |
8000 |
HTTP port |
Full reference: docs/configuration.md. Copy .env.example to .env and fill in the API key.
Quick start
Local (stdio)
cp .env.example .env
# edit STASH_URL and STASH_API_KEY
uv sync
uv run sa-mcp
MCP host example (Claude Desktop / Cursor-style config):
{
"mcpServers": {
"sa-mcp": {
"command": "uv",
"args": ["run", "--directory", "/path/to/sa-mcp", "sa-mcp"],
"env": {
"STASH_URL": "http://localhost:9999",
"STASH_API_KEY": "your-api-key"
}
}
}
}
Docker Compose
export STASH_API_KEY=your-api-key
# If Stash is on the host machine:
export STASH_URL=http://host.docker.internal:9999
docker compose up --build
MCP clients connect to Streamable HTTP at:
http://localhost:8000/mcp
Compose networking details: docs/docker.md.
Tools (overview)
Tools use domain-prefixed names (scene_*, performer_*, …). About 98 tools are registered, including:
| Domain | Examples | Risk mix |
|---|---|---|
| System / health | system_health, system_stats |
read |
| Scenes | scene_find, scene_update, scene_destroy |
read / write / destructive |
| Markers | marker_find, marker_create, marker_destroy |
read / write / destructive |
| Images | image_find, image_update, image_destroy |
read / write / destructive |
| Galleries | gallery_find, gallery_add_images, gallery_destroy |
read / write / destructive |
| Performers / studios / tags / groups | *_find, *_create, *_update, *_destroy |
read / write / destructive |
| Files | file_find, file_move, file_delete |
read / write / destructive |
| Scrapers | scraper_list, scraper_run |
read (proposal data) |
| Metadata / jobs | metadata_scan, job_queue, job_stop |
job / destructive |
| Stash-box | stashbox_submit_*, stashbox_batch_tag |
write / job |
| Escape hatch | stash_graphql |
gated |
Complete GraphQL → tool matrix: docs/tools.md.
Resources (stash://stats, stash://version, scene/performer templates) and prompts (library_overview, organize_scene, …) are also registered.
Safety
STASH_MCP_READ_ONLY=true— all mutation tools refuse to run.- Destructive tools (
*_destroy,file_delete,metadata_cleanwithout dry-run) requireconfirm=true. - Pagination defaults to small pages;
per_pageis capped to avoid blowing the agent context window. - API keys are never logged; errors redact secrets.
Treat sa-mcp like shell access to your library: prefer read-only credentials or mode for untrusted agents.
Versioning & releases
sa-mcp uses a 0.X.Y pre-1.0 scheme. The canonical version is the root VERSION file.
| Context | Form | Example |
|---|---|---|
| Release | 0.X.Y |
0.1.5 |
| Dev branch (source) | {main_ver}-{kind}.{issue#} |
0.1.5-feature.12 |
| Packaging (PEP 440) | hyphen → + local segment |
0.1.5+feature.12 |
| Git / Forgejo tag | v{version} |
v0.1.5 |
| Docker image | sa-mcp:{version} |
sa-mcp:0.1.5 |
./scripts/bump-version.sh patch # 0.1.5 → 0.1.6
./scripts/bump-version.sh feature # 0.1.5 → 0.2.0
python scripts/get-version.py --display # 0.1.5 Beta
Full policy: docs/VERSIONING.md. User-facing changes: CHANGELOG.md.
Documentation
| Document | Description |
|---|---|
| docs/architecture.md | Components, transports, client, errors, safety model |
| docs/tools.md | Capability matrix and tool reference |
| docs/configuration.md | Environment variables |
| docs/docker.md | Image, Compose, networking |
| docs/development.md | Layout, uv, tests, schema sync |
| docs/VERSIONING.md | Application versioning policy |
| AGENTS.md | Rules for AI agents (workflow, safety, lightweight testing) |
| CLAUDE.md | Claude Code commands and architecture pointers |
License
MIT License. You may use, modify, and distribute this software freely. Redistributions and derivative works must include the original copyright notice and license text, attributing sa-mcp to its authors.
Stash itself is separate software under its own license; sa-mcp only speaks its public GraphQL API.