Skip to main content
Glama

MacroMCP

LLM을 실제 기억력을 가진 영양 어시스턴트로 바꿔주는 MCP 서버입니다.

사람에게 말하듯 이야기하면 됩니다: "칠면조 7온스랑 밥 한 컵." 서버는 필요한 것을 묻고, 확인하고, 기록한 뒤 숫자를 읽어줍니다. 나중에 *"이번 주 단백질은 어떠냐"*고 물으면 추측 대신 데이터베이스에서 답합니다.


문제점

영양 기록 앱은 두 가지 방식 중 하나로 실패합니다.

수동 기록형(MyFitnessPal 등)은 정확하지만 힘듭니다. 데이터베이스에서 검색하고, 거의 동일한 여섯 개의 항목 중 하나를 고르고, 1회 제공량을 설정하고, 모든 재료에 대해 이를 반복해야 합니다. 이 마찰이 바로 제품의 주요 기능이자 이탈의 주요 원인입니다.

LLM 채팅 랩퍼는 마찰이 없고 조용히 틀립니다. "치킨과 밥"이라고 하면 모델이 그럴듯한 수치를 지어내고, 영속성도 없고, 출처도 없고, 확인할 것도 없습니다. 일주일 뒤 무엇을 먹었는지 물어보면 아무것도 모릅니다.

MacroMCP는 그 중간을 추구합니다: 대화형 입력은 모델이 이해하고, 데이터베이스가 강제와 계산을 담당하며, 그 사이에 체계적인 버납 단계가 있습니다.


핵심 긴장 관계

엄선성과 마찰은 정확히 반비례합니다. 모든 명확화 질문은 데이터 품질을 높이는 대신 내일 기록할 가능성을 조금씩 낮춥니다. 디자인의 대부분은 정확성을 사기 위해 대화 턴수를 늘리지 않는 방법을 찾는 데 들어갑니다.

두 번째 조직 원칙:

강제성은 시스템 프롬프트가 아니라 서버에 있습니다. "수량을 추측하지 말아라"라는 프롬프트는 잠시 유지되다가 긴 대화의 40번째 턴에서 조용히 실패합니다. 반면, 구체적은 문제 목록과 함께 거부를 반환하는 커밋 함수는 실패할 수 없습니다. 프롬프트는 톤과 질문 문구를 담당하며, 데이터베이스는 표현 가능한 것을 담당합니다.


작동 방식

입력: 파싱 → 분류 → 해결 → 확인 → 커밋 → 읽기

파싱은 발화를 구조화된 초안으로 변환합니다. 이는 전사와 속성 분리이며 추론이 아닙니다. "치과 밥"은 대부분의 필드가 비어 있는 두 항목을 생성하며, 이것이 올바른 출력입니다.

추론을 하지 않고 커밋 시 두 가지 불변 조건이 적용됩니다:

  • 범위 사용 span coverage. 각 항목은 당신이 말한것의 문자열 범위를 지시합니다. 항목을 생성하지 않은 식품성 텍스트가 보고되므로, 누락된 항목은 3개월 뒤 주간 합계에서 발견하는 것이 아니라 기계적으로 잡히게 됩니다.

  • 서식 없는 화물 no unanchored items. 범위가 없는 항목은 환각이므로 거부됩니다. 이는 특히 모델이 언급하지 않은 요리용 지방을 걸다가 도와주지 않도록 방지합니다.

분류는 각 공칙을 유형으로 태그하여, 추후 어시스턴트가 일반적인 "어느 정도?" 대신 대상적으로 묻을 수 있게 합니다. 분류 체계가 핵심입니다:

예시

중요성

예측이 낮은 용기

"그릇 하나", "컵 하나"

계량 컵인가 서랍의 컵인가?

모호한 단위

"8 oz"

우유는 부피, 닭고기는 무게. 음식에 따라 정해짐.

조리 상태

"밥"

건조와 취사는 약 3배 차이. 가장 큰 단일 과오 원인

