Building MCP Connect: MCP iOS App for Servers
tech
tech
ios
swift
mcp

Building MCP Connect: MCP iOS App for Servers

I built MCP Connect, a native MCP iOS app for connecting to servers, browsing tools, and chatting with AI on the go.

Uygar DuzgunUUygar Duzgun
Mar 22, 2026
10 min read

What if your iPhone could talk to your own MCP servers anywhere? That is exactly what I built with MCP iOS app MCP Connect, a native mobile client for the Model Context Protocol. In this article, I explain how I designed, shipped, and deployed it, and why this approach matters if you want real AI tools on mobile.

What is MCP Connect?

MCP Connect is my MCP iOS app for connecting to MCP servers over HTTP, browsing tools, and chatting with AI on the go. I built it in Swift and SwiftUI so it feels native, fast, and stable on iPhone.

The app lets you:

connect to any MCP server via HTTP
browse available tools on each server
chat with AI through your tools
monitor server health and latency
manage multiple server connections
switch between English and Swedish

I wanted the app to feel premium, not like a wrapper. So I designed it with a dark cinema style, glassmorphism, spring animations, and haptic feedback. That design choice matters because mobile AI tools need to feel quick and clear, especially when users switch between chats and servers.

Why I built an MCP iOS app

I built this MCP iOS app because I wanted direct access to my own tools from my phone. Desktop-only workflows slow you down when you are away from your desk. On iPhone, I wanted the same control I already had in the browser and on my Mac.

In my experience building products in Gothenburg, the best mobile apps solve a painful, narrow problem well. MCP Connect does that for me. It gives me secure access to my MCP servers, and it does it without adding another complicated layer.

This also fits the direction of the Model Context Protocol itself. Anthropic’s MCP spec is built around a clean client-server model, which makes it a strong fit for mobile apps that need structured tool access. I kept the implementation aligned with that idea so the app stays maintainable as the protocol evolves.

The user problem I solved

Most AI tools still assume you sit at a desktop. That breaks when you need to check a server, trigger a tool, or inspect a result while travelling. With MCP Connect, I reduced that friction.

The result is simple: I can open the app, select a server, and interact with my tools in seconds. That speed is the whole point of the MCP iOS app.

The tech stack behind the MCP iOS app

I kept the stack focused and modern. I did not want a bloated architecture or unnecessary dependencies.

LayerTechnology
------
PlatformiOS 17+, Swift 6, SwiftUI
ArchitectureMVVM + Coordinators
BackendSupabase (Auth, PostgreSQL, Realtime)
MCP TransportJSON-RPC over HTTP
PersistenceSwiftData
IAPStoreKit 2
i18nString Catalogs (EN + SV)
DeploymentXcode + XcodeGen

This stack gave me a strong base for the MCP iOS app. SwiftUI handled the interface well, SwiftData supported offline-first storage, and Supabase gave me authentication and sync without extra backend overhead.

I also used familiar production tools like Keychain for secrets and StoreKit 2 for subscriptions. That kept the app focused on product quality instead of infrastructure noise.

Step 1: I designed the system first

I always start with the design system, because it saves time later. In this project, I built the tokens and shared components before I wrote feature code.

The Dark Cinema palette uses deep blacks, subtle elevated surfaces, and an indigo accent. Every surface uses a glassmorphism treatment with `.ultraThinMaterial` and a thin border so the UI feels layered but not heavy.

The system includes:

ColorTokens for semantic colors
TypographyTokens for UI and code styles
SpacingTokens built around a 4/8 rhythm
a reusable GlassMorphism modifier
spring animations with consistent motion
haptic feedback for each interaction

I built reusable components like `GlassCard`, `AccentButton`, `StatusBadge`, `ShimmerLoader`, and `GlassTextField`. That made the MCP iOS app easier to scale because new screens inherited the same visual language.

Step 2: I separated models from persistence

I split domain models from SwiftData persistence models. This kept the business logic clean and testable.

The main models are:

`MCPServer` for connection settings
`Conversation` for each chat session
`Message` for user and assistant messages
`ToolCall` for tool input, output, and timing

That separation mattered more than it sounds. It gave me room to change storage details without rewriting the app logic. For a MCP iOS app, that kind of boundary makes future features easier to ship.

Security decision: Keychain only for API keys

I made one rule that I would not break: API keys never touch Supabase. I store only an `apiKeyRef` in the database, while the actual key lives in the iOS Keychain.

That means a database breach does not expose credentials. The tradeoff is that keys do not sync automatically across devices. Users must re-enter them on a new phone, but that takes seconds and removes a serious security risk.

Step 3: I built the MCP client

The client uses JSON-RPC over HTTP, which matches the Streamable HTTP transport in the MCP specification. Each request goes out as a standard HTTP POST with a JSON-RPC body.

The app supports four core operations:

`initialize` to negotiate protocol version and session setup
`tools/list` to discover available tools
`tools/call` to execute a tool with arguments
`ping` to measure latency and check health

I load authorization tokens from the Keychain at request time. That keeps the MCP iOS app secure and avoids storing secrets in memory longer than needed.

