Set up OAuth on a custom MCP server
Give your whole org a custom MCP server that signs in the way your identity provider intends: through OAuth, with no pasted tokens. Each member connects their own account, so agents act as the person who runs them. This guide uses Snowflake as the worked example. The same steps fit any remote MCP server that signs in with OAuth.
Before you start
- Role: admin or owner in Marshal. You also need someone who can create an OAuth client at the provider. For Snowflake, that is a role that can create security integrations.
- Available when your organization allows custom MCP servers (Settings > MCP Servers).
- The server must run remotely and be reachable over https.
Pick your setup
| If the provider… | You enter | Go to |
|---|---|---|
| Publishes its OAuth settings and registers clients automatically | Only the server URL | Set up from the URL |
| Publishes its settings but needs a client you create | The client ID and secret | Set up by hand |
| Publishes nothing, as Snowflake does | The client, both endpoints and the scopes | Set up by hand |
Marshal looks for the published settings as soon as you enter the URL, so you always start in the right place.
Set up from the URL
- Open Settings > MCP Servers and choose Add MCP server.
- Choose Remote (URL), fill in Name and Display name, and enter the Remote URL.
- Turn on Sign in with OAuth.
- Marshal looks up the server’s OAuth settings. When it finds them, it shows the Authorize and Token endpoints it will use. If the provider registers clients automatically, there is no client ID or secret to enter. If it does not, Marshal asks for the client you created there.
- Choose Save, then continue to Test the connection.
Prefer to enter everything yourself? Turn on Enter details manually at any time.
Set up by hand
The Snowflake example below shows every field. Replace <account> with your Snowflake account identifier and <ROLE> with the role the agents should use.
1. Create the OAuth client at the provider
In Snowflake, create a security integration for a custom OAuth client. You will register the redirect URI in step 2, so keep the values handy.
CREATE SECURITY INTEGRATION marshal_mcp
TYPE = OAUTH
OAUTH_CLIENT = CUSTOM
OAUTH_CLIENT_TYPE = 'CONFIDENTIAL'
OAUTH_REDIRECT_URI = '<redirect URI from step 2>'
OAUTH_ISSUE_REFRESH_TOKENS = TRUE
ENABLED = TRUE;Then read the client ID and secret Snowflake generated for it:
SELECT SYSTEM$SHOW_OAUTH_CLIENT_SECRETS('MARSHAL_MCP');2. Add the server and copy the redirect URI
- Open Settings > MCP Servers and choose Add MCP server.
- Choose Remote (URL), fill in Name and Display name, and enter the Remote URL of your Snowflake managed MCP server.
- Turn on Sign in with OAuth.
- Find Redirect URI and choose Copy. This is the exact address the provider sends people back to after they sign in. Register it in the security integration (
OAUTH_REDIRECT_URI).
Each Marshal installation has its own redirect URI. Register the one the form shows for the installation you are using.
3. Enter the client and endpoints
Turn on Enter details manually, then fill in:
| Field | Snowflake value |
|---|---|
| Client ID | The client ID from step 1 |
| Client secret | The client secret from step 1 |
| Token authentication | Basic header |
| Authorize endpoint | https://<account>.snowflakecomputing.com/oauth/authorize |
| Token endpoint | https://<account>.snowflakecomputing.com/oauth/token-request |
| Scopes | session:role:<ROLE> refresh_token |
A few notes on the fields:
- Public client is for providers that issue a client with no secret. Switch it on and the secret field goes away. Sign-in is always protected by PKCE for a public client.
- Token authentication is how the client proves itself at the token endpoint. Choose Form body for providers that expect the credentials in the request body.
- PKCE is on by default and stays on unless your provider rejects it.
- Scopes accept spaces, commas or new lines.
4. Choose who connects
Under Who connects, pick one:
- Each member connects their own account (the default). Each person signs in at the provider once, and their agents act as them, with their own access and identity.
- One shared connection for the whole org. The account that passes the test connection is used for everyone, and members do not connect.
With a shared connection, every member’s agents act as that one account, with its access and identity at the provider. Choose it for a service account you are comfortable sharing with everyone in your org.
Choose Save. The server starts as Unverified. Members get a Connect action only after the test connection passes.
Test the connection
- Open the server from Settings > MCP Servers and choose Test connection.
- Sign in at the provider and approve access.
- When the provider confirms the sign-in, Marshal brings you back to Settings > MCP Servers and the server shows Verified.
If the provider reports a problem, Marshal shows its message. A wrong client secret or a redirect URI that is not registered at the provider are the usual causes; fix the value and test again.
Changing the client, the endpoints or the scopes returns the server to Unverified and asks members to reconnect. Switching between per-member and shared does the same and removes the connections made under the old choice. Run Test connection again after you save.
Members connect
Once the server is Verified, each member opens Connections, finds the server, and chooses Connect. They sign in at the provider, and agents in their spaces can use the server’s tools as them. Marshal keeps the sign-in fresh, so members do not connect again as long as the provider keeps the grant alive. The connection lists the access the provider actually granted.
With One shared connection for the whole org, nobody has to connect. The settings page names who made the shared connection, and it keeps working if that admin later leaves the org.
Reconnect
When a provider ends a grant, for example when a Snowflake refresh token expires, Marshal tells the person who owns the connection:
- Home shows Reconnect next to the server’s name.
- Connections marks the connection Needs reconnect. Choose Reconnect and sign in again.
- A space that needs the connection says so when you start it: “The connection to
<server>needs reconnecting. Reconnect it in Connections.” After you reconnect, it starts as usual.
For a shared connection, every org admin sees the notice, and any of them can run Test connection to renew it.
Identity providers on a private network
By default, Marshal reaches your provider over https on a public address, on port 443. If your identity provider runs on a private network, on another port, or with a certificate from your own certificate authority, an org admin turns on a setting:
- Open Settings > OAuth apps.
- Below the package list, open the Advanced section, labeled Private networks for custom MCP servers, and turn on Allow private networks and any port. While the setting is on, the section header says so and the section opens by itself.
- If the provider’s certificate comes from your own certificate authority, paste it under Certificate (PEM) (or upload the file) and choose Save certificate. Marshal shows its SHA-256 fingerprint. The certificate is trusted in addition to the standard roots, for your org’s custom MCP sign-in calls only.
The setting is off by default and applies to your org only. Marshal still requires https and still keeps loopback, link-local and cloud metadata addresses out of reach. Every change is recorded in the audit log with the certificate’s fingerprint.
This setting lets your org’s admins make the Marshal installation call hosts on its private network. On an installation shared by several organizations, turn it on only when that is what you intend.
What you should see
- The server shows Verified with the date after Test connection.
- Members see Connect on the server in Connections, and a connected server lists the access that was granted.
- A space that includes the server lists its tools, and each call carries the signed-in member’s access.
Next
Install a package into a manifest: put the server into the manifests your spaces start from.