Stash-box catalogues

Pesquise cenas, performers, estúdios e tags nos catálogos públicos do stash-box.

Documentação

mcp-stashbox

npm CI license MCP Registry M8ven LobeHub Install in Cursor Install in VS Code

Um stash-box é um catálogo compartilhado de metadados: ele registra cenas, os artistas creditados nelas, os estúdios que as lançaram e as tags sob as quais são arquivadas, cada um curado por submissão e revisão. Um catálogo não contém mídia — um registro indica onde algo foi publicado e não carrega nada dele — e identifica um arquivo pelas impressões digitais calculadas a partir dele. Cinco desses catálogos operam de forma independente, cada um emitindo sua própria chave para uma conta registrada.

Este servidor conecta um cliente de chat a todos eles de uma só vez. Você pode pesquisar cenas, artistas, estúdios e tags de cada catálogo para o qual possui uma chave, ler um registro como um único cartão montado a partir de todos os catálogos que o possuem, identificar um arquivo por suas impressões digitais e perguntar o que cada catálogo foi medido respondendo. Ele precisa de uma chave por catálogo e lê apenas os catálogos para os quais possui uma.

Versão francesa


Instalação

Instalação com um clique

Install in Cursor Install in VS Code

Claude Code

claude mcp add stashbox --env STASHBOX_STASHDB_KEY=your-key -- npx -y mcp-stashbox

Claude Desktop, Cursor e qualquer cliente que use o formato de configuração padrão

{
  "mcpServers": {
    "stashbox": {
      "command": "npx",
      "args": ["-y", "mcp-stashbox"],
      "env": {
        "STASHBOX_STASHDB_KEY": "your-key"
      }
    }
  }
}

Node 24 ou posterior é necessário. Defina uma chave para cada catálogo que deseja ler; os demais são indicados como ausentes em cada resposta.

Com Docker

{
  "mcpServers": {
    "stashbox": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "STASHBOX_STASHDB_KEY",
        "ghcr.io/smeet666/mcp-stashbox:2.0.1"
      ]
    }
  }
}

-i mantém o stdin aberto, que é por onde o protocolo trafega, e -t é omitido porque um TTY reescreve o fluxo. O contêiner precisa de HTTPS de saída para os catálogos para os quais você possui chaves, e as chaves vêm do seu ambiente: sem volume, sem porta.

Pacote, sem npm

Baixe mcp-stashbox-2.0.1.mcpb de o lançamento mais recente e abra-o. Um cliente que suporta pacotes MCP o instala por conta própria, sem npm para executar. As chaves ainda são definidas na configuração do cliente.

O que você pode perguntar

  • "Quais catálogos estou realmente lendo?"
  • "Encontre os artistas creditados sob esse nome."
  • "Leia o registro desse estúdio."
  • "O que é este arquivo? Aqui está o MD5 dele."
  • "Em quais cenas esses dois atuaram juntos?"

O caminho comum vai de uma pesquisa a um cartão: uma linha carrega um id escrito instance:uuid, e a ferramenta de registro o lê em cada catálogo que o possui.

Os catálogos

CatálogoEndereçoChave
StashDBstashdb.orgSTASHBOX_STASHDB_KEY
TPDBtheporndb.netSTASHBOX_TPDB_KEY
FansDBfansdb.ccSTASHBOX_FANSDB_KEY
PMV Stashpmvstash.orgSTASHBOX_PMV_KEY
JAVStashjavstash.orgSTASHBOX_JAVSTASH_KEY

Eles respondem a superfícies diferentes: StashDB responde a todas as rotas que este servidor conhece, e os outros respondem a menos. get_sources informa o que cada um foi medido respondendo e o dia em que foi medido. Um catálogo sem chave é indicado como ausente em cada resposta, portanto, uma resposta com linhas de alguns deles nunca é lida como o todo.

Ferramentas

FerramentaO que faz
get_sourcesInforma o que cada catálogo responde e quais chaves estão disponíveis.
search_scenesPesquisa as cenas de cada catálogo configurado.
search_performersPesquisa os artistas.
search_studiosPesquisa os estúdios.
search_tagsPesquisa as tags.
get_sceneLê uma cena como um único cartão.
get_performerLê um artista como um único cartão.
get_studioLê um estúdio como um único cartão.
get_tagLê uma tag como um único cartão.
find_by_fingerprintIdentifica um arquivo pelos hashes armazenados para ele.

Cada pesquisa segue dois caminhos exclusivos. query executa o índice de texto próprio de cada catálogo, que lê as palavras como uma união. Os argumentos tipados restringem como uma interseção. Escrever ambos é recusado.