I tested this against my own servers until the request flow felt stable under real use. The result was predictable latency and a much better mobile experience than I expected at the start.

Step 4: I wired up Supabase

I used Supabase for auth and sync because it gives me a fast path to production. The backend has four tables:

`user_profiles` for theme and language settings
`mcp_servers` for per-user server configs
`conversations` for chat sessions
`messages` for message history and tool data

Every table has Row Level Security. That means users can only access their own records. I also added a database trigger that creates a profile automatically after signup.

Auth supports Sign in with Apple and email/password. That gave me a clean sign-up flow without forcing users into one login method. For a MCP iOS app, that flexibility helps adoption.

Step 5: I built the main features

The app has three core surfaces: chat, server management, and settings. I kept each one focused so the experience stays fast on a phone.

Chat interface

The chat uses a state machine: `idle` → `sending` → `streaming` → `toolCalling` → `idle`. Tool calls appear inline as expandable cards with the tool name, arguments, result, and execution time.

That UI matters because it helps users trust what the AI is doing. They can see each step instead of guessing.

Server management

Users can add, edit, and delete servers. I added URL validation, swipe-to-delete, and confirmation dialogs so server changes feel safe and deliberate.

Each server detail view shows health data, latency charts with Swift Charts, and a Tool Explorer that lists the available tools and parameter schemas. That made the MCP iOS app more useful than a simple chat frontend.

Navigation and settings

I used a three-tab layout with `NavigationStack` and type-safe routes. Deep linking works through the `mcpconnect://` URL scheme.

Settings include:

dark, light, and system themes
eight accent color options
in-app language switching between English and Swedish
subscription management

Step 6: I deployed the MCP server endpoint

The hardest part was making a stdio-based MCP server reachable from mobile. My personal site MCP server originally ran as a local Node.js process with `StdioServerTransport`.

To expose it to the MCP iOS app, I added an API route to my Next.js site on Vercel. The route uses the MCP SDK’s `InMemoryTransport` to bridge JSON-RPC requests to the local server implementation.

Each request creates a fresh server/client pair with `createLinkedPair()`, runs the operation, and returns the response. That approach fits serverless infrastructure well because it avoids long-lived connections.

The endpoint lives at `https://uygarduzgun.com/api/mcp`, and it exposes 15 tools that I can call from any MCP client. This setup turned a local tool server into a mobile-ready service without redesigning the whole backend.

Why this architecture works

In practice, it works because each request is stateless and isolated. That reduces operational risk and makes scaling much easier. If you build an MCP iOS app, this pattern is worth considering for serverless deployment.

Step 7: IAP and monetization

I used StoreKit 2 for a simple free/pro model. The free tier is usable, but the Pro tier removes the limits that power users hit fastest.

FeatureFreePro ($4.99/mo)
------:---:
Servers2Unlimited
Conversations50Unlimited
History30 daysUnlimited
ThemesDark + Light+ custom accent
SearchCurrent chatFull-text all

I like this model because it does not punish casual users. It gives enough value up front, then expands naturally when the app becomes part of a real workflow.

Project stats and results

The build ended up larger than I expected, but the structure stayed clean.

50+ Swift source files across 9 feature modules
90+ localized strings in English and Swedish
15 MCP tools exposed through the API endpoint
4 Supabase tables with RLS policies
5 Swift Package Manager dependencies
0 lines of UIKit

Those numbers matter because they show the app is production-grade, not a prototype. I wanted a real MCP iOS app, and I shipped one.

Images I would add for this article

If I publish this post, I would include screenshots with descriptive alt text to help readers and improve SEO.

MCP Connect home screen on iPhone
Tool Explorer inside the MCP iOS app
Server latency dashboard in Swift Charts
Dark Cinema design system components

Key takeaways

I built the MCP iOS app around a clean design system first.
I separated domain models from persistence to keep the codebase maintainable.
I stored API keys in the Keychain only, not in Supabase.
I bridged my MCP server to Vercel with `InMemoryTransport`.
I shipped a native SwiftUI app that works well on mobile.

MCP Connect shows that the MCP iOS app idea is practical, secure, and ready for real use. If you are building mobile AI tools, this architecture can save you time and reduce risk. Read the related post on audio signal levels explained or leave a comment if you want me to break down the server code next.

Frequently Asked Questions

What is an MCP iOS app used for?+
An MCP iOS app lets you connect to Model Context Protocol servers from your iPhone. You can browse tools, run actions, and chat with AI without sitting at a desktop. That makes mobile access to structured AI workflows much more practical.
How do you keep API keys secure in an MCP iOS app?+
I store API keys in the iOS Keychain and keep only a reference in the database. In my experience, that is the safest pattern because a backend breach does not reveal live credentials. It does mean users re-enter keys on new devices.
Why use JSON-RPC over HTTP for MCP on mobile?+
JSON-RPC over HTTP fits mobile well because it works with standard requests and serverless platforms. I used it so the app could call tools, check health, and initialize sessions without maintaining long-lived connections. That keeps the client simple and reliable.