@frontmcp/skills 0.0.1 → 1.0.0-beta.11
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 +2 -2
- package/catalog/TEMPLATE.md +58 -13
- package/catalog/frontmcp-config/SKILL.md +156 -0
- package/catalog/{auth/configure-auth/references/auth-modes.md → frontmcp-config/references/configure-auth-modes.md} +5 -0
- package/catalog/frontmcp-config/references/configure-auth.md +243 -0
- package/catalog/frontmcp-config/references/configure-elicitation.md +183 -0
- package/catalog/frontmcp-config/references/configure-http.md +210 -0
- package/catalog/frontmcp-config/references/configure-session.md +210 -0
- package/catalog/{config/configure-throttle/references/guard-config.md → frontmcp-config/references/configure-throttle-guard-config.md} +5 -0
- package/catalog/frontmcp-config/references/configure-throttle.md +234 -0
- package/catalog/{config/configure-transport/references/protocol-presets.md → frontmcp-config/references/configure-transport-protocol-presets.md} +5 -0
- package/catalog/frontmcp-config/references/configure-transport.md +200 -0
- package/catalog/frontmcp-config/references/setup-redis.md +9 -0
- package/catalog/frontmcp-config/references/setup-sqlite.md +9 -0
- package/catalog/frontmcp-deployment/SKILL.md +152 -0
- package/catalog/frontmcp-deployment/references/build-for-browser.md +143 -0
- package/catalog/frontmcp-deployment/references/build-for-cli.md +191 -0
- package/catalog/{deployment/build-for-sdk/SKILL.md → frontmcp-deployment/references/build-for-sdk.md} +66 -20
- package/catalog/frontmcp-deployment/references/deploy-to-cloudflare.md +218 -0
- package/catalog/{deployment/deploy-to-lambda/SKILL.md → frontmcp-deployment/references/deploy-to-lambda.md} +77 -59
- package/catalog/{deployment/deploy-to-node/references/Dockerfile.example → frontmcp-deployment/references/deploy-to-node-dockerfile.md} +18 -4
- package/catalog/{deployment/deploy-to-node/SKILL.md → frontmcp-deployment/references/deploy-to-node.md} +69 -36
- package/catalog/frontmcp-deployment/references/deploy-to-vercel-config.md +65 -0
- package/catalog/frontmcp-deployment/references/deploy-to-vercel.md +229 -0
- package/catalog/frontmcp-development/SKILL.md +126 -0
- package/catalog/frontmcp-development/references/create-adapter.md +170 -0
- package/catalog/{development/create-agent/references/llm-config.md → frontmcp-development/references/create-agent-llm-config.md} +10 -5
- package/catalog/{development/create-agent/SKILL.md → frontmcp-development/references/create-agent.md} +83 -40
- package/catalog/{development/create-job/SKILL.md → frontmcp-development/references/create-job.md} +62 -15
- package/catalog/{plugins/create-plugin-hooks/SKILL.md → frontmcp-development/references/create-plugin-hooks.md} +100 -7
- package/catalog/frontmcp-development/references/create-plugin.md +506 -0
- package/catalog/{development/create-prompt/SKILL.md → frontmcp-development/references/create-prompt.md} +65 -22
- package/catalog/{development/create-provider/SKILL.md → frontmcp-development/references/create-provider.md} +63 -23
- package/catalog/{development/create-resource/SKILL.md → frontmcp-development/references/create-resource.md} +148 -26
- package/catalog/{development/create-skill-with-tools/SKILL.md → frontmcp-development/references/create-skill-with-tools.md} +174 -20
- package/catalog/{development/create-skill/SKILL.md → frontmcp-development/references/create-skill.md} +114 -28
- package/catalog/{development/create-tool/references/tool-annotations.md → frontmcp-development/references/create-tool-annotations.md} +5 -0
- package/catalog/{development/create-tool/references/output-schema-types.md → frontmcp-development/references/create-tool-output-schema-types.md} +5 -0
- package/catalog/{development/create-tool/SKILL.md → frontmcp-development/references/create-tool.md} +172 -23
- package/catalog/{development/create-workflow/SKILL.md → frontmcp-development/references/create-workflow.md} +61 -14
- package/catalog/frontmcp-development/references/decorators-guide.md +754 -0
- package/catalog/frontmcp-development/references/official-adapters.md +199 -0
- package/catalog/{plugins/official-plugins/SKILL.md → frontmcp-development/references/official-plugins.md} +97 -27
- package/catalog/frontmcp-extensibility/SKILL.md +103 -0
- package/catalog/frontmcp-extensibility/references/vectoriadb.md +289 -0
- package/catalog/frontmcp-guides/SKILL.md +420 -0
- package/catalog/frontmcp-guides/references/example-knowledge-base.md +641 -0
- package/catalog/frontmcp-guides/references/example-task-manager.md +517 -0
- package/catalog/frontmcp-guides/references/example-weather-api.md +297 -0
- package/catalog/frontmcp-production-readiness/SKILL.md +98 -0
- package/catalog/frontmcp-production-readiness/references/common-checklist.md +156 -0
- package/catalog/frontmcp-production-readiness/references/production-browser.md +46 -0
- package/catalog/frontmcp-production-readiness/references/production-cli-binary.md +62 -0
- package/catalog/frontmcp-production-readiness/references/production-cli-daemon.md +61 -0
- package/catalog/frontmcp-production-readiness/references/production-cloudflare.md +52 -0
- package/catalog/frontmcp-production-readiness/references/production-lambda.md +53 -0
- package/catalog/frontmcp-production-readiness/references/production-node-sdk.md +66 -0
- package/catalog/frontmcp-production-readiness/references/production-node-server.md +61 -0
- package/catalog/frontmcp-production-readiness/references/production-vercel.md +52 -0
- package/catalog/frontmcp-setup/SKILL.md +132 -0
- package/catalog/frontmcp-setup/references/frontmcp-skills-usage.md +280 -0
- package/catalog/{setup/multi-app-composition/SKILL.md → frontmcp-setup/references/multi-app-composition.md} +66 -19
- package/catalog/{setup/nx-workflow/SKILL.md → frontmcp-setup/references/nx-workflow.md} +79 -17
- package/catalog/frontmcp-setup/references/project-structure-nx.md +251 -0
- package/catalog/frontmcp-setup/references/project-structure-standalone.md +217 -0
- package/catalog/frontmcp-setup/references/readme-guide.md +226 -0
- package/catalog/{setup/setup-project/SKILL.md → frontmcp-setup/references/setup-project.md} +63 -58
- package/catalog/{setup/setup-redis/SKILL.md → frontmcp-setup/references/setup-redis.md} +60 -82
- package/catalog/{setup/setup-sqlite/SKILL.md → frontmcp-setup/references/setup-sqlite.md} +65 -72
- package/catalog/frontmcp-testing/SKILL.md +135 -0
- package/catalog/{testing/setup-testing/SKILL.md → frontmcp-testing/references/setup-testing.md} +79 -63
- package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-auth.md +5 -0
- package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-browser-build.md +5 -0
- package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-cli-binary.md +5 -0
- package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-direct-client.md +5 -0
- package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-e2e-handler.md +5 -0
- package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-tool-unit.md +6 -0
- package/catalog/skills-manifest.json +337 -382
- package/package.json +2 -2
- package/src/index.d.ts +1 -1
- package/src/index.js.map +1 -1
- package/src/loader.js +0 -1
- package/src/loader.js.map +1 -1
- package/src/manifest.d.ts +15 -3
- package/src/manifest.js +3 -3
- package/src/manifest.js.map +1 -1
- package/catalog/adapters/create-adapter/SKILL.md +0 -127
- package/catalog/adapters/official-adapters/SKILL.md +0 -136
- package/catalog/auth/configure-auth/SKILL.md +0 -250
- package/catalog/auth/configure-session/SKILL.md +0 -201
- package/catalog/config/configure-elicitation/SKILL.md +0 -136
- package/catalog/config/configure-http/SKILL.md +0 -167
- package/catalog/config/configure-throttle/SKILL.md +0 -189
- package/catalog/config/configure-transport/SKILL.md +0 -151
- package/catalog/deployment/build-for-browser/SKILL.md +0 -95
- package/catalog/deployment/build-for-cli/SKILL.md +0 -100
- package/catalog/deployment/deploy-to-cloudflare/SKILL.md +0 -192
- package/catalog/deployment/deploy-to-vercel/SKILL.md +0 -196
- package/catalog/deployment/deploy-to-vercel/references/vercel.json.example +0 -60
- package/catalog/development/decorators-guide/SKILL.md +0 -598
- package/catalog/plugins/create-plugin/SKILL.md +0 -336
- package/catalog/setup/frontmcp-skills-usage/SKILL.md +0 -200
- package/catalog/setup/project-structure-nx/SKILL.md +0 -186
- package/catalog/setup/project-structure-standalone/SKILL.md +0 -153
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/skills",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "1.0.0-beta.11",
|
|
4
4
|
"description": "Curated skills catalog for FrontMCP projects",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"homepage": "https://docs.agentfront.dev",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"main": "./src/index.js",
|
|
26
26
|
"types": "./index.d.js",
|
|
27
27
|
"engines": {
|
|
28
|
-
"node": ">=
|
|
28
|
+
"node": ">=24.0.0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"tslib": "^2.3.0"
|
package/src/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export type { SkillCatalogEntry, SkillManifest, SkillTarget, SkillCategory, SkillBundle, SkillDestination, SkillMergeStrategy, SkillInstallConfig, } from './manifest';
|
|
1
|
+
export type { SkillCatalogEntry, SkillManifest, SkillReferenceEntry, SkillTarget, SkillCategory, SkillBundle, SkillDestination, SkillMergeStrategy, SkillInstallConfig, } from './manifest';
|
|
2
2
|
export { VALID_TARGETS, VALID_CATEGORIES, VALID_BUNDLES } from './manifest';
|
|
3
3
|
export { loadManifest, getSkillsByTarget, getSkillsByCategory, getSkillsByBundle, getInstructionOnlySkills, getResourceSkills, resolveSkillPath, } from './loader';
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAYA,uCAA4E;AAAnE,yGAAA,aAAa,OAAA;AAAE,4GAAA,gBAAgB,OAAA;AAAE,yGAAA,aAAa,OAAA;AAEvD,mCAQkB;AAPhB,sGAAA,YAAY,OAAA;AACZ,2GAAA,iBAAiB,OAAA;AACjB,6GAAA,mBAAmB,OAAA;AACnB,2GAAA,iBAAiB,OAAA;AACjB,kHAAA,wBAAwB,OAAA;AACxB,2GAAA,iBAAiB,OAAA;AACjB,0GAAA,gBAAgB,OAAA","sourcesContent":["export type {\n SkillCatalogEntry,\n SkillManifest,\n SkillReferenceEntry,\n SkillTarget,\n SkillCategory,\n SkillBundle,\n SkillDestination,\n SkillMergeStrategy,\n SkillInstallConfig,\n} from './manifest';\n\nexport { VALID_TARGETS, VALID_CATEGORIES, VALID_BUNDLES } from './manifest';\n\nexport {\n loadManifest,\n getSkillsByTarget,\n getSkillsByCategory,\n getSkillsByBundle,\n getInstructionOnlySkills,\n getResourceSkills,\n resolveSkillPath,\n} from './loader';\n"]}
|
package/src/loader.js
CHANGED
|
@@ -25,7 +25,6 @@ const path = tslib_1.__importStar(require("node:path"));
|
|
|
25
25
|
function loadManifest(catalogDir) {
|
|
26
26
|
const dir = catalogDir ?? path.resolve(__dirname, '..', 'catalog');
|
|
27
27
|
const manifestPath = path.join(dir, 'skills-manifest.json');
|
|
28
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
29
28
|
return require(manifestPath);
|
|
30
29
|
}
|
|
31
30
|
/**
|
package/src/loader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/loader.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAWH,
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/loader.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAWH,oCAIC;AAMD,8CAIC;AAKD,kDAEC;AAKD,8CAIC;AAMD,4DAEC;AAMD,8CAEC;AASD,4CAGC;;AAnED,wDAAkC;AAGlC;;;;;GAKG;AACH,SAAgB,YAAY,CAAC,UAAmB;IAC9C,MAAM,GAAG,GAAG,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IACnE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC;IAC5D,OAAO,OAAO,CAAC,YAAY,CAAkB,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,SAAgB,iBAAiB,CAAC,MAA2B,EAAE,MAAc;IAC3E,OAAO,MAAM,CAAC,MAAM,CAClB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,MAA8C,CAAC,CACvG,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CAAC,MAA2B,EAAE,QAAgB;IAC/E,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,MAA2B,EAAE,MAAc;IAC3E,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACzB,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAiF,CAAC,CACtG,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,wBAAwB,CAAC,MAA2B;IAClE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,SAAgB,iBAAiB,CAAC,MAA2B;IAC3D,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAAC,KAAwB,EAAE,UAAmB;IAC5E,MAAM,GAAG,GAAG,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IACnE,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC","sourcesContent":["/**\n * Skills catalog loader and filtering helpers.\n *\n * Provides functions to query the catalog manifest by target, category, and bundle.\n *\n * @module skills/loader\n */\n\nimport * as path from 'node:path';\nimport type { SkillCatalogEntry, SkillManifest } from './manifest';\n\n/**\n * Load the skills manifest from the catalog directory.\n *\n * @param catalogDir - Absolute path to the catalog directory. Defaults to the bundled catalog.\n * @returns The parsed skills manifest\n */\nexport function loadManifest(catalogDir?: string): SkillManifest {\n const dir = catalogDir ?? path.resolve(__dirname, '..', 'catalog');\n const manifestPath = path.join(dir, 'skills-manifest.json');\n return require(manifestPath) as SkillManifest;\n}\n\n/**\n * Filter skills by deployment target.\n * Returns skills that include the given target or 'all'.\n */\nexport function getSkillsByTarget(skills: SkillCatalogEntry[], target: string): SkillCatalogEntry[] {\n return skills.filter(\n (s) => s.targets.includes('all') || s.targets.includes(target as SkillCatalogEntry['targets'][number]),\n );\n}\n\n/**\n * Filter skills by category.\n */\nexport function getSkillsByCategory(skills: SkillCatalogEntry[], category: string): SkillCatalogEntry[] {\n return skills.filter((s) => s.category === category);\n}\n\n/**\n * Filter skills by bundle membership.\n */\nexport function getSkillsByBundle(skills: SkillCatalogEntry[], bundle: string): SkillCatalogEntry[] {\n return skills.filter((s) =>\n s.bundle?.includes(bundle as SkillCatalogEntry['bundle'] extends (infer U)[] | undefined ? U : never),\n );\n}\n\n/**\n * Get only instruction-only skills (no scripts/, references/, or assets/ directories).\n * These are safe to use with `instructions: { file: ... }` wrappers.\n */\nexport function getInstructionOnlySkills(skills: SkillCatalogEntry[]): SkillCatalogEntry[] {\n return skills.filter((s) => !s.hasResources);\n}\n\n/**\n * Get only resource-carrying skills (have scripts/, references/, or assets/).\n * These need full directory loading via `skillDir()`.\n */\nexport function getResourceSkills(skills: SkillCatalogEntry[]): SkillCatalogEntry[] {\n return skills.filter((s) => s.hasResources);\n}\n\n/**\n * Resolve the absolute path to a skill directory.\n *\n * @param entry - The catalog entry\n * @param catalogDir - Absolute path to the catalog directory\n * @returns Absolute path to the skill directory\n */\nexport function resolveSkillPath(entry: SkillCatalogEntry, catalogDir?: string): string {\n const dir = catalogDir ?? path.resolve(__dirname, '..', 'catalog');\n return path.resolve(dir, entry.path);\n}\n"]}
|
package/src/manifest.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export type SkillTarget = 'node' | 'vercel' | 'lambda' | 'cloudflare' | 'all';
|
|
|
12
12
|
/**
|
|
13
13
|
* Skill categories for organizing the catalog.
|
|
14
14
|
*/
|
|
15
|
-
export type SkillCategory = 'setup' | 'deployment' | 'development' | 'config' | '
|
|
15
|
+
export type SkillCategory = 'setup' | 'deployment' | 'development' | 'config' | 'testing' | 'guides' | 'production' | 'extensibility';
|
|
16
16
|
/**
|
|
17
17
|
* Bundle membership for curated scaffold presets.
|
|
18
18
|
*/
|
|
@@ -36,6 +36,16 @@ export interface SkillInstallConfig {
|
|
|
36
36
|
/** Other skills this depends on (by name) */
|
|
37
37
|
dependencies?: string[];
|
|
38
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Metadata for a single reference file within a skill's references/ directory.
|
|
41
|
+
* Extracted from YAML frontmatter or inferred from the markdown heading.
|
|
42
|
+
*/
|
|
43
|
+
export interface SkillReferenceEntry {
|
|
44
|
+
/** Reference name — matches filename without extension */
|
|
45
|
+
name: string;
|
|
46
|
+
/** Short description from frontmatter or first paragraph */
|
|
47
|
+
description: string;
|
|
48
|
+
}
|
|
39
49
|
/**
|
|
40
50
|
* A single entry in the skills catalog manifest.
|
|
41
51
|
*
|
|
@@ -55,14 +65,16 @@ export interface SkillCatalogEntry {
|
|
|
55
65
|
targets: SkillTarget[];
|
|
56
66
|
/** Whether the skill has scripts/, references/, or assets/ directories */
|
|
57
67
|
hasResources: boolean;
|
|
68
|
+
/** Resolved reference metadata from references/ directory */
|
|
69
|
+
references?: SkillReferenceEntry[];
|
|
58
70
|
/** Target-specific storage defaults (e.g., { node: 'redis-docker', vercel: 'vercel-kv' }) */
|
|
59
71
|
storageDefault?: Record<string, string>;
|
|
60
72
|
/** Tags for secondary filtering and search */
|
|
61
73
|
tags: string[];
|
|
62
74
|
/** Bundle membership for scaffold presets */
|
|
63
75
|
bundle?: SkillBundle[];
|
|
64
|
-
/** Install configuration for future distribution */
|
|
65
|
-
install
|
|
76
|
+
/** Install configuration for future distribution (optional — not yet used by CLI) */
|
|
77
|
+
install?: SkillInstallConfig;
|
|
66
78
|
}
|
|
67
79
|
/**
|
|
68
80
|
* The skills catalog manifest — single source of truth for scaffold and install tooling.
|
package/src/manifest.js
CHANGED
|
@@ -16,10 +16,10 @@ exports.VALID_CATEGORIES = [
|
|
|
16
16
|
'deployment',
|
|
17
17
|
'development',
|
|
18
18
|
'config',
|
|
19
|
-
'auth',
|
|
20
|
-
'plugins',
|
|
21
|
-
'adapters',
|
|
22
19
|
'testing',
|
|
20
|
+
'guides',
|
|
21
|
+
'production',
|
|
22
|
+
'extensibility',
|
|
23
23
|
];
|
|
24
24
|
/** Valid bundles for manifest validation */
|
|
25
25
|
exports.VALID_BUNDLES = ['recommended', 'minimal', 'full'];
|
package/src/manifest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/manifest.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/manifest.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAmGH,uDAAuD;AAC1C,QAAA,aAAa,GAA2B,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;AAEvG,+CAA+C;AAClC,QAAA,gBAAgB,GAA6B;IACxD,OAAO;IACP,YAAY;IACZ,aAAa;IACb,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,YAAY;IACZ,eAAe;CAChB,CAAC;AAEF,4CAA4C;AAC/B,QAAA,aAAa,GAA2B,CAAC,aAAa,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC","sourcesContent":["/**\n * Skills catalog manifest types.\n *\n * Defines the contract between the catalog, scaffold tooling, and future installer.\n *\n * @module skills/manifest\n */\n\n/**\n * Supported deployment targets for skill filtering.\n */\nexport type SkillTarget = 'node' | 'vercel' | 'lambda' | 'cloudflare' | 'all';\n\n/**\n * Skill categories for organizing the catalog.\n */\nexport type SkillCategory =\n | 'setup'\n | 'deployment'\n | 'development'\n | 'config'\n | 'testing'\n | 'guides'\n | 'production'\n | 'extensibility';\n\n/**\n * Bundle membership for curated scaffold presets.\n */\nexport type SkillBundle = 'recommended' | 'minimal' | 'full';\n\n/**\n * Install destination types for future provider wiring.\n */\nexport type SkillDestination = 'project-local' | '.claude/skills' | 'codex' | 'gemini';\n\n/**\n * Merge strategy when installing a skill that already exists at the destination.\n */\nexport type SkillMergeStrategy = 'overwrite' | 'skip-existing';\n\n/**\n * Install configuration for a catalog skill.\n */\nexport interface SkillInstallConfig {\n /** Where this skill can be installed */\n destinations: SkillDestination[];\n /** How to handle existing skills at the destination */\n mergeStrategy: SkillMergeStrategy;\n /** Other skills this depends on (by name) */\n dependencies?: string[];\n}\n\n/**\n * Metadata for a single reference file within a skill's references/ directory.\n * Extracted from YAML frontmatter or inferred from the markdown heading.\n */\nexport interface SkillReferenceEntry {\n /** Reference name — matches filename without extension */\n name: string;\n /** Short description from frontmatter or first paragraph */\n description: string;\n}\n\n/**\n * A single entry in the skills catalog manifest.\n *\n * This is the core contract connecting SKILL.md files to scaffolding,\n * future installation, and provider-specific destinations.\n */\nexport interface SkillCatalogEntry {\n /** Unique skill name — matches SKILL.md frontmatter `name` */\n name: string;\n /** Skill category for organization */\n category: SkillCategory;\n /** Short description */\n description: string;\n /** Path to the skill directory, relative to catalog/ */\n path: string;\n /** Deployment targets this skill applies to */\n targets: SkillTarget[];\n /** Whether the skill has scripts/, references/, or assets/ directories */\n hasResources: boolean;\n /** Resolved reference metadata from references/ directory */\n references?: SkillReferenceEntry[];\n /** Target-specific storage defaults (e.g., { node: 'redis-docker', vercel: 'vercel-kv' }) */\n storageDefault?: Record<string, string>;\n /** Tags for secondary filtering and search */\n tags: string[];\n /** Bundle membership for scaffold presets */\n bundle?: SkillBundle[];\n /** Install configuration for future distribution (optional — not yet used by CLI) */\n install?: SkillInstallConfig;\n}\n\n/**\n * The skills catalog manifest — single source of truth for scaffold and install tooling.\n */\nexport interface SkillManifest {\n /** Manifest schema version */\n version: 1;\n /** All catalog skills */\n skills: SkillCatalogEntry[];\n}\n\n/** Valid deployment targets for manifest validation */\nexport const VALID_TARGETS: readonly SkillTarget[] = ['node', 'vercel', 'lambda', 'cloudflare', 'all'];\n\n/** Valid categories for manifest validation */\nexport const VALID_CATEGORIES: readonly SkillCategory[] = [\n 'setup',\n 'deployment',\n 'development',\n 'config',\n 'testing',\n 'guides',\n 'production',\n 'extensibility',\n];\n\n/** Valid bundles for manifest validation */\nexport const VALID_BUNDLES: readonly SkillBundle[] = ['recommended', 'minimal', 'full'];\n"]}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: create-adapter
|
|
3
|
-
description: Create custom adapters that convert external definitions into MCP tools, resources, and prompts. Use when building integrations beyond OpenAPI, connecting to proprietary APIs, or generating tools from custom schemas.
|
|
4
|
-
tags: [adapter, custom, dynamic-adapter, integration, codegen]
|
|
5
|
-
priority: 6
|
|
6
|
-
visibility: both
|
|
7
|
-
license: Apache-2.0
|
|
8
|
-
metadata:
|
|
9
|
-
docs: https://docs.agentfront.dev/frontmcp/adapters/overview
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# Creating Custom Adapters
|
|
13
|
-
|
|
14
|
-
Build adapters that automatically generate MCP tools, resources, and prompts from external sources — databases, GraphQL schemas, proprietary APIs, or any definition format.
|
|
15
|
-
|
|
16
|
-
## When to Use
|
|
17
|
-
|
|
18
|
-
Create a custom adapter when:
|
|
19
|
-
|
|
20
|
-
- The built-in OpenAPI adapter doesn't cover your integration (GraphQL, gRPC, custom protocols)
|
|
21
|
-
- You want to auto-generate tools from a database schema or config file
|
|
22
|
-
- You need to dynamically create tools at runtime based on external state
|
|
23
|
-
|
|
24
|
-
## Step 1: Extend DynamicAdapter
|
|
25
|
-
|
|
26
|
-
```typescript
|
|
27
|
-
import { DynamicAdapter, type FrontMcpAdapterResponse } from '@frontmcp/sdk';
|
|
28
|
-
|
|
29
|
-
interface MyAdapterOptions {
|
|
30
|
-
endpoint: string;
|
|
31
|
-
apiKey: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
class MyApiAdapter extends DynamicAdapter<MyAdapterOptions> {
|
|
35
|
-
declare __options_brand: MyAdapterOptions;
|
|
36
|
-
|
|
37
|
-
async fetch(): Promise<FrontMcpAdapterResponse> {
|
|
38
|
-
// Fetch definitions from external source
|
|
39
|
-
const res = await globalThis.fetch(this.options.endpoint, {
|
|
40
|
-
headers: { Authorization: `Bearer ${this.options.apiKey}` },
|
|
41
|
-
});
|
|
42
|
-
const schema = await res.json();
|
|
43
|
-
|
|
44
|
-
// Convert to MCP tool definitions
|
|
45
|
-
return {
|
|
46
|
-
tools: schema.operations.map((op: { name: string; description: string; params: Record<string, unknown> }) => ({
|
|
47
|
-
name: op.name,
|
|
48
|
-
description: op.description,
|
|
49
|
-
inputSchema: this.convertParams(op.params),
|
|
50
|
-
execute: async (input: Record<string, unknown>) => {
|
|
51
|
-
return this.callApi(op.name, input);
|
|
52
|
-
},
|
|
53
|
-
})),
|
|
54
|
-
resources: [],
|
|
55
|
-
prompts: [],
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
private convertParams(params: Record<string, unknown>) {
|
|
60
|
-
// Convert external param definitions to Zod schemas
|
|
61
|
-
// ...
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
private async callApi(operation: string, input: Record<string, unknown>) {
|
|
65
|
-
// Call the external API
|
|
66
|
-
// ...
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Step 2: Register
|
|
72
|
-
|
|
73
|
-
```typescript
|
|
74
|
-
@App({
|
|
75
|
-
name: 'MyApp',
|
|
76
|
-
adapters: [
|
|
77
|
-
MyApiAdapter.init({
|
|
78
|
-
name: 'my-api',
|
|
79
|
-
endpoint: 'https://api.example.com/schema',
|
|
80
|
-
apiKey: process.env.API_KEY!,
|
|
81
|
-
}),
|
|
82
|
-
],
|
|
83
|
-
})
|
|
84
|
-
class MyApp {}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## FrontMcpAdapterResponse
|
|
88
|
-
|
|
89
|
-
The `fetch()` method returns tools, resources, and prompts to register:
|
|
90
|
-
|
|
91
|
-
```typescript
|
|
92
|
-
interface FrontMcpAdapterResponse {
|
|
93
|
-
tools?: AdapterToolDefinition[];
|
|
94
|
-
resources?: AdapterResourceDefinition[];
|
|
95
|
-
prompts?: AdapterPromptDefinition[];
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## Static init()
|
|
100
|
-
|
|
101
|
-
`DynamicAdapter` provides a static `init()` method inherited by all subclasses:
|
|
102
|
-
|
|
103
|
-
```typescript
|
|
104
|
-
// Usage — no manual instantiation needed
|
|
105
|
-
const adapter = MyApiAdapter.init({
|
|
106
|
-
name: 'my-api', // Required: adapter name (used for tool namespacing)
|
|
107
|
-
endpoint: '...',
|
|
108
|
-
apiKey: '...',
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
// Register in @App
|
|
112
|
-
@App({ adapters: [adapter] })
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## Nx Generator
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
nx generate @frontmcp/nx:adapter my-adapter --project=my-app
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
Creates a `DynamicAdapter` subclass in `src/adapters/my-adapter.adapter.ts`.
|
|
122
|
-
|
|
123
|
-
## Reference
|
|
124
|
-
|
|
125
|
-
- Adapter docs: [docs.agentfront.dev/frontmcp/adapters/overview](https://docs.agentfront.dev/frontmcp/adapters/overview)
|
|
126
|
-
- `DynamicAdapter` base: import from `@frontmcp/sdk` — [source](https://github.com/agentfront/frontmcp/tree/main/libs/sdk/src/common/dynamic/dynamic.adapter.ts)
|
|
127
|
-
- `FrontMcpAdapterResponse`: import from `@frontmcp/sdk` — [source](https://github.com/agentfront/frontmcp/tree/main/libs/sdk/src/common/interfaces/adapter.interface.ts)
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: official-adapters
|
|
3
|
-
description: Use the OpenAPI adapter to convert REST APIs into MCP tools automatically. Use when integrating external APIs, OpenAPI specs, or converting Swagger docs to MCP tools.
|
|
4
|
-
tags: [adapters, openapi, rest-api, swagger, integration]
|
|
5
|
-
priority: 7
|
|
6
|
-
visibility: both
|
|
7
|
-
license: Apache-2.0
|
|
8
|
-
metadata:
|
|
9
|
-
docs: https://docs.agentfront.dev/frontmcp/adapters/overview
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# Official Adapters
|
|
13
|
-
|
|
14
|
-
Adapters convert external definitions (OpenAPI specs, Lambda functions, etc.) into MCP tools, resources, and prompts automatically.
|
|
15
|
-
|
|
16
|
-
## OpenAPI Adapter
|
|
17
|
-
|
|
18
|
-
The primary official adapter. Converts OpenAPI/Swagger specifications into MCP tools — one tool per operation.
|
|
19
|
-
|
|
20
|
-
### Installation
|
|
21
|
-
|
|
22
|
-
```typescript
|
|
23
|
-
import { OpenApiAdapter } from '@frontmcp/adapters';
|
|
24
|
-
|
|
25
|
-
@App({
|
|
26
|
-
name: 'MyApp',
|
|
27
|
-
adapters: [
|
|
28
|
-
OpenApiAdapter.init({
|
|
29
|
-
name: 'petstore',
|
|
30
|
-
specUrl: 'https://petstore3.swagger.io/api/v3/openapi.json',
|
|
31
|
-
}),
|
|
32
|
-
],
|
|
33
|
-
})
|
|
34
|
-
class MyApp {}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Each OpenAPI operation becomes an MCP tool named `petstore:operationId`.
|
|
38
|
-
|
|
39
|
-
### With Authentication
|
|
40
|
-
|
|
41
|
-
```typescript
|
|
42
|
-
// API Key auth
|
|
43
|
-
OpenApiAdapter.init({
|
|
44
|
-
name: 'my-api',
|
|
45
|
-
specUrl: 'https://api.example.com/openapi.json',
|
|
46
|
-
auth: {
|
|
47
|
-
type: 'apiKey',
|
|
48
|
-
headerName: 'X-API-Key',
|
|
49
|
-
apiKey: process.env.API_KEY!,
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// Bearer token auth
|
|
54
|
-
OpenApiAdapter.init({
|
|
55
|
-
name: 'my-api',
|
|
56
|
-
specUrl: 'https://api.example.com/openapi.json',
|
|
57
|
-
auth: {
|
|
58
|
-
type: 'bearer',
|
|
59
|
-
token: process.env.API_TOKEN!,
|
|
60
|
-
},
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// OAuth auth
|
|
64
|
-
OpenApiAdapter.init({
|
|
65
|
-
name: 'my-api',
|
|
66
|
-
specUrl: 'https://api.example.com/openapi.json',
|
|
67
|
-
auth: {
|
|
68
|
-
type: 'oauth',
|
|
69
|
-
tokenUrl: 'https://auth.example.com/token',
|
|
70
|
-
clientId: process.env.CLIENT_ID!,
|
|
71
|
-
clientSecret: process.env.CLIENT_SECRET!,
|
|
72
|
-
scopes: ['read', 'write'],
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Spec Polling
|
|
78
|
-
|
|
79
|
-
Automatically refresh the OpenAPI spec at intervals:
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
82
|
-
OpenApiAdapter.init({
|
|
83
|
-
name: 'evolving-api',
|
|
84
|
-
specUrl: 'https://api.example.com/openapi.json',
|
|
85
|
-
polling: {
|
|
86
|
-
intervalMs: 300000, // Re-fetch every 5 minutes
|
|
87
|
-
},
|
|
88
|
-
});
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Inline Spec
|
|
92
|
-
|
|
93
|
-
Provide the OpenAPI spec directly instead of fetching from URL:
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
OpenApiAdapter.init({
|
|
97
|
-
name: 'my-api',
|
|
98
|
-
spec: {
|
|
99
|
-
openapi: '3.0.0',
|
|
100
|
-
info: { title: 'My API', version: '1.0.0' },
|
|
101
|
-
paths: { ... },
|
|
102
|
-
},
|
|
103
|
-
})
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### Multiple Adapters
|
|
107
|
-
|
|
108
|
-
Register adapters from different APIs in the same app:
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
@App({
|
|
112
|
-
name: 'IntegrationHub',
|
|
113
|
-
adapters: [
|
|
114
|
-
OpenApiAdapter.init({ name: 'github', specUrl: 'https://api.github.com/openapi.json' }),
|
|
115
|
-
OpenApiAdapter.init({ name: 'jira', specUrl: 'https://jira.example.com/openapi.json' }),
|
|
116
|
-
OpenApiAdapter.init({ name: 'slack', specUrl: 'https://slack.com/openapi.json' }),
|
|
117
|
-
],
|
|
118
|
-
})
|
|
119
|
-
class IntegrationHub {}
|
|
120
|
-
// Tools: github:createIssue, jira:createTicket, slack:postMessage, etc.
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
## Adapter vs Plugin
|
|
124
|
-
|
|
125
|
-
| Aspect | Adapter | Plugin |
|
|
126
|
-
| ----------- | ------------------------------------ | ----------------------------------- |
|
|
127
|
-
| Purpose | Generate tools from external sources | Add cross-cutting behavior |
|
|
128
|
-
| Output | Tools, resources, prompts | Lifecycle hooks, context extensions |
|
|
129
|
-
| Examples | OpenAPI → MCP tools | Caching, auth, logging |
|
|
130
|
-
| When to use | Integrating APIs | Adding middleware |
|
|
131
|
-
|
|
132
|
-
## Reference
|
|
133
|
-
|
|
134
|
-
- Adapter docs: [docs.agentfront.dev/frontmcp/adapters/overview](https://docs.agentfront.dev/frontmcp/adapters/overview)
|
|
135
|
-
- OpenAPI adapter: [`@frontmcp/adapters`](https://docs.agentfront.dev/frontmcp/adapters/openapi-adapter)
|
|
136
|
-
- Spec polling: [docs.agentfront.dev/frontmcp/adapters/openapi-polling](https://docs.agentfront.dev/frontmcp/adapters/openapi-polling)
|
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: configure-auth
|
|
3
|
-
description: Set up authentication with public, transparent, local, or remote auth modes. Use when adding auth, OAuth, login, session security, or protecting tools and resources.
|
|
4
|
-
tags:
|
|
5
|
-
- auth
|
|
6
|
-
- oauth
|
|
7
|
-
- security
|
|
8
|
-
bundle:
|
|
9
|
-
- recommended
|
|
10
|
-
- full
|
|
11
|
-
visibility: both
|
|
12
|
-
priority: 10
|
|
13
|
-
parameters:
|
|
14
|
-
- name: mode
|
|
15
|
-
description: Authentication mode (public, transparent, local, remote)
|
|
16
|
-
type: string
|
|
17
|
-
required: false
|
|
18
|
-
default: public
|
|
19
|
-
- name: provider
|
|
20
|
-
description: OAuth provider URL for transparent or remote modes
|
|
21
|
-
type: string
|
|
22
|
-
required: false
|
|
23
|
-
examples:
|
|
24
|
-
- scenario: Public mode with anonymous scopes
|
|
25
|
-
parameters:
|
|
26
|
-
mode: public
|
|
27
|
-
expected-outcome: Server accepts all connections with anonymous scopes and session TTL
|
|
28
|
-
- scenario: Transparent mode validating external JWTs
|
|
29
|
-
parameters:
|
|
30
|
-
mode: transparent
|
|
31
|
-
provider: https://auth.example.com
|
|
32
|
-
expected-outcome: Server validates JWTs from the configured provider against the expected audience
|
|
33
|
-
- scenario: Local mode with server-signed tokens
|
|
34
|
-
parameters:
|
|
35
|
-
mode: local
|
|
36
|
-
expected-outcome: Server signs its own JWT tokens for client authentication
|
|
37
|
-
- scenario: Remote mode with full OAuth flow
|
|
38
|
-
parameters:
|
|
39
|
-
mode: remote
|
|
40
|
-
provider: https://auth.example.com
|
|
41
|
-
expected-outcome: Server redirects clients through a remote OAuth authorization flow
|
|
42
|
-
license: Apache-2.0
|
|
43
|
-
compatibility: Requires Node.js 18+ and @frontmcp/auth package
|
|
44
|
-
metadata:
|
|
45
|
-
category: auth
|
|
46
|
-
difficulty: intermediate
|
|
47
|
-
docs: https://docs.agentfront.dev/frontmcp/authentication/overview
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
# Configure Authentication for FrontMCP
|
|
51
|
-
|
|
52
|
-
This skill covers setting up authentication in a FrontMCP server. FrontMCP supports four auth modes, each suited to different deployment scenarios. All authentication logic lives in the `@frontmcp/auth` library.
|
|
53
|
-
|
|
54
|
-
## Auth Modes Overview
|
|
55
|
-
|
|
56
|
-
| Mode | Use Case | Token Issuer |
|
|
57
|
-
| ------------- | ------------------------------------------ | ------------------- |
|
|
58
|
-
| `public` | Open access with optional scoping | None |
|
|
59
|
-
| `transparent` | Validate externally-issued JWTs | External provider |
|
|
60
|
-
| `local` | Server signs its own tokens | The FrontMCP server |
|
|
61
|
-
| `remote` | Full OAuth 2.1 flow with external provider | External provider |
|
|
62
|
-
|
|
63
|
-
## Mode 1: Public
|
|
64
|
-
|
|
65
|
-
Public mode allows all connections without authentication. Use this for development or open APIs where access control is handled elsewhere.
|
|
66
|
-
|
|
67
|
-
```typescript
|
|
68
|
-
@App({
|
|
69
|
-
auth: {
|
|
70
|
-
mode: 'public',
|
|
71
|
-
sessionTtl: 3600,
|
|
72
|
-
anonymousScopes: ['read'],
|
|
73
|
-
},
|
|
74
|
-
})
|
|
75
|
-
class MyApp {}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
- `sessionTtl` -- session lifetime in seconds.
|
|
79
|
-
- `anonymousScopes` -- scopes granted to all unauthenticated clients.
|
|
80
|
-
|
|
81
|
-
## Mode 2: Transparent
|
|
82
|
-
|
|
83
|
-
Transparent mode validates JWTs issued by an external provider without initiating an OAuth flow. The server fetches the provider's JWKS to verify token signatures.
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
@App({
|
|
87
|
-
auth: {
|
|
88
|
-
mode: 'transparent',
|
|
89
|
-
provider: 'https://auth.example.com',
|
|
90
|
-
expectedAudience: 'my-api',
|
|
91
|
-
},
|
|
92
|
-
})
|
|
93
|
-
class MyApp {}
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
- `provider` -- the authorization server URL. FrontMCP fetches JWKS from `{provider}/.well-known/jwks.json`.
|
|
97
|
-
- `expectedAudience` -- the `aud` claim value that tokens must contain.
|
|
98
|
-
|
|
99
|
-
Use transparent mode when clients already have tokens from your identity provider and the server only needs to verify them.
|
|
100
|
-
|
|
101
|
-
## Mode 3: Local
|
|
102
|
-
|
|
103
|
-
Local mode lets the FrontMCP server sign its own JWT tokens. This is useful for internal services or environments where an external identity provider is not available.
|
|
104
|
-
|
|
105
|
-
```typescript
|
|
106
|
-
@App({
|
|
107
|
-
auth: {
|
|
108
|
-
mode: 'local',
|
|
109
|
-
local: {
|
|
110
|
-
issuer: 'my-server',
|
|
111
|
-
audience: 'my-api',
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
})
|
|
115
|
-
class MyApp {}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
- `local.issuer` -- the `iss` claim set in generated tokens.
|
|
119
|
-
- `local.audience` -- the `aud` claim set in generated tokens.
|
|
120
|
-
|
|
121
|
-
The server generates a signing key pair on startup (or loads one from the configured key store). Clients obtain tokens through a server-provided endpoint.
|
|
122
|
-
|
|
123
|
-
## Mode 4: Remote
|
|
124
|
-
|
|
125
|
-
Remote mode performs a full OAuth 2.1 authorization flow with an external provider. Clients are redirected to the provider for authentication and return with an authorization code.
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
@App({
|
|
129
|
-
auth: {
|
|
130
|
-
mode: 'remote',
|
|
131
|
-
provider: 'https://auth.example.com',
|
|
132
|
-
clientId: 'xxx',
|
|
133
|
-
},
|
|
134
|
-
})
|
|
135
|
-
class MyApp {}
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
- `provider` -- the OAuth 2.1 authorization server URL.
|
|
139
|
-
- `clientId` -- the OAuth client identifier registered with the provider.
|
|
140
|
-
|
|
141
|
-
## OAuth Local Dev Flow
|
|
142
|
-
|
|
143
|
-
For local development with `remote` or `transparent` mode, you can skip the full OAuth flow by setting the environment to development:
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
@App({
|
|
147
|
-
auth: {
|
|
148
|
-
mode: 'remote',
|
|
149
|
-
provider: 'https://auth.example.com',
|
|
150
|
-
clientId: 'dev-client-id',
|
|
151
|
-
},
|
|
152
|
-
})
|
|
153
|
-
class MyApp {}
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
When `NODE_ENV=development`, FrontMCP relaxes token validation to support local identity provider instances (e.g., a local Keycloak or mock OAuth server). Tokens are still validated, but HTTPS requirements and strict issuer checks are loosened.
|
|
157
|
-
|
|
158
|
-
## Multi-App Auth
|
|
159
|
-
|
|
160
|
-
Each `@App` in a FrontMCP server can have a different auth configuration. This is useful when a single server hosts multiple logical applications with different security requirements:
|
|
161
|
-
|
|
162
|
-
```typescript
|
|
163
|
-
@App({
|
|
164
|
-
name: 'public-api',
|
|
165
|
-
auth: {
|
|
166
|
-
mode: 'public',
|
|
167
|
-
sessionTtl: 3600,
|
|
168
|
-
anonymousScopes: ['read'],
|
|
169
|
-
},
|
|
170
|
-
tools: [PublicSearchTool, PublicInfoTool],
|
|
171
|
-
})
|
|
172
|
-
class PublicApi {}
|
|
173
|
-
|
|
174
|
-
@App({
|
|
175
|
-
name: 'admin-api',
|
|
176
|
-
auth: {
|
|
177
|
-
mode: 'remote',
|
|
178
|
-
provider: 'https://auth.example.com',
|
|
179
|
-
clientId: 'admin-client',
|
|
180
|
-
},
|
|
181
|
-
tools: [AdminTool, ConfigTool],
|
|
182
|
-
})
|
|
183
|
-
class AdminApi {}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
## Credential Vault
|
|
187
|
-
|
|
188
|
-
The credential vault stores downstream API tokens obtained during the OAuth flow. Use it when your MCP tools need to call external APIs on behalf of the authenticated user:
|
|
189
|
-
|
|
190
|
-
```typescript
|
|
191
|
-
@App({
|
|
192
|
-
auth: {
|
|
193
|
-
mode: 'remote',
|
|
194
|
-
provider: 'https://auth.example.com',
|
|
195
|
-
clientId: 'mcp-client-id',
|
|
196
|
-
},
|
|
197
|
-
vault: {
|
|
198
|
-
encryption: {
|
|
199
|
-
secret: process.env['VAULT_SECRET'],
|
|
200
|
-
},
|
|
201
|
-
providers: [
|
|
202
|
-
{
|
|
203
|
-
name: 'github',
|
|
204
|
-
type: 'oauth2',
|
|
205
|
-
scopes: ['repo', 'read:user'],
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
name: 'slack',
|
|
209
|
-
type: 'oauth2',
|
|
210
|
-
scopes: ['chat:write', 'channels:read'],
|
|
211
|
-
},
|
|
212
|
-
],
|
|
213
|
-
},
|
|
214
|
-
})
|
|
215
|
-
class MyApp {}
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
Tools access downstream credentials via the `this.authProviders` context extension:
|
|
219
|
-
|
|
220
|
-
```typescript
|
|
221
|
-
@Tool({ name: 'create_github_issue' })
|
|
222
|
-
class CreateGithubIssueTool extends ToolContext {
|
|
223
|
-
async execute(input: { title: string; body: string }) {
|
|
224
|
-
// Access downstream credentials via the authProviders context extension
|
|
225
|
-
const github = await this.authProviders.get('github');
|
|
226
|
-
const headers = await this.authProviders.headers('github');
|
|
227
|
-
// Use headers to call GitHub API
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
The `authProviders` accessor (from `@frontmcp/auth`) provides:
|
|
233
|
-
|
|
234
|
-
- `get(provider)` -- get the credential/token for a provider.
|
|
235
|
-
- `headers(provider)` -- get pre-formatted auth headers for HTTP requests.
|
|
236
|
-
- `has(provider)` -- check if a provider is configured.
|
|
237
|
-
- `refresh(provider)` -- force refresh the credential.
|
|
238
|
-
|
|
239
|
-
## Common Mistakes
|
|
240
|
-
|
|
241
|
-
- **Using memory session store in production** -- sessions are lost on restart. Use Redis or Vercel KV.
|
|
242
|
-
- **Hardcoding secrets** -- use environment variables for `clientId`, vault secrets, and Redis passwords.
|
|
243
|
-
- **Missing audience validation** -- always set the audience field. Without it, tokens from any audience would be accepted.
|
|
244
|
-
|
|
245
|
-
## Reference
|
|
246
|
-
|
|
247
|
-
- Auth docs: [docs.agentfront.dev/frontmcp/authentication/overview](https://docs.agentfront.dev/frontmcp/authentication/overview)
|
|
248
|
-
- Auth package: `@frontmcp/auth` — [source](https://github.com/agentfront/frontmcp/tree/main/libs/auth)
|
|
249
|
-
- Auth options interface: import `AuthOptionsInput` from `@frontmcp/auth` — [source](https://github.com/agentfront/frontmcp/tree/main/libs/auth/src/options)
|
|
250
|
-
- Credential vault: import from `@frontmcp/auth` — [source](https://github.com/agentfront/frontmcp/tree/main/libs/auth/src/vault)
|