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
66
examples/lazy-auth-server/src/mcp-app.css
Normal file
66
examples/lazy-auth-server/src/mcp-app.css
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
.main {
|
||||
width: 100%;
|
||||
max-width: 480px;
|
||||
box-sizing: border-box;
|
||||
|
||||
> * {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
> * + * {
|
||||
margin-top: var(--spacing-md);
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--spacing-sm);
|
||||
}
|
||||
|
||||
button {
|
||||
padding: var(--spacing-sm) var(--spacing-md);
|
||||
border: none;
|
||||
border-radius: var(--border-radius-md);
|
||||
color: var(--color-text-on-accent);
|
||||
font-weight: var(--font-weight-bold);
|
||||
background-color: var(--color-accent);
|
||||
cursor: pointer;
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background-color: color-mix(
|
||||
in srgb,
|
||||
var(--color-accent) 85%,
|
||||
var(--color-background-inverse)
|
||||
);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: calc(var(--border-width-regular) * 2) solid
|
||||
var(--color-ring-primary);
|
||||
outline-offset: var(--border-width-regular);
|
||||
}
|
||||
}
|
||||
|
||||
.result {
|
||||
padding: var(--spacing-sm) var(--spacing-md);
|
||||
border: var(--border-width-regular) solid
|
||||
color-mix(in srgb, var(--color-text-primary) 25%, transparent);
|
||||
border-radius: var(--border-radius-md);
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.875em;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: var(--color-text-danger, light-dark(#b91c1c, #f87171));
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
Loading…
Reference in a new issue