Add lazy-auth-server example (#679)
Adds an example MCP App server demonstrating lazy (on-demand) OAuth: the server connects and lists tools without authentication, and only prompts for auth when a protected tool is called, by responding 401 with a WWW-Authenticate header pointing at protected-resource metadata. - Public `show_auth_button` app calls the protected `get_secret` tool via callServerTool; the host runs the OAuth flow on 401 and retries - Embedded mock authorization server (authorization-code + PKCE, short-lived HS256 tokens, refresh + session revocation) so the whole flow runs from a single process - TTL-scoped endpoint paths (/ttl/<seconds>/mcp) let slow or automated clients request longer-lived tokens per connection, threaded through OAuth via RFC 8707 resource indicators - `elicit_url` / `elicit_by_error` tools demonstrating URL elicitation
This commit is contained in:
parent
9a37ad7182
commit
fcc4b03bde
1 changed files with 1737 additions and 0 deletions
42
examples/lazy-auth-server/main.ts
Normal file
42
examples/lazy-auth-server/main.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* Entry point for running the Lazy Auth demo MCP server.
|
||||
* Run with: npx mcp-server-lazy-auth
|
||||
* Or: node dist/index.js
|
||||
*
|
||||
* This example is HTTP-only (no stdio mode): the lazy-auth flow it demonstrates
|
||||
* relies on HTTP status codes (401 + WWW-Authenticate) and OAuth endpoints.
|
||||
*
|
||||
* To test with a remote MCP host, expose the server through a public tunnel
|
||||
* and set PUBLIC_URL to the tunnel URL so OAuth metadata and callback URLs
|
||||
* use it (see docs/testing-mcp-apps.md in the repository root).
|
||||
*/
|
||||
import { createApp, PORT } from "./server.js";
|
||||
|
||||
async function main() {
|
||||
const app = createApp();
|
||||
|
||||
const httpServer = app.listen(PORT, (err) => {
|
||||
if (err) {
|
||||
console.error("Failed to start server:", err);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(
|
||||
`Lazy Auth demo MCP server listening on http://localhost:${PORT}/mcp`,
|
||||
);
|
||||
console.log(
|
||||
` Tools: show_auth_button, get_secret [PROTECTED], revoke_auth_token [PROTECTED], elicit_url, elicit_by_error`,
|
||||
);
|
||||
});
|
||||
|
||||
const shutdown = () => {
|
||||
console.log("\nShutting down...");
|
||||
httpServer.close(() => process.exit(0));
|
||||
};
|
||||
process.on("SIGINT", shutdown);
|
||||
process.on("SIGTERM", shutdown);
|
||||
}
|
||||
|
||||
main().catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
Loading…
Reference in a new issue