Metadata-Version: 2.5
Name: tvpulse-mcp
Version: 1.0.0
Summary: Local (stdio) MCP server exposing the TVPulse customer API to MCP clients such as Claude Code.
Project-URL: Homepage, https://gateway.tvpulse.io/apidocs
Project-URL: Repository, https://gitlab.imind.dev/tvpulse/tvpulse
Author-email: InfiniMind <support@infinimind.io>
License: Proprietary
Keywords: claude-code,mcp,model-context-protocol,tvpulse
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: mcp<2.0.0,>=1.6.0
Requires-Dist: tvpulse<2,>=1.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.20; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# tvpulse-mcp

TVPulse カスタマーAPI（日本のテレビCM/露出分析SaaS）を Claude Code などの MCP クライアントから
ローカル（stdio）で使うための MCP サーバーです。

## これは何か

`/v1/api/searches`（検索定義＋投影）を土台に、1回の課金付き検索作成のあとに無料の集計・証跡取得を
組み合わせた12個のツールを公開します。生のOCR/ASR検索を都度課金する方式ではなく、1つの質問に対して
1回の検索を作成し、トレンド・内訳・番組・証跡をまとめて返します。支出はすべて人の承認を経てから実行
されます（下記「承認フローと予算」）。

## インストール

3つの方法があります。迷ったら **Claude Codeプラグイン**（設定不要でAPIキーを安全に保存）を
おすすめします。

### 方法1: Claude Codeプラグイン（推奨）

```
/plugin marketplace add https://tvpulse.io/claude/marketplace.json
/plugin install tvpulse@tvpulse
```

Claude Code バージョン 2.1.224 以降が必要です。インストール時にAPIキーの入力を求められます
（安全に保存され、チャット欄には表示されません）。承認しきい値・セッション予算はデフォルト値
（20クレジット / 200クレジット）のままで構いません。監視スキルも同時にインストールされます。
詳細は [distribution/claude-plugin/README.md](distribution/claude-plugin/README.md) を
参照してください。

