Codex with ChatGPT Planning Loop
XiaoDuoYa/codex-with-chatgpt
Uses ChatGPT in the browser as the planning and review brain for a Codex session, with Codex keeping all execution and ChatGPT reading the workspace through a bridge.
How to build production MCP servers with MCP Fusion using the MVA (Model-View-Agent) pattern.
$ npx skills add vinkius-labs/mcpfusion --skill mcpfusion-development -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install vinkius-labs/mcpfusion mcpfusion-development --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/vinkius-labs/mcpfusion.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/mcpfusion-development .claude/skills/mcpfusion-development && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "mcpfusion-development" agent skill from https://github.com/vinkius-labs/mcpfusion/tree/main/.claude/skills/mcpfusion-development into .claude/skills/mcpfusion-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mcpfusion-development", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/vinkius-labs/mcpfusion/tree/main/.claude/skills/mcpfusion-developmentType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add vinkius-labs/mcpfusion --skill mcpfusion-development -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install vinkius-labs/mcpfusion mcpfusion-development --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/vinkius-labs/mcpfusion.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/mcpfusion-development .agents/skills/mcpfusion-development && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "mcpfusion-development" agent skill from https://github.com/vinkius-labs/mcpfusion/tree/main/.claude/skills/mcpfusion-development into .agents/skills/mcpfusion-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mcpfusion-development", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add vinkius-labs/mcpfusion --skill mcpfusion-development -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install vinkius-labs/mcpfusion mcpfusion-development --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/vinkius-labs/mcpfusion.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/mcpfusion-development .cursor/skills/mcpfusion-development && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "mcpfusion-development" agent skill from https://github.com/vinkius-labs/mcpfusion/tree/main/.claude/skills/mcpfusion-development into .cursor/skills/mcpfusion-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mcpfusion-development", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/vinkius-labs/mcpfusion.git --path .claude/skills/mcpfusion-development--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add vinkius-labs/mcpfusion --skill mcpfusion-development -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install vinkius-labs/mcpfusion mcpfusion-development --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/vinkius-labs/mcpfusion.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/mcpfusion-development .gemini/skills/mcpfusion-development && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "mcpfusion-development" agent skill from https://github.com/vinkius-labs/mcpfusion/tree/main/.claude/skills/mcpfusion-development into .gemini/skills/mcpfusion-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mcpfusion-development", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install vinkius-labs/mcpfusion mcpfusion-developmentInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add vinkius-labs/mcpfusion --skill mcpfusion-development -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/vinkius-labs/mcpfusion.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/mcpfusion-development .github/skills/mcpfusion-development && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "mcpfusion-development" agent skill from https://github.com/vinkius-labs/mcpfusion/tree/main/.claude/skills/mcpfusion-development into .github/skills/mcpfusion-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mcpfusion-development", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add vinkius-labs/mcpfusion --skill mcpfusion-development -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install vinkius-labs/mcpfusion mcpfusion-development --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/vinkius-labs/mcpfusion.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/mcpfusion-development .opencode/skills/mcpfusion-development && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "mcpfusion-development" agent skill from https://github.com/vinkius-labs/mcpfusion/tree/main/.claude/skills/mcpfusion-development into .opencode/skills/mcpfusion-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mcpfusion-development", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
mcpfusion-developmentHow to build production MCP servers with MCP Fusion using the MVA (Model-View-Agent) pattern.
Mcpfusion Development is an agent skill from vinkius-labs/mcpfusion. How to build production MCP servers with MCP Fusion using the MVA (Model-View-Agent) pattern. Use this skill whenever writing, modifying, or reviewing MCP Fusion code — including tools, Presenters, Models, middleware, prompts, routers, tests, or server configuration. Activate even when the user just says "create a tool", "add an endpoint", "write a Presenter", or mentions @mcpfusion/core, defineModel, definePresenter, initMCPFusion, FluentToolBuilder, or any MCP Fusion API. This skill covers the entire framework…
Its SKILL.md is about 4.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 5 other files, including reference files (for example `references/example-complete-crud.ts`, `references/example-proxy-api.ts` and `references/example-server-setup.ts`). Compatibility notes: Requires Node.js = 18, TypeScript 5.7+
It sits in Agent Workflows, covering MCP servers. It works with Model Context Protocol and OpenAI. The repository describes itself as: MCP Fusion - The TypeScript framework for secure MCP servers. The licence is Apache-2.0.
6 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 1dab501. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships script files (TypeScript), which the agent can run.
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Requires Node.js >= 18, TypeScript 5.7+
From compatibility in the SKILL.md frontmatter.
Mcpfusion Development loads about 4.3k tokens when it runs, and up to ~12k if it reads all its reference files. Until then it costs about 137 tokens; SKILL.md has 737 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from vinkius-labs/mcpfusion at commit 1dab501, republished under its Apache-2.0 licence (© vinkius-labs). 737 words, ~4,347 tokens.
.claude/skills/mcpfusion-development/SKILL.md (or your agent's skills folder). This skill also uses 4 other files; get the full folder from GitHub.MCP Fusion is a TypeScript framework for MCP servers built on the MVA (Model-View-Agent) pattern. The Model validates data, the Presenter (View) shapes what the AI perceives, and Tools (Agent layer) wire it all together.
For the complete API reference with all type signatures, read llms.txt at the root of the repository. This skill covers the essential patterns and rules.
Complete, runnable examples are available in references/. Read them for concrete implementation patterns:
| Example | Domain | Patterns Shown |
|---|---|---|
| example-complete-crud.ts | Product Catalog | Full MVA lifecycle: Model → Presenter → Router → Query/Mutation/Action, ErrorBuilder, State Sync |
| example-proxy-api.ts | Blog Platform | .proxy() API pass-through, .fromModel(), field aliases, path params (:id), .handle() vs .proxy() decision tree |
| example-server-setup.ts | Generic App | Full server bootstrap: context, initMCPFusion(), middleware, autoDiscover(), prompts, State Sync policies, startServer() |
| example-testing.ts | Customer Service | @mcpfusion/testing: Egress Firewall assertions, JIT System Rules, RBAC middleware, error handling, Symbol Invisibility |
src/
├── models/ ← M — defineModel() declarations
│ ├── InvoiceModel.ts
│ └── UserModel.ts
├── views/ ← V — Presenters
│ ├── invoice.presenter.ts
│ └── user.presenter.ts
├── agents/ ← A — Tool definitions
│ ├── billing.tool.ts
│ └── users.tool.ts
├── index.ts ← ToolRegistry + registerAll()
└── server.ts ← attachToServer() bootstrapLayer import rule: agents/ → views/ → models/ → @mcpfusion/core. Never import backwards.
defineModel() for domain entity schemas — never raw z.object(). Models go in models/..schema(MyModel) — the Presenter is the egress firewall.with*() methods are for tool INPUT parameters only (filters, IDs, pagination) — NOT for domain schemas.success() automatically. No boilerplate.f.query() = readOnly, f.mutation() = destructive, f.action() = neutral.Every domain entity starts here. Produces a Model with a compiled Zod .schema.
import { defineModel } from '@mcpfusion/core';
export const InvoiceModel = defineModel('Invoice', m => {
m.casts({
id: m.string(),
amount_cents: m.number('CRITICAL: in CENTS. Divide by 100 for display.'),
status: m.enum('Status', ['paid', 'pending', 'overdue']),
client_name: m.string('Client name'),
});
});
export const UserModel = defineModel('User', m => {
m.casts({
id: m.string(),
name: m.string('Full name'),
email: m.string('Email address'),
role: m.enum('Role', ['admin', 'member', 'guest']),
});
m.hidden(['password_hash', 'stripe_token']); // Never exposed
m.timestamps(); // created_at + updated_at
m.fillable({
create: ['name', 'email', 'role'],
update: ['name', 'email'],
});
});| Method | Produces | Use |
|---|---|---|
m.string(label?) | z.string() | General text |
m.text(label?) | z.string() | Markdown / long content |
m.number(label?) | z.number() | Numeric |
m.boolean(label?) | z.boolean() | Flags |
m.date(label?) | z.string() | YYYY-MM-DD |
m.timestamp(label?) | z.string() | ISO datetime |
m.uuid(label?) | z.string() | UUID |
m.id(label?) | z.number() | Always required |
m.enum(label, values) | z.enum() | Valid values |
m.enum('Status', ['open', 'done']).default('open')
m.string('Display name').alias('displayName') // agent says 'name', API gets 'displayName'
m.number('Score').examples([85, 92, 100])Strips undefined values and renames aliased fields. Used automatically by .proxy(), call explicitly in .handle():
const data = TaskModel.toApi(input);
// { title: 'X', body: 'Y' } ← alias applied, undefined strippedThe Presenter is the egress firewall between your handler and the wire. Schema MUST come from defineModel().
import { definePresenter, ui } from '@mcpfusion/core';
export const InvoicePresenter = definePresenter({
name: 'Invoice',
schema: InvoiceModel, // ← Model, never z.object()
// autoRules: true (default) — .describe() annotations become system rules
ui: (inv) => [ui.echarts({ series: [{ type: 'gauge', data: [{ value: inv.amount_cents / 100 }] }] })],
agentLimit: { max: 50, onTruncate: (n) => ui.summary({ omitted: n, hint: 'Use filters.' }) },
suggestActions: (inv) => inv.status === 'pending'
? [{ tool: 'billing.pay', reason: 'Process payment', args: { id: inv.id } }]
: [],
embeds: [{ key: 'client', presenter: ClientPresenter }],
});import { createPresenter, ui } from '@mcpfusion/core';
const UserPresenter = createPresenter('User')
.schema(UserModel)
.systemRules(['Display name in bold'])
.uiBlocks((user) => [ui.summary({ total: 1, showing: 1 })])
.agentLimit(50, { warningMessage: 'Showing {shown} of {total}. Use filters.' })
.suggestActions((user) => [
{ tool: 'users.update', reason: 'Edit this user', args: { id: user.id } },
])
.embed('team', TeamPresenter);| Layer | What It Does |
|---|---|
| Egress Firewall | .parse() strips undeclared fields — PII never reaches the wire |
| JIT System Rules | Rules travel with data, not in the global prompt |
| Server-Rendered UI | ECharts, Mermaid — deterministic, no hallucinated charts |
| Cognitive Guardrails | .agentLimit() truncates + injects guidance |
| Action Affordances | .suggestActions() — HATEOAS for agents |
| Relational Composition | .embed() — child Presenters inherit the full pipeline |
| Prompt Bridge | PromptMessage.fromView() — same source of truth for tools AND prompts |
import { initMCPFusion } from '@mcpfusion/core';
interface AppContext { db: PrismaClient; user: { id: string; role: string } }
export const f = initMCPFusion<AppContext>();
// f.query() — readOnly: true (GET, no side effects)
// f.mutation() — destructive: true (DELETE, irreversible)
// f.action() — neutral (PUT/POST, no assumptions)export default f.query('billing.get_invoice')
.describe('Get an invoice by ID')
.withString('id', 'The invoice ID')
.returns(InvoicePresenter)
.handle(async (input, ctx) => {
// input.id: string ✅ — fully typed, zero manual interfaces
return await ctx.db.invoices.findUnique({ where: { id: input.id } });
// ↑ Return raw data — Presenter handles validation, stripping, rendering
});Each call narrows the TypeScript generic — input is fully typed in .handle():
| Method | Adds |
|---|---|
.withString(name, desc?) | Record<K, string> |
.withOptionalString(name, desc?) | Partial<Record<K, string>> |
.withNumber(name, desc?) | Record<K, number> |
.withOptionalNumber(name, desc?) | Partial<Record<K, number>> |
.withBoolean(name, desc?) | Record<K, boolean> |
.withEnum(name, values, desc?) | Record<K, V> (literal union) |
.withArray(name, itemType, desc?) | Record<K, T[]> |
Bulk variants reduce verbosity — .withStrings({...}), .withOptionalStrings({...}), etc.:
f.query('tasks.filter')
.withStrings({
company_slug: 'Workspace identifier',
project_slug: 'Project identifier',
})
.withOptionalStrings({
title: 'Filter by title',
workflow: 'Column name',
})
.withOptionalNumbers({ per_page: 'Results per page' })Terminal method (alternative to .handle()) — auto-generates a handler that proxies to ctx.client:
// HTTP method inferred from verb: query → GET, mutation → POST, action → PUT
// Path params resolved from input: ':id' consumes input.id
// Auto-unwraps { data: ... } envelopes
f.query('user.get')
.withString('id', 'User UUID')
.proxy('users/:id'); // → GET users/abc-123When to use: .proxy() for simple pass-through, .handle() when you need business logic.
Imports fillable fields from a Model's profile — zero manual .with*() calls:
const createTask = f.mutation('tasks.create')
.fromModel(TaskModel, 'create') // imports title, description, status
.proxy('tasks');
const updateTask = f.action('tasks.update')
.fromModel(TaskModel, 'update')
.handle(async (input, ctx) => {
const data = TaskModel.toApi(input); // alias applied, undefined stripped
await ctx.client.put(`tasks/${input.id}`, data);
});Decision tree:
.fromModel() + .proxy().fromModel() + .handle() + Model.toApi()f.query('docs.search')
.describe('Search internal documentation')
.instructions('Use ONLY when the user asks about internal policies. Do NOT use for general questions.')Injected as [INSTRUCTIONS] in the tool description — reduces hallucination.
Shares prefix, middleware, and tags across child tools:
const users = f.router('users')
.describe('User management')
.use(requireAuth)
.tags('core');
const listUsers = users.query('list')
.withOptionalNumber('limit', 'Max results')
.handle(async (input, ctx) => ctx.db.users.findMany({ take: input.limit }));
const deleteUser = users.mutation('delete')
.withString('id', 'User ID')
.handle(async (input, ctx) => ctx.db.users.delete({ where: { id: input.id } }));tRPC-style context derivation — enriches ctx type for .handle():
const requireAuth = f.middleware(async (ctx) => {
const user = await db.getUser(ctx.token);
if (!user) throw new Error('Unauthorized');
return { user, permissions: user.permissions };
});
// ctx.user and ctx.permissions — fully typed downstream
f.mutation('admin.action')
.use(requireAuth)
.handle(async (input, ctx) => {
ctx.user; // ← typed!
ctx.permissions; // ← typed!
});const project = await ctx.db.projects.findUnique({ where: { id: input.id } });
if (!project) {
return f.error('NOT_FOUND', `Project "${input.id}" not found`)
.suggest('Check the ID. Use projects.list to see valid IDs.')
.actions('projects.list', 'projects.search')
.details({ searched_id: input.id })
.retryAfter(0);
}Prevents temporal blindness — the agent knows when cached data is stale:
f.query('geo.countries').cached(); // immutable — cache forever
f.query('billing.balance').stale(); // volatile — never cache
f.mutation('sprints.update').invalidates('sprints.*', 'tasks.*'); // causal invalidationimport { definePrompt, PromptMessage } from '@mcpfusion/core';
const AuditPrompt = definePrompt<AppContext>('audit', {
args: { invoiceId: 'string' } as const,
handler: async (ctx, { invoiceId }) => {
const invoice = await ctx.db.getInvoice(invoiceId);
return {
messages: [
PromptMessage.system('You are a Senior Financial Auditor.'),
...PromptMessage.fromView(InvoicePresenter.make(invoice, ctx)),
PromptMessage.user('Begin the audit.'),
],
};
},
});PromptMessage.fromView() decomposes a Presenter into XML-tagged messages — same schema, rules, and affordances in both tools and prompts.
Runs the REAL execution pipeline in RAM — zero tokens consumed, deterministic:
import { createMCPFusionTester } from '@mcpfusion/testing';
const tester = createMCPFusionTester(registry, {
contextFactory: () => ({ prisma: mockPrisma, tenantId: 't_42', role: 'ADMIN' }),
});
// Egress Firewall — PII physically absent
const result = await tester.callAction('db_user', 'find_many', { take: 5 });
expect(result.data[0]).not.toHaveProperty('passwordHash');
// JIT System Rules — travel with data
expect(result.systemRules).toContain('Email addresses are PII.');
// Middleware — GUEST blocked
const denied = await tester.callAction('db_user', 'find_many', { take: 5 }, { role: 'GUEST' });
expect(denied.isError).toBe(true);Assert every MVA layer: result.data, result.systemRules, result.uiBlocks, result.isError.
// WRONG:
const presenter = definePresenter({
name: 'User',
schema: z.object({ id: z.string(), name: z.string() }), // ← NO!
});
// CORRECT:
const UserModel = defineModel('User', m => {
m.casts({ id: m.string(), name: m.string() });
});
const presenter = definePresenter({ name: 'User', schema: UserModel });// WRONG:
.handle(async (input, ctx) => {
return success(await ctx.db.users.findMany()); // ← unnecessary
});
// CORRECT:
.handle(async (input, ctx) => {
return await ctx.db.users.findMany(); // ← framework wraps automatically
});// WRONG:
.handle(async (input, ctx) => {
const data: Record<string, unknown> = {};
if (input.title) data.title = input.title;
if (input.color) data.color = input.color;
await ctx.client.updateItem(input.id, data);
});
// CORRECT:
.handle(async (input, ctx) => {
const data = ItemModel.toApi(input); // strips undefined, applies aliases
await ctx.client.updateItem(input.id, data);
});// WRONG: model importing from tool
// models/UserModel.ts
import { listUsers } from '../agents/users.tool'; // ← NO!
// CORRECT: agents → views → models → @mcpfusion/core (one direction only)// WRONG: formatting response manually in each handler
// CORRECT: define Presenter ONCE in views/, use .returns(Presenter) in every tool// WRONG: defining domain fields as tool input params
f.mutation('users.create')
.withString('name', 'User name')
.withString('email', 'Email') // ← These are domain fields!
.withString('role', 'User role')
// CORRECT: use .fromModel() for domain fields
f.mutation('users.create')
.fromModel(UserModel, 'create') // ← imports from Model's fillable profile| I want to... | Use |
|---|---|
| Define a domain entity | defineModel('Name', m => { ... }) |
| Shape what the AI sees | definePresenter({ schema: MyModel, ... }) |
| Create a read tool | f.query('entity.list') |
| Create a write tool | f.mutation('entity.delete') |
| Create an update tool | f.action('entity.update') |
| Group related tools | f.router('prefix') |
| Add auth middleware | .use(requireAuth) |
| Return self-healing errors | f.error('CODE', 'message').suggest(...) |
| Proxy to an API | .proxy('endpoint/:id') |
| Import fields from Model | .fromModel(MyModel, 'profile') |
| Test MVA pipeline | createMCPFusionTester(registry, { contextFactory }) |
| Control caching | .cached(), .stale(), .invalidates() |
| Build a prompt | definePrompt('name', { handler }) |
| Bridge Presenter to prompt | PromptMessage.fromView(presenter.make(data, ctx)) |
© vinkius-labs, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 4 other files (references) in .claude/skills/mcpfusion-development of vinkius-labs/mcpfusion.
Open the folder on GitHubat commit 1dab501
Mcpfusion Development next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Mcpfusion Development this skillvinkius-labs/mcpfusion | 256 | — | ~4.3k | Automated safety check: Pass | Apache-2.0 | |
| Codex with ChatGPT Planning LoopXiaoDuoYa/codex-with-chatgpt | 7.1k | — | ~11k | Automated safety check: Notes | MIT | |
| Cao MCP Appsawslabs/cli-agent-orchestrator | 1.4k | — | ~1.9k | Automated safety check: Pass | Apache-2.0 | |
| Chatgpt AppsHaohao-end/openagent | 808 | 1 repos | ~4.9k | Automated safety check: Pass | Apache-2.0 | |
| Chatgpt App Builderalpic-ai/skybridge | 2.1k | — | ~1k | Automated safety check: Pass | MIT | |
| Agent QA Authoringvostride/agent-qa | 903 | — | ~569 | Automated safety check: Pass | Custom licence |
XiaoDuoYa/codex-with-chatgpt
Uses ChatGPT in the browser as the planning and review brain for a Codex session, with Codex keeping all execution and ChatGPT reading the workspace through a bridge.
awslabs/cli-agent-orchestrator
Enable, operate, and extend CAO's MCP Apps surface — the host-rendered fleet dashboard visible inside MCP App hosts (Claude Desktop, ChatGPT, VS Code Copilot, Goose, Postman).
Haohao-end/openagent
Build, scaffold, refactor, and troubleshoot ChatGPT Apps SDK applications that combine an MCP server and widget UI.
alpic-ai/skybridge
Guide developers through creating and updating ChatGPT plugins.
vostride/agent-qa
A skill your agent uses when creating, editing, validating, or running agent-qa tests, suites, or hooks.
awslabs/cli-agent-orchestrator
Load the official MCP Apps builder skills (create-mcp-app, migrate-oai-app, add-app-to-server, convert-web-app) from github.com/modelcontextprotocol/ext-apps.
vinkius-labs/mcpfusion
How to deploy MCP servers to Vinkius Edge using mcpfusion deploy.
Works with
Categories
How to build production MCP servers with MCP Fusion using the MVA (Model-View-Agent) pattern. Mcpfusion Development is an agent skill from vinkius-labs/mcpfusion. How to build production MCP servers with MCP Fusion using the MVA (Model-View-Agent) pattern.
Mcpfusion Development fits situations like: reviewing MCP Fusion code — including tools; server configuration; just says create a tool; add an endpoint.
Run `npx skills add vinkius-labs/mcpfusion --skill mcpfusion-development -a claude-code`. Or copy the skill folder (.claude/skills/mcpfusion-development in vinkius-labs/mcpfusion) into .claude/skills/mcpfusion-development in your project. Claude Code loads it when a task matches its description.
Run `npx skills add vinkius-labs/mcpfusion --skill mcpfusion-development -a codex`. Or copy the skill folder (.claude/skills/mcpfusion-development in vinkius-labs/mcpfusion) into .agents/skills/mcpfusion-development in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add vinkius-labs/mcpfusion --skill mcpfusion-development -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/mcpfusion-development, .gemini/skills/mcpfusion-development, .github/skills/mcpfusion-development and .opencode/skills/mcpfusion-development in your project.
Going by SKILL.md and its folder, Mcpfusion Development needs TypeScript for the scripts in its folder. Our summary lists: Node.js. Compatibility (from SKILL.md): Requires Node.js >= 18, TypeScript 5.7+.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Mcpfusion Development is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.3k tokens (SKILL.md is roughly 17k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 7.9k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Mcpfusion Development: Codex with ChatGPT Planning Loop (XiaoDuoYa/codex-with-chatgpt, 7.1k stars), Cao MCP Apps (awslabs/cli-agent-orchestrator, 1.4k stars), Chatgpt Apps (Haohao-end/openagent, 808 stars) and Chatgpt App Builder (alpic-ai/skybridge, 2.1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
vinkius-labs (a GitHub organization) maintains it in vinkius-labs/mcpfusion, which has 256 GitHub stars. The repository holds 2 skills in this directory. The repository was last updated on September 20, 2026.
Source: vinkius-labs/mcpfusion on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.