조리용 기름

"팬으로 구웠다"

지리 널월 누락되며, 흔히 100~200 kcal

변형 상품

"치킨", "우유"

가슴살 vs 참깨는 지방 2배 차이

복합 품목

"샌드위치 하나"

분해해야 하묘, 아니면 추측

수량 범위

"달걀 두 개와 소시지"

2가 모두에 적용되는가?

중요도 임계점은 추궁이 되지 않도록 하는 장치입니다. 각 갭은 상위 해석 간의 칼로리 차이를 담습니다. 임계값 아래러면 가장 적합한 해석을 선택하고, 추정형으로 표시하고, 턴을 소모하지 않습니다. 블랙 라이 위의 컵-측정 구분은 눅음이지만, 밥에서는 200 kcal 차이입니다.

해결은 그램민과 매크로 밀도를 산출합니다. 확인은 전체 플랜을 한 화면에 보여주며 모든 미해결 사실을 한 턴에 물어봅니다 — 정보를 연속적으로 질문하는 것이 기록 앱이 버려지는 이유입니다.

커밋이 관문입니다. 해결되지 않은 항목, 닫점이 없는 항목, 누락된 범위, 중요한 갭, 그리고 정합성 검사를 통과하지 못한 매크로는 거부합니다.

읽기는 커밋된 항목을 그램, 항목별 매크로, 식사 총합, 일별 총합과 함께 반환합니다. 어시스턴트는 서버가 계산한 숫자를 보고하므로, 긍 대화 중에 초안이 어긋나면 여기에서 드러납니다.

저장: 4단계

meals               the eating event.  "chicken and rice", dinner, Aug 19
  meal_logs         one submission.    eaten_at + logged_at
    log_items       one named thing.   "cheeseburger", fraction 1/2
      item_ingredients                 bun 60g, patty 113g, cheese 19g

각 단계가 존재하는 이유:

  • meals 식사 행사가 이름을 가지며 여러 번 기록할 수 있기 때문입니다. 그 내용을 읽어보면 매 식사당 _소유권_이 있다는 것도 알 수 있습니다 — 아래 "다중 사용자" 참조.

  • meal_logs 무언가 잊는 것은 정상이기 때문, 그리고 언제 먹었는지언제 시스템에 말했는지는 같은 값으로 저장해서는 안 되는 서로거 다른 사실이기 때문입니다.

  • log_items 섭취분률이 여기에 있기 때문입니다. 분할이 로그에 있다면 "버거 절반과 프라가 전부"는 표현이 불가능합니다. 복합 항목도이름을 가지므로, 읽어내면 "치즈버거, 263 kcal"이지 재조립해야 할 세 변 행이 아닙니다.

  • item_ingredients 치즈버거가 번, 패티, 치즈로 구성되기 때문입니다. 모든 항목에는 재료가 있으며 — "밥 한 컵"도 하나의 재료를 가진 항목입니다 — 래퍼 행 하나와 다형성이 없는 단일 롤업 경로를 제공합니다.

meals보다 아래의모든 것은 append-only(추가전용) 입니다. 용結果는 기존 행을 대체하는 새 행으로 기록됩니다. meals.name만 수정 가능한 유일 필드이며, 전체 로그가 변경됩니다.

쿼리

모델은 결코 계산을 하지 않습니다. 모든합계, 평균, 추이는 SQL에서 계산되며 구조화된 JSON으로 반환합니다. LLM이 숫자를 합치면 드물게, 온소 없이 틀릴 수 있고, 이는 데이터베이스가 존재하는 이유를 무시하는 것입니다.

롤업은 재료 → 항목 → 로그 → 식사 → 일별로하며, 중간 과정에서 반올림하지 않고 표시에서 한 번 반올림합니다. 총합에 명확히 맞지 않는 구성 요소는 단일 잘못된 기록보다 더 빨리 신뢰를 부술니다.


다중 사용자

