npm i
npm run dev
Connect your MCP client to http://localhost:3000/mcp (using HTTP Streaming) and it should kick off the authorization flow.
All of the OAuth clients and tokens are stored in memory so if the server restarts, you should clear your OAuth state within your client.
Your client's backend is responsbile for signing the software_statement JWT.
Here's an example using https://www.npmjs.com/package/jose.
import {
generateKeyPair,
SignJWT,
exportJWK,
calculateJwkThumbprint,
} from "jose";
const publicJWK = await exportJWK(publicKey);
publicJWK.kid = await calculateJwkThumbprint(publicJWK);
app.get("/.well-known/jwks.json", (req, res) => {
res.json({
keys: [publicJWK],
});
});
app.post("/sign-client-metadata", authMiddleware, express.json(), async (req, res) => {
const { client_metadata, registration_endpoint } = req.body;
const software_statement = await new SignJWT({
iss: "https://your.mcp.client.com",
aud: registration_endpoint,
jti: randomUUID(),
...client_metadata,
})
.setProtectedHeader({ alg: "RS256", kid: publicJWK.kid })
.setIssuedAt()
.setExpirationTime("1h")
.sign(privateKey);
res.json({
software_statement,
jwks_uri: `http://${HOST}:${PORT}/.well-known/jwks.json`,
});
});