AI Agents Analytics

Google Analytics MCP 서버 만드는 법

Alejandro Rioja
Alejandro Rioja
5 분 읽기
TL;DR

먼저 Google이 직접 만든 GA4 MCP 서버를 써 보세요. 실험 단계이고, Python으로 로컬에서 실행되며, 내 컴퓨터에서 GA4를 쓰는 용도라면 충분합니다. 직접 만들려면 MCP TypeScript SDK와 @google-analytics/data로 run_report 도구 하나를 작성하고, gcloud와 analytics.readonly 범위로 로그인한 뒤, claude mcp add로 등록하면 됩니다. 어려운 부분은 다른 사람을 위해 호스팅할 때입니다. MCP의 OAuth 흐름, 민감한 범위에 대한 Google의 인증(인증되지 않은 앱은 사용자 100명 제한), 그리고 Data API의 속성별 할당량 안에 머물기 위한 캐싱이 필요합니다.

무료 뉴스레터

매주 수요일. 28,400명+ 구독자. 핵심만.

내 노트북에서 돌아가는 GA4 MCP 서버는 오후 한나절이면 만듭니다. 다른 사람이 로그인해서 쓸 수 있는 서버는 훨씬 큰 일입니다. 이 가이드는 한나절 버전을 먼저 드리고, 큰 버전에 무엇이 필요한지 정리합니다. 어느 쪽이 필요한지는 그걸 보고 정하세요.

목차

목차 열기

먼저 공식 서버를 확인하세요

Google은 자체 Google Analytics MCP 서버를 공개하고 있으며, 아직 실험 단계로 표시되어 있습니다. 내 컴퓨터에서 Python으로 실행되고, 쓰기 전에 Google Cloud 프로젝트에서 Google Analytics Admin API와 Data API를 사용 설정해야 합니다. run_report, run_realtime_report, run_funnel_report는 물론 계정, 속성, 맞춤 측정기준, Google Ads 연결을 조회하는 도구도 이미 들어 있습니다. GA4만, 그것도 내 컴퓨터에서만 필요하다면 이걸 쓰세요.

bash
gcloud auth application-default login \
  --scopes https://www.googleapis.com/auth/analytics.readonly,https://www.googleapis.com/auth/cloud-platform \
  --client-id-file=YOUR_CLIENT_JSON_FILE

pipx run analytics-mcp

Google의 설정 페이지에서 Cloud 프로젝트 준비 과정을 단계별로 안내하고, README에는 Claude Code용 claude mcp add 명령이 정확히 나와 있습니다. 호스팅 버전은 없으므로 Python을 실행할 수 있는 곳에서만 작동합니다.

내 질문에 맞춘 도구가 필요할 때, 여러 데이터 소스를 한 번의 답변에 담고 싶을 때, 팀이나 클라이언트도 쓸 수 있는 서버가 필요할 때는 직접 만드세요.

준비물

  • Google Analytics Data API를 사용 설정한 Google Cloud 프로젝트(5분이면 됩니다).
  • 그 프로젝트에서 만든 데스크톱 앱용 OAuth 클라이언트 ID(JSON으로 다운로드). --client-id-file이 가리키는 파일이 바로 이것입니다.
  • Node 22 이상. 현재 @google-analytics/data 패키지가 요구하는 버전입니다.
  • 로그인할 Google 계정에 GA4 속성 뷰어 권한.

1단계: 어떤 보고서든 실행하는 도구 하나

run_report 도구 하나로 시작하세요. Claude는 이미 GA4의 측정항목과 측정기준 이름을 알고 있어서, 유연한 도구 하나로 대부분의 질문을 처리할 수 있습니다. 실제로 어떤 질문을 하는지 보이기 시작하면 그때 더 좁은 도구로 나누면 됩니다.

폴더를 만들고 한 번만 로그인합니다. 두 번째 gcloud 명령은 빼먹지 마세요. Google의 Analytics API는 할당량 프로젝트가 지정되지 않은 사용자 인증 정보를 거부합니다.

bash
mkdir ga4-mcp && cd ga4-mcp
npm init -y && npm pkg set type=module
npm install @modelcontextprotocol/sdk @google-analytics/data zod

gcloud auth application-default login \
  --scopes https://www.googleapis.com/auth/analytics.readonly,https://www.googleapis.com/auth/cloud-platform \
  --client-id-file=YOUR_CLIENT_JSON_FILE
gcloud auth application-default set-quota-project YOUR_PROJECT_ID

그다음 아래 코드를 ga4.ts로 저장합니다.

typescript
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { BetaAnalyticsDataClient } from '@google-analytics/data';
import { z } from 'zod';

const ga = new BetaAnalyticsDataClient(); // Application Default Credentials
const server = new McpServer({ name: 'ga4', version: '1.0.0' });