get_sources

Informa o que cada catálogo configurado foi medido respondendo e o dia em que sua superfície foi lida. Ele não alcança nenhum catálogo e não recebe argumento.

Em retorno: uma entrada por catálogo com seu nome, seu prefixo de identificador, se uma chave está disponível para ele nesta instalação, a variável a definir quando não houver, e as rotas que ele responde. Se uma chave está disponível é um fato sobre esta instalação e não muda nada sobre o que o catálogo faz.

search_scenes

Pesquisa as cenas.

ArgumentoTipoObrigatórioO que faz
querystringnãoPalavras para o índice de texto próprio de cada catálogo.
titlestringnãoPalavras que um título carrega.
codestringnãoA referência própria do estúdio para o lançamento.
aliasstringnãoOutro título pelo qual o lançamento é conhecido.
dateum dia de calendárionãoA data de lançamento para comparar.
date_compareon, before ou afternãoComo essa data é lida.
performer_idslista de identificadoresnãoArtistas creditados nele.
studio_idslista de identificadoresnãoEstúdios que o lançaram.
parent_studio_idum identificadornãoUm estúdio sob o qual o estúdio lançador se encontra.
tag_idslista de identificadoresnãoTags sob as quais é arquivado.
matchall ou anynãoComo uma lista de identificadores é lida.
sorttitle, date, duration, trending, popularity, created_at ou updated_atnãoA ordem que o catálogo aplica.
directionasc ou descnãoEm qual direção essa ordem segue.
pageinteiro, 1 a 1000nãoQual página da ordem própria de cada catálogo.
limitinteiro, 1 a 100nãoLinhas que uma página de um catálogo carrega.
sourceslista de catálogosnãoLer apenas esses catálogos.

Em retorno: linhas que carregam o id escrito instance:uuid, que get_scene recebe, e quais nomes o registro carrega. Uma linha deixa a sinopse, as listas de links e os carimbos de edição para o cartão, já que nenhum deles separa dois lançamentos. A resposta informa por catálogo qual de três situações ele encontrou: uma falha, um catálogo que ninguém pediu ou um vazio que ele estabeleceu. Contagens nunca são somadas entre catálogos. Uma pesquisa escrita apenas com palavras lê as primeiras linhas que cada índice de texto responde, já que essas rotas não recebem página.

search_performers

Pesquisa os artistas.

ArgumentoTipoObrigatórioO que faz
querystringnãoPalavras para o índice de texto próprio de cada catálogo.
namestringnãoPalavras que um nome carrega.
aliasstringnãoOutro nome pelo qual são conhecidos.
disambiguationstringnãoO que o catálogo adiciona para distinguir dois.
genderum dos valores que o catálogo registranãoO gênero que o catálogo registra.
countryum código de país de duas letrasnãoO país que o catálogo registra.
ethnicityum dos valores que o catálogo registranãoA etnia que o catálogo registra.
birth_yearinteiro, 1800 a 2200nãoO ano de nascimento.
career_start_yearinteiro, 1800 a 2200nãoO ano em que uma carreira começou.
career_end_yearinteiro, 1800 a 2200nãoO ano em que uma carreira terminou.
performed_withum identificadornãoAlguém com quem são creditados.
studio_idum identificadornãoUm estúdio em que são creditados.
sortname, birthdate, deathdate, scene_count, career_start_year, debut, last_scene, popularity, created_at ou updated_atnãoA ordem que o catálogo aplica.
directionasc ou descnãoEm qual direção essa ordem segue.
pageinteiro, 1 a 1000nãoQual página.
limitinteiro, 1 a 100nãoLinhas que uma página de um catálogo carrega.
sourceslista de catálogosnãoLer apenas estes catálogos.

alias é declarado e nunca enviado. Nenhuma rota facetada de catálogo o aplica: uma solicitação que o carrega responde tão amplamente quanto uma que não carrega nenhum, então ele é omitido e a resposta o nomeia como um estreitamento que ninguém recebeu.

Em retorno: as linhas e a contabilidade por catálogo que search_scenes retorna.

search_studios

Pesquisa os estúdios.

ArgumentoTipoObrigatórioO que faz
querystringnãoPalavras para o índice de texto próprio de cada catálogo.
namestringnãoPalavras que um nome carrega.
parent_idum identificadornãoUm estúdio sob o qual ele está.
has_parentbooleanonãoSe ele está sob outro estúdio ou não.
sortname, created_at ou updated_atnãoA ordem que o catálogo aplica.
directionasc ou descnãoEm qual direção essa ordem segue.
pageinteiro, 1 a 1000nãoQual página.
limitinteiro, 1 a 100nãoLinhas que uma página de um catálogo carrega.
sourceslista de catálogosnãoLer apenas estes catálogos.

