ios-vibe-mcp00 0.1.2
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.
- package/README.md +182 -0
- package/dist/index.js +17 -0
- package/dist/iosVibe.js +113 -0
- package/dist/rules.js +48 -0
- package/dist/templates.js +300 -0
- package/ios-vibe-mcp0-0.1.1.tgz +0 -0
- package/package.json +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# ios-vibe-mcp π
|
|
2
|
+
|
|
3
|
+
Transform any idea into a complete iOS application using AI in Cursor.
|
|
4
|
+
Works with **ANY LLM** (Claude, GPT-4, Gemini, etc.).
|
|
5
|
+
|
|
6
|
+
`ios-vibe-mcp` is an MCP (Model Context Protocol) server designed for **vibe coding** iOS apps with SwiftUI.
|
|
7
|
+
It generates full project specs, architecture plans, coding steps, UI/UX guidance, and test strategies β all as Markdown files.
|
|
8
|
+
|
|
9
|
+
> Note: The tool is currently in MVP stage.
|
|
10
|
+
> The GitHub repository is private for now.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## π Quick Start
|
|
15
|
+
|
|
16
|
+
### Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx ios-vibe-mcp
|
|
20
|
+
Add to Cursor
|
|
21
|
+
Add the following configuration to your Cursor mcp.json file:
|
|
22
|
+
|
|
23
|
+
{
|
|
24
|
+
"mcpServers": {
|
|
25
|
+
"ios-vibe-factory": {
|
|
26
|
+
"command": "npx",
|
|
27
|
+
"args": ["-y", "ios-vibe-mcp00"]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
Restart Cursor completely after adding this.
|
|
32
|
+
|
|
33
|
+
π§ Basic Usage (No JSON Required)
|
|
34
|
+
You donβt need to write JSON.
|
|
35
|
+
Just type commands in plain text inside Cursor chat.
|
|
36
|
+
|
|
37
|
+
1οΈβ£ Generate project blueprint
|
|
38
|
+
plan: SwiftUI offline-first notes app with CoreData
|
|
39
|
+
Creates:
|
|
40
|
+
|
|
41
|
+
PROJECT_BLUEPRINT.md
|
|
42
|
+
|
|
43
|
+
TODO.md
|
|
44
|
+
|
|
45
|
+
IOS_RULES.md
|
|
46
|
+
|
|
47
|
+
RUNBOOK.md
|
|
48
|
+
|
|
49
|
+
BACKLOG.md
|
|
50
|
+
|
|
51
|
+
2οΈβ£ Create architecture plan
|
|
52
|
+
architecture
|
|
53
|
+
Creates:
|
|
54
|
+
|
|
55
|
+
STAGE_ARCHITECTURE.md
|
|
56
|
+
|
|
57
|
+
3οΈβ£ Generate coding plan
|
|
58
|
+
coding
|
|
59
|
+
Creates:
|
|
60
|
+
|
|
61
|
+
STAGE_CODING.md
|
|
62
|
+
|
|
63
|
+
4οΈβ£ Generate UI/UX guide
|
|
64
|
+
uiux
|
|
65
|
+
Creates:
|
|
66
|
+
|
|
67
|
+
STAGE_UIUX.md
|
|
68
|
+
|
|
69
|
+
5οΈβ£ Generate test strategy
|
|
70
|
+
test
|
|
71
|
+
Creates:
|
|
72
|
+
|
|
73
|
+
STAGE_TEST.md
|
|
74
|
+
|
|
75
|
+
π οΈ Commands
|
|
76
|
+
Command What it does Output file
|
|
77
|
+
plan: <idea> Generates full product blueprint PROJECT_BLUEPRINT.md
|
|
78
|
+
architecture Defines app structure & data layer STAGE_ARCHITECTURE.md
|
|
79
|
+
coding Feature-by-feature coding roadmap STAGE_CODING.md
|
|
80
|
+
uiux UX/UI checklist & design rules STAGE_UIUX.md
|
|
81
|
+
test Testing strategy & critical flows STAGE_TEST.md
|
|
82
|
+
review Consistency checks REVIEW_REPORT.md
|
|
83
|
+
ship App Store readiness checklist SHIP_CHECKLIST.md
|
|
84
|
+
π Key Features
|
|
85
|
+
Command-based workflow for building iOS apps
|
|
86
|
+
|
|
87
|
+
SwiftUI-first architecture
|
|
88
|
+
|
|
89
|
+
Enforces:
|
|
90
|
+
|
|
91
|
+
MVVM + Repository pattern
|
|
92
|
+
|
|
93
|
+
Offline-first behavior
|
|
94
|
+
|
|
95
|
+
No Firebase by default
|
|
96
|
+
|
|
97
|
+
Generates:
|
|
98
|
+
|
|
99
|
+
Product spec
|
|
100
|
+
|
|
101
|
+
Architecture spec
|
|
102
|
+
|
|
103
|
+
Coding roadmap
|
|
104
|
+
|
|
105
|
+
UI/UX guide
|
|
106
|
+
|
|
107
|
+
Test plan
|
|
108
|
+
|
|
109
|
+
App Store checklist
|
|
110
|
+
|
|
111
|
+
Perfect for:
|
|
112
|
+
|
|
113
|
+
MVP generation
|
|
114
|
+
|
|
115
|
+
Vibe coding
|
|
116
|
+
|
|
117
|
+
AI pair programming
|
|
118
|
+
|
|
119
|
+
Rapid prototyping
|
|
120
|
+
|
|
121
|
+
ποΈ How It Works
|
|
122
|
+
Workflow
|
|
123
|
+
plan β architecture β coding β uiux β test β review β ship
|
|
124
|
+
Each step generates a Markdown spec file and locks scope for the next step.
|
|
125
|
+
|
|
126
|
+
Files Generated
|
|
127
|
+
File Purpose
|
|
128
|
+
PROJECT_BLUEPRINT.md Full product definition
|
|
129
|
+
TODO.md Task list for entire app
|
|
130
|
+
IOS_RULES.md Enforced iOS architecture rules
|
|
131
|
+
RUNBOOK.md How to run and debug
|
|
132
|
+
BACKLOG.md Scope lock for new ideas
|
|
133
|
+
STAGE_ARCHITECTURE.md Folder structure + data layer
|
|
134
|
+
STAGE_CODING.md Feature-by-feature coding plan
|
|
135
|
+
STAGE_UIUX.md UX rules & components
|
|
136
|
+
STAGE_TEST.md Testing strategy
|
|
137
|
+
SHIP_CHECKLIST.md App Store readiness
|
|
138
|
+
π± Platforms Supported
|
|
139
|
+
iOS (SwiftUI)
|
|
140
|
+
|
|
141
|
+
Storage:
|
|
142
|
+
|
|
143
|
+
CoreData (default)
|
|
144
|
+
|
|
145
|
+
SwiftData (experimental)
|
|
146
|
+
|
|
147
|
+
π Requirements
|
|
148
|
+
Node.js 18+
|
|
149
|
+
|
|
150
|
+
Cursor IDE (with MCP enabled)
|
|
151
|
+
|
|
152
|
+
Any LLM (Claude, GPT-4, Gemini, etc.)
|
|
153
|
+
|
|
154
|
+
macOS + Xcode (for iOS development)
|
|
155
|
+
|
|
156
|
+
π₯ Perfect For
|
|
157
|
+
Beginners β Turn ideas into real iOS apps
|
|
158
|
+
|
|
159
|
+
Developers β Speed up SwiftUI development
|
|
160
|
+
|
|
161
|
+
Startups β Rapid MVP creation
|
|
162
|
+
|
|
163
|
+
Students β Learn by building real apps
|
|
164
|
+
|
|
165
|
+
Indie hackers β Vibe coding workflows
|
|
166
|
+
|
|
167
|
+
π§ͺ Example Workflow
|
|
168
|
+
plan: expense tracker app
|
|
169
|
+
architecture
|
|
170
|
+
coding
|
|
171
|
+
uiux
|
|
172
|
+
test
|
|
173
|
+
ship
|
|
174
|
+
π‘οΈ License
|
|
175
|
+
MIT
|
|
176
|
+
|
|
177
|
+
π€ Author
|
|
178
|
+
Talha Pakdil
|
|
179
|
+
GitHub: https://github.com/talhapakdil7
|
|
180
|
+
LinkedIn: https://www.linkedin.com/in/talhapakdil
|
|
181
|
+
|
|
182
|
+
```
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { registerIosVibeTool } from "./iosVibe.js";
|
|
5
|
+
const server = new McpServer({
|
|
6
|
+
name: "iOS Vibe Factory",
|
|
7
|
+
version: "0.1.0",
|
|
8
|
+
});
|
|
9
|
+
registerIosVibeTool(server);
|
|
10
|
+
async function main() {
|
|
11
|
+
const transport = new StdioServerTransport();
|
|
12
|
+
await server.connect(transport);
|
|
13
|
+
}
|
|
14
|
+
main().catch((err) => {
|
|
15
|
+
console.error("Fatal MCP server error:", err);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
});
|
package/dist/iosVibe.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { renderFilesForCommand } from "./templates.js";
|
|
3
|
+
import { validateWorkflow } from "./rules.js";
|
|
4
|
+
const CommandSchema = z.enum(["plan", "architecture", "coding", "uiux", "test", "review", "ship"]);
|
|
5
|
+
const InputSchema = z.object({
|
|
6
|
+
command: CommandSchema,
|
|
7
|
+
idea: z.string().optional(),
|
|
8
|
+
config: z
|
|
9
|
+
.object({
|
|
10
|
+
appName: z.string().default("MyApp"),
|
|
11
|
+
iosMin: z.string().default("17.0"),
|
|
12
|
+
storage: z.enum(["coredata", "swiftdata"]).default("coredata"),
|
|
13
|
+
tone: z.string().default("soft pink"),
|
|
14
|
+
constraints: z.array(z.string()).default(["offline-first", "no firebase", "mvvm", "repository"]),
|
|
15
|
+
})
|
|
16
|
+
.optional(),
|
|
17
|
+
state: z
|
|
18
|
+
.object({
|
|
19
|
+
projectBlueprintMd: z.string().optional(),
|
|
20
|
+
todoMd: z.string().optional(),
|
|
21
|
+
stageArchitectureMd: z.string().optional(),
|
|
22
|
+
stageCodingMd: z.string().optional(),
|
|
23
|
+
stageUiuxMd: z.string().optional(),
|
|
24
|
+
stageTestMd: z.string().optional(),
|
|
25
|
+
iosRulesMd: z.string().optional(),
|
|
26
|
+
runbookMd: z.string().optional(),
|
|
27
|
+
backlogMd: z.string().optional(),
|
|
28
|
+
})
|
|
29
|
+
.optional(),
|
|
30
|
+
});
|
|
31
|
+
/**
|
|
32
|
+
* Accepts both:
|
|
33
|
+
* 1) JSON input (object): { command: "plan", idea: "..." }
|
|
34
|
+
* 2) Human text input (string): "plan: ..." or "architecture" etc.
|
|
35
|
+
* Also supports { text: "plan: ..." } shape as a convenience.
|
|
36
|
+
*/
|
|
37
|
+
function normalizeInput(raw) {
|
|
38
|
+
const text = typeof raw === "string"
|
|
39
|
+
? raw
|
|
40
|
+
: raw && typeof raw === "object" && "text" in raw && typeof raw.text === "string"
|
|
41
|
+
? raw.text
|
|
42
|
+
: null;
|
|
43
|
+
if (!text)
|
|
44
|
+
return raw;
|
|
45
|
+
const t = text.trim();
|
|
46
|
+
// plan: <idea>
|
|
47
|
+
const planMatch = t.match(/^plan\s*:\s*(.+)$/i);
|
|
48
|
+
if (planMatch) {
|
|
49
|
+
return { command: "plan", idea: planMatch[1].trim() };
|
|
50
|
+
}
|
|
51
|
+
// Single-word commands
|
|
52
|
+
const lower = t.toLowerCase();
|
|
53
|
+
const allowed = ["architecture", "coding", "uiux", "test", "review", "ship"];
|
|
54
|
+
if (allowed.includes(lower)) {
|
|
55
|
+
return { command: lower };
|
|
56
|
+
}
|
|
57
|
+
// If user writes just "plan" without idea, let workflow validator handle it
|
|
58
|
+
if (/^plan$/i.test(t)) {
|
|
59
|
+
return { command: "plan", idea: "" };
|
|
60
|
+
}
|
|
61
|
+
// Fallback: keep original raw so Zod can throw a clear error
|
|
62
|
+
return raw;
|
|
63
|
+
}
|
|
64
|
+
export function registerIosVibeTool(server) {
|
|
65
|
+
server.tool("ios_vibe", {
|
|
66
|
+
// Keep this permissive so the tool can accept either object inputs
|
|
67
|
+
// or "text" wrappers depending on the client
|
|
68
|
+
command: z.string().optional(),
|
|
69
|
+
idea: z.string().optional(),
|
|
70
|
+
config: z.any().optional(),
|
|
71
|
+
state: z.any().optional(),
|
|
72
|
+
text: z.string().optional(),
|
|
73
|
+
}, async (raw) => {
|
|
74
|
+
const normalized = normalizeInput(raw);
|
|
75
|
+
const parsed = InputSchema.safeParse(normalized);
|
|
76
|
+
if (!parsed.success) {
|
|
77
|
+
return {
|
|
78
|
+
content: [
|
|
79
|
+
{
|
|
80
|
+
type: "text",
|
|
81
|
+
text: `Invalid input: ${parsed.error.message}`,
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const input = parsed.data;
|
|
87
|
+
// 1) Workflow gatekeeping
|
|
88
|
+
const flow = validateWorkflow(input);
|
|
89
|
+
if (!flow.ok) {
|
|
90
|
+
return {
|
|
91
|
+
content: [
|
|
92
|
+
{
|
|
93
|
+
type: "text",
|
|
94
|
+
text: `Command blocked: ${flow.reason}\n\n` +
|
|
95
|
+
`Fix: ${flow.fix}\n\n` +
|
|
96
|
+
`Suggested next: ${flow.suggestedNext}`,
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// 2) Generate files
|
|
102
|
+
const result = renderFilesForCommand(input);
|
|
103
|
+
// 3) MCP output
|
|
104
|
+
return {
|
|
105
|
+
content: [
|
|
106
|
+
{
|
|
107
|
+
type: "text",
|
|
108
|
+
text: JSON.stringify(result, null, 2),
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
}
|
package/dist/rules.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export function validateWorkflow(input) {
|
|
2
|
+
const s = input.state ?? {};
|
|
3
|
+
if (input.command === "plan") {
|
|
4
|
+
if (!input.idea || input.idea.trim().length < 10) {
|
|
5
|
+
return {
|
|
6
|
+
ok: false,
|
|
7
|
+
reason: "`plan` requires a non-trivial `idea` (>= 10 chars).",
|
|
8
|
+
fix: "Call ios_vibe with { command: 'plan', idea: '...' }",
|
|
9
|
+
suggestedNext: "plan",
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
return { ok: true };
|
|
13
|
+
}
|
|
14
|
+
// plan sonrasΔ± her Εey iΓ§in blueprint Εart
|
|
15
|
+
if (!s.projectBlueprintMd || s.projectBlueprintMd.trim().length < 50) {
|
|
16
|
+
return {
|
|
17
|
+
ok: false,
|
|
18
|
+
reason: "Missing PROJECT_BLUEPRINT.md state. Run `plan` first (or pass blueprint in state).",
|
|
19
|
+
fix: "Call `plan`, write PROJECT_BLUEPRINT.md to disk, then pass it back in `state.projectBlueprintMd`.",
|
|
20
|
+
suggestedNext: "plan",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
if (input.command === "coding" && (!s.stageArchitectureMd || s.stageArchitectureMd.trim().length < 50)) {
|
|
24
|
+
return {
|
|
25
|
+
ok: false,
|
|
26
|
+
reason: "`coding` requires STAGE_ARCHITECTURE.md (architecture step).",
|
|
27
|
+
fix: "Run `architecture` first and pass the generated STAGE_ARCHITECTURE.md back in state.",
|
|
28
|
+
suggestedNext: "architecture",
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (input.command === "uiux" && (!s.stageCodingMd || s.stageCodingMd.trim().length < 50)) {
|
|
32
|
+
return {
|
|
33
|
+
ok: false,
|
|
34
|
+
reason: "`uiux` works best after `coding` (needs screen & component plan).",
|
|
35
|
+
fix: "Run `coding` first and pass STAGE_CODING.md back in state.",
|
|
36
|
+
suggestedNext: "coding",
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (input.command === "test" && (!s.stageCodingMd || s.stageCodingMd.trim().length < 50)) {
|
|
40
|
+
return {
|
|
41
|
+
ok: false,
|
|
42
|
+
reason: "`test` requires at least STAGE_CODING.md to know critical flows.",
|
|
43
|
+
fix: "Run `coding` first and pass STAGE_CODING.md back in state.",
|
|
44
|
+
suggestedNext: "coding",
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return { ok: true };
|
|
48
|
+
}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
const md = (s) => s.trim() + "\n";
|
|
2
|
+
export function renderFilesForCommand(input) {
|
|
3
|
+
const cfg = {
|
|
4
|
+
appName: input.config?.appName ?? "MyApp",
|
|
5
|
+
iosMin: input.config?.iosMin ?? "17.0",
|
|
6
|
+
storage: input.config?.storage ?? "coredata",
|
|
7
|
+
tone: input.config?.tone ?? "soft pink",
|
|
8
|
+
constraints: input.config?.constraints ?? ["offline-first", "no firebase", "mvvm", "repository"],
|
|
9
|
+
};
|
|
10
|
+
const files = [];
|
|
11
|
+
const warnings = [];
|
|
12
|
+
const iosRules = md(`
|
|
13
|
+
# IOS_RULES.md
|
|
14
|
+
|
|
15
|
+
## Non-negotiables
|
|
16
|
+
- SwiftUI only
|
|
17
|
+
- MVVM + Repository pattern
|
|
18
|
+
- Storage: ${cfg.storage.toUpperCase()}
|
|
19
|
+
- Offline-first by default
|
|
20
|
+
- No Firebase (unless explicitly allowed)
|
|
21
|
+
- Every screen must define: Loading / Empty / Error states
|
|
22
|
+
- New feature requests go to BACKLOG.md (do not expand MVP silently)
|
|
23
|
+
|
|
24
|
+
## Folder structure (fixed)
|
|
25
|
+
- App/
|
|
26
|
+
- Features/
|
|
27
|
+
- <Feature>/
|
|
28
|
+
- Views/
|
|
29
|
+
- ViewModels/
|
|
30
|
+
- Models/
|
|
31
|
+
- Core/
|
|
32
|
+
- DesignSystem/
|
|
33
|
+
- Persistence/
|
|
34
|
+
- Utilities/
|
|
35
|
+
- Resources/
|
|
36
|
+
- Tests/
|
|
37
|
+
`);
|
|
38
|
+
const runbook = md(`
|
|
39
|
+
# RUNBOOK.md
|
|
40
|
+
|
|
41
|
+
## Requirements
|
|
42
|
+
- macOS + Xcode (CLI tools installed)
|
|
43
|
+
- iOS ${cfg.iosMin}+
|
|
44
|
+
|
|
45
|
+
## How to run
|
|
46
|
+
- Open the Xcode project/workspace
|
|
47
|
+
- Select a simulator
|
|
48
|
+
- Run (Cmd+R)
|
|
49
|
+
|
|
50
|
+
## Troubleshooting
|
|
51
|
+
- Build fails: check Signing settings (for device) or run on Simulator first
|
|
52
|
+
- If tests fail: run the failing test target only and re-check data seeding
|
|
53
|
+
`);
|
|
54
|
+
const backlog = md(`
|
|
55
|
+
# BACKLOG.md
|
|
56
|
+
New ideas go here. Do not expand MVP scope without explicitly moving items into TODO.md.
|
|
57
|
+
`);
|
|
58
|
+
// PLAN
|
|
59
|
+
if (input.command === "plan") {
|
|
60
|
+
const idea = input.idea ?? "";
|
|
61
|
+
const blueprint = md(`
|
|
62
|
+
# PROJECT_BLUEPRINT.md β ${cfg.appName}
|
|
63
|
+
|
|
64
|
+
## Product snapshot
|
|
65
|
+
**One-liner:** ${idea}
|
|
66
|
+
|
|
67
|
+
## Goals (MVP)
|
|
68
|
+
- Deliver the core value in the simplest possible way
|
|
69
|
+
- Offline-first experience
|
|
70
|
+
- Clean MVVM + Repository structure
|
|
71
|
+
|
|
72
|
+
## Non-goals (Scope lock)
|
|
73
|
+
- Authentication / accounts
|
|
74
|
+
- Backend sync
|
|
75
|
+
- Social feed / chat
|
|
76
|
+
- Payments
|
|
77
|
+
|
|
78
|
+
## Constraints
|
|
79
|
+
${cfg.constraints.map((c) => `- ${c}`).join("\n")}
|
|
80
|
+
|
|
81
|
+
## Target platform
|
|
82
|
+
- iOS ${cfg.iosMin}+
|
|
83
|
+
- SwiftUI
|
|
84
|
+
|
|
85
|
+
## Screens (initial)
|
|
86
|
+
- Onboarding (optional): explain what app does
|
|
87
|
+
- Home: main action + list
|
|
88
|
+
- Detail: item details
|
|
89
|
+
- Profile/Settings: app preferences
|
|
90
|
+
|
|
91
|
+
## Data model (draft)
|
|
92
|
+
- Entity: **UserProfile** (id, name, createdAt)
|
|
93
|
+
- Entity: **Item** (id, title, note, createdAt, updatedAt)
|
|
94
|
+
|
|
95
|
+
## Navigation map
|
|
96
|
+
Onboarding β Home β Detail
|
|
97
|
+
Home β Settings
|
|
98
|
+
|
|
99
|
+
## Done criteria
|
|
100
|
+
- App runs on simulator
|
|
101
|
+
- Core flow works end-to-end offline
|
|
102
|
+
- Basic empty/error states exist
|
|
103
|
+
- TODO checklist completed
|
|
104
|
+
`);
|
|
105
|
+
const todo = md(`
|
|
106
|
+
# TODO.md
|
|
107
|
+
|
|
108
|
+
## 0) Scope lock β
|
|
109
|
+
- [ ] Confirm Goals + Non-goals
|
|
110
|
+
- [ ] Confirm screen list
|
|
111
|
+
- [ ] Confirm data model entities
|
|
112
|
+
- [ ] Confirm constraints
|
|
113
|
+
|
|
114
|
+
## 1) Architecture
|
|
115
|
+
- [ ] Create folder structure (App/Features/Core/Resources/Tests)
|
|
116
|
+
- [ ] Setup ${cfg.storage.toUpperCase()} persistence layer
|
|
117
|
+
- [ ] Define Repository protocols
|
|
118
|
+
- [ ] Define Navigation skeleton
|
|
119
|
+
|
|
120
|
+
## 2) Coding
|
|
121
|
+
- [ ] Implement Home (View + VM + Repo)
|
|
122
|
+
- [ ] Implement Detail (View + VM + Repo)
|
|
123
|
+
- [ ] Implement Settings/Profile
|
|
124
|
+
- [ ] Handle Loading/Empty/Error states
|
|
125
|
+
|
|
126
|
+
## 3) UI/UX
|
|
127
|
+
- [ ] Define design tokens (spacing/typography)
|
|
128
|
+
- [ ] Build reusable components (PrimaryButton, EmptyStateView, etc.)
|
|
129
|
+
- [ ] Microcopy pass (onboarding + empty states)
|
|
130
|
+
|
|
131
|
+
## 4) Test
|
|
132
|
+
- [ ] Unit tests for Repository + ViewModel
|
|
133
|
+
- [ ] 1 UI test for critical flow
|
|
134
|
+
- [ ] Final βship checklistβ
|
|
135
|
+
`);
|
|
136
|
+
files.push({ path: "PROJECT_BLUEPRINT.md", content: blueprint }, { path: "TODO.md", content: todo }, { path: "IOS_RULES.md", content: iosRules }, { path: "RUNBOOK.md", content: runbook }, { path: "BACKLOG.md", content: backlog });
|
|
137
|
+
return {
|
|
138
|
+
files,
|
|
139
|
+
nextCommand: "architecture",
|
|
140
|
+
warnings,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// Always keep these
|
|
144
|
+
files.push({ path: "IOS_RULES.md", content: iosRules }, { path: "RUNBOOK.md", content: runbook }, { path: "BACKLOG.md", content: backlog });
|
|
145
|
+
if (input.command === "architecture") {
|
|
146
|
+
files.push({
|
|
147
|
+
path: "STAGE_ARCHITECTURE.md",
|
|
148
|
+
content: md(`
|
|
149
|
+
# STAGE_ARCHITECTURE.md
|
|
150
|
+
|
|
151
|
+
## Architecture decisions
|
|
152
|
+
- SwiftUI + MVVM
|
|
153
|
+
- Repository layer between VM and persistence
|
|
154
|
+
- Persistence: ${cfg.storage.toUpperCase()}
|
|
155
|
+
|
|
156
|
+
## Folder structure (create exactly)
|
|
157
|
+
- App/
|
|
158
|
+
- Features/
|
|
159
|
+
- Home/
|
|
160
|
+
- Detail/
|
|
161
|
+
- Settings/
|
|
162
|
+
- Core/
|
|
163
|
+
- Persistence/
|
|
164
|
+
- DesignSystem/
|
|
165
|
+
- Utilities/
|
|
166
|
+
- Resources/
|
|
167
|
+
- Tests/
|
|
168
|
+
|
|
169
|
+
## TODO (Architecture)
|
|
170
|
+
- [ ] Create folders
|
|
171
|
+
- [ ] Create PersistenceController (${cfg.storage})
|
|
172
|
+
- [ ] Define ItemRepository protocol + default implementation
|
|
173
|
+
- [ ] Define UserProfileRepository protocol + default implementation
|
|
174
|
+
- [ ] Add app-level dependency container (simple struct)
|
|
175
|
+
- [ ] Define navigation routes
|
|
176
|
+
`),
|
|
177
|
+
});
|
|
178
|
+
return { files, nextCommand: "coding", warnings };
|
|
179
|
+
}
|
|
180
|
+
if (input.command === "coding") {
|
|
181
|
+
files.push({
|
|
182
|
+
path: "STAGE_CODING.md",
|
|
183
|
+
content: md(`
|
|
184
|
+
# STAGE_CODING.md
|
|
185
|
+
|
|
186
|
+
## Implementation order (feature-by-feature)
|
|
187
|
+
1) Persistence + repositories
|
|
188
|
+
2) Home (list + create)
|
|
189
|
+
3) Detail (view/edit/delete)
|
|
190
|
+
4) Settings/Profile (basic)
|
|
191
|
+
|
|
192
|
+
## TODO (Coding)
|
|
193
|
+
- [ ] Implement Core/Persistence stack
|
|
194
|
+
- [ ] Implement repositories (CRUD)
|
|
195
|
+
- [ ] HomeView + HomeViewModel
|
|
196
|
+
- [ ] DetailView + DetailViewModel
|
|
197
|
+
- [ ] SettingsView + SettingsViewModel
|
|
198
|
+
- [ ] Wire navigation + previews
|
|
199
|
+
- [ ] Edge states: Loading/Empty/Error
|
|
200
|
+
`),
|
|
201
|
+
});
|
|
202
|
+
return { files, nextCommand: "uiux", warnings };
|
|
203
|
+
}
|
|
204
|
+
if (input.command === "uiux") {
|
|
205
|
+
files.push({
|
|
206
|
+
path: "STAGE_UIUX.md",
|
|
207
|
+
content: md(`
|
|
208
|
+
# STAGE_UIUX.md
|
|
209
|
+
|
|
210
|
+
## Visual direction
|
|
211
|
+
- Tone: ${cfg.tone}
|
|
212
|
+
- Simple, minimal, readable
|
|
213
|
+
- Components first
|
|
214
|
+
|
|
215
|
+
## Screen checklist (must have)
|
|
216
|
+
For each screen:
|
|
217
|
+
- Purpose
|
|
218
|
+
- Primary action
|
|
219
|
+
- Empty state copy
|
|
220
|
+
- Error state copy
|
|
221
|
+
- Loading state UI
|
|
222
|
+
|
|
223
|
+
## TODO (UI/UX)
|
|
224
|
+
- [ ] Define typography + spacing tokens
|
|
225
|
+
- [ ] Create reusable components:
|
|
226
|
+
- PrimaryButton
|
|
227
|
+
- EmptyStateView
|
|
228
|
+
- ErrorBanner
|
|
229
|
+
- CardRow
|
|
230
|
+
- [ ] Apply consistent navigation titles + toolbar actions
|
|
231
|
+
`),
|
|
232
|
+
});
|
|
233
|
+
return { files, nextCommand: "test", warnings };
|
|
234
|
+
}
|
|
235
|
+
if (input.command === "test") {
|
|
236
|
+
files.push({
|
|
237
|
+
path: "STAGE_TEST.md",
|
|
238
|
+
content: md(`
|
|
239
|
+
# STAGE_TEST.md
|
|
240
|
+
|
|
241
|
+
## Test strategy
|
|
242
|
+
- Unit: repositories + view models
|
|
243
|
+
- UI: critical flow end-to-end
|
|
244
|
+
|
|
245
|
+
## Critical flow (example)
|
|
246
|
+
Home β create Item β open Detail β edit β back β delete
|
|
247
|
+
|
|
248
|
+
## TODO (Tests)
|
|
249
|
+
- [ ] Repo unit tests: create/update/delete
|
|
250
|
+
- [ ] VM unit tests: state transitions (empty β loaded)
|
|
251
|
+
- [ ] 1 UI test for critical flow
|
|
252
|
+
- [ ] Run through RUNBOOK and confirm ship readiness
|
|
253
|
+
`),
|
|
254
|
+
});
|
|
255
|
+
return { files, nextCommand: "review", warnings };
|
|
256
|
+
}
|
|
257
|
+
if (input.command === "review") {
|
|
258
|
+
files.push({
|
|
259
|
+
path: "REVIEW_REPORT.md",
|
|
260
|
+
content: md(`
|
|
261
|
+
# REVIEW_REPORT.md
|
|
262
|
+
|
|
263
|
+
## Consistency checks
|
|
264
|
+
- [ ] Goals/Non-goals present
|
|
265
|
+
- [ ] Screen list matches coding plan
|
|
266
|
+
- [ ] Data model defined
|
|
267
|
+
- [ ] Architecture rules repeated in IOS_RULES.md
|
|
268
|
+
- [ ] TODO has checkboxes for all stages
|
|
269
|
+
|
|
270
|
+
## Output
|
|
271
|
+
If anything is missing, add it to TODO.md and/or BACKLOG.md.
|
|
272
|
+
`),
|
|
273
|
+
});
|
|
274
|
+
return { files, nextCommand: "ship", warnings };
|
|
275
|
+
}
|
|
276
|
+
if (input.command === "ship") {
|
|
277
|
+
files.push({
|
|
278
|
+
path: "SHIP_CHECKLIST.md",
|
|
279
|
+
content: md(`
|
|
280
|
+
# SHIP_CHECKLIST.md
|
|
281
|
+
|
|
282
|
+
## App Store readiness
|
|
283
|
+
- [ ] App name, subtitle, keywords
|
|
284
|
+
- [ ] Screenshots list (per device size)
|
|
285
|
+
- [ ] Privacy notes (data collected?)
|
|
286
|
+
- [ ] Permissions text (if any)
|
|
287
|
+
- [ ] Versioning + build number
|
|
288
|
+
|
|
289
|
+
## Technical readiness
|
|
290
|
+
- [ ] No crash on cold start
|
|
291
|
+
- [ ] Works offline
|
|
292
|
+
- [ ] Tests pass
|
|
293
|
+
- [ ] Empty/error states done
|
|
294
|
+
`),
|
|
295
|
+
});
|
|
296
|
+
return { files, nextCommand: "plan", warnings };
|
|
297
|
+
}
|
|
298
|
+
warnings.push("Unknown command");
|
|
299
|
+
return { files, nextCommand: "plan", warnings };
|
|
300
|
+
}
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ios-vibe-mcp00",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "MCP server for vibe coding iOS apps with command-based workflow (plan, architecture, coding, uiux, test)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"ios-vibe-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc -p tsconfig.json",
|
|
12
|
+
"prepublishOnly": "npm run build",
|
|
13
|
+
"start": "node dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"mcp",
|
|
17
|
+
"cursor",
|
|
18
|
+
"ios",
|
|
19
|
+
"swiftui",
|
|
20
|
+
"vibe-coding",
|
|
21
|
+
"generator",
|
|
22
|
+
"ai-tools"
|
|
23
|
+
],
|
|
24
|
+
"author": "Talha Pakdil",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
28
|
+
"zod": "^4.3.6"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"typescript": "^5.6.3",
|
|
32
|
+
"@types/node": "^20.11.30"
|
|
33
|
+
}
|
|
34
|
+
}
|