feishu-inout について
feishu-inout は、Feishu/Lark のドキュメント、メッセージ、カレンダー、会議、Bitable、グループを操作するスキルです。公式リモート MCP サービスと Open API を併用し、認証設定も案内します。
主な機能
- 01ドキュメントの閲覧と編集
- 02ドキュメントとメッセージの検索
- 03カレンダーと会議の管理
- 04Bitable テーブルの操作
- 05グループチャットの管理
- 06認証情報と OAuth の設定案内
活用シーン
- 01Feishu/Lark ドキュメントの検索や更新
- 02メッセージ送信とチャット履歴の確認
- 03予定や会議スケジュールの管理
- 04Bitable レコードの閲覧や更新
MCP 対応
`https://mcp.feishu.cn/mcp` の公式リモート MCP サービスをメッセージなどの操作に使用します。カレンダー、Bitable、グループ管理には Open API を使用します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ joe960913/ feishu-inout --skill feishu-inoutインストール後、Claude Code で/feishu-inoutを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSE.gitignoreREADME.mdREADME_CN.mdscripts/feishu_mcp.py詳細
Feishu InOut - Feishu/Lark のドキュメント、メッセージ、カレンダー、Bitable、グループ操作
公式 Feishu/Lark リモート MCP サービス(https://mcp.feishu.cn/mcp)と Open API を使って、クラウドドキュメントの操作、メッセージの送信・検索、カレンダーイベントや会議の管理、Bitable(多次元テーブル)の操作、グループチャットの管理を行います。依存関係はなく、純粋な Python で動作します。
セキュリティ:認証情報の取り扱いルール
重要 — 常に以下のルールに従ってください:
- シェルコマンド内に
FEISHU_APP_IDまたはFEISHU_APP_SECRETの値を絶対に直接記述しないでください - App Secret の値をエコー、表示、出力しないでください
- スクリプトコマンドを実行する前に、環境変数が読み込まれていることを確認してください。
echo $FEISHU_APP_IDが空の場合は、まずsource ~/.zshrc(またはsource ~/.bashrc)を実行してください - スクリプトは環境変数から認証情報を自動的に読み込むため、引数として渡す必要はありません
クイックチェック:ユーザーはすでに設定済みですか?
次の2点を確認してください:
- 環境変数
FEISHU_APP_IDとFEISHU_APP_SECRETが設定されていますか?(echo $FEISHU_APP_IDを実行し、空の場合は先にsource ~/.zshrcを実行してください) - 有効な UAT トークンがありますか?(スクリプトの
whoamiコマンドを実行してください)
両方の準備ができている場合は、使い方に進んでください。 どちらかが不足している場合は、ユーザーを初回セットアップに案内してください。
初回セットアップ
ユーザーに次のように伝えてください:「セットアップには約5分かかります。手順を追ってご案内しますので、それぞれの手順が終わったら教えてください。」
開始する前に、ユーザーに尋ねてください:
どの機能が必要ですか?
- 読み取り専用(検索、読み取り、閲覧)— 必要な権限が最小限で、セットアップも最速です
- 読み取りと書き込み(+作成、編集、コメント)— 推奨。ほとんどの用途に対応します
- すべての機能(+メッセージの送信・検索、カレンダー・会議、Bitable、グループ管理)— メッセージ機能はユーザーの ID(UAT)を使った MCP、カレンダー・Bitable・グループ機能は Open API を使用します
ユーザーの選択に応じて、ステップ2で該当する権限文字列を表示してください。ステップ6(ボット機能)は、どの選択肢でも任意であることを伝えてください。
ユーザーの選択に対応する権限文字列を必ず表示してください:
選択肢1(読み取り専用):
docx:document:readonly,search:docs:read,wiki:wiki:readonly,im:chat:read,task:task:read
選択肢2(読み取りと書き込み、推奨):
docx:document:readonly,search:docs:read,wiki:wiki:readonly,im:chat:read,task:task:read,docx:document,docx:document:create,docx:document:write_only,docs:document.media:upload,docs:document.media:download,wiki:node:read,wiki:node:create,docs:document.comment:read,docs:document.comment:create,contact:user:search,contact:contact.base:readonly,contact:user.base:readonly,board:whiteboard:node:read,drive:drive
選択肢3(すべての機能):
docx:document:readonly,search:docs:read,wiki:wiki:readonly,im:chat:read,task:task:read,docx:document,docx:document:create,docx:document:write_only,docs:document.media:upload,docs:document.media:download,wiki:node:read,wiki:node:create,docs:document.comment:read,docs:document.comment:create,contact:user:search,contact:contact.base:readonly,contact:user.base:readonly,board:whiteboard:node:read,drive:drive,im:message,im:message:send_as_bot,im:chat,search:message,im:message.send_as_user,im:message.p2p_msg:get_as_user,im:message.group_msg:get_as_user,calendar:calendar:readonly,calendar:calendar,bitable:app:readonly,bitable:app,im:chat:create
後から追加機能を利用する際に再認可が必要にならないよう、すべての権限を一度に有効にすること(選択肢3)を推奨してください。ユーザーが最小限の権限を希望する場合は、該当する選択肢を表示してください。
ユーザーに、文字列をオープンプラットフォーム → 権限管理 → 一括インポート/エクスポートに貼り付けるよう案内してください。
重要:一括インポート後、以下の表で「承認が必要」と記されている一部の権限(im:message.send_as_user、search:message、im:message.p2p_msg:get_as_user、im:message.group_msg:get_as_user など)には、管理者の承認が必要であることをユーザーに伝えてください。承認を待つ間も、その他の機能は通常どおり利用できます。ユーザーはすぐにドキュメント、コメント、カレンダー、Bitable を使い始められます。
手順は全部で6つです。次の手順に進む前に、各手順が完了したことを確認してください。
ステップ1:Feishu/Lark アプリを作成する
- Lark Open Platform(中国: open.feishu.cn)にアクセスしてログインします
- 右上の カスタムアプリを作成 をクリックします
- アプリ名(「My Doc Assistant」など、任意の名前)と説明を入力します
- 作成後、アプリの詳細ページに移動します
- 認証情報と基本情報ページで、以下を確認します:
- App ID(形式:
cli_xxxxxxxxxxxxxxxx) - App Secret(英数字の文字列)
- App ID(形式:
これらを環境変数として設定するようユーザーに伝えてください(ステップ4を参照)。ユーザーに App Secret をあなたに送ったり、会話に貼り付けたりさせないでください。
手順 2:API 権限を有効にする
アプリ → 権限管理 → 一括インポート/エクスポートに移動し、上記のユーザーの選択肢に対応する権限文字列を貼り付けます。
または、個別に有効にします。
コア(必須):
| Scope | Description | Auth Type |
|---|---|---|
docx:document:readonly | ドキュメントを表示 | App |
search:docs:read | ドキュメントを検索 | User |
wiki:wiki:readonly | Wiki を表示 | User + App |
im:chat:read | チャット情報を表示 | App |
task:task:read | タスクを表示 | App |
書き込み/編集(追加、置換、挿入、上書き、削除、ドキュメント作成):
| Scope | Description | Auth Type |
|---|---|---|
docx:document | ドキュメントを表示・編集 | App |
docx:document:create | ドキュメントを作成 | App |
docx:document:write_only | ドキュメントを書き込み | App |
docs:document.media:upload | 画像をアップロード | App |
wiki:node:read | Wiki ノードを表示 | App |
wiki:node:create | Wiki ノードを作成 | App |
コメント(コメントの取得、追加):
| Scope | Description | Auth Type |
|---|---|---|
docs:document.comment:read | コメントを読む | App |
docs:document.comment:create | コメントを作成 | App |
ユーザー(ユーザーの検索、取得):
| Scope | Description | Auth Type |
|---|---|---|
contact:user:search | ユーザーを検索 | User |
contact:contact.base:readonly | 連絡先情報 | App |
contact:user.base:readonly | ユーザー情報 | App |
ファイル(ファイルの取得):
| Scope | Description | Auth Type |
|---|---|---|
docs:document.media:download | 画像/添付ファイルをダウンロード | App |
board:whiteboard:node:read | ホワイトボードを表示 | App |
drive:drive | ドライブファイルを管理 | App |
メッセージ(メッセージの送信、返信、取得、検索など):
| Scope | Description | Auth Type |
|---|---|---|
im:message | メッセージを管理 | App |
im:message:send_as_bot | ボットとして送信 | App |
im:chat | チャットを管理 | App |
search:message | メッセージを検索 | User(承認が必要) |
im:message.send_as_user | ユーザーとして送信 | User(承認が必要) |
im:message.p2p_msg:get_as_user | ダイレクトメッセージの履歴を読む | User(承認が必要) |
im:message.group_msg:get_as_user | ユーザーとしてグループチャットのメッセージを読む | User(承認が必要) |
カレンダー/会議(イベントの作成、一覧表示):
| Scope | Description | Auth Type |
|---|---|---|
calendar:calendar:readonly | カレンダーを表示 | User |
calendar:calendar | カレンダーとイベントを管理 | User |
Bitable/多次元テーブル(テーブルの一覧表示、レコードの一覧表示、作成、更新):
| Scope | Description | Auth Type |
|---|---|---|
bitable:app:readonly | Bitable データを表示 | User |
bitable:app | Bitable データを管理 | User |
グループ管理(グループの作成、メンバーの追加、グループの一覧表示):
| Scope | Description | Auth Type |
|---|---|---|
im:chat:create | グループを作成 | App |
注:メッセージ、カレンダー、Bitable、グループ管理の権限は、ユーザーが「すべての機能」を選択した場合にのみ有効にする必要があります。メッセージ機能は UAT(ユーザー ID)を使用して公式 MCP 経由で動作します。ボット機能は任意であり、必須ではありません。カレンダー、Bitable、グループ管理は Open API を使用します。
有効にした後、「User」タイプの権限に「ユーザーの範囲と一致」と表示されるのは正常です。「App」タイプに「-」と表示されるのも正常です。
すべての権限が ✅ 有効 と表示されていることを確認します。
手順 3:リダイレクト URL を追加する(OAuth 用)
アプリ → セキュリティ設定 → リダイレクト URL に移動し、次を追加します。
http://localhost:9876/callback
これは、ユーザーアクセストークン(UAT)を取得するための OAuth コールバック URL です。
ステップ 4:環境変数を設定する
ユーザー自身で認証情報を設定するよう案内します。ユーザーに App Secret を送らせないでください。また、会話内で認証情報の値を出力したり、そのまま繰り返したりしないでください。
ユーザーの OS に応じて設定します。
macOS / Linux:
echo 'export FEISHU_APP_ID="your_app_id"' >> ~/.zshrc
echo 'export FEISHU_APP_SECRET="your_app_secret"' >> ~/.zshrc
source ~/.zshrc
Windows (PowerShell):
[System.Environment]::SetEnvironmentVariable('FEISHU_APP_ID', 'your_app_id', 'User')
[System.Environment]::SetEnvironmentVariable('FEISHU_APP_SECRET', 'your_app_secret', 'User')
設定後、ターミナルまたは IDE を再起動してください。
確認(App ID のみ。Secret は絶対に出力しないでください):
- macOS/Linux:
echo $FEISHU_APP_ID - Windows:
echo $env:FEISHU_APP_ID
ステップ 5:OAuth ログインで UAT を取得する
ログインコマンドを実行します。
python3 ~/.claude/skills/feishu-inout/scripts/feishu_mcp.py login
手順:
- スクリプトがブラウザーで Feishu/Lark の認証ページを開きます
- 「権限が不足しています」と表示された場合、ブラウザーに不足している権限が正確に表示されます。オープンプラットフォームでその権限を有効にして「再試行」をクリックしてください。一度にすべての権限を有効にする必要はありません
- ユーザーがブラウザーで認証をクリックします
- ブラウザーに「認証に成功しました。このページを閉じてかまいません」と表示されます
- ターミナルに
UAT saved!と表示されたら完了です
トークンの有効期限は 2 時間です。スクリプトは refresh_token を使って自動的に更新します。期限切れから時間が経ちすぎている場合は、login を再実行してください。
準備が整っていることを確認します。
python3 ~/.claude/skills/feishu-inout/scripts/feishu_mcp.py whoami
python3 ~/.claude/skills/feishu-inout/scripts/feishu_mcp.py search-doc "test"
ステップ 6:ボット機能(任意)
MCP 経由のメッセージ送信には UAT(ユーザー ID)が使われるため、メッセージの送受信にボット機能は必要ありません。send-message MCP ツールはボットではなく、認証済みのユーザーとしてメッセージを送信します。
ただし、ボット ID を使いたい場合(例:ボットとして自動通知を送信する場合)は、任意で有効にできます。
- アプリに移動し、機能を追加 → ボットを有効にします
- バージョン管理とリリースに移動し、バージョンを作成して承認を申請します
- 承認後、対象のグループにボットを追加します
この手順は完全に任意です。自分自身としてメッセージを送信するだけであれば、省略してください。
セットアップ完了!
すべての手順が完了したら、ユーザーを祝福し、正常に動作することを確認するために次の操作を試すよう案内してください。
準備完了です!次のいずれかを試してみましょう。
- 「自分の Feishu/Lark ドキュメントを表示して」
- 「[トピック] に関するドキュメントを検索して」
- 「[タイトル] という名前の新しいドキュメントを作成して」
- 「今日の会議を教えて」
- 「[名前] にメッセージを送って:こんにちは!」
自然な言葉で話しかけるだけで大丈夫です。あとは私が対応します。
認証
スクリプトは最適なトークンを自動で選択します。
- UAT(ユーザーアクセストークン) — 優先して使用します。ドキュメントの検索、個人ドキュメントへのアクセス、その他のユーザーレベルの操作に対応しています
- TAT(テナントアクセストークン) — UAT を利用できない場合の代替です。機能に制限があり、検索は利用できず、アプリにアクセス権が付与されたドキュメントのみアクセスできます
2 つのトークンでは、異なる MCP ヘッダーを使用します。
- UAT →
X-Lark-MCP-UAT - TAT →
X-Lark-MCP-TAT
現在の状態を確認します。
python3 ~/.claude/skills/feishu-inout/scripts/feishu_mcp.py whoami
再ログイン(トークンの期限切れ時):
python3 ~/.claude/skills/feishu-inout/scripts/feishu_mcp.py login
ドキュメント ID の抽出
Feishu/Lark の URL から docID を抽出します。
https://xxx.feishu.cn/docx/ABC123def → docID = ABC123def
https://xxx.larksuite.com/docx/ABC123def → docID = ABC123def
https://xxx.feishu.cn/wiki/XYZ789abc → docID = XYZ789abc
https://xxx.feishu.cn/docs/doccn123c → docID = doccn123c
ルール:docID は、/docx/、/wiki/、または /docs/ の後に続く最後のパスセグメントです。
使い方
すべての操作で scripts/feishu_mcp.py スクリプトを使います($S = 以下に示す完全なパス)。
S=~/.claude/skills/feishu-inout/scripts/feishu_mcp.py
# Auth
python3 $S login # OAuth login to get UAT
python3 $S whoami # Show current token status
# Read documents
python3 $S fetch-doc <docID> # Read full document
python3 $S fetch-doc <docID> 0 5000 # Paginated read (offset, limit)
# Search
python3 $S search-doc <keyword> # Search documents (needs UAT)
python3 $S search-user <keyword> # Search users
# Browse
python3 $S list-docs # List "My Library"
python3 $S list-docs <docID> # List child docs
python3 $S get-user # Get current user info
python3 $S get-user <open_id> # Get specific user info
# Create document (one step, with markdown content)
python3 $S create-doc <title> '<markdown>'
python3 $S create-doc <title> '<markdown>' '{"wiki_space":"my_library"}'
python3 $S create-doc <title> '<markdown>' '{"folder_token":"fldcnXXX"}'
# Update document (7 modes)
python3 $S append <docID> '<markdown>' # Append to end
python3 $S overwrite <docID> '<markdown>' # Overwrite entire doc (use with caution)
python3 $S replace <docID> '<selection>' '<md>' # Replace matched range
python3 $S insert-after <docID> '<sel>' '<md>' # Insert after match
python3 $S insert-before <docID> '<sel>' '<md>' # Insert before match
python3 $S delete-range <docID> '<selection>' # Delete matched content
# Comments
python3 $S get-comments <docID> # Get all comments
python3 $S get-comments <docID> whole # Whole-doc comments only
python3 $S get-comments <docID> segment # Inline comments only
python3 $S add-comments <docID> <text> # Add a text comment
# Files
python3 $S fetch-file <token> # Get file/image content
python3 $S fetch-file <token> whiteboard # Get whiteboard content
# Messaging (via MCP)
python3 $S send-msg <chat_id|open_id> <text> [--user] # Send markdown message
python3 $S send-card <chat_id|open_id> '<json>' [--user] # Send interactive card
python3 $S reply <message_id> <text> [--thread] # Reply to a message
python3 $S get-msgs <chat_id> [time] [count] # Get group chat history
python3 $S get-msgs-user <open_id> [time] [count] # Get DM history
python3 $S search-msgs <keyword> [time] # Search messages across chats
python3 $S get-thread <thread_id> # Get thread replies
# Calendar / Meeting (via Open API)
python3 $S create-event <title> <start> <end> [attendees_json] # Create event with video meeting
python3 $S list-events [date] # List events (default: today)
# Bitable / Multi-dimensional Table (via Open API)
python3 $S list-tables <app_token> # List tables in a bitable
python3 $S list-records <app_token> <table_id> [page_size] # List records
python3 $S create-record <app_token> <table_id> '<fields_json>' # Create a record
python3 $S update-record <app_token> <table_id> <record_id> '<fields_json>' # Update a record
# Group Management (via Open API, uses TAT/bot identity)
python3 $S create-group <name> [members_json] # Create a group chat
python3 $S add-members <chat_id> '<members_json>' # Add members to group
python3 $S list-groups # List groups bot is in
# Advanced (raw JSON call to any tool)
python3 $S call <toolName> '<jsonArgs>'
python3 $S update-doc '{"doc_id":"xxx","mode":"replace_range","selection_by_title":"## Section","markdown":"New content"}'
選択構文(置換/挿入/削除用)
- 範囲指定:
start text...end text— 2 つのテキスト断片の間にあるすべての内容に一致します - 完全一致:
exact text—...を含まず、完全に一致します - タイトル指定:
update-docの JSON モードでselection_by_title: "## Title"を使い、セクション全体を対象にします
ワークフロー
ドキュメントを読む
- ユーザーの URL から docID を抽出します
fetch-doc <docID>を実行します- 返された JSON を解析します。
result.content[0].textに Markdown コンテンツが含まれています - 大きなドキュメントではページネーションを使用します:
fetch-doc <docID> <offset> <limit>
検索して読む
search-doc <keyword>を実行してドキュメントを検索します- 結果の
items配列からid(docID)とtitleを抽出します - 結果が複数ある場合は一覧を表示し、ユーザーに選んでもらいます
fetch-doc <docID>を実行して、選択したドキュメントを読み込みます
ドキュメントを作成する(1 ステップ)
create-doc <title> '<markdown>'を実行して、コンテンツを含むドキュメントを作成します- 場所は任意で指定できます:wiki ノード
wiki_node、wiki スペースwiki_space(my_library= 個人ライブラリ)、またはフォルダーfolder_token doc_idとdoc_urlが返されます- 注:場所を指定しない場合、ドキュメントは個人スペースのルートに作成され、「最近」リストには表示されません。ユーザーが簡単に見つけられるよう、
wiki_space: "my_library"を指定することをおすすめします
ドキュメントを編集する
上書きより部分的な更新を優先してください:
append— コンテンツを末尾に追加しますreplace— 特定のコンテンツを検索して置換します(start...endの範囲一致、または完全一致を使用します)insert-after/insert-before— 指定した位置に挿入しますdelete-range— 一致したコンテンツを削除しますoverwrite— 最終手段として使用します。ドキュメント全体が消去されます(画像、コメントなども失われます)
タイトルでセクション全体を指定する(セクション全体の置換や削除に便利です):
python3 $S call update-doc '{"doc_id":"xxx","mode":"replace_range","selection_by_title":"### Section Title","markdown":"### Section Title\n\nReplaced content"}'
selection_by_title は、見出しから同じレベルの次の見出しまでを対象にします。
Wiki を閲覧する
list-docsを実行して「マイライブラリ」を表示します- または
list-docs <docID>を実行して子ドキュメントを表示します(応答にはhas_childフィールドが含まれます) - 下位の階層を再帰的に閲覧します
@メンションのワークフロー
search-user <name>を実行して、ユーザーのopen_idを取得しますadd-commentsの詳細モードを使用します:call add-comments '{"doc_id":"xxx","elements":[{"type":"mention","open_id":"ou_xxx"}]}'
ドキュメントを作成してグループチャットに送信する
create-doc <title> '<markdown>'を実行してドキュメントを作成しますsend-msg <chat_id> <text>を実行して、ドキュメントのリンクをグループに共有します(テキストにドキュメントの URL を含めます)- @メンションするには、メッセージテキストで
<mention-user id="openId"/>構文を使用します(先にsearch-userを実行して open_id を取得します)
メッセージを送信する
メッセージは UAT(ユーザーの本人性)を使用して、公式の Feishu/Lark MCP 経由で送信されます。ボット機能は必要ありません。
- グループメッセージ:
send-msg <chat_id> <text>— 認証済みユーザーとして送信します - DM:
send-msg <open_id> <text> --user— open_id を指定してユーザーに送信します - インタラクティブカード:
send-card <chat_id|open_id> '<json>' [--user]— カードメッセージを送信します - 返信:
reply <message_id> <text>— 特定のメッセージに返信します - スレッド内で返信:
reply <message_id> <text> --thread— スレッド内で返信します - グループの履歴:
get-msgs <chat_id> [time] [count]— 時間フィルターを指定してチャット履歴を取得します - DM の履歴:
get-msgs-user <open_id> [time] [count]— DM の履歴を読み取ります - 検索:
search-msgs <keyword> [time]— すべてのチャットのメッセージを検索します - スレッドの返信:
get-thread <thread_id>— スレッド内のすべての返信を取得します
Markdown の書式設定:send-msg はメッセージテキスト内の Markdown 構文に対応しています。
@メンションの構文:
- 特定のユーザーにメンションする:
<mention-user id="openId"/> - 全員にメンションする:
<mention-user id="all"/> - 絵文字に対応しています:[SMILE]、[THUMBSUP] など
get-msgs、get-msgs-user、search-msgs の時間フィルター:today、yesterday、this_week、last_week、this_month、last_month、last_30_minutes、last_3_days など
会議を作成する
create-event <title> <start> <end>を実行します。Feishu/Lark のビデオ会議が自動的に作成されます- 参加者を招待するには、
create-event "Sprint Review" "2026-03-28T14:00+08:00" "2026-03-28T15:00+08:00" '["ou_xxx","ou_yyy"]'を実行します - 先に
search-userを使用して、参加者の open_id を取得します
Bitable を使用する
- Bitable の URL から app_token を抽出します:
https://xxx.feishu.cn/base/XXX— app_token = XXX list-tables <app_token>を実行して、利用可能なテーブルを確認しますlist-records <app_token> <table_id>を実行して、データを読み取りますcreate-recordまたはupdate-recordを実行して、データを書き込みます
グループを作成してメンバーを追加する
create-group "Project Alpha" '["ou_xxx","ou_yyy"]'を実行して、初期メンバーを含めて作成します- または
create-group "Project Alpha"を実行してから、add-members <chat_id> '["ou_xxx"]'を実行します - グループ管理にはボットの本人性(TAT)が使用され、ボット機能を有効にする必要があります
エラー処理
| コード | 意味 | 解決方法 |
|---|---|---|
-32011 | 認証情報がありません | FEISHU_APP_ID と FEISHU_APP_SECRET の環境変数が設定されていることを確認してください |
-32003 | 認証情報が無効または期限切れです | TAT:App Secret を確認してください。UAT:login を実行して再認証してください |
-32601 | ツールまたはメソッドが見つかりません | tools を実行して、利用可能なツールを確認してください |
-32602 | パラメーターが無効です | パラメーター名と形式を確認してください |
-32700 | JSON の解析エラーです | JSON 引数の形式を確認してください |
429 | レート制限に達しました | 数秒待ってから再試行してください |
99991679 | ユーザーがこのスコープを許可していません | login を再実行するか、アプリの権限管理で権限を有効にしてください |
よくある問題
search-doc が「required ... search:docs:read」を返す
→ この権限にはユーザーの本人確認が必要です(UAT)。login を実行して UAT を取得してください。
fetch-doc が「permission denied」を返す
→ TAT モードでは、アプリをドキュメントの共同編集者に追加する必要があります。UAT を使用すると(login の実行後)、ユーザーが権限を持つすべてのドキュメントにアクセスできます。
ログイン後にブラウザーが応答しない
→ リダイレクト URL http://localhost:9876/callback がアプリのセキュリティ設定に追加されていることを確認してください。
UAT の期限が切れた
→ スクリプトは refresh_token による更新を自動的に試みます。refresh_token も期限切れの場合(30 日)、login を再実行してください。