Em retorno: as linhas e a contabilidade por catálogo que search_scenes retorna.

search_tags

Pesquisa as tags.

ArgumentoTipoObrigatórioO que faz
querystringnãoPalavras para o índice de texto próprio de cada catálogo.
namestringnãoPalavras que um nome carrega.
category_idum identificadornãoUma categoria à qual a tag pertence.
sortname, created_at ou updated_atnãoA ordem que o catálogo aplica.
directionasc ou descnãoEm qual direção essa ordem segue.
pageinteiro, 1 a 1000nãoQual página.
limitinteiro, 1 a 100nãoLinhas que uma página de um catálogo carrega.
sourceslista de catálogosnãoLer apenas estes catálogos.

Em retorno: as linhas e a contabilidade por catálogo que search_scenes retorna.

get_scene

Lê uma cena como um único cartão.

ArgumentoTipoObrigatórioO que faz
idum identificador escrito instance:uuidsimO registro a ler.
sectionsqualquer um de basic, fingerprints, imagesnãoOs blocos lidos ao lado do cartão.
sourceslista de catálogosnãoLer apenas estes catálogos.
preferlista de catálogosnãoA ordem preferida onde eles discordam.

Em retorno: um cartão, lido em todos os catálogos que possuem o registro e alcançado pelo link que cada um deles publica para o mesmo registro em outro lugar. Cada valor nomeia os catálogos que o disseram, e onde eles discordam, a leitura que ninguém preferiu é publicada ao lado da que venceu. Se omitido, a ordem do próprio registro se mantém, e cada cartão declara a ordem aplicada.

get_performer

Lê um performer como um único cartão.

ArgumentoTipoObrigatórioO que faz
idum identificador escrito instance:uuidsimO registro a ler.
sectionsqualquer um de basic, appearance, images, studiosnãoOs blocos lidos ao lado do cartão.
sourceslista de catálogosnãoLer apenas estes catálogos.
preferlista de catálogosnãoA ordem preferida onde eles discordam.

studios é a tabela inteira de estúdios em que eles são creditados, que chega a centenas de linhas.

Em retorno: o cartão que get_scene retorna, para um performer.

get_studio

Lê um estúdio como um único cartão.

ArgumentoTipoObrigatórioO que faz
idum identificador escrito instance:uuidsimO registro a ler.
sourceslista de catálogosnãoLer apenas estes catálogos.
preferlista de catálogosnãoA ordem preferida onde eles discordam.

Em retorno: o cartão que get_scene retorna, para um estúdio.

get_tag

Lê uma tag como um único cartão.

ArgumentoTipoObrigatórioO que faz
idum identificador escrito instance:uuidsimO registro a ler.
sourceslista de catálogosnãoLer apenas estes catálogos.
preferlista de catálogosnãoA ordem preferida onde eles discordam.

Em retorno: o cartão que get_scene retorna, para uma tag.

find_by_fingerprint

Identifica um arquivo a partir dos hashes mantidos para ele.

ArgumentoTipoObrigatórioO que faz
fingerprintsuma lista de { hash, algorithm }, o algoritmo MD5, OSHASH ou PHASHsimOs hashes a serem consultados.
sectionsqualquer um de basic, fingerprints, imagesnãoOs blocos lidos ao lado de cada cartão. Uma chamada responde a um cartão por registro alcançado, então um bloco solicitado aqui alcança um leitor uma vez por correspondência.
sourceslista de catálogosnãoLer apenas estes catálogos.
preferlista de catálogosnãoA ordem preferida quando eles discordam.

MD5 e OSHASH nomeiam os bytes de um arquivo. PHASH declara uma semelhança, que uma reencodificação, um corte ou outra cena da mesma gravação pode satisfazer: leia uma correspondência de PHASH como uma semelhança, não como uma identidade.

Em retorno: cada registro alcançado, respondido como um cartão lido em cada catálogo que o contém.

O que uma resposta declara sobre os catálogos

Cada resposta presta contas de cada catálogo separadamente, porque mesclá-los perderia o que um chamador precisa. Um catálogo que falhou, um que ninguém pediu e um que respondeu com nada são três coisas diferentes, e são relatados como três. As contagens permanecem ao lado do catálogo que as produziu e nunca são somadas. Em um cartão, cada valor nomeia os catálogos que o disseram, e uma discordância é publicada em vez de resolvida silenciosamente.

Configuração

