Documentation Index
Fetch the complete documentation index at: https://docs.agentfront.dev/llms.txt
Use this file to discover all available pages before exploring further.
This guide assumes you have a FrontMCP project set up. If you’re new to FrontMCP, start with the installation guide first.
From zero to skilled MCP server
Save a fixture bundle
Create
bundle.json in your project. This is the canonical worked example used in the rest of the docs and the e2e suite — one invoices skill bundling three OpenAPI operations against a billing service.bundle.json
Register the plugin
Add
SkilledOpenApiPlugin.init(...) to your FrontMCP server. The dev: true flag bypasses the signing requirement so you can iterate without a keypair — see Security before flipping to production.src/main.ts
Run a tiny mock REST server (the upstream the bundle points at)
The bundle’s Run it in a separate terminal:
services[0].baseUrl is http://127.0.0.1:9876 — point it at a real upstream and the plugin will execute real HTTP calls. For the quickstart, save this stub alongside src/main.ts:src/mock-billing.ts
Connect MCP Inspector and verify
Boot your FrontMCP server (
npx tsx src/main.ts) and connect MCP Inspector to http://localhost:3010. You should see:tools/listreturns onlysearch_skill,load_skill,execute_action. The three OpenAPI operations are hidden.skills/listreturns theinvoicesskill.search_skill({ query: "create invoice" })returns[{ skillId: "invoices", ... }].load_skill({ skillId: "invoices" })returns the markdown instructions plus three actions with their JSON Schemas.execute_action({ skillId: "invoices", actionId: "createInvoice", input: { customerId: "cus_1", amount: 4200 } })returns{ ok: true, status: 201, data: { id: "inv_1", status: "open" } }and the mock server logs the hit.
What you just did
You ran the same flow the e2e suite tests on every commit:- The plugin parsed your bundle, validated it against the strict Zod schema, and registered the
invoicesskill intoscope.skillsviaSkillRegistry.registerSkillContent(). - It populated a plugin-private
HiddenOpRegistrywith the three operation descriptors, keyed by(skillId, actionId). These never touchscope.tools, so they can’t leak intotools/list. - When the MCP client called
execute_action, the plugin:- looked up
(invoices, createInvoice)in the hidden-op registry, - ran the ABAC guard (no
requiredAuthoritieson this op → granted), - resolved the
bearerauth binding via the in-memoryCredentialResolver(seeded by yourcredentials: { ... }option), - delegated to
@frontmcp/adapters/openapi’sbuildRequest→fetch→parseResponse, - SSRF-checked the resolved URL against the bundle’s declared
services[].baseUrlhost allowlist, - returned a structured
{ ok, status, data }envelope to the MCP client.
- looked up
Hot-swap test
While the server is running, editbundle.json — bump the version to "1.0.1" and tweak the skill’s instructions. The plugin’s StaticSource watches the file, the BundleSyncService applies the diff atomically, and clients receive notifications/skills/list_changed. Polling clients can read the new bundleVersion directly from the skill content (the notification is best-effort; many MCP clients don’t honor it).
Next steps
Bundle format
The full wire format, including the signature envelope you’ll need before going to production.
Sources
Move from
static to npm (pinned) or saas (CI-driven, signed, hot-pulled) source.Meta-tools
search_skill / load_skill / execute_action — exact contracts and prompts for the LLM.Security
Sign your bundles, switch off
dev: true, wire credentials to libs/auth’s vault.