On November 3, 2026, Anthropic announced that Claude can connect plugins for people the moment they log in, with no sign-in page and no consent screen, when the plugin's MCP server accepts Claude as a trusted issuer. This guide shows what your server has to do to support that, with working code.
We built this into Server4Agent's authorization server, and wrote this while doing it. Claude's documentation tells you what to check. This adds the order things go wrong in, the code, and the traps that are not on any checklist, including one place where the general MCP guidance points the opposite way.
On this page: Quick answer · What it means · EMA, ID-JAG and XAA · Claude-issued or IdP-issued · The five steps · Full code · Mistakes to avoid · Testing · Troubleshooting · FAQ
Quick answer
To accept Claude as a trusted issuer, your MCP server's authorization server has to do four things:
- Advertise and accept the JWT bearer grant (
urn:ietf:params:oauth:grant-type:jwt-bearer, RFC 7523) at its token endpoint. - Recognize Claude as a client without Dynamic Client Registration, which in practice means supporting Client ID Metadata Documents. DCR does not work with this flow.
- Let each customer's admin register one trusted issuer for their workspace, in your product's own settings.
- Validate every assertion in a fixed order, including an exact issuer match and a replay check, then find the user by a verified email address inside that one workspace.
Your MCP server itself barely changes. It still answers an unauthenticated call with a 401, and still receives an ordinary bearer token.
Key takeaways
- Availability: Claude-issued auth is in beta on Claude's Team and Enterprise plans as of November 2026. The identity provider version is generally available.
- The issuer URL has the form
https://identity.anthropic.com/issuers/<issuer-id>, and each Claude organization has its own. Match it as an exact string. - DCR is out. A registered client's generated id can never match the
client_idin an assertion. - Ignore grant types you do not issue. Claude's client document lists the JWT bearer grant, and resolvers that refuse unknown entries reject the whole document with errors like
Invalid client_id. - Find people by email, not sub, for Claude-issued assertions. This is the reverse of the general advice for identity assertions.
- Assertions are short-lived: each expires within a minute and can be used once. Allow at most 60 seconds of clock skew.
- No refresh token. Claude asks for a new assertion each time your access token expires, so a one-hour token costs the user nothing.
- Your token endpoint has 10 seconds to answer, and must not redirect.
What does accepting Claude as a trusted issuer mean?
A trusted issuer is the one signer a customer workspace has told your authorization server to believe. Accepting Claude as one means that when Claude presents a signed JWT saying "this is a current member of this Claude organization, at this email address", and that workspace has registered that exact issuer, your server hands back an access token without showing anyone a consent screen.
The person experiences this as the plugin simply working. An admin sets it up once, on both sides, and members of the organization never see a Connect card. Anthropic calls the user-facing feature auto-connect.
EMA, ID-JAG, XAA and auto-connect: what each name means
These terms get used interchangeably, and they are not the same thing. Each names a different layer.
| Name | What it is | Who defines it |
|---|---|---|
| Enterprise-Managed Authorization (EMA) | The MCP extension, io.modelcontextprotocol/enterprise-managed-authorization. Its stable specification is dated 2026-07-28 | MCP maintainers |
| ID-JAG (Identity Assertion JWT Authorization Grant) | The signed token itself, with the type header oauth-id-jag+jwt | An IETF OAuth working group draft, not yet an RFC |
| JWT bearer grant | How the token is redeemed at your token endpoint | RFC 7523 |
| Cross App Access (XAA) | The general pattern of an identity provider brokering app-to-app access, and the name Okta's product uses | Okta and the wider identity industry |
| Enterprise Managed Auth | Claude's connector feature that implements all of the above | Anthropic |
| Claude-issued, or auto-connect | The option where Claude signs the assertion instead of an identity provider. In beta | Anthropic |
Claude-issued or identity provider-issued?
Claude can present an assertion signed by either. The token format and the exchange are the same, and each workspace trusts one issuer. The differences are in what the assertion proves and how you find the person.
| Claude-issued | Identity provider-issued | |
|---|---|---|
| Who signs it | Claude, under a URL unique to the Claude organization | The customer's identity provider, under its own URL |
| Availability | Beta, Team and Enterprise | Generally available, Team and Enterprise |
| What the customer needs | Nothing extra. No SSO or verified domain | SSO into Claude through their identity provider, such as Okta |
| Not offered when | The organization signs in to Claude through Okta | The organization has no identity provider |
| How to find the user | By email. The sub is opaque and differs per issuer | By iss and sub, which match your SSO subject |
email claim | Always present, lowercase | Optional |
| What it proves | Current membership of the Claude organization. No SSO, MFA or group claims | Whatever the identity provider's policy enforced |
Build Claude-issued first. A Team organization you create for testing qualifies as it is, so you can test the same day. It is also the only option if your product has no SSO to match a subject against, which was our situation.
What happens at sign-in
- Claude calls one of your tools with no token, and your MCP server answers
401with aWWW-Authenticateheader pointing at your protected resource metadata. - Claude reads that metadata, then your authorization server metadata, and sees the JWT bearer grant listed.
- If the organization has set this up for your connector, Claude posts a signed assertion to your token endpoint instead of showing a Connect card.
- You validate it and return an access token.
- Claude retries the tool call with that token. The person sees nothing.
The request looks like this:
POST /oauth/token HTTP/1.1
Host: auth.northstar.example
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&assertion=eyJhbGciOiJFUzI1NiIs...
&client_id=https://claude.ai/oauth/mcp-oauth-client-metadata
&resource=https://mcp.northstar.exampleAnd the decoded assertion has this shape:
{
"iss": "https://identity.anthropic.com/issuers/4f1c9b7a",
"sub": "an-opaque-value-that-differs-per-issuer",
"email": "alex@northstar.example",
"aud": ["https://auth.northstar.example"],
"client_id": "https://claude.ai/oauth/mcp-oauth-client-metadata",
"iat": 1793750000,
"nbf": 1793749985,
"exp": 1793750045,
"jti": "a-unique-id-you-may-accept-once"
}aud_tenant appears too if the customer's admin entered your tenant ID. scope is optional.
Step 1: change your authorization server metadata
Claude reads your RFC 8414 metadata and only sends assertions if the grant is listed, even if your token endpoint would already accept it.
{
"issuer": "https://auth.northstar.example",
"token_endpoint": "https://auth.northstar.example/oauth/token",
"grant_types_supported": [
"authorization_code",
"refresh_token",
"urn:ietf:params:oauth:grant-type:jwt-bearer"
],
"token_endpoint_auth_methods_supported": ["none"],
"client_id_metadata_document_supported": true
}The jwt-bearer entry and the last line are the additions. Three rules come with them:
issuerhas to match the URL the metadata was fetched from.token_endpointhas to share a registrable domain withissuer, and has to answer at that exact URL, because Claude does not follow redirects on this request.- Keep
issuerbyte for byte as published, trailing slash included. It is the audience of every assertion, and a Claude-issued setup records it, so changing it later stops sign-ins for that customer.
Claude caches this document for about five minutes, so allow for that when testing a change.
Step 2: support Client ID Metadata Documents
This is the part that surprises people, and it is bigger than it looks.
Every assertion carries a client_id, and your server has to recognize that client before the first one arrives. A client created through Dynamic Client Registration gets a generated id that can never match, so DCR is out. Your options are Anthropic-held client credentials or a Client ID Metadata Document, where the client_id is an HTTPS URL and the document at that URL describes the client. Claude's is at https://claude.ai/oauth/mcp-oauth-client-metadata, and its grant_types already lists the JWT bearer grant.
Claude picks CIMD only when your metadata has both client_id_metadata_document_supported: true and "none" in token_endpoint_auth_methods_supported. Otherwise it falls back to DCR.
The catch: once you advertise it, every host that supports it switches to it for new connections, for ordinary interactive sign-in as well. So this has to work end to end at your authorization endpoint, not just at the token endpoint. Connections people already made through DCR keep working, as long as you keep DCR running beside it.
What we check when a client_id is a URL:
- It is
https, has a path, carries no credentials or fragment, and is spelled canonically, because the document has to name itself exactly. - The document's own
client_idfield equals the URL, it listsredirect_uris, and it does not claim a confidential auth method. - The requested
redirect_urimatches the document exactly, except that loopback addresses match on any port. Claude Code and VS Code both publish loopback addresses and bind whatever port is free when they run (RFC 8252, section 7.3). - The consent screen names the URL's host as the app, not the document's
client_name. The document is self-asserted, and the host is the only part you verified.
Do not validate the document's grant types strictly. People are already hitting this one. Claude's document lists three grant types: authorization_code, refresh_token and the JWT bearer grant. VS Code's lists the device code grant. A client publishes one document for every server it talks to and cannot tailor it to yours, so an entry you do not support tells you nothing about whether it can use your server. A resolver that treats that entry as fatal refuses the whole document, and the person just sees a failed connection.
Here is how it has shown up, as of November 2026:
| Where | What you see | Status |
|---|---|---|
| django-oauth-toolkit | client metadata must declare exactly one non-refresh grant type, surfacing at the authorize step as Invalid client_id parameter value | Fixed in its repository, not yet in a release as of 3.4.1 |
| Oracle OCI IAM identity domains | invalid_cimd_request | Open |
| ToolHive, with VS Code's document | invalid_client: The requested OAuth 2.0 Client does not exist | Fixed |
The fix is to drop the entries you do not issue, and refuse the document only if nothing you need remains:
const WE_ISSUE = new Set(["authorization_code", "refresh_token", JWT_BEARER_GRANT]);
const declared = Array.isArray(doc.grant_types) ? doc.grant_types : ["authorization_code"];
const grants = declared.filter((grant) => WE_ISSUE.has(grant));
if (!grants.includes("authorization_code")) throw new Error("no flow we support");Ours does not read the field at all, because what a client may do is decided by the token request and the checks on it, not by what its document declares. If you are on a hosted identity platform that rejects the document, you cannot fix it from your side, because Anthropic hosts it. Raise it with your vendor, and follow the Oracle issue above.
You are also now fetching a URL an unauthenticated stranger chose, from your own server, so treat it like a webhook destination: refuse addresses that resolve to private ranges, refuse redirects, cap the size, set a short timeout, cap how many you fetch per minute, and cache the result, including failures. We also refuse client_id URLs on our own domains. Customers' apps live under ours, and "someone.apps.ourdomain.com wants to connect" reads as us.
If your codes or refresh tokens have a foreign key to a clients table, store a row at the moment someone approves, not when the document is first read. Otherwise anyone can fill the table by asking.
Step 3: let an admin register the issuer
Give each workspace's admins one field for the trusted issuer URL, and show your tenant ID beside it if you have one. Only admins may set it, and it should be logged like the access decision it is. The admin copies the URL from the Issuer URL box in Claude's Managed authorization setup for your connector. Linear's setup is a good public example of the flow from a customer's side.
Accept only a URL you are willing to fetch. If you support Claude-issued assertions and nothing else, as we do today, validate the field against that exact shape. That removes a whole class of problem: an admin's input never becomes an arbitrary URL your server reaches out to, and nobody can point a workspace at an identity provider of their own and have it vouch for any address it likes.
Step 4: run the nine checks, in order
First find the one workspace the assertion is for: the one aud_tenant names, or otherwise the only one that registered iss. Everything before the signature check is reading unverified claims, and choosing where to look is the only thing you may use them for. Any failure below returns invalid_grant.
| # | Check | What goes wrong without it |
|---|---|---|
| 1 | iss exactly equals the workspace's registered issuer, before fetching any key | A prefix or host match admits other customers' users, and an unknown issuer makes you fetch from it |
| 2 | Keys come from <iss>/.well-known/openid-configuration, whose issuer must equal iss, then its jwks_uri | Trusting a key or key URL from the JWT's own header means trusting the attacker |
| 3 | Signature verifies. Accept ES256 and RS256 only | none and HMAC algorithms are the classic forgeries. Claude-issued assertions use ES256 |
| 4 | The typ header is oauth-id-jag+jwt | A different kind of token signed by the same issuer gets through |
| 5 | aud is your own issuer, as a string or a one-element array | An assertion meant for another service works on yours |
| 6 | The client_id claim equals the request's client_id | An assertion issued to one client is spent by another |
| 7 | sub is present | Malformed assertions pass |
| 8 | exp has not passed, iat is not in the future, nbf has passed, with at most 60 seconds of skew | Old or not-yet-valid assertions work |
| 9 | jti is present and has never been used by this issuer | A captured assertion works twice. If you cannot check, refuse |
Two details that only show up when you build it:
- A Claude issuer's discovery document is not a full OpenID configuration. It holds
issuerandjwks_uri, with noauthorization_endpointortoken_endpoint, so a library that validates the whole document will reject it. Read those two fields yourself, then build the key set fromjwks_uri. - Make the replay check atomic. A primary key on issuer and
jti, with an insert that does nothing on conflict, means two simultaneous exchanges of one assertion cannot both win. Each row only has to live until the assertion's expiry plus your skew, which for Claude is about a minute.
Step 5: find the person, and be strict about it
For a Claude-issued assertion, find the user by email.
- Compare the whole address, ignoring case. Keep dots and plus tags as they are.
- Look only among the members of the workspace the assertion resolved to.
- Sign someone in by email only if you have verified that address yourself, or the address is on a domain the workspace has verified.
- If nobody matches, refuse. Create a user only for an address on a domain the workspace has verified. We have no verified domains, so we create nobody, and the admin invites people first.
Then answer with a normal token response, including expires_in, and no refresh token. Claude does not use one from this grant. When the access token runs out it gets a new assertion and exchanges it again, with nothing for the person to do, so a short lifetime costs nothing. An hour is reasonable. Keep issuing refresh tokens in your interactive flow.
The whole exchange, in code
This is the logic from our token endpoint, condensed and using jose. Use a real JWT library rather than verifying signatures yourself. db stands in for your own data layer, and at the route you turn any thrown error into invalid_grant.
import { createRemoteJWKSet, decodeJwt, jwtVerify, type JWTVerifyGetKey } from "jose";
// Your metadata's `issuer`, byte for byte. It is every assertion's audience.
const OUR_ISSUER = "https://auth.northstar.example";
const CLAUDE_ISSUER = /^https:\/\/identity\.anthropic\.com\/issuers\/[A-Za-z0-9][A-Za-z0-9._~-]*$/;
const keySets = new Map<string, JWTVerifyGetKey>();
async function keysFor(iss: string): Promise<JWTVerifyGetKey> {
const cached = keySets.get(iss);
if (cached) return cached;
const res = await fetch(`${iss}/.well-known/openid-configuration`, {
redirect: "error",
signal: AbortSignal.timeout(4_000),
});
const doc = await res.json();
if (doc.issuer !== iss) throw new Error("discovery names a different issuer");
// Refetches by itself when an assertion names a key it has not seen.
const keys = createRemoteJWKSet(new URL(doc.jwks_uri), { timeoutDuration: 4_000 });
keySets.set(iss, keys);
return keys;
}
export async function exchangeAssertion(assertion: string, clientId: string) {
// Unverified, and used for one thing: deciding where to look.
const claims = decodeJwt(assertion);
const iss = String(claims.iss ?? "");
const workspace =
typeof claims.aud_tenant === "string"
? await db.workspaceById(claims.aud_tenant)
: await db.onlyWorkspaceTrusting(iss); // null for none, and for more than one
// 1. Issuer: an exact match, before any key is fetched.
if (!workspace || workspace.trustedIssuer !== iss || !CLAUDE_ISSUER.test(iss)) {
throw new Error("issuer is not registered for one workspace");
}
// 2 to 5, 7 and 8.
const { payload } = await jwtVerify(assertion, await keysFor(iss), {
issuer: iss,
audience: OUR_ISSUER,
algorithms: ["ES256", "RS256"],
typ: "oauth-id-jag+jwt",
clockTolerance: 60,
requiredClaims: ["exp", "iat", "sub", "jti"],
});
// jose only reads iat when given a maximum age, so this one is yours.
if (payload.iat! > Date.now() / 1000 + 60) throw new Error("iat is in the future");
// 6. Client.
if (payload.client_id !== clientId) throw new Error("issued to a different client");
// 9. Replay. Last, so a refused assertion does not use up its id.
const firstUse = await db.spendJti(iss, payload.jti!, payload.exp! + 60);
if (!firstUse) throw new Error("already used");
// The person: a verified address, a member of this workspace, and nobody else.
const user = await db.userByEmail(String(payload.email ?? ""));
if (!user?.emailVerified || !(await db.isMember(workspace.id, user.id))) {
throw new Error("no verified member with that email");
}
// Good for this one workspace, whatever else the person belongs to.
return issueAccessToken({ user, workspace, clientId, expiresIn: 3600 });
}Write error_description values an admin can act on. Claude's connection test shows them directly, so "No verified teammate on this account has that email address" saves a support ticket.
Six mistakes to avoid
1. Matching on the subject because the spec says to. The MCP extension's guidance says to use the subject as the primary identifier and fall back to email. That is right for an identity provider. For a Claude-issued assertion it fails every time: the sub is opaque, differs per issuer, and will never match anything you hold. Use the email, and only when verified.
2. Putting a unique index on the issuer column. It feels like good hygiene. But an issuer URL is not a secret, so a unique index lets anyone lock a customer out of their own setup by registering their URL first. Allow duplicates, refuse the assertion when more than one workspace registered its issuer, and let the customer's admin resolve it with your tenant ID, which arrives as aud_tenant.
3. Falling back to the person's own account. This one is not on any checklist, because it depends on your code. Our MCP endpoint resolves which account a token acts on, and that lookup falls back to the person's own account when they are no longer a member of the requested one. For an API key that is right: a stale account id shows you your own things instead of someone else's. For a token earned by an assertion it would have been a hole. Someone removed from a team would keep a working token, now pointed at a personal account nobody ever consented to. So these tokens carry the issuer that earned them, and every call checks that the person still has a role on that exact account and that the account still trusts that issuer. There is no fallback. It also means an admin turning the feature off takes effect on the next request rather than within the hour.
4. Advertising CIMD before your authorization endpoint handles it. The flag changes every compatible host's behavior for new connections, not just this flow. A half-finished version breaks ordinary sign-in.
5. Trusting any issuer that looks right. Matching on a prefix or host admits every other customer of that issuer. And if you accept arbitrary issuers while matching by email, an issuer URL someone registered in a workspace they control can vouch for any address it likes.
6. Not refusing a viewer. If your product has a read-only role, decide what an assertion means for it. Membership of the workspace is not the same as permission to use your tools. We refuse viewers, because every tool we expose is a build tool.
How to test it
Start with Claude-issued assertions, because a Team organization you create for testing qualifies with no SSO, verified domain or identity provider. Do not use an organization that signs in to Claude through Okta, where the option is not offered.
- Add your MCP server as a custom connector for the organization, signed in as an Owner.
- Open the connector, click Set up on the Managed authorization row, and choose Claude-issued under Identity source.
- Copy the Issuer URL into a test workspace in your product, and enter your tenant ID in Claude if you use one.
- Click Run test. It shows which step failed, what Claude sent and what came back, and the decoded claims.
For the identity provider flow, Okta's Cross App Access sandbox exercises your server without a Claude organization at all.
Before launch, make sure each of these is refused, not only that the happy path works:
- An
issno workspace registered. - An
issregistered by two workspaces, with no tenant ID. - An
aud_tenantnaming a workspace that registered a different issuer. - The same assertion a second time.
- An
audthat is not your issuer. - A correct assertion for an address you have not verified, on a domain the workspace has not verified.
Troubleshooting
| What you see | Likely cause | Fix |
|---|---|---|
Invalid client_id, invalid_client or invalid_cimd_request at the authorize step, as soon as CIMD is on | Your CIMD code refuses Claude's document because it lists the JWT bearer grant | Drop grant types you do not issue, and refuse only if nothing you need remains. See Step 2 |
| Claude shows a Connect card instead of connecting silently | The grant is missing from grant_types_supported, or the organization has not finished setup | List the grant even if the endpoint already accepts it, and allow five minutes for the cache |
| No Managed authorization row on the connector | It was added from the directory, and the listing is not marked as supporting this | Test as a custom connector at the same URL |
| Claude registers through DCR instead of using its metadata URL | One of the two CIMD values is missing from your metadata | Advertise client_id_metadata_document_supported: true and "none" in the auth methods |
invalid_client on the token request | Your server cannot fetch or accept Claude's client document | Check outbound access to claude.ai, and that the fetch is not refused by your private-address or size limits |
| Your MCP server gets the request, but your authorization server sees nothing | Discovery is failing, often a firewall in front of it | Check the resource_metadata pointer on your 401, and allow Anthropic's egress range, 160.79.104.0/21 |
invalid_grant on every assertion, signature fine | aud mismatch, often a trailing slash | Compare aud with your metadata's issuer, byte for byte |
| Key lookup fails | A validator expects a full OpenID configuration | Read issuer and jwks_uri from the document yourself |
| Works for one person, fails for another | Their Claude email differs from their account, or it is unverified | Match the addresses, and verify the email on your side |
| Works, then fails intermittently | Slow token endpoint | Claude waits 10 seconds. Cache the keys and the client document |
Do you have to build this yourself?
Not necessarily. The MCP documentation keeps a list of products that accept ID-JAGs, including Okta, Descope, Stytch, Auth0 and WorkOS AuthKit (the last two in early access), Keycloak (experimental), and frameworks such as Cloudflare's workers-oauth-provider and FastMCP.
Before you rely on one for Claude-issued assertions, check three things: it runs every check in the table above, it can register an issuer URL that does not belong to a customer's identity provider, and it can find a user by email rather than by SSO subject. A platform built around identity providers may not do the last two. We run our own authorization server, so we built it directly.
Which connectors support it?
At launch in November 2026, the Claude-issued beta listed fourteen: Amplitude, Apollo.io, Atlassian, Datadog, Dropbox, Figma, Granola, HubSpot, Linear, Mixpanel, Notion, PagerDuty, Semrush and Supabase. A server not on the list can still implement this and test it through a custom connector.
Getting your connector listed
Implementing it does not change your directory listing on its own. Once your server passes end to end:
- Publish a setup guide for your customers' admins, including how to enter a Claude issuer URL. Claude links to it from the admin console. Ours is a template if you want one: four steps, what the feature does and does not vouch for, and what each error means.
- Add the guide's URL to your directory listing.
- Email
mcp-review@anthropic.comwith your listing's name and which kinds of assertion you accept.
FAQ
What is Claude plugin auto-connect?
It is Claude connecting a plugin for members of an organization at login, with no sign-in page or consent screen. It works when the plugin's MCP server accepts Claude as a trusted issuer, and an admin has set it up on both sides. It is in beta on Claude's Team and Enterprise plans.
What does it mean for an MCP server to accept Claude as a trusted issuer?
A customer's admin registers their Claude organization's issuer URL in your product. When Claude then presents a signed identity assertion from that URL, your authorization server validates it and returns an access token, instead of sending the person through a consent screen.
What is the Claude issuer URL?
It has the form https://identity.anthropic.com/issuers/ followed by an id that is unique to each Claude organization and is not the organization's ID. An admin copies it from the Managed authorization setup for your connector in Claude.
Is Claude-issued the same as Enterprise Managed Auth?
It is one of two options inside it. Enterprise Managed Auth is the overall feature, where Claude presents a signed assertion instead of an interactive sign-in. The assertion is either signed by the customer's identity provider or, with the Claude-issued option, by Claude.
Does this work with Dynamic Client Registration?
No. Your server has to recognize the client_id before the first assertion, and a DCR client's generated id can never match. Support Client ID Metadata Documents or Anthropic-held credentials. You can keep DCR running for everything else.
Why does my server reject Claude's client metadata document?
Usually because the document lists the JWT bearer grant alongside authorization_code and refresh_token, and your code refuses any grant type it does not support. It often shows up as Invalid client_id or invalid_client at the authorize step. Drop the entries you do not issue, and refuse the document only if nothing you need remains.
Why not find the user by the sub claim?
Because a Claude-issued sub is opaque and differs under each issuer, so it never matches a subject you already hold. Find the user by email, among the members of that workspace, and only if the address is verified. For an identity provider-issued assertion, use iss and sub instead.
Do I need to issue refresh tokens for the JWT bearer grant?
No, and you should not. Claude requests a new assertion each time the access token expires, with nothing for the person to do. Keep refresh tokens for your interactive flow.
Does it work with lazy authentication?
Yes. If some of your tools need no account, the 401 on a protected tool triggers the silent exchange instead of a Connect card. A fully authless server never returns a 401, so this cannot apply to it.
Does a Claude-issued assertion prove the person used SSO or MFA?
No. It proves current membership of the Claude organization and the email on that account, and it carries no group claims. If a customer needs SSO enforced, their identity provider has to issue the assertion instead.
What happens when someone leaves the company?
Claude stops signing assertions once they are removed from the Claude organization, but any access token you already issued lives until it expires. Short lifetimes bound that, and customers should remove the person on your side too.
Related reading
- Connect your whole team from Claude: the admin's setup guide for Server4Agent.
- Claude auto-connect: give your whole team a server: the same feature from the admin's and the team's side.
- What is an MCP server in AI?: start here if the protocol is new to you.
- Give your AI agent its own server: what we build on top of MCP.
External references
- Enterprise Managed Auth for connectors, Claude's developer documentation
- Authentication for connectors, including CIMD and callback URLs
- Lazy authentication for MCP servers
- Auto-connect your organization's apps to Claude, the admin's view
- Enterprise-Managed Authorization, the MCP extension
- Identity Assertion JWT Authorization Grant, the IETF draft
- RFC 7523, the JWT bearer grant
- Client ID Metadata Document, the IETF draft
- CIMD sign-in fails with OCI IAM identity domains, the open report against Claude's document
- CIMD: a metadata document is rejected when it declares an extra grant_type, django-oauth-toolkit
- XAA vs ID-JAG vs EMA, from Descope
- Bringing enterprise-managed authorization to Rovo MCP, from Atlassian
About Server4Agent
Server4Agent is a hosted server for AI agents. Your assistant builds a tool, site, API or bot on it from a plain-English request and ships it to a live URL, private by default and under a hard budget cap. Admins can connect a whole team from Claude with the setup guide.