Uma chave por catálogo, e todo o resto opcional. Tudo isso vai no bloco env da configuração do seu cliente.

VariávelPadrãoO que faz
STASHBOX_STASHDB_KEYnenhumA chave que o StashDB emite para a sua conta.
STASHBOX_TPDB_KEYnenhumA chave que o TPDB emite para a sua conta.
STASHBOX_FANSDB_KEYnenhumA chave que o FansDB emite para a sua conta.
STASHBOX_PMV_KEYnenhumA chave que o PMV Stash emite para a sua conta.
STASHBOX_JAVSTASH_KEYnenhumA chave que o JAVStash emite para a sua conta.
SB_USER_AGENTa identidade do projetoNomeia seu aplicativo para os catálogos, com um endereço onde uma pessoa pode ser contatada.
SB_MIN_INTERVAL_MS1000Intervalo entre duas solicitações, de 1000 a 60000.
SB_TIMEOUT_MS20000Prazo para uma solicitação, de 1 a 600000.
SB_MAX_RETRIES3Tentativas após uma falha transitória, de 0 a 10.
SB_CACHE_TTL_MS300000Por quanto tempo uma resposta permanece na memória, de 0 a 86400000.
SB_CACHE_MAX_ENTRIES500Respostas mantidas na memória de uma vez, de 1 a 100000.
SB_LOG_LEVELerrorsilent, error, info ou debug, escrito em stderr.

Cada catálogo emite sua chave para uma conta registrada, nas configurações dessa conta. Este servidor não possui chave própria, e cada usuário traz a sua. Um valor fora do intervalo retorna ao padrão, e o motivo é escrito em stderr.

Erros

Cada falha carrega um dos seis códigos, uma mensagem e, onde ajuda, uma dica nomeando o próximo passo.

CódigoO que aconteceuO que fazer
not_foundUm catálogo respondeu e não contém tal registro.Verifique o identificador com uma pesquisa.
invalid_inputOs argumentos foram recusados antes de qualquer solicitação sair.Leia a mensagem, que nomeia o argumento.
rate_limitedUm catálogo pediu que este cliente desacelerasse.Aguarde e chame novamente com os mesmos argumentos. O registro ainda está lá.
parse_failureUma resposta chegou em um formato que este cliente não consegue ler.Reporte em o rastreador de problemas.
network_errorA solicitação não foi concluída.Tente novamente em breve.
timeoutA solicitação passou do prazo.Aumente SB_TIMEOUT_MS, ou peça menos linhas.

Um catálogo que falhou é relatado por catálogo, em vez de falhar toda a resposta, então um catálogo silencioso nunca esconde os outros.

Como biblioteca

A camada que lê os catálogos é publicada separadamente, com seu ritmo, seu cache e seus erros, e sem protocolo anexado.

import { Catalogues } from "mcp-stashbox/client";

const client = new Catalogues();
const read = await client.searchPerformers({ name: "example", limit: 5 });
console.log(read.data.rows.length, read.cached);

Cada leitura responde { data, cached } e lança um erro carregando um dos seis códigos. O piso de um segundo entre duas solicitações também vale aqui.

Ritmo e atribuição

As solicitações saem uma de cada vez, com pelo menos um segundo entre elas, e esse piso vale independentemente de como o servidor está configurado. O User-Agent sempre termina com a identidade do projeto e um endereço onde uma pessoa pode ser contatada.

Cada registro carrega o endereço de sua página no catálogo de onde veio, e um cartão carrega o link que cada catálogo publica para o mesmo registro em outro lugar. Os catálogos são construídos pelas pessoas que enviam e revisam seus registros.

Este servidor MCP é um projeto não oficial, sem afiliação a nenhum dos catálogos que lê.

Privacidade

Este servidor não coleta nada sobre você e não envia nada ao seu autor. Ele roda na sua máquina, contata apenas os catálogos para os quais você tem uma chave, mantém suas respostas na memória enquanto roda e não grava nada em disco. Suas chaves são lidas do ambiente e enviadas apenas ao seu próprio catálogo. PRIVACY.md declara o que uma solicitação carrega e quais configurações alteram qualquer parte disso.

Desenvolvimento

npm install
npm run build:fixtures
npm test
npm run check

Os testes rodam contra fixtures geradas e não fazem nenhuma solicitação de rede. A suíte ao vivo, npm run test:live, faz uma solicitação por rota e roda todas as noites contra os próprios catálogos.

Contribuindo

Bugs, perguntas e ideias pertencem ao rastreador de problemas. Pull requests são bem-vindos; abrir um problema primeiro ajuda a concordar sobre a forma da mudança. Veja CONTRIBUTING.md.

