Skip to content

Commit d8e637d

Browse files
committed
feat(mcp): HTTPS for in-app server with self-signed cert + Keychain trust install — v6.3.0 (build 97)
Claude Desktop refuses plain http:// URLs as a security policy, even for localhost. v6.3.0 adds TLS termination so the in-app MCP server can be used by Claude Desktop directly — no Node, no mcp-remote proxy, no external tooling. Same 13 tools. Added: - MCPCertificate.swift — generates a P-256 EC key + self-signed X.509 certificate via Apple's swift-crypto + swift-certificates packages. SAN: dnsName=localhost + ipAddress=127.0.0.1. 10-year validity. Persists to ~/Library/Containers/<id>/.../Application Support/ AstroBlinkV2/mcp-tls/{cert,key}.pem (key with 0600 perms). - NIOSSLServerHandler wired into the NIO HTTP1 pipeline as the first handler. Same port (8765), now TLS-encrypted. - MCP Connector window: new "1. Install Certificate" button that calls SecItemAdd + SecTrustSettingsSetTrustSettings(.user) — adds the cert to the login keychain and marks it trusted for SSL. `.user` domain avoids the admin password prompt. macOS shows one keychain access prompt the first time. - Live preflight in MCP Connector: three traffic-light rows (server up, cert trusted, Claude Desktop installed). Changed: - Endpoint URL format: https://127.0.0.1:8765/mcp (was http://). - Claude config snippet shipped to users uses the https URL. - "Test Connection" disabled until cert is trusted (avoid confusing TLS handshake errors). Migration: existing users just click "1. Install Certificate" once and then "2. Install to Claude Desktop". Old mcp-remote-via-npx workarounds can be removed from claude_desktop_config.json. kAlgorithmVersion unchanged.
1 parent 2a808be commit d8e637d

8 files changed

Lines changed: 430 additions & 37 deletions

File tree

