Set up per-user OAuth so each end-user of your AVCodex agent connects with their own account on third-party services.
Consumer OAuth lets every end-user authenticate with their own credentials on third-party systems (Crestron XiO Cloud, Q-SYS Reflect, ServiceNow, Microsoft 365, Google Workspace) instead of every action running through one shared API key. The agent then acts on the user's behalf and you keep accountability per tech, per programmer, per client.
Use Consumer OAuth when:
- Each user needs access to their own data (their tickets, their calendar, their assigned rooms in XiO Cloud).
- The third-party API requires user-specific authentication.
- You need accountability for which person performed each action.
- The service enforces per-user rate limits or permissions.
Use a shared Bearer Token when:
- The agent reads shared resources that everyone is allowed to see (a company-wide rack-elevation library, an internal product catalog).
- The MCP server fronts an internal API you fully control.
- You want the simplest possible setup.
- A tech or programmer starts a chat with your AVCodex agent.
- The agent calls a tool that needs user-specific authentication.
- AVCodex detects the user has not connected that account yet.
- The user sees an OAuth prompt and clicks to authenticate.
- A browser tab opens the third-party login page.
- The user authorizes your AVCodex agent to access their data.
- The callback returns with an authorization code.
- AVCodex exchanges the code for access and refresh tokens.
- Tokens are stored securely per user in the database.
- The tool executes with the user's access token.
After that, requests use the stored tokens. AVCodex refreshes expired tokens with the refresh token automatically.
Configure Consumer OAuth in the Pro Actions modal when adding a custom MCP server.
Step 1: Create the OAuth App on the Third-Party Service#
Register an OAuth application with the service you want to integrate (Salesforce, Crestron XiO, ServiceNow, Microsoft, Google).
You will configure:
| Setting | Value |
|---|---|
| Redirect URI | https://app.avcodex.com/api/chat/mcp/oauth/callback |
| Scopes | The minimum scopes your tools need |
After registration you receive:
- Client ID. Public identifier for your OAuth app.
- Client Secret. Private key. Keep it in a secret store.
Step 2: Find the OAuth Endpoints#
Look up the OAuth 2.0 endpoints in the provider's docs:
| Endpoint | Description | Example |
|---|---|---|
| Authorize URL | Where users grant permission | https://login.salesforce.com/services/oauth2/authorize |
| Token URL | Where codes are exchanged for tokens | https://login.salesforce.com/services/oauth2/token |
Step 3: Configure in AVCodex#
- Open your agent's Build tab.
- Open the Pro Actions modal.
- Click Add Custom MCP Server.
- Enter your MCP Server URL.
- Pick Consumer OAuth (per-user) as the auth type.
Fill in the OAuth fields (client ID, client secret, authorize URL, token URL, scopes, token request style).
Step 4: Test the Configuration#
Click Test OAuth Configuration:
- A new window opens to the third-party login page.
- Sign in and approve the connection.
- The window closes and reports success.
- On success, your MCP server's tools are fetched and cached.
Tip: Test with your own account first. If the round trip completes and tools load, the configuration is correct.
Different OAuth providers expect credentials in different shapes during the token exchange. Pick the style that matches your provider:
form_post (most common)#
Credentials in the form-encoded body. Try this first.
POST /oauth/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=AUTH_CODE&
client_id=YOUR_CLIENT_ID&
client_secret=YOUR_CLIENT_SECRET&
redirect_uri=https://app.avcodex.com/api/chat/mcp/oauth/callback
Used by: Google, GitHub, LinkedIn, most OAuth providers.
json_basic#
Credentials in HTTP Basic Authorization header, body as JSON.
POST /oauth/token HTTP/1.1
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/json
{
"grant_type": "authorization_code",
"code": "AUTH_CODE",
"redirect_uri": "https://app.avcodex.com/api/chat/mcp/oauth/callback"
}
Used by: Some enterprise APIs, Stripe.
form_basic#
Credentials in Basic header, body as form-encoded.
POST /oauth/token HTTP/1.1
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=AUTH_CODE&
redirect_uri=https://app.avcodex.com/api/chat/mcp/oauth/callback
Used by: Salesforce, some enterprise OAuth providers.
Warning: If token exchange fails, try a different style. Provider error messages often do not point at the wrong style.
After a user authenticates, AVCodex passes their access token to your MCP server in the Authorization header:
POST /mcp HTTP/1.1
Authorization: Bearer USER_ACCESS_TOKEN
Content-Type: application/json
Your MCP server reads the token and calls the upstream API on the user's behalf:
// In your MCP server
server.tool(
"get_my_xio_rooms",
"Fetch the rooms the calling tech has access to in Crestron XiO Cloud",
{},
async (args, context) => {
// The user's access token is in the Authorization header
const userToken = context?.meta?.authorization?.replace("Bearer ", "");
const response = await fetch("https://api.crestron.io/xio/rooms", {
headers: {
"Authorization": `Bearer ${userToken}`
}
});
const rooms = await response.json();
return {
content: [{ type: "text", text: JSON.stringify(rooms, null, 2) }]
};
}
);
Access tokens expire. AVCodex handles refresh:
- Before each MCP call, AVCodex checks whether the token is expired (with a 5-minute buffer).
- If it is expired and a refresh token exists, AVCodex requests a new access token.
- The new token is stored and used for the request.
- If refresh fails, the user is prompted to re-authenticate.
Your MCP server does not need to handle refresh. AVCodex manages it.
Note: Some providers (Google, for example) only return a refresh token on the first authorization. If a user needs to re-authenticate, they may have to revoke access in their account settings first.
When a tech chats with your agent and the agent needs a tool that requires Consumer OAuth:
- First time: the user sees a message asking them to connect the account.
- Click to connect: the OAuth provider's login and consent page opens.
- Authorize: the user grants access.
- Automatic return: the browser tab closes and the chat continues.
- Subsequent chats: no prompts. Stored tokens are reused.
What Users See#
This action needs access to your Crestron XiO Cloud account.
[Connect Crestron XiO]
We will only request the scopes this agent needs.
After connecting:
Connected to Crestron XiO as jordan@yourintegrator.com
Pulling your assigned rooms now...
- Store client secrets in a real secret manager. Never in source.
- Request the minimum scopes the agent needs. A field-tech assistant rarely needs admin scopes.
- Set short token TTLs upstream where the provider allows it.
- Revoke tokens promptly when a user is removed from your AVCodex workspace.
- Audit which tools requested user tokens and when (see the audit logs guide).
"Invalid redirect_uri" error#
The redirect URI in your OAuth app does not match what AVCodex sends.
Fix: Set your OAuth app's redirect URI to exactly:
https://app.avcodex.com/api/chat/mcp/oauth/callback
"Invalid client" error#
Wrong client ID or secret.
Fix: Re-check the credentials. Many providers issue separate credentials for sandbox and production.
Token exchange fails silently#
Wrong token request style.
Fix: Try each style (form_post, json_basic, form_basic) until one works.
"Access denied" during authorization#
The user declined consent, or the requested scopes are not approved.
Fix:
- Confirm the user clicked Allow.
- Verify your OAuth app is approved for the requested scopes.
- Some scopes require provider review.
Refresh token missing#
The provider only issues refresh tokens on the first authorization.
Fix:
- Have the user revoke access in the provider's settings.
- Re-authorize to receive a new refresh token.
- Some providers want
access_type=offlineorprompt=consenton the authorize URL.
Tools do not load after OAuth#
OAuth succeeded but no tools appear.
Fix:
- Confirm your MCP server is running and reachable.
- Verify the server URL.
- Check the server logs.
- Make sure the server returns a valid
tools/listresponse.
A sales-engineering agent for a managed-services AV firm uses Salesforce to look up the calling SE's open opportunities and pull contact details for the room-refresh quote they are working on.
1. Create a Connected App in Salesforce#
- Go to Setup -> Apps -> App Manager.
- Click New Connected App.
- Configure:
- Connected App Name: AVCodex SE Assistant - API Name: AVCodex_SE_Assistant - Enable OAuth Settings: on - Callback URL: https://app.avcodex.com/api/chat/mcp/oauth/callback - Selected OAuth Scopes: api, refresh_token, offline_access
- Save and wait for activation (about 10 minutes).
- Copy Consumer Key (Client ID) and Consumer Secret.
2. Configure in AVCodex#
| Field | Value |
|---|---|
| OAuth Client ID | 3MVG9... (your Consumer Key) |
| OAuth Client Secret | ABC123... (your Consumer Secret) |
| Authorize URL | https://login.salesforce.com/services/oauth2/authorize |
| Token URL | https://login.salesforce.com/services/oauth2/token |
| Scopes | api refresh_token offline_access |
| Token Request Style | form_basic |
3. Build Your MCP Server Tool#
server.tool(
"search_salesforce_contacts",
"Search contacts in the calling SE's Salesforce org (e.g. the IT director on a 40-room refresh)",
{
query: z.string().describe("Search query for contact name or email")
},
async ({ query }, context) => {
const token = context?.meta?.authorization?.replace("Bearer ", "");
// Get instance URL from token info (simplified)
const instanceUrl = "https://your-instance.salesforce.com";
const soql = `SELECT Id, Name, Email, Phone FROM Contact WHERE Name LIKE '%${query}%' LIMIT 10`;
const response = await fetch(
`${instanceUrl}/services/data/v58.0/query?q=${encodeURIComponent(soql)}`,
{
headers: { "Authorization": `Bearer ${token}` }
}
);
const results = await response.json();
return {
content: [{ type: "text", text: JSON.stringify(results.records, null, 2) }]
};
}
);
- Building Custom MCP Servers. Full guide to building MCP servers.
- Pro Actions Getting Started. Pre-built MCP integrations.
- AVCodex MCP Server. Connect Claude Code to manage your AVCodex agents.
*AVCodex · Your AV expertise. Amplified by AI.*