How to use Eightfold MCP
Choose your credential model
| Dimension | PAT (personal access token) | OAuth client |
|---|---|---|
| Who mints | You, self-serve | A tenant admin registers a client; each user then connects individually |
| Enabled by |
mcp_gate for the tenant — request this from the Eightfold team, then registration itself is self-service via OAuth Token Management Page |
mcp_gate for the tenant — also requested from the Eightfold team, then registration itself is self-service via Admin Console |
| Scoped by | A scope group you choose at token creation | The client's allowed_scopes, chosen by the admin at registration |
| Lifetime | Default Max is 90 days (configurable by Admin); up to 10 tokens per user | Access token up to 1h, refresh token up to 30d |
| Best for | Pilots, individual users, CLI and IDE clients | Production rollouts, custom plugins on public clients (Claude.ai, ChatGPT, Copilot), or agents that support client secret post or JWT bearer auth flows |
| Revocation | Revoke your own token, or the gate is turned off | Delete the client |
Set up personal access tokens (admin)
- Ask Eightfold to enable MCP for your tenant (request
mcp_gate). - Once enabled, admins can change the default expiry, the maximum expiry, or the per-user token limit — or turn PATs off entirely. These settings live in
oauth_v2_config, which Eightfold edits on request. - Review which permission sets (scope groups) users will see. The permissions picker only shows groups the user qualifies for: Talent Management for all employees; Talent Acquisition for recruiters, admins, and hiring managers (no tools in this release); Resource Management where RM is enabled. For this rollout, set up Talent Management only.
- Share the
/oauth/tokenslink with users. Optionally, add a link in Career Hub so users can reach it from Career Hub → Settings → Account. To configure this: in Career Hub base config → advanced section in the Admin Console, addtokenManagementto the account settings field ordering.
Career Hub base config — adding tokenManagement to account settings field ordering
- Verify: have a test user create a token, copy the MCP URL and list the tools, and confirm the call appears in Data Hub.
https://<host>/oauth/tokens directly. There's no nav link by default; Career Hub only shows one if the tenant configures it (step d). The Eightfold MCP page at /integrations/eightfold_mcp has two tabs: OAuth Client Manager (covered in Path B below) and Settings → Configuration for PAT and scope group settings. To adjust PAT settings — on/off, default and maximum expiry, per-user token limit, and scope groups — open the Settings → Configuration tab on the same page.Path A — Get a PAT (self-serve)
- Open the token management page at
/oauth/tokens. - Click Create token — give it a name and pick a scope group.
- Copy the token — it's shown only once. Copy the MCP server URL shown on the same page — this is the URL your AI client connects to.
- Paste it into your MCP client as an
Authorization: Bearer <token>header.
The /oauth/tokens page — click Create token, name it, and pick a scope group
Path B — Register an OAuth client (admin)
Access the OAuth Client Manager
- Log in and open the Admin Console.
- In the left navigation, expand the Integration group.
- Click Eightfold MCP (listed below "Eightfold API").
The Registered clients page opens — a table of existing clients plus a Register client button. If mcp_gate is off, this nav item is hidden entirely — request the gate from the Eightfold team first. If you aren't a tenant admin, the page may load but client data won't.
The Registered clients page — existing clients listed with Register client button
Register a client — 3-step wizard
| Step | What to do |
|---|---|
| 1 — Client information | Client name, Description, Logo URL, Homepage URL, Scopes, Access token expiry (seconds). Name, Scopes, and expiry are required. |
| 2 — Authentication | Choose one: Client secret (basic), Client secret (post), or Private key JWT. This choice shapes Step 3. |
| 3 — Access grant | Grant type(s) and related fields (redirect URIs, refresh-token expiry, PKCE, or IdP settings) — available options depend on Step 2. |
| Success screen | Copy the new client_id (always shown) and, for secret-based methods, the client_secret — shown once. |
Step 1: Client information — enter name, scopes, and access token expiry
Three authentication methods
| Method | How it proves identity | Allowed grant type(s) | What you get |
|---|---|---|---|
| A — Client secret (basic) |
client_id + secret in the HTTP Authorization: Basic header |
authorization_code (+ refresh_token) | A one-time client secret |
| B — Client secret (post) |
client_id + secret as fields in the POST body |
authorization_code (+ refresh_token) | A one-time client secret |
| C — Private key JWT | A signed JWT "client assertion," signed with your private key | jwt-bearer and/or authorization_code (+ refresh_token) | Only a client_id — no secret |
Step 2: Authentication — choose Client secret (basic/post) or Private key JWT
jwt-bearer grant only works with Method C — you can't use it with a secret-based method; registration is rejected if you try.Method A: Eightfold generates the
client_secret at creation, shown once. Provide redirect URIs (required, valid http(s) URL) and a refresh-token expiry exceeding the access-token expiry. PKCE defaults to on.Method B: identical to A, except send the secret in the token-request POST body instead of the Authorization header.
Grant types & validation rules
Registration is rejected if you violate one:
-
authorization_coderequires at least one redirect URI. -
authorization_coderequiresrefresh_tokentoo. - Secret-based methods cannot use the
jwt-bearergrant. - Private key JWT requires at least one public key.
-
jwt_issuerandidp_public_keysare provided together or not at all. - Refresh-token expiry must exceed access-token expiry; access-token expiry is required and capped at the platform maximum.
- At least one scope must be requested.
You can register at most 10 clients per tenant — delete one to free a slot.
Edit and delete a client
| You can edit | Locked at creation |
|---|---|
| Client name, description, logo URL, homepage URL | Authentication method & keys |
| Allowed scopes | Grant types, redirect URIs |
| Access token expiry | — |
| Refresh-token expiry, jwt_issuer, IdP keys, PKCE | — |
Editing doesn't re-issue the secret. Editing allowed scopes only affects new tokens — already-issued tokens keep their original scope until they expire.
Delete a client: click delete (trash), confirm. Can't be undone from the UI. Soft-deletes the client (no new tokens), but already-issued tokens keep working until they expire naturally (~1 hour).
Gating & visibility
| Condition | Result |
|---|---|
| Gate ON + you're a tenant admin | "Eightfold MCP" visible in nav; page renders; clients list loads. |
| Gate ON + you're not an admin | APIs reject you; client data doesn't load. |
| Gate OFF | Nav item hidden entirely — this is what a gate request from the Eightfold team fixes. |
Method C in full — Private key JWT
No shared secret ever leaves you. Generate an RSA key pair locally and register only the public key. Your client signs a short-lived JWT assertion with the private key; Eightfold verifies it with the registered public key. Supported algorithms: RS256, RS384, RS512.
Quick start (6 steps)
- Generate RSA key pair (private.pem, public.pem).
- Share the public key + client name with Eightfold → receive client_id.
- Create a client assertion JWT, signed with your private key.
- Create a JWT assertion on behalf of the user (or have your IDP share one, if registered with the client).
- Exchange both JWTs at the Eightfold OAuth Token Endpoint → receive an access token.
- Call the MCP server with
Authorization: Bearer <token>.
Step 1 — Generate your key pair
# Generate a 2048-bit RSA private key openssl genrsa -out private.pem 2048 # Extract the public key openssl rsa -in private.pem -pubout -out public.pem
Store private.pem securely (never commit to Git). Share only public.pem with Eightfold. The private key signs JWTs; the public key is what Eightfold uses to verify them.
openssl genrsa isn't available (newer OpenSSL 3.x builds sometimes drop it), use the equivalent:openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private_key.pemopenssl pkey -in private_key.pem -pubout -out public_key.pemIf openssl itself isn't installed: macOS
brew install openssl · Debian/Ubuntu sudo apt-get install openssl · RHEL/CentOS sudo yum install openssl
Step 2 — Register your client
Client registration is self-service in the Admin Console — no engineering ticket needed. It requires mcp_gate to be enabled for your tenant.
- Log in and open the Admin Console.
- In the left navigation, expand Integration and click Eightfold MCP.
- On the Registered clients page, click Register client.
- Client information: enter Client name, Description, Logo URL, Homepage URL, Scopes, and Access token expiry.
- Authentication: choose Private key JWT. Paste the full
public_key.pemblock into Client public keys. Give it a Key ID (kid) — any unique label, e.g.key-1. - Access grant: choose jwt-bearer as the grant type (preferred). You can optionally also enable
authorization_code+refresh_token. - Self-issued (default, recommended): leave JWT Issuer blank — it defaults to your
client_id. External IdP (e.g. Entra ID): set JWT Issuer and IDP public keys instead. - On the success screen, copy the
client_id. No secret is generated for this method.
private_key_jwt with a self-issued jwt-bearer assertion is the simplest configuration for this flow — use it unless you specifically need an external IdP to sign your tokens.Step 3 — Create a client assertion JWT
# pip install pyjwt cryptography requests
import jwt
import datetime
import uuid
with open("private.pem", "rb") as f:
private_key = f.read()
CLIENT_ID_FROM_EIGHTFOLD = ""
now = datetime.datetime.utcnow()
client_assertion_payload = {
"iss": CLIENT_ID_FROM_EIGHTFOLD, # client_id
"sub": CLIENT_ID_FROM_EIGHTFOLD, # must match iss
"aud": "urn:eightfold:oauth-server:token-endpoint",
"jti": str(uuid.uuid4()), # unique — prevents replay
"exp": now + datetime.timedelta(minutes=5), # max 5 min from iat
"iat": now,
}
client_assertion = jwt.encode(client_assertion_payload, private_key, algorithm="RS256", headers={"kid": "key-1"})
print(client_assertion)
Rules: never reuse assertions (unique jti every time); exp must be ≤ 5 minutes after iat; sign only with RS256/RS384/RS512; aud must always be urn:eightfold:oauth-server:token-endpoint; iss must match sub, both equal to your client_id. Include kid in the header if you have multiple registered keys (optional with just one).
Step 4 — Create a JWT assertion on behalf of the user
If an IDP is involved, this assertion must be signed by the IDP. Otherwise, sign it yourself:
CLIENT_ID_FROM_EIGHTFOLD = ""
EIGHTFOLD_USER_EMAIL = "Eightfold_User_Email"
now = datetime.datetime.utcnow()
jwt_assertion_payload = {
"iss": CLIENT_ID_FROM_EIGHTFOLD, # client_id or IDP issuer
"sub": EIGHTFOLD_USER_EMAIL,
"aud": "urn:eightfold:oauth-server:token-endpoint",
"jti": str(uuid.uuid4()),
"exp": now + datetime.timedelta(minutes=5),
"iat": now,
}
jwt_assertion = jwt.encode(jwt_assertion_payload, private_key, algorithm="RS256", headers={"kid": "key-1"})
Same rules as Step 3, plus: iss must match the IDP issuer claim from client registration; sub can be the Eightfold user email, or email:group_id (e.g. demo@eightfold.com:eightfold.com).
Step 5 — Exchange both JWTs for an access token
curl -X POST https://app.eightfold.ai/oauth/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \ -d "assertion=$JWT_ASSERTION" \ -d "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer" \ -d "client_assertion=$CLIENT_ASSERTION"
Or in Python:
import requests
token_endpoint = 'https://app.eightfold.ai/oauth/token'
data = {
'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion': jwt_assertion,
'client_assertion_type': 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
'client_assertion': client_assertion,
}
response = requests.post(token_endpoint, data=data, headers={'Content-Type': 'application/x-www-form-urlencoded'})
response.raise_for_status()
print(response.json())
Sample response:
{ "token_type": "Bearer", "access_token": "ACCESS_TOKEN_HERE", "expires_in": 3600 }
Use https://app.eightfold.ai/oauth/token or your https://customer-domain.eightfold.ai/oauth/token.
Step 6 — Test the connection
Python:
# pip install mcp (version > 1.9, supports streamablehttp_client)
import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client as http_client
SERVER_URL = 'https://mcp.eightfold.ai/mcp/'
async def main():
headers = {'Authorization': 'Bearer (access token obtained from OAuth server)'}
async with http_client(SERVER_URL, headers=headers) as transport_layer:
read, write, _ = transport_layer
async with ClientSession(read, write) as session:
await session.initialize()
print(await session.list_tools())
if __name__ == '__main__':
asyncio.run(main())
Cursor AI Editor config:
{
"mcpServers": {
"eightfold": {
"url": "https://mcp.eightfold.ai/mcp/",
"headers": { "Authorization": "Bearer (mcp_token)" }
}
}
}
/mcp/, not /mcp — this is a real, common connection failure. The URL is region-dependent: EU https://mcp.eightfold-eu.ai/mcp/, WU https://mcp.eightfold-wu.ai/mcp/ (full region table in the Overview tab).Complete OAuth client configuration reference
| Field | Description | Default / Required |
|---|---|---|
| Allowed Scopes | List of Eightfold's OAuth scopes | Required |
| Client Name | Used in the consent screen and internal dashboards | Required |
| Client Logo URL | Branding on the consent screen | Optional |
| Client Homepage URL | Branding on the consent screen | Optional |
| Client Description | Branding on the consent screen | Optional |
| Client Authentication Methods |
client_secret_basic, client_secret_post, private_key_jwt
|
Required to choose one |
| Client Public Keys |
kid → public key dictionary |
Required if private_key_jwt is enabled |
| Client JWKS / JWKS URI | Not supported yet — will replace public keys in future | N/A |
| Enabled Grant Types |
authorization_code, refresh_token, urn:ietf:params:oauth:grant-type:jwt-bearer (one or more) |
Optional — default: all supported grants |
| JWT Issuer | Issuer claim to validate in JWT-bearer flow if an IDP signs the token; defaults to client_id if self-signed |
Optional |
| IDP Public Keys | Dictionary of kid → public key, used to verify IDP-signed JWTs; defaults to client public keys |
Optional |
| Redirect URIs | One or more, for the authorization_code grant |
Required if authorization_code is enabled |
| Access Token Expiry | Max allowed: 3600 seconds | Optional — default 3600s |
| Refresh Token Expiry | Only applies if refresh_token grant is enabled |
Optional — default 2,592,000 seconds (30 days) |
Connect a specific client
Claude — detailed setup
Part 1 — Eightfold admin registers an OAuth client for Claude
- Sign in to Eightfold and open the Admin Console.
- Go to Integrations → Eightfold MCP, then click Register client.
- Client information:
• Client name: for example, "Claude". Users see this name on the Eightfold consent screen.
• Description, Logo URL, Homepage URL: optional.
• Scopes:talent_management.
• Access token expiry (seconds): keep 3600 (the maximum). - Authentication: set Authentication method to Client secret (post).
- Access grant:
• OAuth flow: Authorization Code.
• Redirect URIs:https://claude.ai/api/mcp/auth_callback, exactly as shown.
• Refresh token expiry (seconds): keep 2592000 (30 days).
• Disable PKCE: leave it unchecked. Claude always uses PKCE. - Click Register. On "Client registered successfully", copy the Client ID and Client secret. The secret is shown only once — if it's lost, delete the client and register a new one.
- Send the Client ID, the secret, and your region's MCP URL to your Claude Owner through a secure channel such as a password manager. Don't use email or chat.
Step 3: Access grant — set redirect URI to https://claude.ai/api/mcp/auth_callback
Part 2 — Claude Owner adds the connector
- In Claude, go to Organization settings → Connectors.
- Click Add, choose Custom, and if asked for the type, choose Web.
- Enter a name (for example, "Eightfold"). Users see it in their connectors list.
- Enter the MCP server URL for your region exactly as shown, including the trailing
/. Click Continue. - Authentication: choose Sign in now.
- OAuth client: choose Use your own OAuth client, then enter the Client ID and Client secret from Part 1. Don't choose "Use Claude's published identity" or "Register automatically" — Eightfold doesn't support those.
- Leave Request headers empty and click Add.
The connector now appears for everyone in your organization with a Custom label.
Part 3 — Each user connects
- In Claude, go to Customize → Connectors.
- Find the Eightfold connector (marked Custom) and click Connect.
- Sign in to Eightfold if asked, with your employee account.
- On the Eightfold consent screen, check the scopes listed and click Allow.
- You're returned to Claude. Open the connector to see the tools available to you.
Claude Code (CLI) — setup with a PAT
- Create a personal access token: open your Career Hub → Settings → Token management console, create a Talent Management token, and copy it.
- In your terminal, add the server:
claude mcp add --transport http eightfold_production https://mcp.eightfold.ai/mcp/ --header "Authorization: Bearer <token>"
Replace<token>with the token you copied. - Verify the connection: run
claudein your terminal, then type/mcp. Check thateightfold_productionappears in the server list.
GPT
The following steps are possible for Admin only.
- In ChatGPT, go to Settings → Plugins, then click Browse plugins.
- Click + to start a new plugin.
- Enter a Name and optional Description, set Connection to Server URL, and set Authentication to OAuth.
- Open Advanced OAuth settings and copy the auto-generated Callback URL — you'll need it when registering the client in Eightfold.
- In the Eightfold Admin Console, register the OAuth client and paste this Callback URL into Redirect URIs. Use the client secret post method, and leave PKCE disabled for GPT (unlike Claude, where PKCE stays enabled).
- Back in ChatGPT, paste the Client ID and Client Secret from Eightfold, and set Token endpoint auth method to
client_secret_post. - Check "I understand and want to continue" to accept the custom-MCP-server risk notice, then click Create.
- Click Sign in with [connector name]. You'll be redirected to Eightfold's consent screen — review the requested scopes and click Allow.
- Once installed, open the connector's settings and click Refresh under Actions. The tool list is empty until you do this.
- To use the connector in a chat, type
@followed by its name (e.g.@My EF MCP what should be my next roles?).
Microsoft Copilot Studio — full walkthrough
Pieces involved: MCP server (region-dependent URL) · OAuth client · Tool/connector · Connection · Agent.
Reference values
| Field | Value |
|---|---|
| Server URL | Region-dependent |
| Authentication | OAuth 2.0 |
| Type | Manual |
| Authorization URL |
https://app.eightfold.ai/oauth/authorize (stage: https://stage.eightfold.ai/oauth/authorize) |
| Token URL / Refresh URL |
https://app.eightfold.ai/oauth/token (stage: https://stage.eightfold.ai/oauth/token) |
| Scopes | Space-separated, e.g. talent_management
|
| Redirect URL | Leave blank — Copilot Studio generates it after you save |
Steps
- Register the OAuth client in Eightfold first. Admin Console → Integration → Eightfold MCP → Add client. Set Token endpoint authentication method to Client secret post. Disable PKCE. Enter a placeholder Redirect URI — you'll replace it in Step 5. Set Scopes. Save and copy Client ID and Client secret.
- Copilot Studio → Tools → New tool → Model Context Protocol.
- Name it, set Server URL to
https://mcp.eightfold.ai/mcp/, Authentication → OAuth 2.0, Type → Manual. Fill in Client ID/secret/URLs/Scopes from the reference table. Leave Redirect URI blank. - Click Create — Copilot Studio generates a Redirect URL.
- Update the Redirect URI on your Eightfold client: open the tool's Security tab, copy the generated URL; go back to Admin Console → Edit the client → Access grant step → paste it in → Save.
- Create and authorize the connection: Test step → Update connection → New connection → review the Eightfold consent screen → Allow → close the editor.
- Agents → open/create an agent → Tools → Add a tool → choose yours → Add.
- Ask a test query (e.g. "give me the top 10 Python jobs in the USA"). Results = connected.
- If you see "Let's get you connected first…": open Connection Manager, connect, retry.
Troubleshooting
| If you see this | Do this |
|---|---|
| "Let's get you connected first…" | Open Connection Manager, connect, retry (Step 9). |
| Authorization fails / redirect error after Allow | Redirect URL isn't registered — re-copy from Security tab, add via Edit → Access grant (Step 5); must match exactly. |
| Consent screen shows wrong/missing permissions | Align the tool's scopes with the client's registered scopes. |
| "Enter the complete server path to continue" | Use the full URL with trailing /mcp/. |
| Token/refresh errors, repeated logout | Token URL and Refresh URL must point at the same environment as the client. |
| Changed a setting, nothing happened | Re-open Test step, click Update connection. |
Set up any other client
| Client | Credential | What to configure |
|---|---|---|
| Cursor | PAT |
.cursor/mcp.json — url plus headers.Authorization
|
| Claude Code (CLI) | PAT | claude mcp add <name> --transport http <url> --header "Authorization: Bearer $TOKEN" |
| VS Code / GitHub Copilot | PAT or OAuth client | MCP server entry with a header, or OAuth |
| Claude.ai / Desktop (custom connector) | OAuth client (recommended) or PAT | Admin settings → Connectors → Add custom connector → MCP URL + client_id/client_secret. Redirect URI: https://claude.ai/api/mcp/auth_callback. |
| ChatGPT | OAuth client | Same shape as Claude |
| M365 Copilot / Copilot Studio | OAuth client | Standard OAuth; disable PKCE for this client |
| Codex CLI, or any client without header support | PAT | Proxy via npx -y mcp-remote <url> --header "Authorization: Bearer <token>"
|
Enable MCP for a brand-new tenant
Same procedure for production or sandbox — sandbox tenants share the regional deployment, nothing extra to provision.
New tenant MCP enablement checklist
| # | Step | Verify |
|---|---|---|
| 1 | Confirm the region, pick the matching MCP URL | — |
| 2 | Pre-flight the capability list against /docs?scope=…
|
A gap here is a product-entitlement issue, not MCP |
| 3 | Request mcp_gate from the Eightfold team (self-service ask — support ticket should be raised). It turns on both personal access tokens and client registration. |
A named user can open /careerhub/oauth/tokens and create a token; an admin sees the Eightfold MCP tab under Admin Console → Integrations |
| 4 | Nothing more to request — mcp_gate already turns on client registration |
An admin sees the Eightfold MCP tab in Admin Console → Integrations |
| 5 | Scope groups — usually nothing to do, tenants inherit defaults | A test user sees the expected scope groups when creating a token |
| 6 | Issue a credential (PAT, or register a client — now fully self-service once the gate is on) | The client lists the expected tools |
| 7 | Confirm the audit trail — the step most often skipped, and the one that makes support possible later | A row appears in mcp_server_log_analytics with the right tenant, token, tool, latency |
Quick recipes
-
Enable a tenant, PAT-only (fastest pilot path): request
mcp_gatefrom the Eightfold team → leaveoauth_v2_configalone → mint a token at/oauth/tokens. Set the scope group totalent_managementonly — other scope groups (such astalent_acquisition) have no enabled tools yet. -
Add OAuth client registration: do the above (
mcp_gatealready turns this on), then confirm the registering person is a group admin. - Give a tenant a custom scope group or longer-lived tokens: go to Admin Console → Integration → Eightfold MCP → Settings → Configuration and update the Scope Groups or Personal Access Tokens settings there.
-
Audit a change: run
get_changelogon the config name, optionally filtered by partition.