AstroTriage.xcodeproj/project.pbxproj

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,10 @@
4949
3D029D52F10611A437BC2B5F /* NINAFilenameParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958EAAFB0801AA6BF89E7E57 /* NINAFilenameParser.swift */; };
5050
3ED3F0F9A74454F562857A09 /* ConditionsChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8C040E3CFD178726618C93F /* ConditionsChart.swift */; };
5151
40557783208A1A13EB363AF9 /* FrameHistoryModel+Domain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FF1A1ABDDC0D8F5A76F24E7 /* FrameHistoryModel+Domain.swift */; };
52+
419BC0421E6AC4B288626582 /* MCPCertificate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7397D39B2A1E4534DDA49642 /* MCPCertificate.swift */; };
5253
458EC62EC43F48825111DDEB /* AstroRootStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6CA403E08B94D8B54CCF812 /* AstroRootStore.swift */; };
5354
46B1B8F966ADC9FDC262D7A6 /* CoffeeSupportDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C8D25832AC0BBE69EE662AF /* CoffeeSupportDialog.swift */; };
55+
46D6E019F63A16B563DC3155 /* NIOSSL in Frameworks */ = {isa = PBXBuildFile; productRef = B64E480C709131A549E84FB8 /* NIOSSL */; };
5456
46DC95B31DFC767922E2AA34 /* ThresholdLearnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32608B6B9596DA5E7F7C9F1D /* ThresholdLearnerTests.swift */; };
5557
47D998D3FD88DF482089211D /* SetupComparisonChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6087ADC4D2B2398C1923BC7E /* SetupComparisonChart.swift */; };
5658
49AAD6D113938C331D999DBC /* MosaicGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E6FA09107C45349725E7DCF /* MosaicGenerator.swift */; };
@@ -106,6 +108,7 @@
106108
9B91613EEB76EB27A7DCB3FC /* CalibrationDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 511D5503EE634473FF2EC433 /* CalibrationDatabase.swift */; };
107109
9CDAC0C839D728DDA6F4E8D5 /* QualityEstimator+Historical.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CFD7069A619FC9F6E4DB412 /* QualityEstimator+Historical.swift */; };
108110
9D950EBF4E4EBC1A00430834 /* StarAnalyzerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C73F68266BEC1BE0872283EB /* StarAnalyzerTests.swift */; };
111+
9DA053B075ACAF50B435905E /* Crypto in Frameworks */ = {isa = PBXBuildFile; productRef = 041D79A454A1682F8A5DCE31 /* Crypto */; };
109112
9F741F47A7830BD9A405A511 /* FrameHistoryMigrations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80A7F31F7DBA920A68B6787D /* FrameHistoryMigrations.swift */; };
110113
9FE0865A0F4D4378F7A43D7A /* ArchiveScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32B55DBDF2FD18BEF1399C8D /* ArchiveScanner.swift */; };
111114
A1C2006F19F3C1DEE8EEAB9C /* SessionScoreChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55ABE4E540ACACE563997661 /* SessionScoreChart.swift */; };
@@ -129,6 +132,7 @@
129132
B6FAD33DBA5A722B4EC6F6AA /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = ADBD75B471EEBE3262306C84 /* Shaders.metal */; };
130133
BB2883D764B3CBC10EBB66BB /* WienerDeconvolution.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DAC3DD9E30EB2E746271068 /* WienerDeconvolution.swift */; };
131134
BC5A88BD113B62D7A7442646 /* ExportOptions-AppStore.plist in Resources */ = {isa = PBXBuildFile; fileRef = 18EE01FC0CDFE150906040B3 /* ExportOptions-AppStore.plist */; };
135+
BCCE630F18EC9F83F0BD6A1C /* X509 in Frameworks */ = {isa = PBXBuildFile; productRef = 6EF3E4A01DC7C719F1007BF5 /* X509 */; };
132136
BD7A31D9AF626FB19873EC7E /* SessionOverviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D35D584AE1D7CFEB4B41638 /* SessionOverviewView.swift */; };
133137
BF9CBFE8BFFC1A572EE95211 /* AIsaacView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EC26299CC364924D0AF79AC /* AIsaacView.swift */; };
134138
BFD9D646DC78249F8654CC1D /* PreviewGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0EFA1508203190F9C1216AE /* PreviewGenerator.swift */; };
@@ -287,6 +291,7 @@
287291
7196FBBA0783630389EA7125 /* FileListView+Coordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileListView+Coordinator.swift"; sourceTree = "<group>"; };
288292
72482E3B4DA87C1D05E5BC54 /* PlaybackController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaybackController.swift; sourceTree = "<group>"; };
289293
72BFE1A73BD5AD652BD34CB8 /* SessionCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionCache.swift; sourceTree = "<group>"; };
294+
7397D39B2A1E4534DDA49642 /* MCPCertificate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MCPCertificate.swift; sourceTree = "<group>"; };
290295
740CADC7ADA01E2160E95DCC /* QuickStackWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickStackWindow.swift; sourceTree = "<group>"; };
291296
763931350538CED5EA81290D /* KeyboardHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardHandler.swift; sourceTree = "<group>"; };
292297
76A68D583C36500C4A7BD068 /* AIsaacService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AIsaacService.swift; sourceTree = "<group>"; };
@@ -401,6 +406,9 @@
401406
7B1D9FF8DB1944D136F0F370 /* NIOCore in Frameworks */,
402407
F864163455D858895EDDCDEC /* NIOPosix in Frameworks */,
403408
90D66094225C0B673556F5CB /* NIOHTTP1 in Frameworks */,
409+
46D6E019F63A16B563DC3155 /* NIOSSL in Frameworks */,
410+
9DA053B075ACAF50B435905E /* Crypto in Frameworks */,
411+
BCCE630F18EC9F83F0BD6A1C /* X509 in Frameworks */,
404412
);
405413
runOnlyForDeploymentPostprocessing = 0;
406414
};
@@ -541,6 +549,7 @@
541549
AA671A0260128DA976044970 /* FrameHistoryModel.swift */,
542550
9FF1A1ABDDC0D8F5A76F24E7 /* FrameHistoryModel+Domain.swift */,
543551
3BCBBE41D0B90CC98443F843 /* GradientRemoval.swift */,
552+
7397D39B2A1E4534DDA49642 /* MCPCertificate.swift */,
544553
902BCBDCAFC1512717C38357 /* MCPHTTPServer.swift */,
545554
A226549D37668A050D48CEC5 /* MCPToolRegistry.swift */,
546555
52B1105B97D63754F8E1C54C /* MCPViewModelBridge.swift */,
@@ -762,6 +771,9 @@
762771
D711DA2B67C4940FBDCFC8DB /* NIOCore */,
763772
9E63F9A690DC9EF63EFBC9F9 /* NIOPosix */,
764773
E363B2B8ABDF5BCBDBF274D8 /* NIOHTTP1 */,
774+
B64E480C709131A549E84FB8 /* NIOSSL */,
775+
041D79A454A1682F8A5DCE31 /* Crypto */,
776+
6EF3E4A01DC7C719F1007BF5 /* X509 */,
765777
);
766778
productName = AstroTriage;
767779
productReference = FE4AA1827176F2392E89D989 /* AstroTriage.app */;
@@ -824,7 +836,10 @@
824836
packageReferences = (
825837
25C99D2C35845C466F7C0B6A /* XCRemoteSwiftPackageReference "GRDB.swift" */,
826838
D1BD6C474B8B6D883E2EC661 /* XCRemoteSwiftPackageReference "swift-sdk" */,
839+
7E8070EFD3BB031E29014F41 /* XCRemoteSwiftPackageReference "swift-certificates" */,
840+
55454F53199585BA38150D61 /* XCRemoteSwiftPackageReference "swift-crypto" */,
827841
B21990F400821782A35E53C4 /* XCRemoteSwiftPackageReference "swift-nio" */,
842+
CBFA3C4EE7214FF3E5791476 /* XCRemoteSwiftPackageReference "swift-nio-ssl" */,
828843
711A8E73ED2A7AA4A852AE7C /* XCLocalSwiftPackageReference "Packages/ImageDecoder" */,
829844
);
830845
preferredProjectObjectVersion = 77;
@@ -988,6 +1003,7 @@
9881003
1473E32DB057975151C0B24F /* ImagePreviewWindow.swift in Sources */,
9891004
F47A29B58D39DCB30BDB290A /* ImageViewerView.swift in Sources */,
9901005
2AC85F5C8AE08A1DB6A74261 /* KeyboardHandler.swift in Sources */,
1006+
419BC0421E6AC4B288626582 /* MCPCertificate.swift in Sources */,
9911007
8D25E45D70F2C1822D552DF8 /* MCPConnectorWindow.swift in Sources */,
9921008
E56D72CDE056EB4C345B1AE1 /* MCPHTTPServer.swift in Sources */,
9931009
0356B8132747B06A5AE18BE8 /* MCPToolRegistry.swift in Sources */,
@@ -1085,7 +1101,7 @@
10851101
CODE_SIGN_ENTITLEMENTS = QuickLookExtension/QuickLookExtension.entitlements;
10861102
CODE_SIGN_STYLE = Automatic;
10871103
COMBINE_HIDPI_IMAGES = YES;
1088-
CURRENT_PROJECT_VERSION = 96;
1104+
CURRENT_PROJECT_VERSION = 97;
10891105
DEVELOPMENT_TEAM = FDSVBU33S8;
10901106
ENABLE_APP_SANDBOX = YES;
10911107
ENABLE_HARDENED_RUNTIME = YES;
@@ -1097,7 +1113,7 @@
10971113
"@executable_path/../../../../Frameworks",
10981114
);
10991115
MACOSX_DEPLOYMENT_TARGET = 14.0;
1100-
MARKETING_VERSION = 6.2.0;
1116+
MARKETING_VERSION = 6.3.0;
11011117
OTHER_LDFLAGS = (
11021118
"-lz",
11031119
);
@@ -1116,7 +1132,7 @@
11161132
CODE_SIGN_ENTITLEMENTS = QuickLookPreview/QuickLookPreview.entitlements;
11171133
CODE_SIGN_STYLE = Automatic;
11181134
COMBINE_HIDPI_IMAGES = YES;
1119-
CURRENT_PROJECT_VERSION = 96;
1135+
CURRENT_PROJECT_VERSION = 97;
11201136
DEVELOPMENT_TEAM = FDSVBU33S8;
11211137
ENABLE_APP_SANDBOX = YES;
11221138
ENABLE_HARDENED_RUNTIME = YES;
@@ -1128,7 +1144,7 @@
11281144
"@executable_path/../../../../Frameworks",
11291145
);
11301146
MACOSX_DEPLOYMENT_TARGET = 14.0;
1131-
MARKETING_VERSION = 6.2.0;
1147+
MARKETING_VERSION = 6.3.0;
11321148
OTHER_LDFLAGS = (
11331149
"-lz",
11341150
);
@@ -1147,7 +1163,7 @@
11471163
CODE_SIGN_ENTITLEMENTS = QuickLookExtension/QuickLookExtension.entitlements;
11481164
CODE_SIGN_STYLE = Automatic;
11491165
COMBINE_HIDPI_IMAGES = YES;
1150-
CURRENT_PROJECT_VERSION = 96;
1166+
CURRENT_PROJECT_VERSION = 97;
11511167
DEVELOPMENT_TEAM = FDSVBU33S8;
11521168
ENABLE_APP_SANDBOX = YES;
11531169
ENABLE_HARDENED_RUNTIME = YES;
@@ -1159,7 +1175,7 @@
11591175
"@executable_path/../../../../Frameworks",
11601176
);
11611177
MACOSX_DEPLOYMENT_TARGET = 14.0;
1162-
MARKETING_VERSION = 6.2.0;
1178+
MARKETING_VERSION = 6.3.0;
11631179
OTHER_LDFLAGS = (
11641180
"-lz",
11651181
);
@@ -1178,7 +1194,7 @@
11781194
CODE_SIGN_ENTITLEMENTS = AstroTriage/AstroTriage.entitlements;
11791195
CODE_SIGN_STYLE = Automatic;
11801196
COMBINE_HIDPI_IMAGES = YES;
1181-
CURRENT_PROJECT_VERSION = 96;
1197+
CURRENT_PROJECT_VERSION = 97;
11821198
DEVELOPMENT_TEAM = FDSVBU33S8;
11831199
ENABLE_APP_SANDBOX = YES;
11841200
ENABLE_HARDENED_RUNTIME = YES;
@@ -1188,7 +1204,7 @@
11881204
"$(inherited)",
11891205
"@executable_path/../Frameworks",
11901206
);
1191-
MARKETING_VERSION = 6.2.0;
1207+
MARKETING_VERSION = 6.3.0;
11921208
METAL_COMPILER_FLAGS = "";
11931209
OTHER_LDFLAGS = (
11941210
"-lz",
@@ -1311,7 +1327,7 @@
13111327
CODE_SIGN_ENTITLEMENTS = AstroTriage/AstroTriage.entitlements;
13121328
CODE_SIGN_STYLE = Automatic;
13131329
COMBINE_HIDPI_IMAGES = YES;
1314-
CURRENT_PROJECT_VERSION = 96;
1330+
CURRENT_PROJECT_VERSION = 97;
13151331
DEVELOPMENT_TEAM = FDSVBU33S8;
13161332
ENABLE_APP_SANDBOX = YES;
13171333
ENABLE_HARDENED_RUNTIME = YES;
@@ -1321,7 +1337,7 @@
13211337
"$(inherited)",
13221338
"@executable_path/../Frameworks",
13231339
);
1324-
MARKETING_VERSION = 6.2.0;
1340+
MARKETING_VERSION = 6.3.0;
13251341
METAL_COMPILER_FLAGS = "";
13261342
OTHER_LDFLAGS = (
13271343
"-lz",
@@ -1399,7 +1415,7 @@
13991415
CODE_SIGN_ENTITLEMENTS = QuickLookPreview/QuickLookPreview.entitlements;
14001416
CODE_SIGN_STYLE = Automatic;
14011417
COMBINE_HIDPI_IMAGES = YES;
1402-
CURRENT_PROJECT_VERSION = 96;
1418+
CURRENT_PROJECT_VERSION = 97;
14031419
DEVELOPMENT_TEAM = FDSVBU33S8;
14041420
ENABLE_APP_SANDBOX = YES;
14051421
ENABLE_HARDENED_RUNTIME = YES;
@@ -1411,7 +1427,7 @@
14111427
"@executable_path/../../../../Frameworks",
14121428
);
14131429
MACOSX_DEPLOYMENT_TARGET = 14.0;
1414-
MARKETING_VERSION = 6.2.0;
1430+
MARKETING_VERSION = 6.3.0;
14151431
OTHER_LDFLAGS = (
14161432
"-lz",
14171433
);
@@ -1489,6 +1505,22 @@
14891505
minimumVersion = 7.4.0;
14901506
};
14911507
};
1508+
55454F53199585BA38150D61 /* XCRemoteSwiftPackageReference "swift-crypto" */ = {
1509+
isa = XCRemoteSwiftPackageReference;
1510+
repositoryURL = "https://github.com/apple/swift-crypto";
1511+
requirement = {
1512+
kind = upToNextMajorVersion;
1513+
minimumVersion = 3.10.0;
1514+
};
1515+
};
1516+
7E8070EFD3BB031E29014F41 /* XCRemoteSwiftPackageReference "swift-certificates" */ = {
1517+
isa = XCRemoteSwiftPackageReference;
1518+
repositoryURL = "https://github.com/apple/swift-certificates";
1519+
requirement = {
1520+
kind = upToNextMajorVersion;
1521+
minimumVersion = 1.10.0;
1522+
};
1523+
};
14921524
B21990F400821782A35E53C4 /* XCRemoteSwiftPackageReference "swift-nio" */ = {
14931525
isa = XCRemoteSwiftPackageReference;
14941526
repositoryURL = "https://github.com/apple/swift-nio";
@@ -1497,6 +1529,14 @@
14971529
minimumVersion = 2.100.0;
14981530
};
14991531
};
1532+
CBFA3C4EE7214FF3E5791476 /* XCRemoteSwiftPackageReference "swift-nio-ssl" */ = {
1533+
isa = XCRemoteSwiftPackageReference;
1534+
repositoryURL = "https://github.com/apple/swift-nio-ssl";
1535+
requirement = {
1536+
kind = upToNextMajorVersion;
1537+
minimumVersion = 2.30.0;
1538+
};
1539+
};
15001540
D1BD6C474B8B6D883E2EC661 /* XCRemoteSwiftPackageReference "swift-sdk" */ = {
15011541
isa = XCRemoteSwiftPackageReference;
15021542
repositoryURL = "https://github.com/modelcontextprotocol/swift-sdk";
@@ -1508,6 +1548,11 @@
15081548
/* End XCRemoteSwiftPackageReference section */
15091549

15101550
/* Begin XCSwiftPackageProductDependency section */
1551+
041D79A454A1682F8A5DCE31 /* Crypto */ = {
1552+
isa = XCSwiftPackageProductDependency;
1553+
package = 55454F53199585BA38150D61 /* XCRemoteSwiftPackageReference "swift-crypto" */;
1554+
productName = Crypto;
1555+
};
15111556
0823264441FF3A7874FE3975 /* ImageDecoderBridge */ = {
15121557
isa = XCSwiftPackageProductDependency;
15131558
productName = ImageDecoderBridge;
@@ -1522,6 +1567,11 @@
15221567
package = 25C99D2C35845C466F7C0B6A /* XCRemoteSwiftPackageReference "GRDB.swift" */;
15231568
productName = GRDB;
15241569
};
1570+
6EF3E4A01DC7C719F1007BF5 /* X509 */ = {
1571+
isa = XCSwiftPackageProductDependency;
1572+
package = 7E8070EFD3BB031E29014F41 /* XCRemoteSwiftPackageReference "swift-certificates" */;
1573+
productName = X509;
1574+
};
15251575
8A263D3D8B89B08DB446B5AB /* ImageDecoderBridge */ = {
15261576
isa = XCSwiftPackageProductDependency;
15271577
productName = ImageDecoderBridge;
@@ -1535,6 +1585,11 @@
15351585
isa = XCSwiftPackageProductDependency;
15361586
productName = ImageDecoderBridge;
15371587
};
1588+
B64E480C709131A549E84FB8 /* NIOSSL */ = {
1589+
isa = XCSwiftPackageProductDependency;
1590+
package = CBFA3C4EE7214FF3E5791476 /* XCRemoteSwiftPackageReference "swift-nio-ssl" */;
1591+
productName = NIOSSL;
1592+
};
15381593
D711DA2B67C4940FBDCFC8DB /* NIOCore */ = {
15391594
isa = XCSwiftPackageProductDependency;
15401595
package = B21990F400821782A35E53C4 /* XCRemoteSwiftPackageReference "swift-nio" */;

0 commit comments

Comments
 (0)