Platform-API verification and cross-platform equivalence for native code

Run with it.

Every platform API in your diff, graded against Apple and Android SDKs. Ask for the other platform's equivalent for an answer in seconds, with no toolchain and in any language your agent writes.

platform-oracle · mcp
// One platform in, the other out. Curated, index-verified.
equivalent_apis("UNUserNotificationCenter")
→ notifications.local  Local notifications · high confidence
   android
     app.NotificationManager  · API 1  ↗ docs
     app.NotificationChannel  required API 26+  · API 26  ↗ docs
     app.Notification.Builder  · API 11  ↗ docs
     app.AlarmManager  scheduling  · API 1  ↗ docs
   iOS schedules via triggers on the center; Android posts immediately and schedules with AlarmManager.

// Correct code, wrong decade. Graded against targetSdk 36.
check_symbols([onBackPressed, overridePendingTransition, announceForAccessibility, onCreate])
→ deprecated 33  Activity.onBackPressed
→ deprecated 34  Activity.overridePendingTransition
→ deprecated 36  View.announceForAccessibility
→ ok             Activity.onCreate

$

Add it to your agent

claude mcp add --transport http sdkrun https://sdk.run/mcp

full quickstart ↓

Platforms
3macOS · iOS · Android
Frameworks
450+
Symbols
129k+
Members
340k+
With availability + native names
275k+
Any language, one verifier

Swift, Kotlin, React Native, NativeScript. Same SDK truth, both platforms.

The check reads your project's deployment target (Xcode project, Podfile, Gradle, nativescript.config) and grades every native API call against it. Native calls made from TypeScript get the same treatment as Swift and Kotlin: that surface is exactly the one no compiler inspects.

LocationService.swift ↔ LocationService.kttarget iOS 15.0 · minSdk 24 · detected from both projects; mapping from equivalent_apis
// iOS
let manager = CLLocationManager()equivalent · location.updates → android.location.LocationManager
manager.delegate = self   // CLLocationManagerDelegateequivalent · → android.location.LocationListener (callbacks)
manager.startUpdatingLocation()ok · introduced 2.0
 
// Android, ported
val manager = context.getSystemService(LocationManager::class.java)ok · introduced API 1
manager.requestLocationUpdates(GPS_PROVIDER, 1000L, 1f, listener)ok · introduced API 1
val listener = LocationListener { loc -> onLocationChanged(loc) }ok · introduced API 1

→ Same capability, both platforms, every symbol verified. Note from the map: most Android apps use Play Services FusedLocationProviderClient (not in the platform SDK); LocationManager is the platform equivalent.

Why verification

Frontier models know the API. Nothing proves it until you ship.

We benchmarked it honestly: on nine native tasks across Swift, Kotlin, and React Native (common APIs, Metal, MediaCodec, iOS 26 and Android 16 surface), a frontier model wrote correct API calls with no tools at all. That is not the problem anymore. The problem is what confident code hides: an API deprecated at your targetSdk, a call that does not exist below your deployment target, a spelling that compiles in one context and not another. Compiled Swift and Kotlin get most of that from the compiler. Native calls made from React Native or NativeScript get none of it, and no compiler enforces a deprecation policy against the target you choose, or the one you are moving to.

sdk.run answers with verdicts, not prose: built from the same compiler-parsed metadata NativeScript uses to call these APIs at runtime, so every symbol carries its exact signature, native selector, framework, and per-version availability. It graded our own hosted oracle and found two defects our launch tests had missed. Verification does that.

  • deprecated 33flagged against your targetSdk / deployment target
  • too new · introduced 26.0available check against the OS you actually support
  • existsmember_existswith the exact signature and native selector
  • member_inheritednames the declaring ancestor
  • exists_case_mismatchwith the exact spelling
  • not_foundnot in the indexed SDK, with the nearest real names
What it does

One index. Verify in the editor, gate in CI, prove on the OS.

Verify · remote MCP

The Platform API Oracle

Deterministic verdicts for the code your agent just wrote, one symbol or fifty in a single call, graded against your deployment target. Plus ranked task-phrase search, token-budgeted typing slices, and a capability graph.

check_symbols · check_symbol · search_platform_apis · get_typings · capability_graph

Run · local MCP

The Simulator Sandbox

Send UIKit or Foundation code to a booted iOS simulator and get the value back in milliseconds, then look at the screen. No project, no build. The NativeScript runtime executes it, SimDeck shows it, and every run is verified against the oracle first. iOS today, Android next. Try it →

npx -y @sdkrun/agent-runtime ios · run_snippet · verify_snippet

Gate · CI & benchmark

sdkrun check

Every platform-API reference in a diff, extracted and graded: too new for the deployment target, deprecated at your targetSdk, wrong spelling, against policy. Runs on a toolchain-free runner before the native build. The same grader powers PlatformAPIBench, the public benchmark that told us frontier models don't hallucinate these APIs. We published that anyway.

sdkrun check · @sdkrun/platform-oracle bench

Quickstart

Two commands. Any MCP-capable agent.

Verify: hosted, no auth

$ claude mcp add --transport http sdkrun https://sdk.run/mcp

Run: local, iOS simulator + macOS

$ claude mcp add agent-runtime -- npx -y @sdkrun/agent-runtime serve

The sandbox runs real native code: iOS snippets inside the host app on the simulator, macOS snippets with your user's privileges in a disposable child process. A local development tool, never something to expose to untrusted callers. Open the sandbox →

Reading this as an agent?

Start at /llms.txt. Symbol names use the JavaScript projection of ObjC selectors: colon segments camelCase into one name (initWithContentRect:styleMask:backing:defer: → initWithContentRectStyleMaskBackingDefer). A not_found verdict means the API is not in the indexed SDK; check the spelling and platform before assuming it exists. Pass your deployment target (or let the local server detect it) to get availability verdicts. Prefer check_symbols to verify everything you wrote in one call.