Licença

MIT, veja LICENSE. Os registros pertencem aos catálogos e às pessoas que os construíram.


mcp-stashbox (francês)

Versão em inglês

Um stash-box é um catálogo de metadados compartilhado: ele registra cenas, os intérpretes creditados nelas, os estúdios que as publicaram e as etiquetas sob as quais estão organizadas, tudo mantido por submissão e revisão. Um catálogo não contém nenhuma mídia — uma ficha nomeia onde algo foi publicado e não carrega nada disso — e identifica um arquivo pelas impressões digitais calculadas sobre ele. Cinco catálogos desse tipo funcionam independentemente, cada um emitindo sua própria chave para uma conta registrada.

Este servidor conecta um cliente de conversa a todos ao mesmo tempo. Pode-se buscar cenas, intérpretes, estúdios e etiquetas de cada catálogo para o qual se tem uma chave, ler uma ficha como um cartão único montado a partir de todos os catálogos que a possuem, identificar um arquivo pelas suas impressões digitais e perguntar o que cada catálogo foi medido respondendo. Ele exige uma chave por catálogo e só lê aqueles para os quais tem uma.

Instalação

Instalação em um clique

Install in Cursor Install in VS Code

Claude Code

claude mcp add stashbox --env STASHBOX_STASHDB_KEY=votre-cle -- npx -y mcp-stashbox

Claude Desktop, Cursor e qualquer cliente no formato de configuração padrão

{
  "mcpServers": {
    "stashbox": {
      "command": "npx",
      "args": ["-y", "mcp-stashbox"],
      "env": {
        "STASHBOX_STASHDB_KEY": "votre-cle"
      }
    }
  }
}

Node 24 ou mais recente é necessário. Coloque uma chave por catálogo a ser lido; os outros são nomeados como ausentes de cada resposta.

Com Docker

{
  "mcpServers": {
    "stashbox": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "STASHBOX_STASHDB_KEY",
        "ghcr.io/smeet666/mcp-stashbox:2.0.1"
      ]
    }
  }
}

-i mantém a entrada padrão aberta, que é o canal do protocolo, e -t é omitido porque um TTY reescreve o fluxo. O contêiner precisa de acesso HTTPS de saída para os catálogos para os quais você tem as chaves, e dessas chaves tiradas do seu ambiente: nenhum volume, nenhuma porta.

Bundle, sem npm

Baixe mcp-stashbox-2.0.1.mcpb de a última publicação e abra-o. Um cliente que gerencia bundles MCP o instala sozinho, sem npm para executar. As chaves sempre são colocadas na configuração do cliente.

O que se pode pedir

  • « Quais catálogos eu realmente leio? »
  • « Encontre os intérpretes creditados sob este nome. »
  • « Leia-me a ficha deste estúdio. »
  • « O que é este arquivo? Aqui está o MD5 dele. »
  • « Em quais cenas esses dois atuaram juntos? »

O caminho comum vai de uma busca a um cartão: uma linha carrega um id escrito instance:uuid, e a ferramenta de ficha o lê em cada catálogo que o possui.

Os catálogos

CatálogoEndereçoChave
StashDBstashdb.orgSTASHBOX_STASHDB_KEY
TPDBtheporndb.netSTASHBOX_TPDB_KEY
FansDBfansdb.ccSTASHBOX_FANSDB_KEY
PMV Stashpmvstash.orgSTASHBOX_PMV_KEY
JAVStashjavstash.orgSTASHBOX_JAVSTASH_KEY

Eles respondem a superfícies diferentes: StashDB responde a todas as rotas que este servidor conhece, os outros a menos. get_sources diz o que cada um foi medido respondendo e o dia da medição. Um catálogo sem chave é nomeado como ausente de cada resposta, então uma resposta carregando as linhas de alguns nunca se lê como o conjunto.

As ferramentas

FerramentaO que ela faz
get_sourcesDiz o que cada catálogo responde e quais chaves são definidas.
search_scenesBusca as cenas de cada catálogo configurado.
search_performersBusca os intérpretes.
search_studiosBusca os estúdios.
search_tagsBusca as etiquetas.
get_sceneLê uma cena como um mapa único.
get_performerLê um intérprete como um mapa único.
get_studioLê um estúdio como um mapa único.
get_tagLê uma etiqueta como um mapa único.
find_by_fingerprintIdentifica um arquivo pelas impressões que dele se tem.

Cada busca toma dois caminhos exclusivos. query consulta o índice textual de cada catálogo, que lê as palavras como uma união. Os argumentos tipados restringem como uma interseção. Escrever ambos é recusado.