MacroMCP는 단일 사용자로 시작했으나 이제 소규모 그룹 기반입니다 — 한 가정이나 소수의 친구가 자체 호스팅 인스턴스를 공유하는 형태이며 공용 멀티테나이트 제품이 아닙니다.

모든 식사는 사용자 소유입니다. meals.user_id가 실체의 근원이며, 그 아래의 모든 것 (meal_logs, log_items, item_ingredients)은 자체 사본을 담는 대신 여기로 연결하여 범위가 지정됩니다. 모든 커밋 경로 함수 — commit_log, rename_meal, supersede_log, find_attachable_meals — 호출 사용자의 id를 명시적 인자로 받아들여 어떤 동작 하기 전에 소유권을 확인합니다. 즉, staging_id가 모델로부터 신뢰되지 않고 서버에서 발행되는 것과 같습니다.

다중 사용자가 주는 이점: 두 사람이 각자의 로그, 중복 감지, 추새 사이의 간섭 없이 하나의 인스턴스를 공유할 수 있습니다. 샘이 로그한 치킨과 밥이 루카가 5분 전에 기록한 것과 중복이 아닌 경우는 서로를 침해하지 않습니다. 루가의 화요일 총합이 샘의 것과 조용히 합쳐지지 않습니다.

의도적으로 포함하지 않는 점: 인증. 이 스키마에는 암호나 토큰이 없습니다 — user_id는 그대로 신뢰되며, 누가 실제로 호출하는지를 해결하는 것(API 키, 로그인 세션, 사용자 MCP 서버)은 API 레이어의 결정이지 데이터베이스의 결정이 아닙니다. 또한 공유 모델(사용자 간 완전히 격리되어 있고, 서로의 로그를 볼 수 있는 가족 구성이 아닌)도 포함되지 않습니다. 공유의 시각이 필요해진다면, 이것은 프로젝트 차원의 임무가 아니라 위에 추가적 기능으로 도입됩니다.

전체 목록은 docs/design-notes.md에서 확인할 수 있습니다 — 어떤 부분에 교차 조정 보호가 있고 그 이유, 그리고 행 수준보안(Security)을 지금 생략하기로 한 주관적 선택.


The v0 bet

No reference dataset. 참조 데이터베이스가 없습니다. USDA 수집, Open Food Facts, 바코드 경로, 포션 테이블이 없습니다. 매크로 질량은 모델이 알고 있거나 샘 가 정리한 것을 재료에 저장합니다.

실제 배팅이 맞으므로 양쪽의 장단점을 살j고.

장점: 현대 모델은 치케 가슴 165kr/100g이라는 정보와 케 곰배기 - 밥 158g 얀 단위를 알고 있습니다. 조회하는 것은 지연을 높일 뿐이며, 지연이 심한 입력은 기록 없음, 그리고 수집 파이프라인 전체가 필요 없습니다. 기록 시간에 과거 기록은 바 팔림 — 외부 원천 데이터는 과거 기록을 조융히 변경할 수 없습니다.

단점: 외부에서 검증하는 것이 없습니다. 남은 유일한 자동 검토는 Atwater 식 (칼로리 ≈ 4·단백질 + 4·탄수 + 9·지방)이며, 이는 자리 바꿈과 일관성 없는 추측을 잡지만 일관된 오답은 잡지 못합니다. 지리 단백질이 그 런듬하게 매크로 조합으로 100/100g으로 등록면 커밋되지만, 실제 파일리는 대략 270입니다. 이를 잡는 곳이 확인 단계이므로, 확인 블록은 그램 뿐 아니라 매크로도 표시합니다.

이 선택을 의존 가능하게 만든 두 가지 요소:

매크로는 절대적인 값이 아니라 100g당 전송됩니다. "치킨은 165 kcal/g" 은 기억이고 "213g 치킨은 351 kcal"는 연산입니다. 모델은 첫 번째는 신뢰 신뢰하지만 두 번째는 악위하지 바탕으로 합니다. 100g 단위 전송은 서버가 여전히 모든 곱셈을 수행하므로 항목 분해가 마찬가지로 기능합니다.

