2 Commits

Author SHA1 Message Date
b3918c3ee6 Fix Windows sign-in: don't launch the browser through cmd.exe (v1.0.1)
cmd's `start` splits unquoted commands at "&", truncating the OAuth authorize
URL after the first query parameter — Windows users hit AADSTS900144 (missing
'scope'). Launch via rundll32 url.dll,FileProtocolHandler instead, which takes
the URL as a plain argument with no shell parsing.

Same fix as claude-msplanner b07a241, applied to the canonical skill copy and
synced into the extension bundle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 08:01:12 -06:00
7d80e9f586 docs: ship unsigned — mcpb sign corrupts the bundle (CLI bug)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 17:43:37 -06:00
6 changed files with 33 additions and 16 deletions

View File

@@ -620,14 +620,23 @@ function startRedirectServer(expectedState, timeoutMs, listenPort = 0) {
/** Best-effort open of a URL in the system browser (macOS / Windows / Linux). */ /** Best-effort open of a URL in the system browser (macOS / Windows / Linux). */
function openBrowser(url) { function openBrowser(url) {
const cmd =
process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
try { try {
const child = spawn(cmd, process.platform === "win32" ? ["", url] : [url], { let child;
stdio: "ignore", if (process.platform === "win32") {
detached: true, // Never route the URL through cmd.exe (`start`): cmd splits unquoted
shell: process.platform === "win32", // commands at "&", which truncates the authorize URL after the first
}); // query parameter (the user then sees AADSTS900144: missing 'scope').
// rundll32 opens the default browser with the URL as a plain argument.
child = spawn("rundll32", ["url.dll,FileProtocolHandler", url], {
stdio: "ignore",
detached: true,
});
} else {
child = spawn(process.platform === "darwin" ? "open" : "xdg-open", [url], {
stdio: "ignore",
detached: true,
});
}
child.on("error", () => {}); // ignore; the CLI also prints the URL as a fallback child.on("error", () => {}); // ignore; the CLI also prints the URL as a fallback
child.unref(); child.unref();
} catch { } catch {

View File

@@ -84,11 +84,19 @@ npx -y @anthropic-ai/mcpb validate manifest.json
npx -y @anthropic-ai/mcpb info ms-todo.mcpb npx -y @anthropic-ai/mcpb info ms-todo.mcpb
``` ```
### Optional: sign the extension ### Signing — currently disabled
Unsigned extensions install with a "not verified" warning. You can self-sign so Unsigned extensions install with a "not verified" warning, which is fine for
the warning shows your identity (full removal of the warning needs a CA-issued internal distribution (just click through it).
cert your org trusts):
> ⚠️ **Do not sign with `mcpb sign` right now.** As of `@anthropic-ai/mcpb` 2.1.2
> (and 2.0.x/2.1.x), `sign` corrupts the bundle: it writes an invalid ZIP EOCD
> comment length, so Claude Desktop fails to open it ("Invalid comment length …
> extra bytes at the end of the file") and `mcpb verify` reports it as unsigned.
> Ship the **unsigned** bundle until this is fixed upstream.
When signing works again (or with a CA-trusted cert deployed to your fleet), the
command is:
```bash ```bash
npx -y @anthropic-ai/mcpb sign ms-todo.mcpb --cert cert.pem --key key.pem npx -y @anthropic-ai/mcpb sign ms-todo.mcpb --cert cert.pem --key key.pem

View File

@@ -2,7 +2,7 @@
"manifest_version": "0.3", "manifest_version": "0.3",
"name": "ms-todo", "name": "ms-todo",
"display_name": "Microsoft To Do", "display_name": "Microsoft To Do",
"version": "1.0.0", "version": "1.0.1",
"description": "Read and write your Microsoft To Do tasks, lists, and subtasks from Claude.", "description": "Read and write your Microsoft To Do tasks, lists, and subtasks from Claude.",
"long_description": "Connects Claude to Microsoft To Do via the Microsoft Graph API. You sign in once as yourself (a browser window opens); the connection then reads and writes your task lists, tasks, and checklist items. Each user's sign-in is private to their own machine.", "long_description": "Connects Claude to Microsoft To Do via the Microsoft Graph API. You sign in once as yourself (a browser window opens); the connection then reads and writes your task lists, tasks, and checklist items. Each user's sign-in is private to their own machine.",
"author": { "author": {

View File

@@ -1,12 +1,12 @@
{ {
"name": "ms-todo-mcp-extension", "name": "ms-todo-mcp-extension",
"version": "1.0.0", "version": "1.0.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ms-todo-mcp-extension", "name": "ms-todo-mcp-extension",
"version": "1.0.0", "version": "1.0.1",
"dependencies": { "dependencies": {
"@modelcontextprotocol/sdk": "^1.12.0", "@modelcontextprotocol/sdk": "^1.12.0",
"zod": "^3.23.8" "zod": "^3.23.8"

View File

@@ -1,6 +1,6 @@
{ {
"name": "ms-todo-mcp-extension", "name": "ms-todo-mcp-extension",
"version": "1.0.0", "version": "1.0.1",
"private": true, "private": true,
"type": "module", "type": "module",
"description": "Microsoft To Do MCP server, packaged as a Claude Desktop .mcpb extension", "description": "Microsoft To Do MCP server, packaged as a Claude Desktop .mcpb extension",

View File

@@ -108,7 +108,7 @@ const TASK_WRITE_FIELDS = {
// ---- server --------------------------------------------------------------- // ---- server ---------------------------------------------------------------
const server = new McpServer({ name: "ms-todo", version: "1.0.0" }); const server = new McpServer({ name: "ms-todo", version: "1.0.1" });
// --- auth --- // --- auth ---
server.registerTool( server.registerTool(