get_sources

Diz o que cada catálogo configurado foi medido respondendo e o dia em que sua superfície foi lida. Ele não junta nenhum catálogo e não aceita nenhum argumento.

Em retorno: uma entrada por catálogo com seu nome, seu prefixo de identificador, a presença de uma chave nessa instalação, a variável a definir quando não há uma, e as rotas às quais ele responde. A presença de uma chave é um fato sobre essa instalação e não muda o que o catálogo faz.

search_scenes

Busca as cenas.

ArgumentoTipoObrigatórioO que faz
querystringnãoPalavras para o índice textual de cada catálogo.
titlestringnãoPalavras que um título carrega.
codestringnãoA referência própria do estúdio para a publicação.
aliasstringnãoOutro título pelo qual ela é conhecida.
dateum dia de calendárionãoA data de publicação a comparar.
date_compareon, before ou afternãoComo essa data é lida.
performer_idslista de identificadoresnãoOs intérpretes que são creditados nela.
studio_idslista de identificadoresnãoOs estúdios que a publicaram.
parent_studio_idum identificadornãoUm estúdio sob o qual o estúdio editor se classifica.
tag_idslista de identificadoresnãoAs etiquetas sob as quais ela é classificada.
matchall ou anynãoComo uma lista de identificadores é lida.
sorttitle, date, duration, trending, popularity, created_at ou updated_atnãoA ordem que o catálogo aplica.
directionasc ou descnãoO sentido dessa ordem.
pageinteiro, 1 a 1000nãoQual página da ordem própria de cada catálogo.
limitinteiro, 1 a 100nãoLinhas que uma página de um catálogo carrega.
sourceslista de catálogosnãoLer apenas esses catálogos.

Em retorno: linhas que carregam o id escrito instance:uuid, que get_scene retoma, e o que nomeia a ficha. Uma linha deixa ao mapa o sinopse, as listas de links e os horodatagens de edição, dos quais nenhum distingue duas publicações. A resposta diz por catálogo qual das três ele encontrou: uma falha, um catálogo que ninguém consultou, ou um vazio que ele estabeleceu. Os contadores nunca são somados entre catálogos. Uma busca escrita apenas com palavras lê as primeiras linhas que cada índice textual retorna, essas rotas não aceitando nenhuma página.

search_performers

Busca os intérpretes.

ArgumentoTipoObrigatórioO que faz
querystringnãoPalavras para o índice textual.
namestringnãoPalavras que um nome carrega.
aliasstringnãoOutro nome pelo qual eles são conhecidos.
disambiguationstringnãoO que o catálogo adiciona para distinguir dois.
genderum dos valores que o catálogo registranãoO gênero que o catálogo registra.
countryum código de país de duas letrasnãoO país que o catálogo registra.
ethnicityum dos valores que o catálogo registranãoA etnia que o catálogo registra.
birth_yearinteiro, 1800 a 2200nãoO ano de nascimento.
career_start_yearinteiro, 1800 a 2200nãoO ano em que uma carreira se abriu.
career_end_yearinteiro, 1800 a 2200nãoO ano em que uma carreira se encerrou.
performed_withum identificadornãoAlguém ao lado de quem eles são creditados.
studio_idum identificadornãoUm estúdio no qual eles são creditados.
sortname, birthdate, deathdate, scene_count, career_start_year, debut, last_scene, popularity, created_at ou updated_atnãoA ordem que o catálogo aplica.
directionasc ou descnãoO sentido dessa ordem.
pageinteiro, 1 a 1000nãoQual página.
limitinteiro, 1 a 100nãoLinhas que uma página de um catálogo carrega.
sourceslista de catálogosnãoLer apenas esses catálogos.

alias é declarado e nunca enviado. Nenhuma rota facetada o aplica: uma consulta que o carrega responde tão ampla quanto uma consulta sem ele, portanto ele é deixado de lado e a resposta o nomeia como um estreitamento que ninguém recebeu.

Em retorno: as linhas e a contabilidade por catálogo que search_scenes retorna.

search_studios

Busca os estúdios.

ArgumentoTipoObrigatórioO que faz
querystringnãoPalavras para o índice textual.
namestringnãoPalavras que um nome carrega.
parent_idum identificadornãoUm estúdio sob o qual se classifica.
has_parentbooleanonãoSe se classifica sob outro.
sortname, created_at ou updated_atnãoA ordem que o catálogo aplica.
directionasc ou descnãoO sentido dessa ordem.
pageinteiro, 1 a 1000nãoQual página.
limitinteiro, 1 a 100nãoLinhas que uma página de catálogo carrega.
sourceslista de catálogosnãoLer apenas esses catálogos.