출처가 모든 재료에 기록됩니다: llm_knowledge, llm_estimate, user_stated. v_daily_data_quality는 식당의 총 칼로리 중 각 소스가 차지하는 비율을 제공합니다. 하루가 모델 추측 80%와 패키지 판독 80%는 다른 신뢰도를 가지며, 이 지표만이 어느 하루야 알 수 있습니다.

참고: 바권 코드 탐색은 아래의 지연 목록에 포함되어 있으며 이 동일 선택 이후에 하류에 있습니다 — 별도의 단계가 아닙니다. UPC→매그로 조회 테이블이 없는 것은 참조 데이터베이스가 전혀 없기 때문입니다. 하나를 구축하는 것은 둘 다를 동시에 지연 해제하는 일입니다.


알아 둘 필요가 있는 설계 결정

스테이지에서 문맥 창에 있습니다. 임시 테이블이나 Redis 없음. 대화 이미 진행 중 요소를 내재적으로 보류합니다. Redis와 write-through가 계획된 다음 단계이며; 커밋 관문 기능은 그 랜딩 시에도 변하지 않습니다. 배운 컴필레이션 인자로 페이로드를 테이블 읽지 않고 전달받기 때문입니다.

중복은 내용으로, 로깅 순서 없는 키가 아닙니다. (meal, timestamp) 키는 "아, 그리고 바나나 하나" — 가장 흔한 로깅 패턴 하나를 거부합니다. 대신: 해석된 재료를 해시, 기존 행의 시각과 윈도우 내 비교, 사용자 하나의 범위. 동일 식사표/서로 상이 조직 수준으로 모두 약량(약)이어야 합니다. 왜냐하면 하루에 동일한 프로테인 셰이크 2개는 실제 존재하기 때문입니다.

Idempotency is from a single unique column. **고유 컬럼 하나에서 생성됩니다. 서버가 발급하는 staging_id이며 전 사용자에 걸쳐 UNIQUE. 재시도, 에이전트-루프 재발사, 동시 호출 모두 중복이 아니라 기존 항목을 사용합니다.

첨부는 결코 파생되지 않습니다. "잊어먹은 소스를" 잘못된 식사에 첨부하는 것은 실수로 올바른 식사를 망치는 것보다 나빠서, 잘못된 식사를 첨부하는 것보다 않도록 서버는 호출자 자신의 식사에서 후보를 제안하며, 하나 일치 시에도 확인이 필요합니다.

이름은 다시 생성되지 않습니다. 잊은 소스추가하면 "치켄 앤 라이스"는 "치킨, 라이스, 시라치"로 되급지 않고 그대로 유지됩니다. 끊임없이 바뀌는 로그인 이름은 약간 불완전한 것보다 나쁩니다.

날 갱신은 오전 4시에, 자정이 아님자정이 아닌 오전 4시에 열립니다. 밤 1:30의 스냑 당신이 아직 밖이 있는 그날에 속합니다. log_date는 커밋 시 처리되고 식사의 첫 로그로 파생되어 식사가 이영에 걸쳐 분할될 수 없습니다.

정밀도는 정확성이 아닙니다. 대강 눈으로 추정한 포션에 대한 정확한 유리 산술 분석은 여전ㅡ estimated로 표시됩니다. 시스템은 그 둘을 혼동하지 않습니다.

