AIが急速に進化する中、Claudeのような大規模言語モデル (LLM) と企業のシステムやAPIを連携させるニーズが高まっています。Boxでは、これらの強力なAI機能を使用してコンテンツ管理プラットフォームを強化する方法を模索してきました。この記事では、Model Context Protocol (MCP) フレームワークを使用してどのようにBox APIを直接操作するかをClaudeに教える方法について説明します。
Model Context Protocolとは
Model Context Protocol (MCP) とは、AIモデルによるさまざまなデータソースやサービスの操作方法を標準化することを目的としたフレームワークです。LLMと外部システムの架け橋となるため、LLMはトレーニング用データセット以外のデータにアクセスして操作できるようになります。
MCPの詳細については、以下を参照してください。
Box MCPサーバー
Model Context Protocolを介してBoxのAPIを公開する方法を紹介するためのコミュニティプロジェクトとして、このサーバーを開発しました。
このオープンソースのPython実装では、ClaudeがBoxに保存されているドキュメントをシームレスに操作できるようにするサンプルツールキットを提供しています。
これらのテクノロジを橋渡しすることで、AIアシスタントが最小限の負荷で企業のコンテンツ管理機能にアクセスできる基盤を構築し、インテリジェントなドキュメント処理および分析の新たな可能性を切り開きました。
実装したツール
- box_who_am_i - 現在のユーザーの情報を取得し、接続のステータスを確認する
- box_authorize_app_tool - Boxアプリケーションの承認プロセスを開始する
- box_search_tool - クエリ、ファイル拡張子、その他のパラメータを使用してBox内のファイルを検索する
- box_read_tool - 特定のBoxファイルのテキストコンテンツを読み取る
- box_ask_ai_tool - ファイルの内容についてBox AIに質問する
- box_search_folder_by_name - Box内のフォルダを名前で検索する
- box_ai_extract_data - AIを使用してファイルから構造化データを抽出する
- box_list_folder_content_by_folder_id - フォルダのコンテンツのリストを取得する
これらのツールは、Box APIにアクセスするための最もシンプルで直接的な方法を使用して実装しました。
Claudeがさまざまなツールを調査して組み合わせ、特定のタスクを実行する過程を目の当たりにするのは興味深いことです。
認証フロー
Claudeは、Boxに接続しているかどうかを確認し、接続していない場合は接続を確立する方法を知っている必要があります。
今回は、Box OAuthを実装することが理にかなっているため、Claudeで認証プロセスを開始できるようにする必要があります。
async def box_authorize_app_tool() -> str:
"""
Authorize the Box application.
Start the Box app authorization process
return:
str: Message
"""
result = authorize_app()
if result:
return "Box application authorized successfully"
else:
return "Box application not authorized"
ユーザーがこのプロセスを完了すると、Claudeはユーザーのセキュリティコンテキストを使用してBoxにアクセスできます。
接続が機能しているかどうかを確認するには、従来のwho_am_aiを使用します。これは、既存の資格情報を使用して自動的にBoxへのログインを試行し、現在ログインしているユーザーを返します。
検索機能
Boxの検索には多くのパラメータがあるため、Claudeが目的に応じて検索をどのように変更するかを確認するテストに適しています。
検索ツールを使用して、ClaudeはBox内のファイルを検索できます。
async def box_search_tool(
ctx: Context,
query: str,
file_extensions: List[str] | None = None,
where_to_look_for_query: List[str] | None = None,
ancestor_folder_ids: List[str] | None = None,
) -> str:
"""
Search for files in Box with the given query.
Args:
query (str): The query to search for.
file_extensions (List[str]): The file extensions to search for, for example *.pdf
content_types (List[SearchForContentContentTypes]): where to look for the information, possible values are:
NAME
DESCRIPTION,
FILE_CONTENT,
COMMENTS,
TAG,
ancestor_folder_ids (List[str]): The ancestor folder IDs to search in.
return:
str: The search results.
"""
# Get the Box client
box_client: BoxClient = cast(
BoxContext, ctx.request_context.lifespan_context
).client
# Convert the where to look for query to content types
content_types: List[SearchForContentContentTypes] = []
if where_to_look_for_query:
for content_type in where_to_look_for_query:
content_types.append(SearchForContentContentTypes[content_type])
# Search for files with the query
search_results = box_search(
box_client, query, file_extensions, content_types, ancestor_folder_ids
)
# Return the "id", "name", "description" of the search results
search_results = [
f"{file.name} (id:{file.id})"
+ (f" {file.description}" if file.description else "")
for file in search_results
]
return "\n".join(search_results)
驚いたことに、上記の情報だけで、Claudeはパラメータを使用して検索を変更しました。たとえば、PDFドキュメントや先祖フォルダに検索を限定したり、ドキュメント名でのみクエリを検索したりします。
Claudeが検索結果で迷う可能性があることを考慮して、list_folder_content_by_folder_idを使用してフォルダ構造を確認する方法と、より具体的で制約のあるsearch_forder_by_nameも実装しました。
ドキュメントを読み取る
この統合における重要な機能は、ClaudeがBoxに保存されているコンテンツを読み取れるようにすることです。これを実現するために、さまざまなドキュメント形式からテキストコンテンツを抽出するテキストレプリゼンテーション機能を使用します。
Claudeがドキュメントを分析する必要がある場合、MCPサーバーはBox APIを介してこのテキストレプリゼンテーションをリクエストし、ドキュメントのコンテンツのクリーンで標準化されたバージョンを提供します。
このアプローチは、PDF、Officeドキュメント、プレーンテキストファイルなど、複数のファイルの種類でシームレスに機能するため、Claudeは元の形式に関係なく情報を処理して理解できます。
async def box_read_tool(ctx: Context, file_id: Any) -> str:
"""
Read the text content of a file in Box.
Args:
file_id (str): The ID of the file to read.
return:
str: The text content of the file.
"""
# log parameters and its type
logging.info(f"file_id: {file_id}, type: {type(file_id)}")
# check if file id isn't a string and convert to a string
if not isinstance(file_id, str):
file_id = str(file_id)
# Get the Box client
box_client: BoxClient = cast(
BoxContext, ctx.request_context.lifespan_context
).client
response = box_file_text_extract(box_client, file_id)
return response
Box AIに質問する
Box AIの機能も搭載しました。ClaudeがBox AIにドキュメントの内容について質問すると、興味深い動きがあります。このアプローチは効果的に機能するため、Boxから外部プラットフォームにドキュメントのコンテンツを転送する必要がなくなります。
今回の実装では、Claudeを使用するようBox AIエージェントを構成し、Claudeが異なるシステムを介してClaude自体と効果的に通信するシナリオを作成しました。
async def box_ask_ai_tool(ctx: Context, file_id: Any, prompt: str) -> str:
"""
Ask box ai about a file in Box.
Args:
file_id (str): The ID of the file to read.
prompt (str): The prompt to ask the AI.
return:
str: The text content of the file.
"""
# log parameters and its type
logging.info(f"file_id: {file_id}, type: {type(file_id)}")
# check if file id isn't a string and convert to a string
if not isinstance(file_id, str):
file_id = str(file_id)
# Get the Box client
box_client: BoxClient = cast(
BoxContext, ctx.request_context.lifespan_context
).client
ai_agent = box_claude_ai_agent_ask()
response = box_file_ai_ask(box_client, file_id, prompt=prompt, ai_agent=ai_agent)
return response
デモ
ClaudeによるBox APIの操作を示す使用例をいくつか紹介します。
MCP Server Boxの使用
このサンプルコードは、コミュニティのリポジトリから直接入手できます。
設定してClaudeデスクトップアプリケーションと統合する方法については、README.mdを参照してください。
まとめ
今回は、Model Context Protocolを介してClaudeとBox APIを連携させることで、LLMのインテリジェンスとBoxの堅牢なコンテンツ管理機能を組み合わせたシステムを構築しました。この統合により、ユーザーはBoxのコンテンツやその他のソースをより自然かつ合理的な方法で操作できるようになるため、ドキュメントの管理と分析の新たな可能性が広がります。
MCP Server Boxプロジェクトでは、企業のシステムをAI機能で拡張し、より直感的かつ強力なユーザーエクスペリエンスを実現する方法を紹介しています。LLMとコンテンツプラットフォームが進化し続ける中で、コンテンツとの関わり方を変えるような革新的な統合が増えていくことを期待しています。
- トピックス:
- 開発者