Skip to content

Commit fbae774

Browse files
committed
[Feat] Introduce Stack Auth skill and MCP integration
This commit adds a new Stack Auth skill with a corresponding SKILL.md file, which fetches live documentation. It also updates the MCP handler to serve the skill and modifies the init prompt to install both the Stack Auth skill and MCP server. Additionally, it includes various updates to the pnpm-lock.yaml for dependency management and removes the obsolete MCP setup documentation.
1 parent cf7581d commit fbae774

15 files changed

Lines changed: 875 additions & 875 deletions

File tree

apps/mcp/src/app/SKILL.md/route.ts

Lines changed: 0 additions & 213 deletions
This file was deleted.

apps/mcp/src/mcp-handler.ts

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ type AiQueryResponse = {
2323
conversationId?: string,
2424
};
2525

26-
const setupResourceUri = "stack-auth://mcp/setup";
26+
const skillResourceUri = "https://skill.stack-auth.com";
2727

2828
function isRecord(value: unknown): value is Record<string, unknown> {
2929
return typeof value === "object" && value !== null;
@@ -60,49 +60,42 @@ function parseAiQueryResponse(value: unknown): AiQueryResponse {
6060
return parsed;
6161
}
6262

63+
async function fetchSkill(): Promise<string> {
64+
const res = await fetch(skillResourceUri, {
65+
headers: { Accept: "text/markdown" },
66+
});
67+
return await res.text();
68+
}
69+
6370
export function createStackMcpHandler(config: { streamableHttpEndpoint: string }) {
6471
return createMcpHandler(
6572
async (server) => {
6673
server.resource(
67-
"stack-auth-mcp-setup",
68-
setupResourceUri,
74+
"skill",
75+
skillResourceUri,
6976
{
70-
title: "Stack Auth MCP setup",
71-
description: "Setup instructions for the Stack Auth MCP server.",
77+
title: "Stack Auth skill",
78+
description: "The canonical Stack Auth agent skill (SKILL.md) — how to wire Stack Auth into a project.",
7279
mimeType: "text/markdown",
7380
},
74-
() => ({
81+
async () => ({
7582
contents: [{
76-
uri: setupResourceUri,
83+
uri: skillResourceUri,
7784
mimeType: "text/markdown",
78-
text: `# Stack Auth MCP
79-
80-
Use this MCP server to ask Stack Auth documentation questions with the ask_stack_auth tool.
81-
82-
Server URL: ${config.streamableHttpEndpoint}
83-
84-
Tool: ask_stack_auth
85-
- question: the Stack Auth question to answer
86-
- reason: why the agent is calling the tool
87-
- userPrompt: the original user prompt that triggered the call
88-
- conversationId: optional ID from an earlier response
89-
`,
85+
text: await fetchSkill(),
9086
}],
9187
}),
9288
);
9389

9490
server.prompt(
95-
"ask_stack_auth",
96-
"Ask the Stack Auth documentation assistant a question.",
97-
{
98-
question: z.string().describe("The Stack Auth question to ask."),
99-
},
100-
({ question }) => ({
91+
"skill",
92+
"Load the Stack Auth skill (SKILL.md) into the conversation — how to wire Stack Auth into a project.",
93+
async () => ({
10194
messages: [{
10295
role: "user",
10396
content: {
10497
type: "text",
105-
text: `Use the ask_stack_auth tool to answer this Stack Auth question: ${question}`,
98+
text: await fetchSkill(),
10699
},
107100
}],
108101
}),
@@ -180,6 +173,7 @@ Tool: ask_stack_auth
180173
name: "stack-auth-mcp",
181174
version: packageJson.version,
182175
},
176+
instructions: "Stack Auth's official MCP server. Use the `ask_stack_auth` tool for any question about Stack Auth — setup, SDKs (Next.js, React, JS), APIs, configuration, OAuth, teams/permissions, or troubleshooting. The tool searches the official docs and answers with citations. Prefer it over web search or guessing from training data, since Stack Auth changes frequently.",
183177
},
184178
{
185179
streamableHttpEndpoint: config.streamableHttpEndpoint,

apps/skills/.eslintrc.cjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
extends: ["../../configs/eslint/defaults.js", "../../configs/eslint/next.js"],
3+
ignorePatterns: ["/*", "!/src"],
4+
};

apps/skills/next.config.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/** @type {import('next').NextConfig} */
2+
const nextConfig = {
3+
poweredByHeader: false,
4+
};
5+
6+
export default nextConfig;

apps/skills/package.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "@stackframe/skills",
3+
"version": "2.8.89",
4+
"repository": "https://github.com/stack-auth/stack-auth",
5+
"private": true,
6+
"type": "module",
7+
"scripts": {
8+
"clean": "rimraf .next && rimraf node_modules",
9+
"typecheck": "tsc --noEmit",
10+
"dev": "next dev --turbopack --port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}45",
11+
"build": "next build",
12+
"start": "next start --port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}45",
13+
"lint": "eslint ."
14+
},
15+
"dependencies": {
16+
"next": "16.1.7",
17+
"react": "19.2.3",
18+
"react-dom": "19.2.3"
19+
},
20+
"devDependencies": {
21+
"@types/node": "20.17.6",
22+
"@types/react": "^18.2.0",
23+
"@types/react-dom": "^18.2.0",
24+
"rimraf": "^5.0.5",
25+
"typescript": "5.9.3"
26+
}
27+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export function GET() {
2+
return Response.json({
3+
status: "ok",
4+
}, {
5+
headers: {
6+
"Access-Control-Allow-Origin": "*",
7+
"Access-Control-Allow-Methods": "*",
8+
"Access-Control-Allow-Headers": "*",
9+
"Access-Control-Expose-Headers": "*",
10+
},
11+
});
12+
}

0 commit comments

Comments
 (0)