Em retorno: as linhas e a contabilidade por catálogo de search_scenes.

search_tags

Procura as etiquetas.

ArgumentoTipoObrigatórioO que faz
querystringnãoPalavras para o índice textual.
namestringnãoPalavras que um nome carrega.
category_idum identificadornãoUma categoria à qual a etiqueta pertence.
sortname, created_at ou updated_atnãoA ordem que o catálogo aplica.
directionasc ou descnãoO sentido dessa ordem.
pageinteiro, 1 a 1000nãoQual página.
limitinteiro, 1 a 100nãoLinhas que uma página de catálogo carrega.
sourceslista de catálogosnãoLer apenas esses catálogos.

Em retorno: as linhas e a contabilidade por catálogo de search_scenes.

get_scene

Lê uma cena como um mapa único.

ArgumentoTipoObrigatórioO que faz
idum identificador escrito instance:uuidsimA ficha a ler.
sectionsentre basic, fingerprints, imagesnãoOs blocos lidos ao lado do mapa.
sourceslista de catálogosnãoLer apenas esses catálogos.
preferlista de catálogosnãoA ordem preferida onde divergem.

Em retorno: um mapa, lido em cada catálogo que possui a ficha e alcançado pelo link que cada um publica para a mesma ficha em outro lugar. Cada valor nomeia os catálogos que o disseram, e onde divergem, a leitura que ninguém preferiu é publicada ao lado da que vence. Omitido, a ordem própria do registro se aplica, e cada mapa declara a ordem aplicada.

get_performer

Lê um intérprete como um mapa único.

ArgumentoTipoObrigatórioO que faz
idum identificador escrito instance:uuidsimA ficha a ler.
sectionsentre basic, appearance, images, studiosnãoOs blocos lidos ao lado do mapa.
sourceslista de catálogosnãoLer apenas esses catálogos.
preferlista de catálogosnãoA ordem preferida onde divergem.

studios é a tabela inteira dos estúdios nos quais são creditados, que tem centenas de linhas.

Em retorno: o mapa que get_scene retorna, para um intérprete.

get_studio

Lê um estúdio como um mapa único.

ArgumentoTipoObrigatórioO que faz
idum identificador escrito instance:uuidsimA ficha a ler.
sourceslista de catálogosnãoLer apenas esses catálogos.
preferlista de catálogosnãoA ordem preferida onde divergem.

Em retorno: o mapa que get_scene retorna, para um estúdio.

get_tag

Lê uma etiqueta como um mapa único.

ArgumentoTipoObrigatórioO que faz
idum identificador escrito instance:uuidsimA ficha a ler.
sourceslista de catálogosnãoLer apenas esses catálogos.
preferlista de catálogosnãoA ordem preferida onde divergem.

Em retorno: o mapa que get_scene retorna, para uma etiqueta.

find_by_fingerprint

Identifica um arquivo pelas impressões digitais que se possui dele.

ArgumentoTipoObrigatórioO que faz
fingerprintsuma lista de { hash, algorithm }, o algoritmo MD5, OSHASH ou PHASHsimAs impressões digitais a procurar.
sectionsentre basic, fingerprints, imagesnãoOs blocos lidos ao lado de cada mapa. Uma chamada retorna um mapa por ficha alcançada, então um bloco solicitado aqui chega ao leitor uma vez por correspondência.
sourceslista de catálogosnãoLer apenas esses catálogos.
preferlista de catálogosnãoA ordem preferida onde divergem.

MD5 e OSHASH nomeiam os bytes de um arquivo. PHASH declara uma semelhança, que uma re-encodificação, um recorte ou outra cena da mesma filmagem podem satisfazer: leia uma correspondência PHASH como uma semelhança em vez de uma identidade.

Em retorno: cada ficha alcançada, retornada como um mapa lido em cada catálogo que a possui.

O que uma resposta diz sobre os catálogos

Cada resposta presta contas de cada catálogo separadamente, porque fundi-los perderia o que um chamador precisa. Um catálogo que falhou, um que ninguém consultou e um que respondeu vazio são três coisas diferentes, e elas são relatadas como três. As contagens permanecem ao lado do catálogo que as produziu e nunca são somadas. Em um mapa, cada valor nomeia os catálogos que o disseram, e um desacordo é publicado em vez de resolvido em silêncio.

Configuração

Uma chave por catálogo, e todo o resto opcional. Tudo se coloca no bloco env da configuração do cliente.

