ios-agent-mcp 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
5
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
6
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';
7
+ import { createRequire } from 'node:module';
8
+ import { fileURLToPath } from 'node:url';
9
+ import { execFile } from 'node:child_process';
10
+ import { promisify } from 'node:util';
11
+ import { z } from 'zod';
12
+ import { VERSION } from './version.js';
13
+ const require = createRequire(import.meta.url);
14
+ const args = process.argv.slice(2);
15
+ const cli = () => require.resolve('@nagarjuna2002/ios-agent/dist/index.js');
16
+ if (args.includes('--version'))
17
+ console.log(VERSION);
18
+ else if (args.includes('--help'))
19
+ console.log(`ios-agent-mcp ${VERSION}\nOne MCP connection: Swift reviews, Apple references, app creation and simulator tools.\nRequires Node 20+. Simulator operations require macOS/Xcode.\nUsage: ios-agent-mcp [--project PATH]\n ios-agent-mcp new MyApp --brief "Your idea" --xcodegen\nThe starter requires your coding agent to implement the app features.`);
20
+ else if (args[0] === 'new') {
21
+ const child = (await import('node:child_process')).spawn(process.execPath, [cli(), ...args], { stdio: 'inherit' });
22
+ child.on('error', e => { console.error(e.message); process.exitCode = 1; });
23
+ child.on('exit', code => { process.exitCode = code ?? 1; });
24
+ }
25
+ else {
26
+ const clients = [];
27
+ const close = async () => { await Promise.allSettled(clients.map(c => c.close())); };
28
+ try {
29
+ const paths = [fileURLToPath(new URL('./index.js', import.meta.url)), fileURLToPath(new URL('./knowledge-server.js', import.meta.url)), require.resolve('@nagarjuna2002/ios-simulator-mcp')];
30
+ for (const [i, path] of paths.entries()) {
31
+ const client = new Client({ name: 'ios-agent-unified', version: VERSION });
32
+ clients.push(client);
33
+ await client.connect(new StdioClientTransport({ command: process.execPath, args: [path, ...(i === 0 ? args : [])], stderr: 'inherit', env: Object.fromEntries(Object.entries(process.env).filter((pair) => pair[1] !== undefined)) }));
34
+ }
35
+ const catalog = await Promise.all(clients.map(c => c.listTools()));
36
+ const owners = new Map();
37
+ const tools = catalog.flatMap((list, i) => list.tools.map(tool => { if (owners.has(tool.name))
38
+ throw Error(`Duplicate tool ${tool.name}`); owners.set(tool.name, clients[i]); return tool; }));
39
+ tools.push({ name: 'create_app', description: 'Create an editable Swift app starter, implementation brief and optional XcodeGen specification/icon layers. Writes a NEW project; does not implement the full app idea. Then use source retrieval, review and simulator tools to implement and verify it.', inputSchema: { type: 'object', properties: { name: { type: 'string' }, directory: { type: 'string', description: 'Parent directory for the new project' }, brief: { type: 'string' }, xcodegen: { type: 'boolean', default: true } }, required: ['name', 'directory', 'brief'], additionalProperties: false } });
40
+ const server = new Server({ name: 'ios-agent-mcp', version: VERSION }, { capabilities: { tools: {}, resources: {} } });
41
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
42
+ server.setRequestHandler(ListResourcesRequestSchema, () => clients[0].listResources());
43
+ server.setRequestHandler(ReadResourceRequestSchema, request => clients[0].readResource(request.params));
44
+ server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
45
+ if (request.params.name === 'create_app') {
46
+ try {
47
+ const input = z.object({ name: z.string().min(1), directory: z.string().min(1), brief: z.string().min(1), xcodegen: z.boolean().default(true) }).strict().parse(request.params.arguments);
48
+ const result = await promisify(execFile)(process.execPath, [cli(), 'new', input.name, '--into', input.directory, '--brief', input.brief, ...(input.xcodegen ? ['--xcodegen'] : [])], { timeout: 30000, maxBuffer: 1024 * 1024 });
49
+ return { content: [{ type: 'text', text: result.stdout || 'App starter created.' }] };
50
+ }
51
+ catch (error) {
52
+ return { isError: true, content: [{ type: 'text', text: error instanceof Error ? error.message : String(error) }] };
53
+ }
54
+ }
55
+ const owner = owners.get(request.params.name);
56
+ if (!owner)
57
+ throw Error('Unknown tool');
58
+ return owner.callTool(request.params, undefined, { timeout: 21 * 60 * 1000, signal: extra.signal });
59
+ });
60
+ process.once('SIGINT', () => { void close().finally(() => process.exit(0)); });
61
+ process.once('SIGTERM', () => { void close().finally(() => process.exit(0)); });
62
+ server.onclose = () => { void close(); };
63
+ await server.connect(new StdioServerTransport());
64
+ }
65
+ catch (error) {
66
+ await close();
67
+ throw error;
68
+ }
69
+ }
70
+ //# sourceMappingURL=unified.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unified.js","sourceRoot":"","sources":["../src/unified.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "2.4.0";
1
+ export declare const VERSION = "2.5.0";
package/dist/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // GENERATED by scripts/sync-version.mjs — do not edit.
2
2
  // The version lives in package.json. Run `npm run sync-version` after changing it.
