Career Agent
Agente de carreira integrado ao Claude Desktop via MCP. Encontra vagas,calcula compatibilidade com o seu perfil, personaliza seu curriculo de formalegitima, gera mensagens e respostas, e mantem o historico de candidaturas.
A acao externa final e sempre sua. O agente prepara; voce clica.
Novidades da v1.1
| Recurso | Como usar |
|---|---|
| Catálogo persistente de vagas | run_job_search coleta e salva; list_matching_jobs consulta |
| 5 provedores de ATS | Greenhouse, Lever, Ashby, Workable, SmartRecruiters |
| Adzuna (índice nacional BR) | preencha ADZUNA_APP_ID/ADZUNA_APP_KEY no .env |
| Pesos configuráveis | edite data/config/scoring.json |
| 11 dimensões de score | inclui .NET, SAP, fiscal, arquitetura e foco backend |
| Busca agendada | .\scripts\schedule.ps1 -IntervalHours 2 |
| Dashboard local | .\scripts\start-dashboard.ps1 |
| Retry com backoff | automático em todas as fontes HTTP |
Detalhes de cada fonte, com o que foi medido: docs/FONTES.md.
Indice
- Arquitetura
- Pre-requisitos
- Instalacao
- Configuracao
- Configuracao do Claude Desktop
- Como iniciar
- Como testar
- Como adicionar uma nova fonte de vagas
- Como adicionar um novo curriculo
- Como registrar uma candidatura
- Exemplos de comandos no Claude Desktop
- Limitacoes atuais
- Proximos passos
1. Arquitetura
Visao geral
Claude Desktop
|
+---------------+---------------+
| | |
career-agent job-search career-files
(MCP stdio) (MCP stdio) (MCP stdio)
| | |
+---------------+---------------+
|
career_core
(dominio puro - nao conhece MCP)
|
+--------+-----------+-----------+--------+
| | | | |
profile scoring applications resume job_sources
(.md) (7 dim.) (SQLite+JSON) (tailor) (IJobSource)
Decisoes arquiteturais
Dominio separado dos adapters. Toda a regra de negocio vive emsrc/career_core/, que nao importa nada de MCP. Os tres server.py saoadapters finos: traduzem argumentos, chamam o dominio, formatam a resposta.Isso permite testar 100% da logica sem subir servidor nenhum.
SQLite como fonte de verdade, JSON como espelho. SQLite da escritatransacional (o historico nao corrompe se o processo morrer no meio) econsultas de duplicidade baratas, com zero configuracao — ao contrario doPostgreSQL, que exigiria servidor e credenciais sem ganho nenhum na escala deuma pessoa. O applications.json continua existindo, reescrito de formaatomica a cada mudanca, para inspecao a olho nu e versionamento no Git. Ele esomente escrita: nunca e lido de volta, entao nao existe risco de duasfontes divergirem.
Score como dimensoes plugaveis. Cada uma das 7 dimensoes e uma classe queimplementa IScoreDimension e sabe pontuar e explicar um unico aspecto. OJobScorer so soma e classifica. Adicionar uma dimensao nova nao altera osomador (Open/Closed).
Fontes de vagas atras de uma interface. IJobSource tem quatroimplementacoes: MockJobSource (offline), RemotiveJobSource eArbeitnowJobSource (APIs publicas reais, sem autenticacao) eUnavailableJobSource (LinkedIn/Indeed/Gupy — declaradas, porem em modomanual). Adicionar uma fonte e escrever uma classe e registra-la; nada maismuda.
Composition root unico. CareerServices monta o grafo de objetos. Osservidores nao instanciam dependencias a mao, e os testes injetam dublês.
Estrutura de diretorios
career-agent/
├── pyproject.toml # deps + config do pytest (fonte unica)
├── .env.example # modelo de configuracao (versionado)
├── .env # sua configuracao real (NAO versionado)
│
├── src/career_core/ # DOMINIO - nao conhece MCP
│ ├── config.py # Settings por ambiente
│ ├── models.py # Job, CandidateProfile, Application, JobScore
│ ├── text.py # normalizacao (aliases de stack, URL, empresa)
│ ├── security.py # politica + maquina de estados (ApprovalGate)
│ ├── paths.py # SandboxedFileSystem (jail em data/)
│ ├── errors.py # hierarquia de erros de dominio
│ ├── logging_setup.py # logging para stderr + arquivo
│ ├── services.py # composition root
│ ├── job_input.py # vaga colada -> Job normalizado
│ ├── profile/repository.py # perfil .md -> CandidateProfile
│ ├── scoring/ # dimensions.py (7 dimensoes) + scorer.py
│ ├── applications/ # repository.py, dedupe.py, builder.py
│ ├── resume/tailor.py # personalizacao + FactGuard
│ └── job_sources/ # base.py, mock.py, http_sources.py,
│ # unavailable.py, registry.py
│
├── mcp-career/ # MCP 1 - logica de carreira
├── mcp-job-search/ # MCP 2 - obtencao de vagas
├── mcp-career-files/ # MCP 3 - leitura de arquivos (sandbox)
│
├── data/ # UNICO diretorio visivel ao career-files
│ ├── profile/ # profile.md, skills.md, preferences.md
│ ├── resumes/ # curriculo-principal.md (+ variantes)
│ └── applications/ # applications.db (verdade) + .json (espelho)
│
├── agent/career-agent.md # instrucoes de comportamento do agente
├── scripts/ # install.ps1, start.ps1, test.ps1, configure-*
├── tests/ # pytest
└── docs/ # SECURITY.md, SCORING.md, ARCHITECTURE.md
2. Pre-requisitos
| Requisito | Versao | Observacao |
|---|---|---|
| Windows | 10/11 | testado no Windows 11 |
| Python | >= 3.11 | python --version |
| uv | qualquer | o install.ps1 instala se faltar |
| Claude Desktop | atual | necessario para usar os MCPs |
| Git | opcional | para versionar o projeto |
3. Instalacao
cd C:\career-agent
powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1
O script verifica Python, instala uv se faltar, cria o .venv, instala asdependencias, cria a arvore de data/, gera o .env a partir do.env.example e valida que os tres MCPs sobem.
Para tambem gravar a configuracao do Claude Desktop no mesmo passo:
powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1 -ConfigureClaude
4. Configuracao
4.1 Preencha seu perfil
Estes arquivos sao a fonte de verdade. O agente nunca afirma nada que naoesteja neles.
| Arquivo | O que colocar |
|---|---|
data/profile/profile.md |
nome, contatos, resumo, formacao, empresas bloqueadas |
data/profile/skills.md |
tecnologias, arquitetura, dominios |
data/profile/preferences.md |
cargos-alvo, senioridade, modalidade, cidades, salario |
data/resumes/curriculo-principal.md |
seu curriculo completo |
Procure por [PREENCHER] — sao os campos que o agente nao pode inventar.
Dois deles mudam o score na hora:
Anos de experienciaemprofile.md: enquanto estivernao informado, a parte de "anos" da dimensao Experiencia fica neutra. Oagente nao deduz esse numero.Minimo/Alvoempreferences.md: enquanto estiverem[PREENCHER], a dimensao Salario fica neutra para vagas com faixadivulgada.
4.2 Ajuste o .env
CAREER_DATA_ROOT=C:\career-agent\data
CAREER_MIN_SCORE=70
JOB_SEARCH_ENABLE_NETWORK=true
JOB_SEARCH_SOURCES=ats
JOB_SEARCH_ATS_COMPANIES=greenhouse:stone,ashby:nubank,greenhouse:vtex,...
JOB_SEARCH_USER_AGENT=career-agent/1.0 (personal job search; contact: SEU-EMAIL)
Ponha seu e-mail no User-Agent — identificar-se e a forma educada de consumiruma API publica.
Adicionar empresas a busca
A fonte ats so encontra vagas das empresas que voce listar. Para adicionaruma, abra a pagina de carreiras dela e olhe a URL:
| URL da pagina de carreiras | Adicione |
|---|---|
job-boards.greenhouse.io/SLUG |
greenhouse:SLUG |
jobs.lever.co/SLUG |
lever:SLUG |
jobs.ashbyhq.com/SLUG |
ashby:SLUG |
Empresas cuja pagina de carreiras esta na Gupy nao podem ser adicionadas — aGupy nao expoe busca publica. Para essas, use o modo manual.
Nao existe variavel de credencial do LinkedIn neste projeto. Isso edeliberado.
5. Configuracao do Claude Desktop
Automatico (recomendado)
powershell -ExecutionPolicy Bypass -File .\scripts\configure-claude-desktop.ps1
O script faz backup do arquivo existente (.backup-AAAAMMDD-HHMMSS), preservatodas as suas configuracoes e MCPs atuais, e so adiciona/atualiza as tresentradas do Career Agent.
Manual
Arquivo: %APPDATA%\Claude\claude_desktop_config.json(no seu caso: C:\Users\Roger\AppData\Roaming\Claude\claude_desktop_config.json)
{
"mcpServers": {
"career-agent": {
"command": "C:\\career-agent\\.venv\\Scripts\\python.exe",
"args": ["C:\\career-agent\\mcp-career\\server.py"]
},
"job-search": {
"command": "C:\\career-agent\\.venv\\Scripts\\python.exe",
"args": ["C:\\career-agent\\mcp-job-search\\server.py"]
},
"career-files": {
"command": "C:\\career-agent\\.venv\\Scripts\\python.exe",
"args": ["C:\\career-agent\\mcp-career-files\\server.py"]
}
}
}
Caminhos absolutos. Se voce instalou o projeto em outro lugar, troque
C:\\career-agentpelo seu caminho real, em todas as ocorrencias. As barrasinvertidas precisam ser duplicadas — e JSON.
Por que o python do
.venve nao ouv? O Claude Desktop inicia osservidores sem carregar seu PATH de usuario. Apontar direto para ointerpretador do ambiente virtual elimina a dependencia de PATH e torna ainicializacao mais rapida e previsivel. Ouvcontinua sendo a ferramentade instalacao e de execucao dos testes.
Depois de salvar: feche o Claude Desktop completamente (inclusive o iconena bandeja do sistema, ao lado do relogio — fechar a janela nao encerra oprocesso) e abra de novo.
Para confirmar, pergunte no chat: "Quais ferramentas de career voce tem?"
6. Como iniciar
Os servidores sao iniciados pelo proprio Claude Desktop — voce nao precisadeixar nada rodando.
Para verificar manualmente que os tres sobem:
powershell -ExecutionPolicy Bypass -File .\scripts\start.ps1
Logs: C:\career-agent\logs\ (mcp-career.log, mcp-job-search.log,mcp-career-files.log).
7. Como testar
powershell -ExecutionPolicy Bypass -File .\scripts\test.ps1
O script roda a suite pytest e, em seguida, uma validacao ponta a ponta:importacao dos modulos, inicializacao dos tres MCPs, leitura do perfil,calculo de score, registro de candidatura, consulta de historico e deteccao deduplicidade.
Apenas os testes unitarios:
C:\career-agent\.venv\Scripts\python.exe -m pytest tests -v
8. Como adicionar uma nova fonte de vagas
Antes de tudo: verifique se a fonte tem API publica documentada. Se exigirlogin, cookie ou scraping, ela nao entra — use UnavailableJobSource e o modomanual.
- Crie a classe em
src/career_core/job_sources/:
from .base import IJobSource, JobQuery, SourceResult, detect_seniority
class MinhaFonteJobSource(IJobSource):
name = "minhafonte"
provenance = "API JSON publica de X, sem autenticacao."
usable = True
def search(self, query: JobQuery) -> SourceResult:
# ... chamar a API e converter cada item em `Job`
return SourceResult(source=self.name, jobs=jobs, ok=True, message="...")
- Registre em
src/career_core/job_sources/registry.py:
_FACTORIES = {
...,
"minhafonte": (lambda s: MinhaFonteJobSource(...), True), # True = precisa de rede
}
Ative no
.env:JOB_SEARCH_SOURCES=mock,minhafonteAdicione um teste em
tests/test_job_sources.py.
Nenhum outro arquivo do sistema muda. Score, deduplicacao e candidaturafuncionam automaticamente porque a fonte devolve Job normalizado.
9. Como adicionar um novo curriculo
Coloque um .md em C:\career-agent\data\resumes\. O nome do arquivo importa:o agente escolhe automaticamente o curriculo cujo nome tem mais palavras emcomum com a vaga.
data/resumes/
├── curriculo-principal.md # padrao / fallback
├── curriculo-backend-dotnet.md # vence em vagas .NET/backend
├── curriculo-fullstack.md # vence em vagas fullstack/React
└── curriculo-sap.md # vence em vagas SAP
Para forcar um especifico: "Prepare a candidatura usando curriculo-sap.md".
10. Como registrar uma candidatura
Ciclo de vida:
generate_application register_application
(mostra o pacote) --> (grava o historico)
|
v
pending_approval
|
voce aprova |
v
approved
|
VOCE se candidata no site
v
applied
|
+-------------+-----------+-----------+
v v v v
interview technical_test offer rejected
rejected e withdrawn sao estados finais.
Nao existe caminho de pending_approval direto para applied. A tentativae recusada pela maquina de estados. Essa e a garantia, em codigo, de que nadaavanca sem voce ter visto.
11. Exemplos de comandos no Claude Desktop
Buscar
Procure vagas Backend .NET compativeis com meu perfil.
Priorize remoto e hibrido em Goiania.
Mostre somente vagas com score >= 80.
Analisar uma vaga colada
Analise esta vaga:
[cole aqui a URL e a descricao completa]
Preparar candidatura
Prepare minha candidatura para a vaga da Nexatech.
Acompanhar
Mostre minhas candidaturas pendentes.
Quais candidaturas estao aguardando minha aprovacao?
Atualize a candidatura app-xxxx para entrevista.
Aprovar
Aprovo a candidatura app-xxxx.
Diagnostico
Esta tudo configurado no Career Agent?
De onde vem as vagas que voce busca?
Voce consegue se candidatar por mim no LinkedIn?
12. Limitacoes atuais
- LinkedIn, Indeed e Gupy funcionam em modo manual. Nenhum deles ofereceAPI publica de busca para candidatos. Voce copia a vaga; o agente faz oresto. Isso e uma escolha de seguranca, nao uma pendencia.
- A cobertura automatica depende de quais empresas voce configura. A fonte
atsvarre os quadros publicos das empresas emJOB_SEARCH_ATS_COMPANIES.A lista padrao tem 10 empresas verificadas (~1.160 vagas), mas o mercadobrasileiro tem muito mais — adicione as empresas que te interessam. - Nem todo ATS e coberto. Greenhouse, Lever e Ashby tem endpoint publico.Gupy, Solides e Kenoby nao expoem busca publica para candidatos.
- Remotive e Arbeitnow servem para pouca coisa (medido em agosto/2026):a Remotive devolve um feed de amostra de 14 vagas que ignora oparametro
search; o Arbeitnow tem 175 vagas quase todas europeias epresenciais, zero com .NET/C#. Ficam disponiveis, mas fora do padrao. - LinkedIn, Indeed e Gupy continuam em modo manual — nao tem API publicade busca para candidatos, e este projeto nao automatiza login nem scraping.
- A extracao de requisitos e heuristica. Funciona bem com descricoes embullets; com texto corrido, os requisitos saem menos estruturados.
- A deteccao de senioridade e por palavra-chave no titulo e na descricao.Titulos ambiguos podem sair como
nao_informado— informe manualmentequando importar. - Salario so e comparado quando a vaga divulga a faixa. A maioria dasvagas brasileiras nao divulga; nesse caso a dimensao fica neutra.
- O curriculo personalizado sai em Markdown. Nao ha exportacao para PDFou DOCX na V1.
- Instalacao mono-usuario, local. Sem multi-perfil, sem sincronizacao.
13. Proximos passos
Ordenados por relacao valor/esforco:
- Exportar curriculo para PDF/DOCX — hoje o material sai em Markdown evoce converte a mao.
- Ler descricao de vaga a partir de uma URL publica (paginas de carreiraabertas, sem login), reduzindo o copiar-e-colar.
- Fontes brasileiras — mapear ATSs que expoem endpoint publico de vagaspor empresa e implementar como
IJobSource. - Lembretes de follow-up — sinalizar candidaturas paradas em
appliedhamais de N dias. - Metricas do funil — taxa de resposta por score, por stack e pormodalidade, para calibrar os pesos com dados reais.
- Calibracao dos pesos — hoje sao os pesos definidos na especificacao;com historico suficiente, ajustar com base no que realmente converte.
- Deteccao de duplicidade semantica — hoje e por similaridade textual;embeddings pegariam "Dev Backend .NET" vs "Engenheiro de Software C#".
Seguranca
Resumo do que este projeto nao faz, por design:
| Nao faz | Por que |
|---|---|
| Login automatico no LinkedIn | viola os ToS; risco de bloqueio da conta |
| Guardar senha/cookie/token | superficie de ataque desnecessaria |
| Automatizar cliques | viola os ToS |
| Enviar candidatura sozinho | a decisao final e sua |
| Enviar mensagem sozinho | a decisao final e sua |
| Burlar anti-bot / CAPTCHA | ilegitimo |
| Scraping agressivo | ilegitimo e desrespeitoso |
| Inventar experiencia | mentira em curriculo prejudica voce |
Detalhes em docs/SECURITY.md.
O acesso a arquivos do Claude fica restrito a C:\career-agent\data. Ele naoenxerga C:\, nem sua pasta de usuario, nem o codigo do proprio projeto.