VariávelPadrãoO que faz
STASHBOX_STASHDB_KEYnenhumA chave que o StashDB entrega à sua conta.
STASHBOX_TPDB_KEYnenhumA chave que o TPDB entrega à sua conta.
STASHBOX_FANSDB_KEYnenhumA chave que o FansDB entrega à sua conta.
STASHBOX_PMV_KEYnenhumA chave que o PMV Stash entrega à sua conta.
STASHBOX_JAVSTASH_KEYnenhumA chave que o JAVStash entrega à sua conta.
SB_USER_AGENTa identidade do projetoNomeia sua aplicação junto aos catálogos, com um endereço para contatar uma pessoa.
SB_MIN_INTERVAL_MS1000Intervalo entre duas requisições, de 1000 a 60000.
SB_TIMEOUT_MS20000Tempo limite de uma requisição, de 1 a 600000.
SB_MAX_RETRIES3Tentativas após uma falha passageira, de 0 a 10.
SB_CACHE_TTL_MS300000Duração durante a qual uma resposta permanece em memória, de 0 a 86400000.
SB_CACHE_MAX_ENTRIES500Respostas mantidas em memória por vez, de 1 a 100000.
SB_LOG_LEVELerrorsilent, error, info ou debug, escrito na saída de erro.

Cada catálogo entrega sua chave a uma conta registrada, nas configurações dessa conta. Este servidor não embute nenhuma chave, e cada um traz as suas. Um valor fora de sua faixa cai no padrão, e o motivo é escrito na saída de erro.

Erros

Cada falha carrega um dos seis códigos, uma mensagem e, quando ajuda, uma indicação do próximo passo.

CodeO que aconteceuO que fazer
not_foundUm catálogo respondeu e não possui esta ficha.Verifique o identificador com uma pesquisa.
invalid_inputOs argumentos foram recusados antes de qualquer requisição.Leia a mensagem, que nomeia o argumento.
rate_limitedUm catálogo pede que este cliente desacelere.Aguarde e chame novamente com os mesmos argumentos. A ficha ainda está lá.
parse_failureUma resposta chegou em um formato ilegível aqui.Reporte em o rastreador de incidentes.
network_errorA requisição não foi concluída.Tente novamente em breve.
timeoutA requisição excedeu seu tempo limite.Aumente SB_TIMEOUT_MS, ou solicite menos linhas.

Um catálogo que falha é reportado catálogo por catálogo, em vez de fazer falhar toda a resposta, então um catálogo silencioso nunca esconde outros.

Como biblioteca

A camada que lê os catálogos é publicada sozinha, com seu ritmo, seu cache e seus erros, sem protocolo anexado.

import { Catalogues } from "mcp-stashbox/client";

const client = new Catalogues();
const read = await client.searchPerformers({ name: "example", limit: 5 });
console.log(read.data.rows.length, read.cached);

Cada leitura responde { data, cached }, e levanta um erro com um dos seis códigos. O piso de um segundo entre duas requisições também se aplica aqui.

Ritmo e atribuição

As requisições partem uma a uma com pelo menos um segundo entre elas, e esse piso se mantém independentemente da configuração. O User-Agent termina sempre com a identidade do projeto e um endereço para contatar uma pessoa.

Cada ficha carrega o endereço de sua página no catálogo de onde vem, e um cartão carrega o link que cada catálogo publica para a mesma ficha em outro lugar. Os catálogos são construídos por aqueles que submetem e revisam suas fichas.

Este MCP é um projeto não oficial, sem afiliação a nenhum dos catálogos que lê.

Privacidade

Este servidor não coleta nada sobre você e não envia nada ao seu autor. Ele roda na sua máquina, acessa apenas os catálogos dos quais você possui uma chave, mantém suas respostas em memória enquanto roda, e não grava nada no disco. Suas chaves são lidas do ambiente e enviadas apenas ao seu respectivo catálogo. PRIVACY.md diz o que uma requisição carrega e quais configurações alteram isso.

Desenvolvimento

npm install
npm run build:fixtures
npm test
npm run check

Os testes são executados em fixtures geradas e não emitem nenhuma requisição. A suíte ao vivo, npm run test:live, emite uma requisição por rota e roda todas as noites contra os próprios catálogos.

Contribuindo

Anomalias, perguntas e ideias têm seu lugar em o rastreador de incidentes. Propostas de modificação são bem-vindas; abrir um ticket primeiro ajuda a alinhar a forma da mudança. Veja CONTRIBUTING.md.

Licença

MIT, veja LICENSE. As fichas pertencem aos catálogos e àqueles que as construíram.