v0에 의도적으로 제외된 것

  • 바코드 조회 및 이에 의존하는 참조 식품 데이터베이스. USDA/OFF 수집 없음, UPC 조회 테이블 없음 — 이는 위의 "참조 데이터베이스 없음"과 동일한 범위이며, 별도의 두 가지 누락 사항이 아닙니다.

  • 이전 해상도 재사용 ("지난번과 동일?") — 주요 마찰 해소책이며, 이것이 없으면 모든 식사가 전체 확인 비용을 지불합니다.

  • 배치 추적 (한 접시의 분수가 합계 ≤ 1이 되도록 강제하는 것이 없음)

  • 레시피 템플릿

  • 미량 영양소 — 돌아올 때 마이그레이션으로 복귀하지 말고 별도의 긴 형식 테이블을 추가하세요. 매크로와 마이크로는 형태와 쿼리 패턴이 다르기 때문입니다.

  • 인증 및 사용자 간 공유 — 위의 "다중 사용자" 참조. user_id 스코프 지정은 존재하지만, user_id가 실제로 누구인지 검증하는 것과 사용자가 서로의 로그에 대한 가시성을 공유하는 개념은 존재하지 않습니다.


스택

FastAPI + Postgres 16, 소규모 다중 사용자, 자체 호스팅. MCP를 통해 노출되어 모든 MCP 클라이언트가 프론트 엔드가 될 수 있습니다.

실행 방법

MCP 서버(server/)는 얇은 어댑터입니다. docs/intake-agent.md의 계약에서 각 도구를 등록하고, 시작 시 이 프로세스의 user_id를 한 번 해석한 후, 모든 호출에 대해 일치하는 SQL 함수 또는 뷰를 호출합니다. 그 외에는 자체 로직이 없습니다 — 모든 불변식이 실제로 강제되는 곳은 여전히 데이터베이스입니다.

하나의 서버 프로세스 = 한 명의 사용자 (server/config.py 참조). 이것은 docs/design-notes.md의 "호출이 user_id로 어떻게 해석되는가" 질문에 대한 답변입니다. MCP의 경우 구체적으로 각 사용자가 자신의 서버 인스턴스를 실행하며, Claude Desktop/Code가 구성된 도구당 하나의 하위 프로세스를 실행하는 것과 같은 방식입니다.

python3 -m venv .venv && source .venv/bin/activate
pip install -e .

createdb macromcp                       # first time only
psql -d macromcp -f db/schema.sql       # first time only
psql -d macromcp -c "INSERT INTO users (username, display_name) VALUES ('luke','Luke');"

cp .env.example .env   # edit MACROMCP_USERNAME to match the user you just created
export $(cat .env | xargs)
python -m server.server

MCP 클라이언트(Claude Desktop, Claude Code, OpenAI Realtime 함수 호출 브리지)를 해당 환경으로 python -m server.server에 연결하면 docs/intake-agent.md의 모든 도구가 활성화됩니다.

docs/intake-agent.md에 설명된 GPT Realtime 미니 음성 프론트 엔드는 아직 연결되지 않았습니다 — 이 서버는 엔드 투 엔드로 유용하려면 앞에 어떤 MCP 말하기 또는 함수 호출 클라이언트만 있으면 됩니다.

파일

  • db/schema.sql — 전체 DDL, 다중 사용자 커밋 게이트, 롤업 뷰. PG16에서 깨끗하게 로드됩니다.

  • db/tests.sql — 18개의 불변식 테스트(핵심 13개, 사용자 간 격리 검사 5개), 모두 통과.

  • docs/design-notes.md — 전체 설계 근거, 다중 사용자 트레이드오프, 날카로운 모서리.

  • docs/intake-agent.md — 대화형 프론트 엔드(GPT Realtime 미니)를 위한 시스템 프롬프트 및 도구/함수 호출 계약으로, fn_commit_log의 페이로드와 필드별로 일치합니다.

  • docs/erd/ — 스키마 다이어그램(여전히 단일 사용자 형태를 보여줌, 아직 다중 사용자용으로 재생성되지 않음).

  • server/ — 도구 계약을 구현하는 MCP 서버(db.py Postgres 액세스, models.py 페이로드 검증, tools.py 비즈니스 로직, server.py 도구 등록).

  • 이전 단일 사용자 설계 이력: git log db/schema.sql.

-
license - not tested
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

View all MCP Connectors

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/lukew0824/MacroMCPv2'

If you have feedback or need assistance with the MCP directory API, please join our Discord server