server.registerTool(
  'run_report',
  {
    description:
      'Run a GA4 report. Uses GA4 Data API metric and dimension names. ' +
      'Dates accept YYYY-MM-DD, "28daysAgo", "yesterday", "today".',
    inputSchema: {
      propertyId: z.string().describe('Numeric GA4 property ID, e.g. 123456789'),
      metrics: z.array(z.string()).describe('e.g. ["sessions", "engagedSessions"]'),
      dimensions: z.array(z.string()).default([]).describe('e.g. ["sessionDefaultChannelGroup"]'),
      startDate: z.string().default('28daysAgo'),
      endDate: z.string().default('today'),
    },
  },
  async ({ propertyId, metrics, dimensions, startDate, endDate }) => {
    const [res] = await ga.runReport({
      property: `properties/${propertyId}`,
      dateRanges: [{ startDate, endDate }],
      metrics: metrics.map((name) => ({ name })),
      dimensions: dimensions.map((name) => ({ name })),
      limit: 100,
    });
    // Turn GA's nested rows into plain { dimension: value, metric: value } objects.
    const rows = (res.rows ?? []).map((row) => {
      const out: Record<string, string> = {};
      row.dimensionValues?.forEach((v, i) => (out[dimensions[i]] = v.value ?? ''));
      row.metricValues?.forEach((v, i) => (out[metrics[i]] = v.value ?? ''));
      return out;
    });
    return { content: [{ type: 'text', text: JSON.stringify({ rowCount: res.rowCount, rows }) }] };
  },
);

await server.connect(new StdioServerTransport());

파일에는 키가 전혀 없습니다. 클라이언트는 gcloud가 방금 저장한 로그인 정보를 쓰고, 모든 호출은 내 계정으로, 내 뷰어 권한으로 실행됩니다.

2단계: Claude에 추가하기

Claude Code에서는 명령 하나로 등록됩니다. 파일은 전체 경로로 지정하세요. --scope user를 붙이면 모든 프로젝트에서 쓸 수 있고, 빼면 명령을 실행한 폴더에서만 불러옵니다.

bash
claude mcp add --scope user ga4 -- npx -y tsx /full/path/to/ga4-mcp/ga4.ts

그런 다음 이렇게 물어보세요. “속성 123456789에서 지난달 참여 세션이 가장 많았던 채널은 어디야?” Claude가 측정항목을 고르고, 도구를 호출하고, 결과 행을 설명해 줍니다. Claude Desktop에서는 같은 서버를 설정 파일에 넣습니다. 파일 위치는 첫 MCP 서버 만들기 가이드에 나와 있습니다.

3단계: 어려워지는 지점

지금까지는 모두 내 계정으로, 내 컴퓨터에서 실행됩니다. 다른 곳에서 돌려야 하는 순간 이런 것들이 달라집니다.

  1. 호스팅과 OAuth. claude.ai와 모바일 앱은 내 노트북에 있는 서버에 접근할 수 없습니다. 호스팅하는 서버에는 사용자마다 자기 Google 계정으로 로그인하도록 MCP의 OAuth 흐름이 필요하고, 사용자들의 리프레시 토큰을 안전하게 보관할 곳도 있어야 합니다.
  2. Google의 앱 인증. analytics.readonly는 민감한 범위입니다. Google이 앱을 인증하기 전까지 모든 사용자에게 “확인되지 않은 앱” 경고가 뜨고, 사용자는 100명으로 제한됩니다. 인증을 받으려면 내 도메인에 올린 개인정보처리방침, 로그인 과정을 보여주는 데모 영상, 범위별 서면 사유, 그리고 심사가 필요합니다.
  3. 할당량. Data API는 속성별로 토큰을 계산합니다. 표준 속성은 시간당 40,000, 하루 200,000이며, Cloud 프로젝트 하나가 속성별로 쓸 수 있는 양은 시간당 최대 14,000, 동시 요청은 10개까지입니다. 대부분의 요청은 10토큰 이하입니다. 하지만 기간이 길거나, 측정기준이 많거나, 트래픽이 많은 속성은 더 많이 들고, 에이전트는 GA4 화면을 클릭하는 사람보다 훨씬 빠르게 보고서를 요청합니다. 호스팅하면 모든 호출이 내 프로젝트 몫에서 빠져나가니, returnPropertyQuota: true를 추가해 요청마다 비용을 확인하고, 반복되는 결과는 캐시하고, 보고서는 작게 유지하세요.

SiteWide는 호스팅과 로그인을 대신 처리합니다. Google 인증은 아직 진행 중이라, 지금은 SiteWide에서도 GA4에 같은 확인되지 않은 앱 화면이 나옵니다. 이런 걸 직접 만들고 싶지 않다면 SiteWide를 연결하세요.

Claude에게 만들게 하기

빈 폴더에서 Claude Code를 열고 이걸 붙여 넣으세요. 코드가 영어라서 프롬프트도 영어 그대로 두었습니다.

code
Build me a TypeScript MCP server for Google Analytics 4 using @modelcontextprotocol/sdk and @google-analytics/data. Give it one tool, run_report, that takes a property id, metrics, dimensions and a date range. Authenticate with Application Default Credentials. Then give me the exact gcloud command to log in with the analytics.readonly scope, and register the server with `claude mcp add`. Don't invent metric names: link me to Google's API schema page so I can check them.

결과를 믿기 전에, 사용된 측정항목과 측정기준을 하나하나 Google의 API 스키마 페이지와 대조하세요. 지어낸 이름은 코드에서는 멀쩡해 보이다가 API가 거부할 때에야 실패합니다.

광고
계속 읽기

관련 게시물

계속 읽기

AI 플레이북을 받아보세요

매주 수요일. 28,400명+ 구독자. 핵심만.

↵ ↵ 전체 결과 보기 esc esc 닫기