@@ -10,6 +10,7 @@ Adding WebAuthn CDP domain support to chrome-devtools-mcp using strict outside-i
1010## Goal (Definition of Done)
1111
1212A user can:
13+
13141 . Enable WebAuthn virtual authenticator environment via MCP tool
14152 . Add a virtual authenticator (CTAP2/U2F, internal/USB/BLE/NFC)
15163 . Use WebAuthn on a webpage (e.g., webauthn.io) with the virtual authenticator responding
@@ -69,68 +70,84 @@ describe('webauthn', () => {
6970### Phase 1: Minimal Vertical Slice
7071
7172#### Step 1.1: Observe Missing Functionality
73+
7274- [x] Verify no ` webauthn_* ` tools exist in MCP
7375- [x] Navigate to webauthn.io, confirm we can't do WebAuthn without virtual authenticator
7476
7577#### Step 1.2: Failing Test - Tool Exists
78+
7679Create ` tests/tools/webauthn.test.ts ` :
80+
7781``` typescript
78- it (' webauthn_enable tool can be called' )
82+ it (' webauthn_enable tool can be called' );
7983```
84+
8085Run: ` npm run test -- --test-name-pattern="webauthn" `
8186Expected: FAIL (module not found)
8287
8388#### Step 1.3: Implement - Minimal Tool Skeleton
89+
8490- Create ` src/tools/webauthn.ts ` with ` enableWebAuthn ` tool (no-op handler)
8591- Export from ` src/tools/tools.ts `
8692- Run test: Should PASS
8793- Commit: ` feat(webauthn): add webauthn_enable tool skeleton `
8894
8995#### Step 1.4: Verify Tool Appears in MCP
96+
9097- Rebuild: ` npm run build `
9198- Check if MCP picks up changes (may need restart)
9299- Verify tool appears
93100
94101#### Step 1.5: Failing Test - Enable Actually Works
102+
95103``` typescript
96104it (' enables WebAuthn so addVirtualAuthenticator succeeds' , async () => {
97105 await withMcpContext (async (response , context ) => {
98106 await enableWebAuthn .handler ({params: {}}, response , context );
99107 const session = context .getSelectedPage ()._client ();
100108 // This should succeed only if WebAuthn.enable was called
101109 const result = await session .send (' WebAuthn.addVirtualAuthenticator' , {
102- options: { protocol: ' ctap2' , transport: ' internal' }
110+ options: {protocol: ' ctap2' , transport: ' internal' },
103111 });
104112 assert .ok (result .authenticatorId );
105113 });
106114});
107115```
116+
108117Run: FAIL (WebAuthn not enabled)
109118
110119#### Step 1.6: Implement - CDP Call
120+
111121Add to handler:
122+
112123``` typescript
113124await context .getSelectedPage ()._client ().send (' WebAuthn.enable' );
114125```
126+
115127Run test: PASS
116128Commit: ` feat(webauthn): implement WebAuthn.enable CDP call `
117129
118130#### Step 1.7: Verify via MCP
131+
119132- Call ` webauthn_enable ` tool
120133- Confirm no error
121134
122135#### Step 1.8: Failing Test - Add Authenticator Tool
136+
123137``` typescript
124- it (' adds virtual authenticator and returns ID' )
138+ it (' adds virtual authenticator and returns ID' );
125139```
140+
126141Run: FAIL (tool doesn't exist)
127142
128143#### Step 1.9: Implement - Add Authenticator
144+
129145- Add ` addVirtualAuthenticator ` tool with params: protocol, transport, hasResidentKey, hasUserVerification, isUserVerified
130146- Run test: PASS
131147- Commit: ` feat(webauthn): add webauthn_add_authenticator tool `
132148
133149#### Step 1.10: E2E Verification
150+
1341511 . Navigate to webauthn.io
1351522 . Call ` webauthn_enable `
1361533 . Call ` webauthn_add_authenticator ` with ctap2/internal/userVerified
@@ -142,6 +159,7 @@ Commit: `test(webauthn): verify e2e with webauthn.io`
142159### Phase 2: Expand Coverage
143160
144161After vertical slice works:
162+
145163- ` webauthn_disable `
146164- ` webauthn_remove_authenticator `
147165- ` webauthn_get_credentials `
@@ -151,6 +169,7 @@ After vertical slice works:
151169- ` webauthn_set_user_verified `
152170
153171### Phase 3: Polish
172+
154173- Error handling tests
155174- Run ` npm run docs ` to update documentation
156175- Run ` npm run check-format ` and fix any issues
@@ -191,6 +210,7 @@ npm run check-format
191210## Reference: Emulation Tool Pattern
192211
193212From ` src/tools/emulation.ts ` :
213+
194214``` typescript
195215export const emulate = defineTool ({
196216 name: ' emulate' ,
@@ -238,13 +258,27 @@ describe('myTool', () => {
238258
239259Track each step completion here:
240260
241- - [ ] Step 1.1: Observe missing functionality
242- - [ ] Step 1.2: Failing test - tool exists
243- - [ ] Step 1.3: Implement tool skeleton
244- - [ ] Step 1.4: Verify tool appears in MCP
245- - [ ] Step 1.5: Failing test - enable works
246- - [ ] Step 1.6: Implement CDP call
247- - [ ] Step 1.7: Verify via MCP
248- - [ ] Step 1.8: Failing test - add authenticator
249- - [ ] Step 1.9: Implement add authenticator
250- - [ ] Step 1.10: E2E verification
261+ - [x] Step 1.1: Observe missing functionality
262+ - [x] Step 1.2: Failing test - tool exists
263+ - [x] Step 1.3: Implement tool skeleton
264+ - [x] Step 1.4: Verify tool appears in MCP
265+ - [x] Step 1.5: Failing test - enable works
266+ - [x] Step 1.6: Implement CDP call
267+ - [x] Step 1.7: Verify via MCP
268+ - [x] Step 1.8: Failing test - add authenticator
269+ - [x] Step 1.9: Implement add authenticator
270+ - [x] Step 1.10: E2E verification
271+
272+ ** Phase 1 COMPLETE** - Minimal vertical slice working!
273+
274+ ### Commits:
275+
276+ - ` 5f35101 ` feat(webauthn): add webauthn_enable tool skeleton
277+ - ` ce3a0ed ` feat(webauthn): implement WebAuthn.enable CDP call
278+ - ` 300e963 ` feat(webauthn): add webauthn_add_authenticator tool
279+
280+ ### E2E Verified:
281+
282+ - webauthn.io registration + authentication works automatically
283+ - No user interaction required (Touch ID bypassed)
284+ - Virtual authenticator responds to both registration and authentication
0 commit comments