3
- export const VERSION = "2.4.0";
3
+ export const VERSION = "2.5.0";
4
4
  //# sourceMappingURL=version.js.map
package/mcp.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "ios-agent-mcp",
3
3
  "displayName": "iOS Agent",
4
- "version": "2.4.0",
5
- "description": "Static analysis for modern iOS/Swift projects Swift 6 actor isolation, architecture boundaries, SwiftUI, availability guards, and App Store readiness — plus a linter for Agent Skill repositories.",
4
+ "version": "2.5.0",
5
+ "description": "Unified iOS development tools: Swift reviews, Apple source retrieval, app scaffolding and Xcode simulator workflows.",
6
6
  "author": "Nagarjuna Reddy",
7
7
  "license": "MIT",
8
- "homepage": "https://github.com/Nagarjuna2997/ios-agent-skill",
8
+ "homepage": "https://nagarjuna2997.github.io/ios-agent-skill/",
9
9
  "repository": {
10
10
  "type": "git",
11
11
  "url": "https://github.com/Nagarjuna2997/ios-agent-skill.git",
@@ -23,7 +23,7 @@
23
23
  ],
24
24
  "runtime": {
25
25
  "type": "node",
26
- "minimumVersion": "18",
26
+ "minimumVersion": "20",
27
27
  "transport": "stdio",
28
28
  "command": "npx",
29
29
  "args": [
@@ -32,54 +32,146 @@
32
32
  ]
33
33
  },
34
34
  "permissions": {
35
- "filesystem": "read",
36
- "network": "none",
37
- "notes": "Reads .swift, Info.plist, Package.swift, and project.pbxproj files under the path you pass to a tool. Makes no network requests and writes nothing."
35
+ "filesystem": "read-write",
36
+ "network": "tool-dependent",
37
+ "notes": "Reviews and local reference retrieval are read-only. App creation writes a new project. Simulator tools execute Xcode and manage apps/devices; preview serves on loopback. Invoking builds can use network for dependencies."
38
38
  },
39
39
  "tools": [
40
- {
41
- "name": "analyze_swift_project",
42
- "summary": "Project overview plus a finding count for every rule category."
43
- },
44
40
  {
45
41
  "name": "review_swift_concurrency",
46
- "summary": "Swift 6 actor isolation and concurrency defects."
42
+ "summary": "Check a Swift project for Swift 6 concurrency and isolation defects: @Observable types missing @MainActor, Task.detached, DispatchQueue.main.async in async code, @unchecked Sendable, nonisolated(unsafe), unstructured Tasks in onAppear, empty catch blocks, and types named Task that shadow _Concurrency.Task. Use when reviewing Swift code, migrating to Swift 6, or diagnosing a data race."
47
43
  },
48
44
  {
49
45
  "name": "review_swift_architecture",
50
- "summary": "Architecture boundaries, dependency injection, testability."
46
+ "summary": "Check a Swift project for architecture and testability defects: dependencies defaulting to live implementations, the presentation layer naming concrete data-layer types (URLSession, APIClient, ModelContext), singletons resolved inside view models, the domain layer importing UI frameworks, nested NavigationStacks, and deprecated NavigationView. Use when reviewing MVVM or Clean Architecture code, or when a screen cannot be previewed without a network."
51
47
  },
52
48
  {
53
49
  "name": "review_swiftui",
54
- "summary": "SwiftUI view and state defects, Dynamic Type, design tokens."
50
+ "summary": "Check SwiftUI code for view and state defects: fixed font sizes and heights that break Dynamic Type, AnyView, deprecated .cornerRadius, literal spacing values instead of design tokens, materials applied over solid backgrounds, transient presentation state stored on models, legacy ObservableObject and @EnvironmentObject, and try!. Use when reviewing or building SwiftUI screens."
55
51
  },
56
52
  {
57
53
  "name": "check_availability_guards",
58
- "summary": "Missing and over-restrictive @available guards."
54
+ "summary": "Verify that version-gated Apple APIs are guarded on the version where they were INTRODUCED rather than the newest SDK. Catches both missing guards and over-restrictive ones — for example Liquid Glass (iOS 26) guarded at iOS 27, which silently drops every iOS 26 device to the fallback. Also flags Foundation Models used without a runtime SystemLanguageModel.availability check. Use before shipping, or after bumping an SDK."
59
55
  },
60
56
  {
61
57
  "name": "audit_app_store_readiness",
62
- "summary": "Purpose strings, privacy manifest, accessibility, localization."
58
+ "summary": "Check a Swift project for issues that cause App Store rejection or runtime termination: permission-gated frameworks used without an Info.plist purpose string, a missing PrivacyInfo.xcprivacy manifest, unlocalized user-facing strings, icon-only buttons with no accessibility label, and print() used for logging. Use before submitting to App Review."
59
+ },
60
+ {
61
+ "name": "analyze_swift_project",
62
+ "summary": "Produce an overview of a Swift project — file and line counts, deployment target, Swift tools version, frameworks in use, whether tests exist — together with a summary count of findings across every rule category (concurrency, architecture, SwiftUI, availability, App Store). Use this first when you are unfamiliar with a codebase, then run the focused tools on whichever category has findings."
63
+ },
64
+ {
65
+ "name": "lint_skill",
66
+ "summary": "Validate the metadata of an Agent Skill repository rather than Swift source: SKILL.md frontmatter (required keys, kebab-case name, semver version, description length limits), subagent definitions in .claude/agents/ (name matches filename, unknown tool names, and read-only agents that are nonetheless granted Edit or Write), whether generated mirror files such as CLAUDE.md and AGENTS.md have drifted from SKILL.md, and backtick-quoted doc paths that do not resolve. Use when authoring or reviewing a skill, before publishing a release, or when a subagent or skill is not being invoked as expected."
63
67
  },
64
68
  {
65
69
  "name": "review_swift_memory",
66
- "summary": "Retain cycles, weak/unowned usage, closure and Task lifetime."
70
+ "summary": "Check a Swift project for retain cycles and lifetime defects: repeating Timers and block-based NotificationCenter observers capturing self strongly, Combine sinks stored in a cancellables set owned by the same object, non-weak delegate properties, stored closure properties capturing self, `unowned self` in escaping closures, and long-running unstructured Tasks that keep an object alive after its screen is gone. Use when memory grows over time, when deinit is never called, or before shipping a screen with timers or subscriptions."
67
71
  },
68
72
  {
69
73
  "name": "review_swift_security",
70
- "summary": "Hardcoded secrets, insecure storage, ATS, TLS, weak crypto, Keychain accessibility."
74
+ "summary": "Check a Swift project for security defects: hardcoded API keys, tokens, and passwords in source; credentials written to UserDefaults instead of the Keychain; App Transport Security disabled; cleartext http:// endpoints; TLS server trust accepted without evaluation; MD5 and SHA-1; Keychain items with over-permissive accessibility; non-cryptographic randomness used for nonces and salts; secrets written to logs; and string interpolation into evaluated JavaScript. Use before shipping, during a security review, or when handling credentials."
71
75
  },
72
76
  {
73
77
  "name": "review_swift_testing",
74
- "summary": "Flaky patterns, vacuous tests, live network in tests, missing coverage."
78
+ "summary": "Check a Swift test suite for defects that make it unreliable or vacuous: tests that wait by sleeping, tests with no assertion at all, `await` inside an XCTAssert autoclosure (which does not compile), live URLSession calls in tests, `try!`, static mutable state that makes results order-dependent, long expectation timeouts covering for races, and XCTAssertTrue on an equality that hides both values on failure. Also reports when a project has no tests or very few. Use when tests are flaky, before trusting a green suite, or when adding coverage."
75
79
  },
76
80
  {
77
81
  "name": "review_swift_performance",
78
- "summary": "Work inside body, eager stacks, unstable ForEach identity, blocking I/O."
82
+ "summary": "Check for runtime cost that shows up as dropped frames: DateFormatter and JSONDecoder allocated inside `body`, collections sorted or filtered on every render, ForEach over indices instead of stable identity, non-lazy stacks inside a ScrollView, AsyncImage with no frame, blocking file or network I/O on the render path, and GeometryReader wrapping an entire body. Use when scrolling stutters, launch is slow, or before shipping a list-heavy screen."
79
83
  },
80
84
  {
81
- "name": "lint_skill",
82
- "summary": "Agent Skill metadata: frontmatter, subagent tool grants, mirror sync, doc references."
85
+ "name": "search_apple_technologies",
86
+ "summary": "Find Apple frameworks, tools, services and legacy technologies in the bundled 405-entry source snapshot."
87
+ },
88
+ {
89
+ "name": "get_apple_technology",
90
+ "summary": "Get a compact technology overview and local source routes by default. Use view full only when the entire guide and API topic map are required."
91
+ },
92
+ {
93
+ "name": "get_apple_updates",
94
+ "summary": "Search dated Apple update and release-note landing pages with version-specific source links. Does not claim live results."
95
+ },
96
+ {
97
+ "name": "plan_ios_app",
98
+ "summary": "Return an implementation workflow and safe CLI argument array for a named app. No files are created and no build is claimed."
99
+ },
100
+ {
101
+ "name": "plan_app_icon",
102
+ "summary": "Return a separate-layer icon specification, Apple workflow and appearance checks. Does not fabricate a native .icon document."
103
+ },
104
+ {
105
+ "name": "search_local_references",
106
+ "summary": "Search complete repository guides, Swift source, templates and assets offline. Returns compact file matches without loading bodies. Source files and guide code blocks have different verification status."
107
+ },
108
+ {
109
+ "name": "read_local_reference",
110
+ "summary": "Read exact bundled file content in bounded character ranges. Use nextOffset to continue without omission; no network or user filesystem access. Offset is a JavaScript UTF-16 string index."
111
+ },
112
+ {
113
+ "name": "get_reference_outline",
114
+ "summary": "Get heading offsets so only the relevant section needs to be read."
115
+ },
116
+ {
117
+ "name": "simulator_list",
118
+ "summary": "List available Simulator devices using xcrun simctl. Use before booting, installing, launching, or capturing screenshots when you do not know the simulator UDID."
119
+ },
120
+ {
121
+ "name": "simulator_boot",
122
+ "summary": "Boot a simulator by UDID using xcrun simctl boot. Use before install_app, launch_app, screenshot, or open_deep_link. This does not erase or reset simulator content."
123
+ },
124
+ {
125
+ "name": "simulator_shutdown",
126
+ "summary": "Shut down a simulator by UDID using xcrun simctl shutdown. Use after runtime validation to clean up a booted simulator. This does not erase content."
127
+ },
128
+ {
129
+ "name": "install_app",
130
+ "summary": "Install a built .app bundle into a simulator using xcrun simctl install. Use after build_project or after locating a derived-data app bundle."
131
+ },
132
+ {
133
+ "name": "launch_app",
134
+ "summary": "Launch an installed app in the simulator by bundle identifier. Optional arguments are passed after the bundle id and are useful for UI-test/debug launch flags."
135
+ },
136
+ {
137
+ "name": "terminate_app",
138
+ "summary": "Terminate a running simulator app by bundle identifier without uninstalling it or resetting its state."
139
+ },
140
+ {
141
+ "name": "open_deep_link",
142
+ "summary": "Open a URL in the simulator using xcrun simctl openurl. Use to verify deep links, universal links, onboarding routes, and state restoration."
143
+ },
144
+ {
145
+ "name": "screenshot",
146
+ "summary": "Capture a simulator screenshot to a PNG path using xcrun simctl io screenshot. Use as evidence for visual review and before/after comparison."
147
+ },
148
+ {
149
+ "name": "build_project",
150
+ "summary": "Run xcodebuild build for a project or workspace. Use before installing and launching the app. Requires a scheme and either project or workspace."
151
+ },
152
+ {
153
+ "name": "run_tests",
154
+ "summary": "Run xcodebuild test for a project or workspace. Use to verify runtime/test behavior before visual review. Requires an explicit destination."
155
+ },
156
+ {
157
+ "name": "simulator_environment",
158
+ "summary": "Report selected Xcode, installed runtimes and real device profiles, including Duo when installed. Does not download or update Xcode."
159
+ },
160
+ {
161
+ "name": "simulator_show",
162
+ "summary": "Boot and wait for a selected available device, then open its native Simulator window for touch/keyboard interaction."
163
+ },
164
+ {
165
+ "name": "simulator_preview_start",
166
+ "summary": "Start a token-protected loopback screenshot viewer for a booted device. Open the returned URL in the client sidebar/browser. Read-only visual preview; interact in the native Simulator. Not a public hosted simulator."
167
+ },
168
+ {
169
+ "name": "simulator_preview_stop",
170
+ "summary": "Stop this server’s preview for a device and remove its temporary screenshots; leaves the Simulator running."
171
+ },
172
+ {
173
+ "name": "create_app",
174
+ "summary": "Create an editable Swift app starter, implementation brief and optional XcodeGen specification/icon layers. Writes a NEW project; does not implement the full app idea. Then use source retrieval, review and simulator tools to implement and verify it."
83
175
  }
84
176
  ],
85
177
  "resources": [
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "ios-agent-mcp",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "MCP server for modern iOS/Swift development — concurrency isolation, architecture boundaries, SwiftUI, and App Store readiness analysis",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "bin": {
8
- "ios-agent-mcp": "dist/index.js",
8
+ "ios-agent-mcp": "dist/unified.js",
9
9
  "ios-agent-knowledge": "dist/knowledge-server.js"
10
10
  },
11
11
  "main": "dist/index.js",
@@ -16,7 +16,7 @@
16
16
  "data"
17
17
  ],
18
18
  "engines": {
19
- "node": ">=18"
19
+ "node": ">=20"
20
20
  },
21
21
  "scripts": {
22
22
  "build": "node scripts/sync-version.mjs && node scripts/bundle-knowledge.mjs && tsc",
@@ -41,7 +41,9 @@
41
41
  ],
42
42
  "dependencies": {
43
43
  "@modelcontextprotocol/sdk": "^1.30.0",
44
- "zod": "^3.23.8"
44
+ "zod": "^3.23.8",
45
+ "@nagarjuna2002/ios-agent": "0.2.0",
46
+ "@nagarjuna2002/ios-simulator-mcp": "0.2.0"
45
47
  },
46
48
  "devDependencies": {
47
49
  "@types/express": "^5.0.6",
@@ -53,7 +55,7 @@
53
55
  "url": "git+https://github.com/Nagarjuna2997/ios-agent-skill.git",
54
56
  "directory": "mcp-server"
55
57
  },
56
- "homepage": "https://github.com/Nagarjuna2997/ios-agent-skill/tree/main/mcp-server",
58
+ "homepage": "https://nagarjuna2997.github.io/ios-agent-skill/",
57
59
  "bugs": {
58
60
  "url": "https://github.com/Nagarjuna2997/ios-agent-skill/issues"
59
61
  }