あなたのiPhoneがどこでも自分のMCPサーバーと話せるとしたらどうでしょうか?それがまさに私がMCP iOSアプリMCP Connectで構築したものです。これは、モデルコンテキストプロトコルのためのネイティブモバイルクライアントです。この記事では、私がどのように設計し、出荷し、展開したのか、そしてこのアプローチがモバイルで本物のAIツールを望む場合に重要である理由を説明します。
MCP Connectとは?
MCP Connectは、HTTP経由でMCPサーバーに接続し、ツールをブラウジングし、移動中にAIとチャットするための私のMCP iOSアプリです。SwiftとSwiftUIで構築したので、iPhone上でネイティブで、速く、安定した感覚を持っています。
このアプリでは、以下のことができます:
私は、アプリがラッパーのように感じられないようにプレミアムな感覚を持たせたかったので、ダークシネマスタイル、グラスモーフィズム、スプリングアニメーション、ハプティックフィードバックでデザインしました。このデザインの選択は重要です。なぜなら、モバイルAIツールは迅速で明確に感じられる必要があり、特にユーザーがチャットとサーバーの間を切り替えるときにそうであるべきだからです。
なぜMCP iOSアプリを構築したのか
私はこのMCP iOSアプリを構築したのは、自分のツールに直接アクセスしたかったからです。デスクトップ専用のワークフローは、デスクから離れているときにあなたを遅くします。iPhoneでは、ブラウザやMacで持っていたのと同じ制御を望んでいました。
私がヨーテボリで製品を構築する経験から、最高のモバイルアプリは痛みを伴う狭い問題をうまく解決します。MCP Connectは私にとってそれを実現しています。これは、私のMCPサーバーへの安全なアクセスを提供し、さらに複雑なレイヤーを追加することなく実現しています。
これは、モデルコンテキストプロトコル自体の方向性にも合致しています。AnthropicのMCP仕様は、クリーンなクライアント-サーバーモデルを中心に構築されており、構造化されたツールアクセスが必要なモバイルアプリに強く適合します。私は、そのアイデアに沿って実装を維持したので、プロトコルが進化するにつれてアプリが保守可能な状態を保つことができます。
私が解決したユーザーの問題
ほとんどのAIツールは、まだあなたがデスクトップに座っていることを前提としています。それは、旅行中にサーバーをチェックしたり、ツールをトリガーしたり、結果を検査する必要があるときに壊れます。MCP Connectを使うことで、その摩擦を減らしました。
結果はシンプルです:アプリを開いてサーバーを選択し、数秒でツールと対話できます。そのスピードがMCP iOSアプリの全てです。
MCP iOSアプリの背後にある技術スタック
私はスタックを集中させ、現代的に保ちました。膨れ上がったアーキテクチャや不必要な依存関係を望んでいませんでした。
| レイヤー | テクノロジー |
|---|---|
| --- | --- |
| プラットフォーム | iOS 17+, Swift 6, SwiftUI |
| アーキテクチャ | MVVM + コーディネーター |
| バックエンド | Supabase (Auth, PostgreSQL, Realtime) |
| MCPトランスポート | JSON-RPC over HTTP |
| 永続性 | SwiftData |
| IAP | StoreKit 2 |
| i18n | ストリングカタログ (EN + SV) |
| デプロイメント | Xcode + XcodeGen |
このスタックは、MCP iOSアプリの強力な基盤を提供しました。SwiftUIはインターフェースをうまく処理し、SwiftDataはオフラインファーストのストレージをサポートし、Supabaseは追加のバックエンドオーバーヘッドなしで認証と同期を提供しました。
また、秘密情報にはKeychain、サブスクリプションにはStoreKit 2など、馴染みのあるプロダクションツールも使用しました。これにより、アプリはインフラのノイズではなく、製品の品質に集中できました。
ステップ1:最初にシステムを設計した
私は常にデザインシステムから始めます。なぜなら、それが後で時間を節約するからです。このプロジェクトでは、機能コードを書く前にトークンと共有コンポーネントを構築しました。
ダークシネマパレットは、深い黒、微妙に高められた表面、インディゴのアクセントを使用しています。すべての表面は、`.ultraThinMaterial`と薄いボーダーを使用したグラスモーフィズム処理を施しているため、UIは層状に感じられますが、重くはありません。
システムには以下が含まれます:
私は、`GlassCard`、`AccentButton`、`StatusBadge`、`ShimmerLoader`、`GlassTextField`のような再利用可能なコンポーネントを構築しました。これにより、MCP iOSアプリはスケールしやすくなり、新しい画面が同じビジュアル言語を継承しました。
ステップ2:モデルを永続性から分離した
私はドメインモデルをSwiftDataの永続性モデルから分離しました。これにより、ビジネスロジックがクリーンでテスト可能な状態を保つことができました。
主なモデルは以下の通りです:
その分離は、思っている以上に重要でした。これにより、アプリロジックを書き直すことなくストレージの詳細を変更する余地ができました。MCP iOSアプリにとって、そのような境界は将来の機能を出荷しやすくします。
セキュリティの決定:APIキーはKeychainのみに
私は破らないルールを一つ作りました:APIキーは決してSupabaseに触れない。私はデータベースに`apiKeyRef`のみを保存し、実際のキーはiOS Keychainに保存します。
これにより、データベースの侵害が資格情報を露出することはありません。トレードオフは、キーがデバイス間で自動的に同期されないことです。ユーザーは新しい電話で再入力する必要がありますが、それは数秒で済み、深刻なセキュリティリスクを取り除きます。
ステップ3:MCPクライアントを構築した
クライアントはJSON-RPC over HTTPを使用しており、これはMCP仕様のストリーミングHTTPトランスポートと一致します。各リクエストは、標準のHTTP POSTとしてJSON-RPCボディを持って送信されます。
アプリは4つのコア操作をサポートしています:
リクエスト時にKeychainから認証トークンを読み込みます。これにより、MCP iOSアプリは安全で、必要以上に秘密をメモリに保持しないようにします。
私は、リクエストフローが実際の使用下で安定していると感じるまで、自分のサーバーに対してこれをテストしました。その結果は予測可能なレイテンシと、当初期待していたよりもはるかに良いモバイル体験でした。
ステップ4:Supabaseを接続した
私は認証と同期のためにSupabaseを使用しました。これにより、迅速にプロダクションに移行できます。バックエンドには4つのテーブルがあります:
すべてのテーブルには行レベルセキュリティがあります。つまり、ユーザーは自分のレコードのみアクセスできます。また、サインアップ後にプロファイルを自動的に作成するデータベーストリガーも追加しました。
認証はAppleでのサインインとメール/パスワードをサポートしています。これにより、ユーザーを一つのログイン方法に強制することなく、クリーンなサインアップフローを提供しました。MCP iOSアプリにとって、その柔軟性は採用を助けます。
ステップ5:主要機能を構築した
アプリには3つのコアインターフェースがあります:チャット、サーバー管理、設定。私はそれぞれを集中させ、体験が電話で速くなるようにしました。
チャットインターフェース
チャットは状態機械を使用しています:`idle` → `sending` → `streaming` → `toolCalling` → `idle`。ツールコールは、ツール名、引数、結果、実行時間を持つ展開可能なカードとしてインラインで表示されます。
そのUIは重要です。なぜなら、ユーザーがAIが何をしているのかを信頼するのを助けるからです。彼らは推測するのではなく、各ステップを見ることができます。
サーバー管理
ユーザーはサーバーを追加、編集、削除できます。私はURL検証、スワイプで削除、確認ダイアログを追加したので、サーバーの変更が安全で意図的に感じられます。
各サーバー詳細ビューには、健康データ、Swift Chartsによるレイテンシチャート、利用可能なツールとパラメータスキーマをリストするツールエクスプローラーが表示されます。これにより、MCP iOSアプリは単なるチャットフロントエンドよりも便利になりました。
ナビゲーションと設定
私は`NavigationStack`と型安全なルートを使用した3タブレイアウトを採用しました。ディープリンクは`mcpconnect://` URLスキームを通じて機能します。
設定には以下が含まれます:
ステップ6:MCPサーバーエンドポイントをデプロイした
最も難しい部分は、stdioベースのMCPサーバーをモバイルからアクセス可能にすることでした。私の個人サイトのMCPサーバーは、元々`StdioServerTransport`を使用してローカルNode.jsプロセスとして実行されていました。
MCP iOSアプリにそれを公開するために、Vercel上のNext.jsサイトにAPIルートを追加しました。このルートは、MCP SDKの`InMemoryTransport`を使用して、JSON-RPCリクエストをローカルサーバー実装にブリッジします。
各リクエストは、`createLinkedPair()`で新しいサーバー/クライアントペアを作成し、操作を実行し、応答を返します。このアプローチは、長期間接続を避けるため、サーバーレスインフラに適しています。
エンドポイントは`https://uygarduzgun.com/api/mcp`にあり、私はどのMCPクライアントからでも呼び出せる15のツールを公開しています。このセットアップにより、ローカルツールサーバーがモバイル対応のサービスに変わり、バックエンド全体を再設計することなく実現しました。
なぜこのアーキテクチャが機能するのか
実際には、各リクエストがステートレスで孤立しているため、機能します。これにより、運用リスクが軽減され、スケーリングがはるかに容易になります。MCP iOSアプリを構築する場合、このパターンはサーバーレスデプロイメントのために検討する価値があります。
ステップ7:IAPと収益化
私はStoreKit 2を使用してシンプルな無料/プロモデルを実現しました。無料プランは使用可能ですが、プロプランはパワーユーザーが最も早く直面する制限を取り除きます。
| 機能 | 無料 | プロ ($4.99/月) |
|---|---|---|
| --- | ---: | ---: |
| サーバー | 2 | 無制限 |
| 会話 | 50 | 無制限 |
| 履歴 | 30日 | 無制限 |
| テーマ | ダーク + ライト | + カスタムアクセント |
| 検索 | 現在のチャット | フルテキスト全体 |
私はこのモデルが好きです。なぜなら、カジュアルユーザーを罰することがないからです。最初に十分な価値を提供し、その後アプリが実際のワークフローの一部になると自然に拡張します。
プロジェクトの統計と結果
ビルドは予想以上に大きくなりましたが、構造はクリーンなままでした。
これらの数字は重要です。なぜなら、アプリがプロダクショングレードであり、プロトタイプではないことを示しているからです。私は本物のMCP iOSアプリを望んでおり、実現しました。
この記事に追加したい画像
この投稿を公開する場合、読者を助け、SEOを改善するために説明的なaltテキストを持つスクリーンショットを含めたいと思います。
重要なポイント
MCP Connectは、MCP iOSアプリのアイデアが実用的で、安全で、実際の使用に準備が整っていることを示しています。もしあなたがモバイルAIツールを構築しているなら、このアーキテクチャは時間を節約し、リスクを減らすことができます。関連する投稿「オーディオ信号レベルの説明」を読んだり、サーバーコードの詳細を知りたい場合はコメントを残してください。