Skip to content

Add Auth debugger tab #355

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 37 commits into from
May 13, 2025
Merged

Add Auth debugger tab #355

merged 37 commits into from
May 13, 2025

Conversation

pcarleton
Copy link
Contributor

@pcarleton pcarleton commented Apr 29, 2025

Motivation and Context

Adds a step-by-step auth debugger, going through the different client steps for a server.

CleanShot 2025-04-29 at 16 47 40@2x

How Has This Been Tested?

I've tested this locally against the python example auth SSE server:
modelcontextprotocol/python-sdk#610

I also tested against:

Breaking Changes

none

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

@pcarleton pcarleton changed the title [wip] auth debugger Add Auth debugger tab May 8, 2025
@QuantGeekDev
Copy link

Hey @pcarleton , I'm also working on something similar. Want to sync on discord? Maybe I can help with something. I'm using Postman since the inspector can't handle it but I was interested in what specific oauth flow you're following. Have you noticed that the specification was updated in draft a few days ago?

@pcarleton
Copy link
Contributor Author

Hi @QuantGeekDev which discord?

Yes, with the new draft, we'll need to add a few more metadata endpoints to check, but that should be okay to just follow what the Typescript SDK does. I'm going to try to land this on the 2025-03-25 spec and update it from there.

@QuantGeekDev
Copy link

@pcarleton The modelcontextprotocol one: https://discord.gg/3uqNS3KRP2
I've got the same username as here - let's collab! How are you testing these? You have your oauth server set up locally?

@pcarleton
Copy link
Contributor Author

@pcarleton pcarleton marked this pull request as ready for review May 8, 2025 14:11
@pcarleton pcarleton requested a review from olaservo May 8, 2025 14:29
ihrpr
ihrpr previously approved these changes May 9, 2025
Copy link
Contributor

@ihrpr ihrpr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

  • Breaking down into components would be good before merging
  • maybe make it explicit that only sse will work for now
  • add small banner to say which spec auth is supporing

const AuthDebuggerWrapper = () => (
<TabsContent value="auth">
<AuthDebugger
sseUrl={sseUrl}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something for the follow up (for myself) - we need to support shttp as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true, I think it should be pretty much the same because this all happens before any MCP protocol initialization.

I've been testing this on the python simple auth server, do we have a streamable http auth example? can modify the existing one to add it if not

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, it should be something like this: modelcontextprotocol/python-sdk#695 will test and publish the PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great, this seems to work.

One thing I didn't fully go through and update is the state parameter in App.tsx, it's still called sseUrl even though it can be either sse or streambleHttp. won't tackle that here, but wanted to mention while it's fresh.

latestError: null,
});

if (authState.oauthStep === "not_started") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pattern matching would be nice (something like a state machine) to have here instead of if-else

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I pulled this out into a state machine... the if/else was getting unwieldy, and also made retrying steps annoying

const provider = new DebugInspectorOAuthClientProvider(sseUrl);

// Helper functions moved inside useCallback to avoid ESLint warning
const validateOAuthMetadata = async (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validateOAuthMetadata and validateClientInformation can be extracted:

  • avoid recreation on every render
  • clean up proceedToNextStep

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 addressed w/ state machine

);
}, [authState.statusMessage]);

const renderOAuthFlow = useCallback(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe break it down into components? Like OAuthStepItem

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea good call, I broke out the Progress flow component, and a smaller component for each step lmkwyt

@olaservo
Copy link
Member

Hi Paul, I started testing with this today to see if it would play nice with my E2E Playwright testing branch, and noticed that the branch is quite a few commits behind main. Since I think there were a few auth related commits since you added this, could you pull the latest from main to verify its still working as expected? (And I'm doing the same with my own testing.)

@pcarleton
Copy link
Contributor Author

ty @olaservo, I was missing the scope auth change (forgot I had hacked it in locally). I've updated the typescript sdk import so that the types for the scope parameter work properly now.

A few things still to go:

  • support the new auth metadata endpoint (will be another upstream typescript-sdk change)
  • show which spec version / auth metadata endpoint we used

Copy link
Contributor

@ihrpr ihrpr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Should we do follow ups as part of a separate PR and merge this one?

@pcarleton
Copy link
Contributor Author

yea this is getting pretty large, will fix w/ follow-ups.

@pcarleton pcarleton merged commit 5e8e78c into main May 13, 2025
5 checks passed
@pcarleton pcarleton deleted the pcarleton/auth-debugger branch May 13, 2025 18:37
@leblancfg
Copy link

@pcarleton question for you, I feel like I'm missing something: why the /oauth/callback/debug URL?

That's not standard AFAICT, why not just reuse /oauth/callback?

@leblancfg
Copy link

leblancfg commented May 27, 2025

Also the authorization URL generated by the debugger isn't the same as the "connect" button. It includes the scopes_supported whereas the main "connect" button doesn't.

I feel like the Connect button also should do that though? Spec isn't exactly prescriptive but the inspector is meant for debugging. 🤔 edit: I'll open a PR actually.

@pcarleton
Copy link
Contributor Author

I feel like I'm missing something: why the /oauth/callback/debug URL?

@leblancfg this was to allow for a different handler when debugging vs. when doing the normal "connect" flow. When you do the step-by-step flow, we show the token and suggest you copy-paste it. We don't want to do that in the normal flow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants