foodvisor-mcp
foodvisor-mcp
Foodvisor 영양 API를 LLM 에이전트(Claude, Cursor 등)에 노출하는 원격 Model Context Protocol 서버입니다. 어시스턴트를 통해 음식을 검색하고, 식단을 기록하며, 진행 상황과 영양 성분을 확인하세요.
면책 조항. 이 프로젝트는 비공식입니다. Foodvisor의 비공개 모바일 API를 리버스 엔지니어링하여 사용하며, Foodvisor와는 아무런 관련이 없습니다. 사용 시 위험은 사용자 본인에게 있으며, 엔드포인트는 예고 없이 변경될 수 있습니다.
주요 기능
🥗 카탈로그 검색: 칼로리, 영양 성분, 브랜드, 이미지, Nutriscore 제공.
📒 식단 기록: 수량 및 1인분 배수를 포함한 식사(아침/점심/저녁/간식/기타*) 기록.
📊 일일 요약: 목표 대비 칼로리 및 영양 성분의 서버 측 집계.
📈 진행 상황: 일일 칼로리, 체중 및 등급 기록(약 90일).
🔥 연속 기록(Streak): 현재 연속 기록 일수 및 사용 가능한 프리즈(freeze).
💧 수분 섭취 기록.
👤 프로필 및 영양 목표: 요일별 칼로리/영양 성분 목표.
🔐 OAuth 2.1 + PKCE: 동적 클라이언트 등록을 지원하며, Claude 원클릭 커넥터로 작동합니다.
🔄 상태 비저장 다중 사용자: 토큰은 자체 포함되어 있습니다(데이터베이스 없음). Foodvisor 리프레시 토큰은 OAuth로 발행된 JWT 내부에 암호화(AES-256-GCM)되어 저장됩니다.
♻️ 자동 액세스 토큰 갱신: 메모리 내 캐싱 및 스탬피드 방지 기능 포함.
사용 가능한 MCP 도구
도구 | 설명 |
| 자유 텍스트 쿼리로 Foodvisor 카탈로그 검색. |
| 하나 이상의 |
| 특정 날짜의 식사 슬롯에 음식 추가. |
| 특정 날짜 범위의 기록된 식사 목록. |
| 목표 대비 하루 총 칼로리/영양 성분. |
| 약 90일간의 일일 칼로리, 체중 및 Foodvisor 등급. |
| 7/30/90일 이동 평균 기간 동안의 A/B/C/D 식사 비율. |
| 현재 연속 기록 및 프리즈 상태. |
| 특정 날짜 범위의 일일 수분 섭취량. |
| 프로필 및 영양 목표. |
Docker를 이용한 빠른 시작
git clone https://github.com/cldt-fr/foodvisor-mcp.git
cd foodvisor-mcp
docker compose up -d이제 서버가 http://localhost:3000/mcp에서 대기합니다. 상태 확인은 /health에서 가능합니다.
공용 도메인에서 리버스 프록시(Caddy, Traefik, nginx) 뒤에서 실행하려면 3000번 포트 앞에서 TLS를 종료하기만 하면 됩니다.
인증
foodvisor-mcp는 두 가지 인증 방식을 지원하며, 둘 다 동일한 기본 자격 증명인 Foodvisor 리프레시 토큰을 사용합니다:
OAuth 2.1 (권장) — 서버는 동적 클라이언트 등록 및 PKCE를 지원하는 완전한 OAuth 인증 서버입니다. 호환되는 MCP 클라이언트(Claude, Cursor 등)가 흐름을 자동으로 처리합니다. 클라이언트는 인증 엔드포인트를 검색하고 스스로를 등록하며, Foodvisor 리프레시 토큰을 한 번 입력하는 로그인 페이지를 엽니다. 이후 서버는 리프레시 토큰이 AES-256-GCM으로 암호화된 자체 JWT를 발행합니다.
Direct Bearer (고급 사용자) — Foodvisor 리프레시 JWT를
Authorization: Bearer …로 직접 전달합니다. 스크립트나 빠른 테스트에 유용합니다. 서버는 토큰 형식을 감지하고 이전과 같이 프록시합니다.
어떤 방식을 사용하든 서버에 사용자별 상태가 저장되지 않습니다. OAuth로 발행된 JWT는 자체 포함되어 있으며, 레거시 모드는 순수하게 패스스루 방식으로 작동합니다.
Foodvisor 리프레시 토큰 얻기
Foodvisor는 iOS에서 Apple 로그인을 통해서만 인증하며, 공개 OAuth나 비밀번호 엔드포인트가 없습니다. Charles Proxy (또는 Proxyman, mitmproxy 등)를 HTTPS 중간자(man-in-the-middle)로 구성하여 실제 iPhone에서 POST /user/auth/ 응답을 캡처하세요:
iPhone에 Charles 루트 인증서를 설치하고 전체 신뢰를 활성화합니다.
Foodvisor 앱을 강제 종료 후 다시 열고 로그인합니다.
POST https://api.foodvisor.io/api/6.0/ios/FR/fr_FR/user/auth/요청을 찾습니다. JSON 응답에 포함된tokens.refresh가 귀하의 장기 자격 증명(약 6개월)입니다.
리프레시 토큰은 귀하의 영양 기록에 대한 전체 액세스 권한을 제공합니다. 비밀번호처럼 취급하세요.
MCP 클라이언트 구성
Claude (웹 / 데스크톱 / 코드) — OAuth
공용 /mcp URL(예: https://foodvisor-mcp.example.com/mcp)을 사용하여 서버를 커넥터로 추가하세요. Claude는 다음을 수행합니다:
/.well-known/oauth-protected-resource및/.well-known/oauth-authorization-server에서 OAuth 메타데이터를 검색합니다.POST /register를 통해 스스로를 등록합니다.브라우저에서
/authorize페이지를 엽니다. 양식에 Foodvisor 리프레시 토큰을 붙여넣고 제출합니다.반환된 코드를 장기 액세스 토큰(기본값 30일)으로 교환합니다.
그 후에는 Claude에서 직접 도구를 사용할 수 있습니다. 액세스 토큰이 만료되면 Claude가 흐름을 다시 실행합니다.
Direct Bearer (Streamable HTTP를 지원하는 모든 MCP 클라이언트)
{
"mcpServers": {
"foodvisor": {
"url": "https://foodvisor-mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer <YOUR_FOODVISOR_REFRESH_TOKEN>"
}
}
}
}로컬 개발
Node ≥ 22 버전이 필요합니다.
npm install
npm run dev # tsx watch on $PORT (default 3000)
npm run typecheck
npm run build && npm start프로젝트 레이아웃
src/
├── index.ts # Node http server + per-request MCP transport + OAuth routes
├── env.ts # zod-validated env vars
├── auth/
│ ├── extract.ts # Bearer parsing — accepts OAuth JWT and legacy Foodvisor refresh
│ └── token-cache.ts # Foodvisor access-token cache + refresh
├── oauth/
│ ├── jwt.ts # HS256 sign/verify + AES-256-GCM encrypt/decrypt
│ ├── store.ts # in-memory clients + auth codes (TTL)
│ ├── login.ts # HTML login page (paste refresh token)
│ ├── handlers.ts # /register, /authorize, /token handlers
│ └── metadata.ts # /.well-known/* metadata builders
├── foodvisor/
│ ├── client.ts # fetch wrapper with 401 retry
│ ├── endpoints.ts # typed endpoint helpers
│ └── types.ts # response shapes
└── mcp/
├── server.ts # createMcpServer(ctx)
└── tools/ # one file per tool group
├── food.ts
├── meal.ts
├── progress.ts
├── trackers.ts
└── profile.tsHTTP 서버는 의도적으로 최소화되어 있습니다(Express/Hono 없음). 각 POST /mcp는 호출자의 userId/refreshToken 및 상태 비저장 StreamableHTTPServerTransport에 바인딩된 새로운 McpServer를 생성합니다.
환경 변수
변수 | 기본값 | 목적 | |||
|
| HTTP 대기 포트 | |||
|
|
|
|
|
|
| 파생됨 | 공용 오리진(예: | |||
| 무작위 | OAuth 발행 토큰 서명에 사용되는 HMAC 비밀키. 최소 32자. 프로덕션 환경에서 명시적으로 설정하세요. 그렇지 않으면 재시작할 때마다 토큰이 무효화됩니다. | |||
|
| OAuth 액세스 토큰의 수명(초 단위, 기본값 30일). | |||
|
| 테스트용으로만 재정의 | |||
|
| 업스트림에서 사용하는 로케일 경로 접두사 |
다음 명령어로 안정적인 비밀키를 생성하세요:
openssl rand -base64 48보안 참고 사항
이 서버는 Foodvisor에 대한 신뢰할 수 있는 프록시입니다. 유효한 Foodvisor 리프레시 토큰을 가진 사람은 누구나 이를 사용하여 해당 사용자의 영양 데이터를 읽고 쓸 수 있습니다. 프로덕션 환경에서는
/mcp엔드포인트 앞에 HTTPS를 배치하고, 공개적으로 노출되는 경우 IP 허용 목록을 고려하세요.토큰은 프로세스 메모리에만 보관됩니다. 디스크에 절대 저장되지 않습니다.
토큰 캐시는 JWT의
user_id를 키로 사용하므로, 동일한 사용자의 동시 요청은 단일 액세스 토큰을 공유하며, 동시 갱신 시도는 진행 중인 맵을 통해 병합됩니다.
로드맵
업로드 엔드포인트가 리버스 엔지니어링되면 사진 기반 식사 인식(Foodvisor의 핵심 기능) 추가.
활동 기록, 체중 측정, 맞춤형 레시피 및 즐겨찾기.
재시작 시 복원력을 위한 선택적 영구 토큰 저장소.
기여
이슈 및 PR은 https://github.com/cldt-fr/foodvisor-mcp에서 환영합니다. Foodvisor 엔드포인트 리버스 엔지니어링에 대한 도움을 요청하는 이슈는 열지 마세요. Charles/Proxyman으로 직접 캡처하여 타입이 지정된 래퍼를 기여해 주시기 바랍니다.
라이선스
MIT — LICENSE를 참조하세요.
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/cldt-fr/foodvisor-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server