LQABR HubSpot MCP Server
LQABR_MCP
LQABR 중앙 HubSpot MCP 서버입니다. FastMCP 를 기반으로 구축되었으며, 독립형입니다 — LQABR 모노레포에 대한 의존성이 없습니다.
RUNNING.md — 실행 방법: 설정, 자격 증명, 두 가지 전송 방식, 에이전트 게이트웨이, 문제 해결. CONSUMING.md — 이메일/음성/스케줄링 에이전트가 이 서버를 호출하는 방법: ADK
McpToolset, 인증, 유선 계약, 도구 범위. 이 파일은 설계 근거 문서입니다. 위 두 파일은 절차 문서입니다.
LQABR_MCP/
├── hubspot-crm-mcp-server/
│ ├── __init__.py (empty, per mcp.odt Step 4)
│ ├── hubspot_crm_server.py the launcher — mcp.odt Step 5
│ ├── test_server.py remote smoke test — handoff S8
│ ├── hubspot_mcp/ THE IMPLEMENTATION (vendored)
│ │ ├── __init__.py provenance + drift warning — read this
│ │ ├── server.py the FastMCP object + the two tools
│ │ ├── secrets.py Secret Manager access
│ │ ├── obs/ the four logs: system/process/audit/tokens
│ │ │ ├── __init__.py
│ │ │ ├── context.py RunContext, run_id, lead_ref_id
│ │ │ └── loggers.py
│ │ └── hubspot/
│ │ ├── __init__.py
│ │ ├── crm.py upsert_lead_profiles / get_lead_profile
│ │ ├── auth.py get_hubspot_token(), short-lived M2M
│ │ ├── schema.py LeadProfile, PushResult, property mapping
│ │ └── failures.py failure taxonomy + CircuitBreaker
│ └── tests/ 61 tests ported from the mono-repo
├── .vscode/hubspot_mcp.json stdio config — mcp.odt Steps 7–8
├── Dockerfile Cloud Run image — handoff S4
├── .dockerignore
├── pytest.ini
├── .python-version 3.12, matching the Dockerfile
├── .env.example mode switches + secret IDs (no values)
├── pyproject.toml
├── RUNNING.md step-by-step runbook — start here
├── CONSUMING.md client integration guide for other agents
└── README.md포크(fork)이지, 이동(move)이 아닙니다
hubspot_mcp/는 모노레포 구현의 복사본입니다. 가져오기(import) 문만 다시 작성되었습니다. 로직, 필드 이름 또는 HubSpot 속성 이름은 변경되지 않았습니다. diff를 통해 확인되었습니다 — 9개 파일 전체에서 유일하게 다른 줄은 다음과 같습니다:
- from lqabr_core.obs import get_obs, utc_now_iso
+ from ..obs import get_obs, utc_now_iso
- from lqabr_core.leadgen.secrets import ...
+ from ..secrets import ...모노레포는 여전히 자신의 복사본이 필요합니다. 삭제하지 마십시오.
모듈 | 다른 용도 |
| lead_profile/src 내 8개 파일, text_voice/src 내 2개 파일, |
| lead_profile 내 12개 파일( |
| lead_profile |
결과: 이제 HubSpot으로 동일한 필드 이름과 동일한 HubSpot 속성 이름을 전달하는 두 개의 쓰기 경로가 존재하며, 데이터 계약은 이러한 이름이 계약 그 자체임을 명시합니다. crm.py의 수정, 인증 변경, HubSpot 속성 이름 변경은 모두 수동으로 두 곳에 적용되어야 합니다. 이를 강제하는 것은 없습니다. 이에 대한 예산을 편성하거나, 한쪽을 폐기할 계획을 세우십시오.
Related MCP server: hubspot-mcp-server
이것이 모노레포 외부에 위치하는 이유
LQABR 저장소는 루트에 말 그대로 mcp라는 이름의 최상위 패키지를 가지고 있어, FastMCP가 의존하는 mcp SDK를 가립니다. 저장소 내부에서 실행하면 FastMCP의 자체 가져오기가 중단됩니다.
LQABR 저장소 루트를 PYTHONPATH에 추가하지 마십시오.
라이브러리: 공식 SDK가 아닌 FastMCP
의존성은 fastmcp>=3.4.7입니다. mcp>=2.0을 추가하지 마십시오 — 두 라이브러리는 상호 배타적입니다:
fastmcp3.4.7은mcp<2.0,>=1.24.0을 전이적으로 고정합니다(mcp1.29를 설치함).공식 SDK의 서버 클래스인
MCPServer는mcp>=2.0에만 존재합니다.
따라서 프로젝트는 FastMCP 또는 MCPServer 중 하나만 사용할 수 있으며, 둘 다 사용할 수 없습니다. 이 프로젝트는 FastMCP를 사용합니다. 여기서 MCPServer를 가져오는 코드는 없습니다.
알아두어야 할 두 가지 결과:
전송 이름이 다릅니다. FastMCP의 HTTP 전송은
"http"이며("streamable-http"는 별칭으로 허용됨), 엔드포인트 경로 키워드 인자는path=입니다. 공식 SDK는streamable_http_path=로 표기합니다.타입 필드가 다릅니다.
mcp가 1.x로 고정되어 있기 때문에, 번들된 타입들은 camelCase를 사용합니다:Tool.inputSchema,input_schema가 아닙니다.
모노레포의 lqabr_core/leadgen/server.py는 여전히 MCPServer를 사용합니다. 이는 이제 포크 위에 추가된 두 코드베이스 간의 두 번째 차이점입니다.
실행 방법
uv sync
# stdio — local ADK MCPToolset, or the VSCode config in .vscode/
uv run python hubspot-crm-mcp-server/hubspot_crm_server.py
# HTTP — what Cloud Run runs
uv run python hubspot-crm-mcp-server/hubspot_crm_server.py \
--transport http --host 0.0.0.0 --port 8080자격 증명
tools/list는 아무것도 필요로 하지 않습니다. 도구 호출은 HubSpot 토큰이 필요하며, 이 토큰은 Secret Manager에서 가져옵니다 — 컨텍스트 §7.6 / CLAUDE.md §5: 비밀 정보는 하드코딩되지 않으며 커밋되지 않습니다.
cp .env.example .env # holds mode switches + secret IDs only
gcloud auth application-default login
uv sync --extra gcp --extra test # both extras; --extra gcp alone drops pytest
export UV_ENV_FILE=.env
uv sync --extra <x>는 정확히 해당 추가 세트만 동기화하므로,--extra gcp만으로는 pytest가 제거됩니다.test_server.py는 pytest 없이 CLI로 실행되지만,uv run pytest는 분명히 pytest가 필요합니다.
.env 파일에는 비밀 값이 없습니다 — HUBSPOT_AUTH_MODE, LQABR_SECRET_PROJECT 및 비밀의 ID만 있습니다. 토큰 자체는 런타임에 Secret Manager API를 통해 가져와 메모리에 유지되며, 절대 로깅되지 않습니다(감사 행에는 길이와 마지막 네 글자만 기록됨). 900초 동안 캐시되므로 회전에 재배포가 필요하지 않습니다.
auth.py와 secrets.py는 모두 실패 시 폐쇄(fail closed)됩니다 — 설정되지 않으면 명시적 오류가 발생하며, 암묵적 기본값이 없습니다.
LQABR_SECRET_BACKEND=env는 오프라인 작업이나 CI를 위한 최후의 수단으로 존재합니다.secrets.py는 이를 "로컬 개발, CI 및 테스트 전용"으로 범위를 제한하며, 자동 대체는 없습니다 — 직접 입력해야 합니다. 이는 실제 자격 증명을 디스크의 파일에 저장합니다. Cloud Run에서는 절대 설정하지 마십시오.
모든 플래그에는 환경 변수 기본값(MCP_TRANSPORT, MCP_HOST, PORT, MCP_PATH)이 있으므로, 컨테이너는 인수 없이 시작됩니다 — Cloud Run이 PORT를 주입합니다.
테스트
uv run pytest # 61 tests, all passing, none touch real HubSpotpytest.ini는 hubspot-crm-mcp-server/를 경로에 추가하여 import hubspot_mcp가 해결되도록 합니다 — 폴더 자체는 하이픈 때문에 패키지가 될 수 없습니다.
계약은 10개 필드, 9개가 아닙니다
LeadProfile는 10개 필드를 가집니다: 모두가 문서화하는 9개에 contact_name(이름/성 매핑을 위해 추가됨)이 더해집니다. 모노레포의 test_wrapper_shape_is_the_nine_fields_plus_ids는 여전히 9개를 주장하고 있었으며, 그곳에서 실패하고 있었습니다 — schema.py는 바이트 단위로 동일하므로 이 프로젝트가 이를 상속했습니다.
2026-08-18에 해결됨: 코드는 올바르고, 숫자는 오래된 것이었습니다. 테스트 이름이 test_wrapper_shape_is_the_contract_fields_plus_ids로 변경되었으며, 이제 개수 대신 필드 이름을 주장하므로, 다음 추가 시 읽을 수 있는 오류가 발생합니다.
동일한 수정이 모노레포에도 여전히 필요합니다 — 그곳의 주장은 변경되지 않았으며 여전히 실패 상태입니다. "9개 필드"라고 말하는 문서도 수정되어야 합니다.
배포된 서버 테스트
# local
uv run python hubspot-crm-mcp-server/test_server.py
# Cloud Run — mints a Google ID token via ADC
uv run python hubspot-crm-mcp-server/test_server.py \
--url https://lqabr-mcp-server-xxxx.a.run.app/mcp --auth google
# one real read against HubSpot — writes nothing
... --auth google --employee-id EMP-00042설계상 읽기 전용: upsert_lead_profile을 호출하지 않습니다. 서버의 감사 로그가 호출을 귀속시킬 수 있도록 X-LQABR-Run-Id를 전송합니다(B10 수정).
ID 토큰 대상(audience)은 서비스 기본 URL에서
/mcp를 제외한 것입니다. 스크립트가 자동으로 제거합니다.
클라이언트는 fastmcp.Client를 사용하며, 이 클라이언트가 초기화 핸드셰이크를 처리하므로 이 파일에는 세션 배관이 없습니다. 헤더는 StreamableHttpTransport에 실려 있습니다. 이제 참조 샘플의 라이브러리와 일치합니다.
Cloud Run에 배포
2단계 uv 빌드, 비루트 mcp 사용자, PID 1은 Python이므로 SIGTERM이 깔끔하게 드레인됩니다. 자체 포함: 형제 폴더나 git 의존성이 없습니다.
docker build -t lqabr-mcp-server .uv.lock을 커밋하고, 프로덕션 전에 동기화를 --frozen으로 전환하십시오.
그런 다음 S5–S8: mcp-server-sa 생성, lqabr-hubspot-access-token에 secretmanager.secretAccessor 권한 부여, --no-allow-unauthenticated로 배포, 세 개의 에이전트 서비스 계정에 roles/run.invoker 부여, test_server.py를 해당 서버로 지정하십시오.
노출된 도구
도구 | 방향 | 참고사항 |
| 쓰기 | 회사 upsert → 연락처 upsert → 연결. 멱등성(idempotent). |
| 읽기 | 계약 필드 + |
중복 제거: 연락처는 employee_id, 회사는 company_id 기준. 이메일은 사용자 정의 email_id 속성에 저장됩니다.
미결 사항. 등록된 도구 이름은
upsert_lead_profile(단수)이지만, 설계 문서, 세션 핸드오프 및 프로젝트 지침은 모두upsert_lead_profiles(복수)라고 말하며, 기본 함수는 복수입니다. 이는 유선 계약입니다 — 클라이언트가 연결되기 전에 해결하십시오.
자격 증명
두 가지이며, 혼동되지 않습니다:
Google ID 토큰은 에이전트 → 이 서버를 증명합니다(Cloud Run 서비스 간).
HubSpot M2M 토큰은 이 서버 → HubSpot을 증명하며, 서버 내부에서 호출 시마다 발급됩니다. 호출자는 절대 이를 볼 수 없습니다.
이 서비스는 HubSpot 자격 증명의 유일한 보유자입니다.
검증됨
오직 fastmcp 3.4.7(mcp 1.29를 가져옴), requests 및 pytest만 포함된 깨끗한 가상 환경에서 — lqabr_core가 없고(ModuleNotFoundError 확인됨), MCPServer가 없고(ImportError 확인됨) — 다음을 확인했습니다:
프로젝트 어디에도
lqabr_core가져오기가 없음이식된 테스트 스위트: 61개 통과, 0개 실패
stdio —
tools/list가 두 도구를 모두 반환,PYTHONPATH가 완전히 제거됨--transport http— 호스트/포트/경로에 바인딩, 전체fastmcp.Client세션--transport streamable-http— 별칭 허용, 동일한 엔드포인트 제공test_server.py— 실행 중인 서버에 대해 PASS, 종료 코드 0test_server.py를 pytest로 실행 — 서버가 있을 때 3개 통과, 없을 때 3개 건너뜀실제
call_tool이 실제 체인에 도달: 전송 → 도구 →crm.py→auth.py→secrets.py, 의도적인AuthConfigError/SecretConfigError가드에서만 실패(테스트 환경에 GCP 구성이 없음). 전체 연결이 종단 간 입증되었습니다.
검증되지 않은 것: Docker 이미지는 한 번도 빌드되지 않았습니다 — 이 파일들이 조합된 곳에서 Docker 데몬을 사용할 수 없었습니다. 실제 HubSpot을 건드린 것은 없으며, 모든 테스트는 가짜(fake)를 사용합니다.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityDmaintenanceEnables comprehensive HubSpot CRM integration through the Model Context Protocol with 15+ tools for managing contacts, companies, and deals. Supports multiple transport protocols (HTTP, SSE, STDIO) with session management and real-time access to CRM data.3MIT
- AlicenseAqualityBmaintenanceEnables interaction with HubSpot CRM through MCP, providing tools to manage contacts, companies, deals, and search/associations via natural language.18182MIT
- Flicense-qualityDmaintenanceImplements Universal Commerce Protocol (UCP) primitives backed by HubSpot CRM, enabling buyer profile, product catalog, cart, and order operations via MCP tools.
- AlicenseAqualityBmaintenanceEnables AI agents to safely operate HubSpot CRM contacts, deals, and pipelines via MCP, with caching, idempotency, audit trails, and robust error handling.15MIT
Related MCP Connectors
LeadConnector / GoHighLevel MCP Pack — wraps the GoHighLevel CRM for AI agents.
Operator-as-agent MCP hub. 6 tools. First $5 free, then $0.001/call.
MCP Hub: AI service discovery, per-user OAuth, and multi-service workflow orchestration
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/bsmahi/LQABR_MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server