前提条件: [uv](https://docs.astral.sh/uv/) がインストールされていること（`uvx` を使用します）。

### 方法2: Claude Desktop拡張機能（.mcpbバンドル）

[https://tvpulse.io/claude/tvpulse.mcpb](https://tvpulse.io/claude/tvpulse.mcpb) から
`tvpulse.mcpb` をダウンロードし、ダブルクリックするか Claude Desktop の
「設定 > 拡張機能 > ローカルにインストール」から追加してください。初回起動時にAPIキーの入力を
求められます。前提条件は方法1と同じく `uv`/`uvx` です。

### 方法3: 手動セットアップ（Claude Code、バージョン固定インストール）

```bash
uvx tvpulse-mcp==1.0.0
```

Claude Code に直接登録する場合:

```bash
claude mcp add tvpulse \
  -e TVPULSE_API_KEY=your-api-key \
  -e TVPULSE_CONFIRM_ABOVE_CREDITS=20 \
  -e TVPULSE_SESSION_BUDGET_CREDITS=200 \
  -- uvx tvpulse-mcp==1.0.0
```

APIキーは環境変数で渡してください（チャット欄に貼り付けないでください）。開発環境（dev gateway）に
向ける場合は `TVPULSE_BASE_URL` を追加します:

```bash
claude mcp add tvpulse \
  -e TVPULSE_API_KEY=your-dev-api-key \
  -e TVPULSE_BASE_URL=https://gateway.dev.tvpulse.io \
  -e TVPULSE_CONFIRM_ABOVE_CREDITS=20 \
  -e TVPULSE_SESSION_BUDGET_CREDITS=200 \
  -- uvx tvpulse-mcp==1.0.0
```

`TVPULSE_BASE_URL` を省略した場合は本番 `https://gateway.tvpulse.io` を使います
(`tvpulse.client.DEFAULT_BASE_URL` と同じ値)。

### APIキーをまだお持ちでない場合

いずれの方法でも、APIキー未設定のまま `tvpulse_check_connection` などのツールを呼び出すと、
発行手順（https://tvpulse.io/account/api-keys ）と、お使いのクライアント別の設定方法を案内する
日本語メッセージが返ります。

登録後、最初にこう聞いて接続を確認してください:

```
TVPulseに接続できているか確認して
```

これは無料の `tvpulse_check_connection` を呼び出し、APIキーの有効性・接続先・残高・設定済み予算を
表示します。

## 承認フローと予算

`tvpulse_search_mentions` と課金付き `tvpulse_export_records_create` は次の順で承認を経ます:

1. まず見積もり（無料）を取り、`interpretation`（キーワード/モード、日本語の局名と地域、明示的な
   JST期間、CMポリシー）を必ず提示します。
2. 見積額が `TVPULSE_CONFIRM_ABOVE_CREDITS`（既定20クレジット）以下なら、そのまま実行します。
3. それを超える場合、MCP elicitation でユーザーに直接確認するか、クライアントが対応していなければ
   `needs_confirmation` と `confirm_token`（10分間有効、1回限り）を返します。ユーザーが承認したら、
   同じツールを `confirm_token` を添えて再実行してください。
4. `TVPULSE_SESSION_BUDGET_CREDITS`（既定200クレジット、このセッション累計の上限）を超える場合は、
   何を渡しても上書きできない拒否になります。より多く使いたい場合は、より大きな値でセッションを
   再起動してください。
5. `outcome=enterprise_review` は予算の問題ではなく個別見積もりが必要な料金区分です。クレジットを
   増やしても解決しません。

**重要**: どちらの上限もツール引数では絶対に上げられません（環境変数のみ）。1回の呼び出しに渡せる
値があるとすれば、それは上限を下げる方向にしか使えない設計です。

## ツール一覧

| ツール | 課金 | ゲートウェイルート |
|---|---|---|
| `tvpulse_check_connection` | 無料 | `GET /v1/api/credits`（キー検証を兼ねる） |
| `tvpulse_list_channels` | 無料 | なし（静的カタログ） |
| `tvpulse_estimate` | 無料 | `POST /v1/api/credits/estimate` |
| `tvpulse_search_mentions` | 課金あり（承認フロー経由） | `POST /v1/api/searches` + `GET .../trend,breakdown,programs,evidence` |
| `tvpulse_get_evidence` | 無料 | `GET /v1/api/searches/{id}/evidence` |
| `tvpulse_get_search_results` | 無料 | `GET /v1/api/searches/{id}/{trend,breakdown,programs,evidence}`（再取得） |
| `tvpulse_save_evidence_csv` | 無料（ローカルファイル書き込み） | `GET /v1/api/searches/{id}/evidence`（ページング） |
| `tvpulse_credits_balance` | 無料 | `GET /v1/api/credits` |
| `tvpulse_export_records_create` | dry_run=falseで課金（承認フロー経由） | `POST /v1alpha1/exports` |
| `tvpulse_export_records_status` | 課金あり（ポーリング毎、失敗時も返金なし） | `GET /v1alpha1/exports/{export_id}` |
| `tvpulse_trend_reports_list` | 無料 | `GET /v1alpha1/trend-watch/catalog/reports` |
| `tvpulse_trend_reports_get` | 無料 | `GET /v1alpha1/trend-watch/catalog/reports/{id}` |

### クレジットと制限に関する注意

- OCR（画面内テキスト）とASR（音声）の件数は単位が異なるため、常に別々に返され、合算されません。
- 対応局は地上波15局（東京7局＋大阪8局）のうち、プリセット `tokyo`（7局）または `osaka`
  （`sun` を含む8局）、あるいは最大14局までの明示指定です。15局すべてを一度に指定すると常に
  `custom_pricing_required` エラーになります（自動的に14局へ絞り込まれることはありません）。
- `sampled_programs` は返された証跡からサンプリングされた番組であり、ランキングでも全放送の
  網羅的な記録でもありません。
- 投影（trend/breakdown/sampled_programs/evidence）がまだ計算中の場合は `0` や空配列ではなく
  `{"status": "unavailable", "reason": ...}` として返されます。`tvpulse_get_search_results`
  （無料）で再取得してください。
- `tvpulse_export_records_status` のポーリングは呼び出すたびに課金され、ジョブが失敗しても
  返金されません。同じ `export_id` へのポーリングは30秒以上間隔を空ける必要があります
  （それより短い間隔はツール側で拒否します）。
- 同一セッション内で全く同じ検索条件を再度呼び出した場合、新規課金せずに既存の `search_id` を
  無料で返します（`refresh=true` で強制的に再見積もり・再実行）。
- 課金系ツールは自動リトライしません（二重課金防止）。実行ごとに専用の Idempotency-Key を使用します。

### 監視スキルの導入

Claude Codeプラグイン（方法1）を使う場合、スキルは自動的にインストールされます。手動セットアップ
（方法3）の場合は、`skill/tvpulse-tv-monitoring/` を Claude Code がスキルを読み込む場所へコピーして
ください:

```bash
cp -r skill/tvpulse-tv-monitoring ~/.claude/skills/tvpulse-tv-monitoring
# or, project-scoped:
cp -r skill/tvpulse-tv-monitoring .claude/skills/tvpulse-tv-monitoring
```

Claude Desktop（方法2）の場合は `sdks/mcp/scripts/sync-distribution.sh` が作成する
`distribution/skill-build/tvpulse-tv-monitoring.zip` を「設定 > Capabilities > Skills」から
アップロードしてください。

## トラブルシューティング

- **「APIキーが設定されていません」と出る**: いずれかの方法でAPIキーを設定してください
  （プラグイン/拡張機能ならインストール時のプロンプト、手動セットアップなら
  `TVPULSE_API_KEY` 環境変数）。`tvpulse_check_connection` を呼ぶとキーの発行先URLと、
  お使いのクライアント別の設定手順が日本語で表示されます。
- **「APIキーが無効です」「401」エラー**: キーが失効・削除されている可能性があります。
  https://tvpulse.io/account/api-keys で新しいキーを発行し、設定し直してください。未設定時とは
  別の、無効キー専用のメッセージが表示されます。
- **`uv`/`uvx` が見つからない**: https://docs.astral.sh/uv/getting-started/installation/
  の手順でインストールしてください。全3つのインストール方法が `uvx` を前提としています。
- **承認プロンプトが表示されない / `confirm_token` が使えない**: MCP elicitationに対応していない
  クライアントでは、承認が必要な呼び出しは実行されず `needs_confirmation` と `confirm_token`
  （10分間有効、1回限り）が返るだけです。表示された内容を確認したうえで、同じツールを
  `confirm_token` を添えて再実行してください。トークンが期限切れの場合は見積もりからやり直します。

---

## English

Local (stdio) MCP server exposing the TVPulse customer API to Claude Code and other MCP
clients, built around `/v1/api/searches`: one billed search-definition create followed
by free trend/breakdown/programs/evidence projections, so one analyst question costs one
charge instead of three. Every spend goes through a human-approval gate before it runs
(see "Approval flow and budgets" below).

### Install

There are three ways to install. If unsure, use the **Claude Code plugin** (no manual
config, API key stored securely).

#### Option 1: Claude Code plugin (recommended)

```
/plugin marketplace add https://tvpulse.io/claude/marketplace.json
/plugin install tvpulse@tvpulse
```

Requires Claude Code 2.1.224 or later. You'll be prompted for your API key at install
time (stored securely, never shown in chat). The confirm-above-credits threshold and
session budget default to 20 and 200 credits. The monitoring skill installs
automatically. See
[distribution/claude-plugin/README.md](distribution/claude-plugin/README.md) for details.

Prerequisite: [uv](https://docs.astral.sh/uv/) installed (provides `uvx`).

#### Option 2: Claude Desktop extension (.mcpb bundle)

Download [tvpulse.mcpb](https://tvpulse.io/claude/tvpulse.mcpb) and double-click
it, or add it via Claude Desktop's Settings > Extensions > Install from file. You'll be
prompted for your API key on first launch. Same `uv`/`uvx` prerequisite as Option 1.

#### Option 3: Manual setup (Claude Code, pinned version)

```bash
uvx tvpulse-mcp==1.0.0
```

```bash
claude mcp add tvpulse \
  -e TVPULSE_API_KEY=your-api-key \
  -e TVPULSE_CONFIRM_ABOVE_CREDITS=20 \
  -e TVPULSE_SESSION_BUDGET_CREDITS=200 \
  -- uvx tvpulse-mcp==1.0.0
```

Set `TVPULSE_API_KEY` via environment, never in chat. For the dev gateway:

```bash
claude mcp add tvpulse \
  -e TVPULSE_API_KEY=your-dev-api-key \
  -e TVPULSE_BASE_URL=https://gateway.dev.tvpulse.io \
  -e TVPULSE_CONFIRM_ABOVE_CREDITS=20 \
  -e TVPULSE_SESSION_BUDGET_CREDITS=200 \
  -- uvx tvpulse-mcp==1.0.0
```

`TVPULSE_BASE_URL` defaults to production (`https://gateway.tvpulse.io`) if unset.

### No API key yet?

With any install method, calling a tool such as `tvpulse_check_connection` without a key
returns a message (Japanese first, then English) with the issuance URL
(https://tvpulse.io/account/api-keys) and per-client setup instructions.

After registering, confirm the connection first by asking:

```
TVPulseに接続できているか確認して
```

(or in English, "check whether TVPulse is connected") -- this calls the free
`tvpulse_check_connection` tool, which validates the API key and shows the base URL,
balance, and configured budgets.

### Approval flow and budgets

`tvpulse_search_mentions` and a non-dry-run `tvpulse_export_records_create` both go
through the same approval gate:

1. Estimate first (free) and always show the `interpretation` block (keyword/mode,
   Japanese station names + region, explicit JST window, CM policy) before spending.
2. At or under `TVPULSE_CONFIRM_ABOVE_CREDITS` (default 20 credits), the call just runs.
3. Above that threshold, the server asks a human directly via MCP elicitation, or -- if
   the connected client doesn't support elicitation -- returns `needs_confirmation` with
   a `confirm_token` (single-use, 10-minute TTL). Once the user approves, re-call the
   same tool with that `confirm_token`.
4. Exceeding `TVPULSE_SESSION_BUDGET_CREDITS` (default 200 credits, cumulative for this
   session) is a hard refusal that no argument can override; restart the session with a
   higher value if more spend is genuinely needed.
5. `outcome=enterprise_review` is a pricing-tier issue, not a budget issue -- raising
   credits will not fix it; the request needs a custom sales quote or a narrower scope.

**Important**: neither ceiling can ever be raised by a tool argument (env vars only). If
a per-call value is ever accepted, it can only lower a ceiling for that call, never
raise it.

### Tools

See the table above (same tools, same routes). Highlights:

- `tvpulse_search_mentions` is the main tool: keyword + JST window + station preset/list
  -> one billed search (after approval), returning separate OCR-observation and
  ASR-segment counts by day and by station, `sampled_programs` (programs seen in the
  sampled evidence, not a ranking), and a capped page of evidence, all timestamps
  normalized to explicit `+09:00` JST strings. Unavailable projections are returned as
  `{"status": "unavailable", "reason": ...}`, never as 0 or an empty list.
- `tvpulse_get_search_results` (free) re-fetches projections for an existing `search_id`
  with bounded backoff, useful when some projections came back unavailable initially.
- `tvpulse_save_evidence_csv` (free, local write) pages already-paid evidence for a
  `search_id` into an Excel-ready CSV: UTF-8 with BOM, JST timestamps, full untruncated
  text, Japanese station names. Refuses to overwrite an existing file unless
  `overwrite=true`.
- `tvpulse_export_records_create` / `tvpulse_export_records_status` are a *different*,
  unfiltered bulk export over `/v1alpha1/exports`: gzip NDJSON, filtered only by
  streams/window/program_title/commercial, with **no keyword filter**. Status polling is
  billed every call and is **not refunded** on failure -- budget accordingly. Use
  `tvpulse_save_evidence_csv` instead if you want a keyword-scoped CSV.
- `visual` search is never exposed by these tools (separate pilot modality/pricing);
  `sources` is limited to `ocr`/`asr`.
- Raw text/voice/combined search and watches (X/news trend-card subscriptions, not TV
  monitoring) are intentionally not exposed in this MCP server -- use the `tvpulse` SDK
  directly if you need them.

### Development

```bash
uv venv --python 3.12 .venv
uv pip install -p .venv/bin/python -e ".[dev]"
.venv/bin/python -m pytest tests/ -q
.venv/bin/python -m ruff check src/ tests/
.venv/bin/python -m mypy src/
```

The `tvpulse` SDK dependency resolves to the local `../python` package during
development via `[tool.uv.sources]` in `pyproject.toml`; the published package requires
`tvpulse>=1.0,<2`.

### Skill install

With the Claude Code plugin (Option 1), the skill installs automatically. For manual
setup (Option 3), bilingual TV-monitoring workflow guidance (cost rules, unit warnings,
coverage limits, JST date-resolution examples) lives in
`skill/tvpulse-tv-monitoring/SKILL.md`. Install it into
`~/.claude/skills/tvpulse-tv-monitoring/` (user-wide) or
`.claude/skills/tvpulse-tv-monitoring/` (project-scoped) to have Claude load it
automatically for TV-monitoring questions.

For Claude Desktop (Option 2), upload the zip produced by
`sdks/mcp/scripts/sync-distribution.sh` at
`distribution/skill-build/tvpulse-tv-monitoring.zip` via Settings > Capabilities > Skills.

## Troubleshooting

- **"No API key configured"**: set one via any install method (the plugin/extension
  prompt at install time, or the `TVPULSE_API_KEY` env var for manual setup). Calling
  `tvpulse_check_connection` shows the issuance URL and per-client setup steps.
- **"Invalid API key" / 401**: the key may be revoked or deleted. Issue a new one at
  https://tvpulse.io/account/api-keys and reconfigure it. This is a distinct message from
  the missing-key case.
- **`uv`/`uvx` not found**: install it from
  https://docs.astral.sh/uv/getting-started/installation/. All three install methods
  require `uvx`.
- **No approval prompt shown / `confirm_token` not accepted**: clients without MCP
  elicitation support won't auto-prompt; a call needing approval returns
  `needs_confirmation` with a `confirm_token` (single-use, 10-minute TTL) instead of
  running. Review what was shown, then re-call the same tool with that `confirm_token`.
  If it has expired, re-estimate and try again.
