From 1035f86f2f803a1f09517c7e6889d8a8ca363a2b Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Sat, 31 Oct 2026 15:57:13 +0000 Subject: [PATCH] docs: Claude Code v2.1.316 - MCP Inspector gains load-test CI gates and TLS; Java/Kotlin SDKs flagged as unable to talk to 2026-07-28-only peers Co-Authored-By: claude-yolo[bot] --- content/.metadata.json | 287 ++++---- .../third-party/claude-desktop/import.md | 10 +- .../mcp/community/interest-groups/security.md | 21 +- content/mcp/community/security.md | 6 +- .../docs/2026-07-28/develop/build-client.md | 695 ++++++++++++------ .../docs/2026-07-28/develop/build-server.md | 26 +- .../docs/2026-07-28/learn/client-concepts.md | 2 +- content/mcp/docs/2026-07-28/sdk.md | 2 +- .../mcp/docs/2026-07-28/tools/debugging.md | 5 + .../docs/2026-07-28/tools/inspector/cli.md | 14 +- .../tools/inspector/configuration.md | 58 +- .../docs/2026-07-28/tools/inspector/mcpdo.md | 12 +- .../tools/inspector/protocol-eras.md | 6 +- .../2026-07-28/tools/inspector/recipes.md | 4 +- .../2026-07-28/tools/inspector/security.md | 2 +- .../docs/2026-07-28/tools/inspector/web.md | 4 +- .../mcp/docs/draft/develop/build-client.md | 695 ++++++++++++------ .../mcp/docs/draft/develop/build-server.md | 26 +- .../mcp/docs/draft/learn/client-concepts.md | 2 +- content/mcp/docs/draft/sdk.md | 2 +- content/mcp/docs/draft/tools/debugging.md | 5 + content/mcp/docs/draft/tools/inspector/cli.md | 8 +- .../draft/tools/inspector/configuration.md | 58 +- .../mcp/docs/draft/tools/inspector/mcpdo.md | 12 +- .../draft/tools/inspector/protocol-eras.md | 2 +- .../mcp/docs/draft/tools/inspector/recipes.md | 4 +- .../docs/draft/tools/inspector/security.md | 2 +- content/mcp/docs/draft/tools/inspector/web.md | 4 +- .../draft/tutorials/security/authorization.md | 65 +- .../auth/oauth-client-credentials.md | 4 +- ...how-do-i-log-out-of-all-active-sessions.md | 2 +- ...k-settings-on-team-and-enterprise-plans.md | 2 +- ...ith-local-mcp-servers-on-claude-desktop.md | 2 +- ...the-claude-lti-in-canvas-by-instructure.md | 2 +- ...being-asked-to-verify-my-payment-method.md | 2 +- .../11869629-use-claude-with-android-apps.md | 2 +- ...or-team-and-seat-based-enterprise-plans.md | 10 +- .../12157520-claude-code-usage-analytics.md | 2 +- .../support/12260368-use-incognito-chats.md | 2 +- ...d-using-the-desktop-extension-allowlist.md | 8 +- .../12618689-use-claude-code-in-the-cloud.md | 6 +- ...analytics-for-team-and-enterprise-plans.md | 24 +- .../12997503-team-plan-billing-faqs.md | 2 +- .../13132885-set-up-single-sign-on-sso.md | 8 +- ...3133195-set-up-jit-or-scim-provisioning.md | 6 +- ...1-configuring-session-security-settings.md | 6 +- .../13189465-log-in-to-your-claude-account.md | 2 +- .../13325567-account-management-faqs.md | 2 +- ...13371040-log-in-to-your-console-account.md | 2 +- ...13641943-visual-and-interactive-content.md | 6 +- .../support/13837440-use-plugins-in-claude.md | 4 +- ...sync-works-for-enterprise-organizations.md | 4 +- ...t-a-default-model-for-your-organization.md | 2 +- ...nage-model-access-for-your-organization.md | 8 +- ...1-get-started-with-1password-for-claude.md | 2 +- ...ing-your-pro-max-or-ultra-plan-invoices.md | 2 +- ...16893491-get-started-with-smart-reports.md | 14 +- ...claude-in-google-docs-sheets-and-slides.md | 4 +- ...ooled-group-budgets-on-enterprise-plans.md | 2 +- .../17203415-set-up-claude-for-intune.md | 22 +- ...rience-for-your-enterprise-organization.md | 4 +- .../8114491-get-started-with-claude.md | 2 +- ...8230524-delete-or-rename-a-conversation.md | 16 +- .../support/8325618-paid-plan-billing-faqs.md | 2 +- ...27-customizing-your-appearance-settings.md | 6 +- ...nt-to-a-team-or-enterprise-organization.md | 2 +- 66 files changed, 1501 insertions(+), 736 deletions(-) diff --git a/content/.metadata.json b/content/.metadata.json index ccf4d14c3..f8128a2c1 100644 --- a/content/.metadata.json +++ b/content/.metadata.json @@ -1,7 +1,7 @@ { "metadata": { "version": "2.0", - "fetch_date": "2026-10-31T06:24:58.459934Z", + "fetch_date": "2026-10-31T15:55:52.574877Z", "section": "all" }, "items": [ @@ -7611,8 +7611,8 @@ "url": "https://modelcontextprotocol.io/community/interest-groups/security", "status": "success", "path": "mcp/community/interest-groups/security.md", - "sha256": "8a7ab6dd81051f82ee0f2d790c9192c7e50899e86aa1c8dc8e5413f7e1f8ebd9", - "size": 7425 + "sha256": "98eab19737b294aac650f3cc1cad97b73da0a4692c0518b52f073936991602ab", + "size": 8131 }, { "url": "https://modelcontextprotocol.io/community/interest-groups/tool-annotations", @@ -7632,8 +7632,8 @@ "url": "https://modelcontextprotocol.io/community/security", "status": "success", "path": "mcp/community/security.md", - "sha256": "f68c49ce673f89001b5963526e7dcc80bf597f08bc079238b333ed8fe809810f", - "size": 3822 + "sha256": "4e254dd1783d863a7772a441eac54aed9be82df26afe85545ef38d8bfe05a306", + "size": 3847 }, { "url": "https://modelcontextprotocol.io/community/sep-guidelines", @@ -8199,15 +8199,15 @@ "url": "https://modelcontextprotocol.io/docs/2026-07-28/develop/build-client", "status": "success", "path": "mcp/docs/2026-07-28/develop/build-client.md", - "sha256": "e210bae2fa06e3559c16f099babb3a35adf5171686b8b4a58ff47b7d4b7c0b83", - "size": 77182 + "sha256": "d3dc26d37e2b36afe162bf855a4c305dc3c26ecb9e84561c460954627261ae5e", + "size": 93811 }, { "url": "https://modelcontextprotocol.io/docs/2026-07-28/develop/build-server", "status": "success", "path": "mcp/docs/2026-07-28/develop/build-server.md", - "sha256": "e7c6dbbd7138b52eb8ba65153151b490fa1a88ce9d24245bdbc99ff5cf8a0978", - "size": 92400 + "sha256": "b7623a05ceed43782ef6d079209728df6559afd3510fe6dbf5946a129f0b4226", + "size": 93260 }, { "url": "https://modelcontextprotocol.io/docs/2026-07-28/develop/build-with-agent-skills", @@ -8255,8 +8255,8 @@ "url": "https://modelcontextprotocol.io/docs/2026-07-28/learn/client-concepts", "status": "success", "path": "mcp/docs/2026-07-28/learn/client-concepts.md", - "sha256": "4336a93b9770b0d1a2b9c8e72271ee98be8764583c037edbab7a15c57fb5bb46", - "size": 17247 + "sha256": "e6c2a5e84393b1fcdbe599890f129a5188d6e9d7798093b71a6b651c91d3ac88", + "size": 17246 }, { "url": "https://modelcontextprotocol.io/docs/2026-07-28/learn/server-concepts", @@ -8276,15 +8276,15 @@ "url": "https://modelcontextprotocol.io/docs/2026-07-28/sdk", "status": "success", "path": "mcp/docs/2026-07-28/sdk.md", - "sha256": "a68f6cb622bd01b29c59279b6922b1188d3e5caeb8098b67280610f3a9cee17e", - "size": 2990 + "sha256": "4ef8c429437efcff2e948e868c53f2a0b129eb62850fda2389ef206e86aaaea9", + "size": 3077 }, { "url": "https://modelcontextprotocol.io/docs/2026-07-28/tools/debugging", "status": "success", "path": "mcp/docs/2026-07-28/tools/debugging.md", - "sha256": "61faea6e4cdebada7bc488493296f268ae2070690e6d1fb5b16f6859d4ec0562", - "size": 11451 + "sha256": "995394ebc98fbd6746783c4e4c18157b95b82f92b3ca68765500493990ce94ac", + "size": 11561 }, { "url": "https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector", @@ -8304,43 +8304,43 @@ "url": "https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/cli", "status": "success", "path": "mcp/docs/2026-07-28/tools/inspector/cli.md", - "sha256": "d63c55d87d46383de0dd78a55bfbed96a80157214296771d1b8bf67f46275081", - "size": 13950 + "sha256": "f12cfeb42ca146991b161d0cc0cb7e42cfc7df5c7421c8e3b4dd93fbbda38d42", + "size": 15467 }, { "url": "https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/configuration", "status": "success", "path": "mcp/docs/2026-07-28/tools/inspector/configuration.md", - "sha256": "bb6b3dbb8b4b789057f720ef144673db81ee590ab255ce373ab123041b8cfa63", - "size": 21152 + "sha256": "63525c4b60b220ec364333618a343da8a18f67602ce677a5a9ad81c56e39dc9f", + "size": 26572 }, { "url": "https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/mcpdo", "status": "success", "path": "mcp/docs/2026-07-28/tools/inspector/mcpdo.md", - "sha256": "c363c3b2847c2d8910583d72e551935eb5a97857bbcf028c982e148450b62021", - "size": 12282 + "sha256": "c28195e4aabf3836ec11ce2ec5c067f62bd4617bbca5a8db8a0608e875b8a34b", + "size": 13491 }, { "url": "https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/protocol-eras", "status": "success", "path": "mcp/docs/2026-07-28/tools/inspector/protocol-eras.md", - "sha256": "0f5bd75cb404f4161fca3f111d189dd56df49576a81baaf167b5fb1ee3e797e0", - "size": 17465 + "sha256": "de255240929d456a02e0e133afd06b99b07a4a55b661bfe4665a751164ec0aa9", + "size": 17596 }, { "url": "https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/recipes", "status": "success", "path": "mcp/docs/2026-07-28/tools/inspector/recipes.md", - "sha256": "cb79d4fdd9d190f82e6bdb3f1415d75fad5ebe73fdae5d213e29ae1e8396fb83", - "size": 17695 + "sha256": "799e664a511b6725dc087dbb904832ff2e91ddadbaae750ce745b4fe98b69d91", + "size": 18041 }, { "url": "https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/security", "status": "success", "path": "mcp/docs/2026-07-28/tools/inspector/security.md", - "sha256": "9d2bc018a335e9633b4495b11e06298c9d8fe1dcab97a60d987c0908788c678a", - "size": 16791 + "sha256": "231c9f836e088e103b879dcc14ab9a98b970b90c7ebeab4a97d44d9e7351038d", + "size": 17234 }, { "url": "https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/tui", @@ -8353,8 +8353,8 @@ "url": "https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/web", "status": "success", "path": "mcp/docs/2026-07-28/tools/inspector/web.md", - "sha256": "4021fef8b137e22cb70227a1d2861bef20f53bd12fe08292e4b322842f02de55", - "size": 15160 + "sha256": "c696df2b8cfeb7496553439898de5a65b16916118d5db90db3ae0903b7b97a7c", + "size": 15845 }, { "url": "https://modelcontextprotocol.io/docs/2026-07-28/tutorials/security/authorization", @@ -8381,15 +8381,15 @@ "url": "https://modelcontextprotocol.io/docs/draft/develop/build-client", "status": "success", "path": "mcp/docs/draft/develop/build-client.md", - "sha256": "e40d9e431e08bad94054c67fcd4498e124d6783968a767643af9a871fe3cfbdd", - "size": 77167 + "sha256": "80b7632b40bdac4d771092a11622e97caeac0e2a7aa9db9a7b5b242d30b09d6f", + "size": 93791 }, { "url": "https://modelcontextprotocol.io/docs/draft/develop/build-server", "status": "success", "path": "mcp/docs/draft/develop/build-server.md", - "sha256": "533f3d787519297b3dd70eff3d5b8b340597727bc2342af03ae493ed084ce8f1", - "size": 92345 + "sha256": "38c3e9439bc84ba609732aae58aa5a3da0aae3e9805ce04269d2aaeca86155a1", + "size": 93195 }, { "url": "https://modelcontextprotocol.io/docs/draft/develop/build-with-agent-skills", @@ -8437,8 +8437,8 @@ "url": "https://modelcontextprotocol.io/docs/draft/learn/client-concepts", "status": "success", "path": "mcp/docs/draft/learn/client-concepts.md", - "sha256": "5ee78743749409b855b700d00bdd941dc5275cb74c6218eceac7987ed3c9027f", - "size": 17217 + "sha256": "44b23a8b96e8369b2295939ac2d4702831bf28cc9f80ce12f18b1d66759af43b", + "size": 17216 }, { "url": "https://modelcontextprotocol.io/docs/draft/learn/server-concepts", @@ -8458,15 +8458,15 @@ "url": "https://modelcontextprotocol.io/docs/draft/sdk", "status": "success", "path": "mcp/docs/draft/sdk.md", - "sha256": "e2b20207429995ecb86263d29ed0827298ad164f3ae1f3aa4811dcf852608eaf", - "size": 2980 + "sha256": "13d33b0d7529dc6b11d2f88841107ad373c6bf7386fbc06b653d9e324e6a1f40", + "size": 3067 }, { "url": "https://modelcontextprotocol.io/docs/draft/tools/debugging", "status": "success", "path": "mcp/docs/draft/tools/debugging.md", - "sha256": "2f489eca9e10496eefe180ad11c3aee244aa8ff68eba51776ca6093217833908", - "size": 11356 + "sha256": "6c8e550b4953602ee02feff813046602bc9c4299fbbe08c51852e7ecfde300eb", + "size": 11466 }, { "url": "https://modelcontextprotocol.io/docs/draft/tools/inspector", @@ -8486,43 +8486,43 @@ "url": "https://modelcontextprotocol.io/docs/draft/tools/inspector/cli", "status": "success", "path": "mcp/docs/draft/tools/inspector/cli.md", - "sha256": "fdcf5950937a92d5dd5547974936a2e56ee1ca6cd32b2b3e101eb7f92a4c1ed6", - "size": 13925 + "sha256": "aa264824344e5f851edf241edde2587462b66f268c09cbe9f19c342e580c6707", + "size": 15437 }, { "url": "https://modelcontextprotocol.io/docs/draft/tools/inspector/configuration", "status": "success", "path": "mcp/docs/draft/tools/inspector/configuration.md", - "sha256": "a3787a8c664e1fe0e7bab8de1804c42b5d0d383977c9de39dad5ad4125ca7d8e", - "size": 21097 + "sha256": "fceab40c010da59a3194d7d7a8b45d2035818a9803b7c16665e4d6b8b9280b81", + "size": 26507 }, { "url": "https://modelcontextprotocol.io/docs/draft/tools/inspector/mcpdo", "status": "success", "path": "mcp/docs/draft/tools/inspector/mcpdo.md", - "sha256": "db93ec4d0ff887d536ec449fc26504a31dff6b42c1f3727b8c4132f2bb0f389e", - "size": 12252 + "sha256": "cda5e4d69ab1913e6a0226c0b095cf67e8d6bd359addff4dda3acabbbd228129", + "size": 13456 }, { "url": "https://modelcontextprotocol.io/docs/draft/tools/inspector/protocol-eras", "status": "success", "path": "mcp/docs/draft/tools/inspector/protocol-eras.md", - "sha256": "0f5bd75cb404f4161fca3f111d189dd56df49576a81baaf167b5fb1ee3e797e0", - "size": 17465 + "sha256": "527a2b418ef1ca1efe5145476b9cb05daaa8f5efaa226c34d70d91d5e6bb52fa", + "size": 17576 }, { "url": "https://modelcontextprotocol.io/docs/draft/tools/inspector/recipes", "status": "success", "path": "mcp/docs/draft/tools/inspector/recipes.md", - "sha256": "d3810eb0e087f5cba683d09d21f4932eef558ca91347454173f7329d32f40616", - "size": 17630 + "sha256": "041a2f26a31d2f7bdb9053ac83953aa675ef319351c37aed785770e7d35163fd", + "size": 17976 }, { "url": "https://modelcontextprotocol.io/docs/draft/tools/inspector/security", "status": "success", "path": "mcp/docs/draft/tools/inspector/security.md", - "sha256": "41b4c38e76f84e04ed8820b1f51636d833fdd86671be99b81bb87ef93ed14156", - "size": 16761 + "sha256": "c1eab9d6bd265f33d01e560b6fe94937718e22c830c48650881da29a886573cb", + "size": 17199 }, { "url": "https://modelcontextprotocol.io/docs/draft/tools/inspector/tui", @@ -8535,15 +8535,15 @@ "url": "https://modelcontextprotocol.io/docs/draft/tools/inspector/web", "status": "success", "path": "mcp/docs/draft/tools/inspector/web.md", - "sha256": "b4ffa9e774032f500c063e313b0a54422a50321d3b27e2caa0ec36777d3d67a6", - "size": 15080 + "sha256": "7e1562e732b4e913c7df1853477a1c0f20352dd998be216ad7cf391519d54335", + "size": 15765 }, { "url": "https://modelcontextprotocol.io/docs/draft/tutorials/security/authorization", "status": "success", "path": "mcp/docs/draft/tutorials/security/authorization.md", - "sha256": "27de2749c25ac4e662a86db8bbd614152e4fd5e7f2bf4496a7e0e29c4bbdd90e", - "size": 47343 + "sha256": "460966ea8e1298018f453a996324fb8c9f74b63ad11f6b82baf7af635a320f36", + "size": 49077 }, { "url": "https://modelcontextprotocol.io/docs/draft/tutorials/security/local-server-security", @@ -8591,7 +8591,7 @@ "url": "https://modelcontextprotocol.io/extensions/auth/oauth-client-credentials", "status": "success", "path": "mcp/extensions/auth/oauth-client-credentials.md", - "sha256": "0cdc1b6bfecd444b4a037b3dad29a9ec93d018923ef01c6d3d4cc0021edc7ba6", + "sha256": "0bc2851331791a086446f013dc6df6b22c1305fa053d5e9aa1c8ccb699ddac49", "size": 12983 }, { @@ -9287,13 +9287,6 @@ "sha256": "1266e0ab470649c34047a3253c5408802b916f77d32b864aabb75c5737e811c9", "size": 2546 }, - { - "url": "https://modelcontextprotocol.io/specification/2025-06-18/architecture", - "status": "success", - "path": "mcp/specification/2025-06-18/architecture.md", - "sha256": "9137c060780716759e8986de0f95684901242aabe3d0b9965945196bd36f91bc", - "size": 5977 - }, { "url": "https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization", "status": "success", @@ -10103,8 +10096,8 @@ "url": "https://support.claude.com/en/articles/8114491-get-started-with-claude", "status": "success", "path": "support/8114491-get-started-with-claude.md", - "sha256": "0225c1519a98ce81190b02fa362c063af6177951b5cede7902c0c26679d466f6", - "size": 5220 + "sha256": "61abefd0c09269d0b8e6e05758cf56db3588afbd97145e272d63ccbc8364238a", + "size": 5210 }, { "url": "https://support.claude.com/en/articles/8114494-how-up-to-date-is-claude-s-training-data", @@ -10180,8 +10173,8 @@ "url": "https://support.claude.com/en/articles/8230524-delete-or-rename-a-conversation", "status": "success", "path": "support/8230524-delete-or-rename-a-conversation.md", - "sha256": "1f96e42d840ab5c759177cbe4ba7cd20079e1db0ffe34cdfe16c9bd1620f598b", - "size": 5883 + "sha256": "2cd671ec7a68c67207909c43ddfb492feb26378bbfd3d5ff445c45c181b710ab", + "size": 5887 }, { "url": "https://support.claude.com/en/articles/8241126-upload-files-to-claude", @@ -10250,7 +10243,7 @@ "url": "https://support.claude.com/en/articles/8325618-paid-plan-billing-faqs", "status": "success", "path": "support/8325618-paid-plan-billing-faqs.md", - "sha256": "d43ffe60dc91ea91d38e852587d3e72044520dad9999207ab737f35be510c853", + "sha256": "45069be906a96435be471f196eda26e503e1d6d6a38df6038b779c8c288ca3ee", "size": 5020 }, { @@ -10313,7 +10306,7 @@ "url": "https://support.claude.com/en/articles/8887527-customizing-your-appearance-settings", "status": "success", "path": "support/8887527-customizing-your-appearance-settings.md", - "sha256": "b4b9a628e7fafce258d25e9da297da6e7c079c824d46399026598d312f7b97a5", + "sha256": "6e589237837f6d67168f8696515fde19b1c88add27e9ef0ed1e2d5eaade3aa9d", "size": 1910 }, { @@ -10488,8 +10481,8 @@ "url": "https://support.claude.com/en/articles/9267400-move-your-personal-claude-account-to-a-team-or-enterprise-organization", "status": "success", "path": "support/9267400-move-your-personal-claude-account-to-a-team-or-enterprise-organization.md", - "sha256": "96bc88a73e6a03ef9da6e1f0684c206d03643aedadc605c2fd983d311fdde5dc", - "size": 10464 + "sha256": "2cd0377e544343eec6a14fa72e93635e6fa2b5e4fb1a0e6abe750939b048eaa1", + "size": 10466 }, { "url": "https://support.claude.com/en/articles/9301722-updates-to-our-acceptable-use-policy-now-usage-policy-consumer-terms-of-service-and-privacy-policy", @@ -10782,7 +10775,7 @@ "url": "https://support.claude.com/en/articles/10310342-how-do-i-log-out-of-all-active-sessions", "status": "success", "path": "support/10310342-how-do-i-log-out-of-all-active-sessions.md", - "sha256": "c7b1cfc00b552c33a8ad7a794f765e226da95b9063aeaf9a46db38500e708f68", + "sha256": "9625d162d3cf2bb7da98aab3f2b45d26890e66491a89ac88330ec7f68b4fdb86", "size": 3103 }, { @@ -10831,7 +10824,7 @@ "url": "https://support.claude.com/en/articles/10504844-manage-user-feedback-settings-on-team-and-enterprise-plans", "status": "success", "path": "support/10504844-manage-user-feedback-settings-on-team-and-enterprise-plans.md", - "sha256": "05956146c65a4c7a4a217b9a3f381af46b8bdfff4fb5d258d13a1318a44fdedb", + "sha256": "b35577c26daf9f5baa5b02d3d0b6709bd1e7efe31e6fba693fefd2a47b24c955", "size": 1036 }, { @@ -10880,8 +10873,8 @@ "url": "https://support.claude.com/en/articles/10949351-getting-started-with-local-mcp-servers-on-claude-desktop", "status": "success", "path": "support/10949351-getting-started-with-local-mcp-servers-on-claude-desktop.md", - "sha256": "6008747532c55d0735a290627a2c6c5bc626135b0dc05018bb9ca08869ed5ccf", - "size": 8957 + "sha256": "6c27f941f6e3b25b4c4cb32bd0650b19a1ce53540e7cf1e770e1bc04a0f0556a", + "size": 8959 }, { "url": "https://support.claude.com/en/articles/11049741-what-is-the-max-plan", @@ -11041,7 +11034,7 @@ "url": "https://support.claude.com/en/articles/11725453-set-up-the-claude-lti-in-canvas-by-instructure", "status": "success", "path": "support/11725453-set-up-the-claude-lti-in-canvas-by-instructure.md", - "sha256": "69225ed2985ebf29befa1287447e1405aa9f44c795cba4e41892d60662c274de", + "sha256": "3da039b6edd250d8a968d92929b89e2ba31227957abe4e57ae41f65458f34462", "size": 2752 }, { @@ -11062,8 +11055,8 @@ "url": "https://support.claude.com/en/articles/11818288-why-am-i-being-asked-to-verify-my-payment-method", "status": "success", "path": "support/11818288-why-am-i-being-asked-to-verify-my-payment-method.md", - "sha256": "7c0e1e8e2e206f70e491d1df1a40898be65d66ce28aa7cfc29f34caec4f3da4d", - "size": 822 + "sha256": "01bba2895ecc2831848e058d93e8437a0b6cb12c028ce306861bb2c20ca26801", + "size": 814 }, { "url": "https://support.claude.com/en/articles/11825384-how-to-update-claude-for-ios", @@ -11097,8 +11090,8 @@ "url": "https://support.claude.com/en/articles/11869629-use-claude-with-android-apps", "status": "success", "path": "support/11869629-use-claude-with-android-apps.md", - "sha256": "ce11c74cdc334446ef68792cdcec67b54fdc3f08c6469860548647dee0ebf54a", - "size": 14025 + "sha256": "1385896d722277c928174e61876d1ab321ef3c30a9b5cb1365f3d0671daab200", + "size": 14023 }, { "url": "https://support.claude.com/en/articles/11932705-automated-security-reviews-in-claude-code", @@ -11132,8 +11125,8 @@ "url": "https://support.claude.com/en/articles/12005970-manage-usage-credits-for-team-and-seat-based-enterprise-plans", "status": "success", "path": "support/12005970-manage-usage-credits-for-team-and-seat-based-enterprise-plans.md", - "sha256": "39d22f8ae23501786b2bf11967ce8db7fc65d8846f6a39f1a29313e2214f82df", - "size": 9713 + "sha256": "150ae6ff2709f18f44dcd23f28a908ed273b02b3e6c488dd1f3dae33b1605e74", + "size": 9715 }, { "url": "https://support.claude.com/en/articles/12012173-get-started-with-claude-in-chrome", @@ -11195,14 +11188,14 @@ "url": "https://support.claude.com/en/articles/12157520-claude-code-usage-analytics", "status": "success", "path": "support/12157520-claude-code-usage-analytics.md", - "sha256": "e6414dcc8d62b0cc5ca2d79d7fef10e033061391cae08cd07f0e391e613648d3", - "size": 6376 + "sha256": "62e5b9f796579906ece621d88002d131f9ef6227cf2f4c0c535ba9a56f652b6b", + "size": 6380 }, { "url": "https://support.claude.com/en/articles/12260368-use-incognito-chats", "status": "success", "path": "support/12260368-use-incognito-chats.md", - "sha256": "c16c68f7e576df721dbdd0cbc56953c917001609777078377aa75ae547da2017", + "sha256": "42f8a61fb52b0232aa4e1509460e773140aa32ae781172bb667b8ac27ac3294b", "size": 4388 }, { @@ -11300,8 +11293,8 @@ "url": "https://support.claude.com/en/articles/12592343-enabling-and-using-the-desktop-extension-allowlist", "status": "success", "path": "support/12592343-enabling-and-using-the-desktop-extension-allowlist.md", - "sha256": "5750c083d8404d4a69b80664d5d5ed288e42ecdeb25ce16a3c9bb86b66327b83", - "size": 5720 + "sha256": "e785615434751bc61fd73fe54a6034e5dbfae2f6908fd5efa945b19e6b6f93ed", + "size": 5718 }, { "url": "https://support.claude.com/en/articles/12611117-deploy-claude-desktop-for-macos", @@ -11314,8 +11307,8 @@ "url": "https://support.claude.com/en/articles/12618689-use-claude-code-in-the-cloud", "status": "success", "path": "support/12618689-use-claude-code-in-the-cloud.md", - "sha256": "27c7a06da3ff83c55d322d4a8b18334c0dbb9704d819f5556ffe831547f45af8", - "size": 11117 + "sha256": "168466e46b1c209b88db97b77df5b5c252331bd482dc6b0274daa6f9ad1f2f3e", + "size": 11121 }, { "url": "https://support.claude.com/en/articles/12622667-enterprise-configuration-for-claude-desktop", @@ -11370,8 +11363,8 @@ "url": "https://support.claude.com/en/articles/12883420-view-usage-analytics-for-team-and-enterprise-plans", "status": "success", "path": "support/12883420-view-usage-analytics-for-team-and-enterprise-plans.md", - "sha256": "6d37299322f563ecc342843636fb65e677f242c53347c30d39362acebc68c4d5", - "size": 15101 + "sha256": "74a41b1501423941b23a2c438a5dee482c715863b03e78e05977cc8c62d98f51", + "size": 15093 }, { "url": "https://support.claude.com/en/articles/12902405-claude-in-chrome-troubleshooting", @@ -11419,7 +11412,7 @@ "url": "https://support.claude.com/en/articles/12997503-team-plan-billing-faqs", "status": "success", "path": "support/12997503-team-plan-billing-faqs.md", - "sha256": "58e86af8c97350ca8c1428f107baa017fca69a7e048988430ca5636c8345fa51", + "sha256": "dbc0326bf98f46668c3eb3cdb2b48e3c4d7e55dbd07b0fa3185b20dc9006da33", "size": 5449 }, { @@ -11468,14 +11461,14 @@ "url": "https://support.claude.com/en/articles/13132885-set-up-single-sign-on-sso", "status": "success", "path": "support/13132885-set-up-single-sign-on-sso.md", - "sha256": "26d9e0950969cb66022c8ddaface9af6bf5238a17abccb784325d269c8463481", - "size": 13637 + "sha256": "8b5fb978eb7a31644db5809036eea4aa42927d472a2d7eac30d19d9667cca52d", + "size": 13645 }, { "url": "https://support.claude.com/en/articles/13133195-set-up-jit-or-scim-provisioning", "status": "success", "path": "support/13133195-set-up-jit-or-scim-provisioning.md", - "sha256": "762cc7aab209391fcac89804364af11cecd26a71afec5d23f24322d4b0c1de6c", + "sha256": "3f0f65a6b905513c674ce7d5c7fd914516e0d9f4ea212a42953682cc73c54119", "size": 22525 }, { @@ -11503,8 +11496,8 @@ "url": "https://support.claude.com/en/articles/13163631-configuring-session-security-settings", "status": "success", "path": "support/13163631-configuring-session-security-settings.md", - "sha256": "155dbee169f0ea1eb1dd42a043e243123b0daf85408e39755570f20cea99c0d9", - "size": 3705 + "sha256": "cf0829c5246ba41dc50acab6b8cfadd387d123b2b59648367661d37f17e5f827", + "size": 3697 }, { "url": "https://support.claude.com/en/articles/13171706-crisis-helpline-support-in-claude", @@ -11517,7 +11510,7 @@ "url": "https://support.claude.com/en/articles/13189465-log-in-to-your-claude-account", "status": "success", "path": "support/13189465-log-in-to-your-claude-account.md", - "sha256": "2a7765495a98acdc85346ab2e4c7979352d406dc0aee2175c56c86f7ec5add30", + "sha256": "8d260d4c2ca0e40e2af4f1c2a39613c7e613e3bce1555ca47b0a53b4a329ac60", "size": 7046 }, { @@ -11545,7 +11538,7 @@ "url": "https://support.claude.com/en/articles/13325567-account-management-faqs", "status": "success", "path": "support/13325567-account-management-faqs.md", - "sha256": "28df520d21e3e2681dd95e30e6b0816c295b0d05d49559efe9f038eb19a171f2", + "sha256": "e7982aed5932c70f32ac3bacf76b00c8e5cf9b2fcbe8ee20930edd78812cce48", "size": 2598 }, { @@ -11580,7 +11573,7 @@ "url": "https://support.claude.com/en/articles/13371040-log-in-to-your-console-account", "status": "success", "path": "support/13371040-log-in-to-your-console-account.md", - "sha256": "ed79f325577a10f8f71efce447e16cd475085e3276cb0e6236cb38bb20ab3e23", + "sha256": "e1e200b490a1f65de093ddcc9c42e26c19f21e7bb7b93b994c94d128c49fd563", "size": 4609 }, { @@ -11636,8 +11629,8 @@ "url": "https://support.claude.com/en/articles/13641943-visual-and-interactive-content", "status": "success", "path": "support/13641943-visual-and-interactive-content.md", - "sha256": "c3ef17a98cc569d5c3a2a3a9dbdb623ee959bcd237c1b025560ef7ef7141929b", - "size": 6513 + "sha256": "56876477a1d3c4c7d1974d29eaf6ac7364e013aca2d79489cf568505350e7027", + "size": 6507 }, { "url": "https://support.claude.com/en/articles/13663666-use-visual-and-interactive-content-on-team-and-enterprise-plans", @@ -11692,8 +11685,8 @@ "url": "https://support.claude.com/en/articles/13837440-use-plugins-in-claude", "status": "success", "path": "support/13837440-use-plugins-in-claude.md", - "sha256": "b656af463870aa4315443be03643f0e29af820bc05a82f855b934aa98224ba78", - "size": 15263 + "sha256": "4f5b360d67572ef4dad44773562cbdb370c60add7eaf65493b25ce2d10377a20", + "size": 15265 }, { "url": "https://support.claude.com/en/articles/13854387-schedule-recurring-tasks-in-claude-cowork", @@ -11881,8 +11874,8 @@ "url": "https://support.claude.com/en/articles/14499648-how-scim-sync-works-for-enterprise-organizations", "status": "success", "path": "support/14499648-how-scim-sync-works-for-enterprise-organizations.md", - "sha256": "8012cc06e8144c23aa5eea2cd323bb37501332bf2ac1b0d9b574d0d4c5e90058", - "size": 7674 + "sha256": "349ad5bba5e1f1c4e2f5d9941b160bea569e6a1308914bedd6b353a0484fbf7a", + "size": 7672 }, { "url": "https://support.claude.com/en/articles/14503520-available-beta-and-research-preview-features", @@ -12105,8 +12098,8 @@ "url": "https://support.claude.com/en/articles/15330088-set-a-default-model-for-your-organization", "status": "success", "path": "support/15330088-set-a-default-model-for-your-organization.md", - "sha256": "8744c8c4e071343001215366ec856a20cd525b5c8d9f9c932d5ab4ffd9902a12", - "size": 11311 + "sha256": "8e7be9526c142e0b88fc2a2f29c19dd14c80161f6bc31fb9198d062f1b69c937", + "size": 11309 }, { "url": "https://support.claude.com/en/articles/15330651-claude-enterprise-admin-api-reference-guide", @@ -12217,8 +12210,8 @@ "url": "https://support.claude.com/en/articles/15694740-manage-model-access-for-your-organization", "status": "success", "path": "support/15694740-manage-model-access-for-your-organization.md", - "sha256": "bda60110354e6d748a768edbece7689d5b0be5c66d074d0a93e6264877e50d21", - "size": 10326 + "sha256": "233491a451e36b8d90dcfc4cc87ef8a2d1bf2722be2ab6ce7b1f0dba68a6c33d", + "size": 10332 }, { "url": "https://support.claude.com/en/articles/15707726-using-claude-for-legal-work-privilege-confidentiality-and-how-to-think-about-configuration", @@ -12252,8 +12245,8 @@ "url": "https://support.claude.com/en/articles/15936181-get-started-with-1password-for-claude", "status": "success", "path": "support/15936181-get-started-with-1password-for-claude.md", - "sha256": "4fa54078b8ec1b334bbff3b46f8b6e663b99fac412892db41c18fa4fd3a0214e", - "size": 5065 + "sha256": "8ed4406fe12b39d8d068e893a4d76abb27a446969871892dbc310a855297fae3", + "size": 5069 }, { "url": "https://support.claude.com/en/articles/16049681-why-claude-switched-models-in-your-conversation-with-opus-5-or-opus-5-5", @@ -12301,8 +12294,8 @@ "url": "https://support.claude.com/en/articles/16607638-understanding-your-pro-max-or-ultra-plan-invoices", "status": "success", "path": "support/16607638-understanding-your-pro-max-or-ultra-plan-invoices.md", - "sha256": "5507ab35df5dcea1fd88c7750858836ccebc858ae120bc02b8f0504ec81892e9", - "size": 5885 + "sha256": "7b88f437a302f4815abe7c56cfbf02c4dec624f069a0a32ff0563a5a3f0c1044", + "size": 5881 }, { "url": "https://support.claude.com/en/articles/16607668-understanding-your-team-plan-invoices", @@ -12385,8 +12378,8 @@ "url": "https://support.claude.com/en/articles/16893491-get-started-with-smart-reports", "status": "success", "path": "support/16893491-get-started-with-smart-reports.md", - "sha256": "f18a6a2db8adb2d16d30988e3c4884b244cf46438ff35a572c2fef787968fc2a", - "size": 17198 + "sha256": "48315e880451976218c9e7613a888321ecf154cac866ec6ecf6ba71b352d863e", + "size": 17212 }, { "url": "https://support.claude.com/en/articles/16923645-get-started-with-claude-docs", @@ -12406,8 +12399,8 @@ "url": "https://support.claude.com/en/articles/16951679-use-claude-in-google-docs-sheets-and-slides", "status": "success", "path": "support/16951679-use-claude-in-google-docs-sheets-and-slides.md", - "sha256": "b35e879bb56da848a05a30371575686a5991bfbf19357c4cafc0e2b1cefa0a5b", - "size": 22001 + "sha256": "734a46a176c59eeb692258949d78243367b15b7b08a484b7a64172a6e120e39a", + "size": 21999 }, { "url": "https://support.claude.com/en/articles/16952184-set-up-salesforce-in-claude-for-your-organization", @@ -12434,8 +12427,8 @@ "url": "https://support.claude.com/en/articles/17005973-manage-pooled-group-budgets-on-enterprise-plans", "status": "success", "path": "support/17005973-manage-pooled-group-budgets-on-enterprise-plans.md", - "sha256": "6cd8027e252e59942ee719ae22abe84d7de80031bd7af742e3ada9dcd97d9d58", - "size": 7833 + "sha256": "355d6faa8267f2634edf44ecc59d02210cab95cb6fef1e66a7b828e17b5d8ce7", + "size": 7829 }, { "url": "https://support.claude.com/en/articles/17007452-what-is-a-limit-reset", @@ -12483,8 +12476,8 @@ "url": "https://support.claude.com/en/articles/17203415-set-up-claude-for-intune", "status": "success", "path": "support/17203415-set-up-claude-for-intune.md", - "sha256": "1f57b81aaaacb331921a1db96f2a6889c04a6a55ec77d224541f97f78dacb458", - "size": 11365 + "sha256": "f08fa6aefa726ae759d738f7a8bbdad434f09d0eca0a45f42881b3175a77011b", + "size": 11375 }, { "url": "https://support.claude.com/en/articles/17318731-use-claude-code-local-mode-and-claude-cowork-local-mode-on-a-hipaa-ready-enterprise-plan", @@ -12511,7 +12504,7 @@ "url": "https://support.claude.com/en/articles/17444462-set-up-and-manage-the-new-unified-claude-experience-for-your-enterprise-organization", "status": "success", "path": "support/17444462-set-up-and-manage-the-new-unified-claude-experience-for-your-enterprise-organization.md", - "sha256": "26d25b99d57388e83e94ee1dfbaa790268fb2bdd777dcbb79936fe48bbe635f3", + "sha256": "6ec54618c9a54ed72a75858084aac52ea9ac2893c3216a1e7fe228c588975fdc", "size": 24638 }, { @@ -14415,8 +14408,8 @@ "url": "https://claude.com/docs/third-party/claude-desktop/import", "status": "success", "path": "claude/third-party/claude-desktop/import.md", - "sha256": "9cf573892771f485efc582297c0db966e288771c73dfc84d1f9ada57a53371b2", - "size": 18930 + "sha256": "7427d69dd01945ee2526863a3e8291a0e580d37f7842f250315a689705631fa4", + "size": 19720 }, { "url": "https://claude.com/docs/third-party/claude-desktop/in-app-configuration", @@ -29989,24 +29982,8 @@ ], "failures": [ { - "url": "https://support.claude.com/en/articles/11145838-use-claude-code-with-your-pro-or-max-plan", - "error": "moved to https://support.claude.com/en/articles/11145838-use-claude-code-with-your-pro-max-or-ultra-plan.md" - }, - { - "url": "https://support.claude.com/en/articles/8325617-cancel-your-pro-or-max-subscription", - "error": "moved to https://support.claude.com/en/articles/8325617-cancel-your-pro-max-or-ultra-subscription.md" - }, - { - "url": "https://support.claude.com/en/articles/16607638-understanding-your-pro-or-max-plan-invoices", - "error": "moved to https://support.claude.com/en/articles/16607638-understanding-your-pro-max-or-ultra-plan-invoices.md" - }, - { - "url": "https://support.claude.com/en/articles/9876003-i-have-a-paid-claude-subscription-pro-max-team-or-enterprise-plans-why-is-claude-api-usage-billed-separately-from-my-paid-claude-plan", - "error": "moved to https://support.claude.com/en/articles/9876003-why-is-claude-api-usage-billed-separately-from-my-paid-claude-plan.md" - }, - { - "url": "https://support.claude.com/en/articles/17154008-monthly-api-credits-for-max-and-team-plans", - "error": "moved to https://support.claude.com/en/articles/17154008-monthly-api-credits-for-max-ultra-and-team-plans.md" + "url": "https://modelcontextprotocol.io/specification/2025-06-18/architecture", + "error": "HTTP 500" } ], "dead": [ @@ -30014,6 +29991,10 @@ "url": "https://code.claude.com/docs/en/claude-tag", "reason": "moved -> https://claude.com/docs/claude-tag/overview" }, + { + "url": "https://support.claude.com/en/articles/11145838-use-claude-code-with-your-pro-or-max-plan", + "reason": "moved -> https://support.claude.com/en/articles/11145838-use-claude-code-with-your-pro-max-or-ultra-plan" + }, { "url": "https://platform.claude.com/docs/en/agent-sdk/stop-reasons", "reason": "moved -> https://code.claude.com/docs/en/agent-sdk" @@ -31118,6 +31099,10 @@ "url": "https://support.claude.com/en/articles/13756069-public-sector-faqs", "reason": "moved -> https://claude.com/solutions/government" }, + { + "url": "https://support.claude.com/en/articles/8325617-cancel-your-pro-or-max-subscription", + "reason": "moved -> https://support.claude.com/en/articles/8325617-cancel-your-pro-max-or-ultra-subscription" + }, { "url": "https://support.claude.com/en/articles/16989529-invite-people-outside-your-organization-to-an-artifact", "reason": "moved -> https://support.claude.com/en/articles/9547008-share-artifacts" @@ -31126,6 +31111,10 @@ "url": "https://support.claude.com/en/articles/14503643-set-up-scim-in-claude-for-government", "reason": "moved -> https://claude.com/docs/government/overview" }, + { + "url": "https://support.claude.com/en/articles/16607638-understanding-your-pro-or-max-plan-invoices", + "reason": "moved -> https://support.claude.com/en/articles/16607638-understanding-your-pro-max-or-ultra-plan-invoices" + }, { "url": "https://support.claude.com/en/articles/14604842-real-time-cyber-safeguards-on-claude-opus-and-sonnet", "reason": "moved -> https://support.claude.com/en/articles/14604842-cyber-verification-program" @@ -31158,6 +31147,14 @@ "url": "https://support.claude.com/en/articles/12650343-use-claude-for-excel", "reason": "moved -> https://claude.com/docs/office-agents/excel" }, + { + "url": "https://support.claude.com/en/articles/9876003-i-have-a-paid-claude-subscription-pro-max-team-or-enterprise-plans-why-is-claude-api-usage-billed-separately-from-my-paid-claude-plan", + "reason": "moved -> https://support.claude.com/en/articles/9876003-why-is-claude-api-usage-billed-separately-from-my-paid-claude-plan" + }, + { + "url": "https://support.claude.com/en/articles/17154008-monthly-api-credits-for-max-and-team-plans", + "reason": "moved -> https://support.claude.com/en/articles/17154008-monthly-api-credits-for-max-ultra-and-team-plans" + }, { "url": "https://claude.com/docs/claude-science/annotations", "reason": "moved -> https://claude.com/docs/claude-science/comments" @@ -31201,9 +31198,9 @@ ], "summary": { "total": 4585, - "downloaded": 4283, + "downloaded": 4282, "skipped": 0, - "failed": 0, + "failed": 1, "dead": 302, "success_rate": 100.0 } diff --git a/content/claude/third-party/claude-desktop/import.md b/content/claude/third-party/claude-desktop/import.md index 04ac254e6..da349b61b 100644 --- a/content/claude/third-party/claude-desktop/import.md +++ b/content/claude/third-party/claude-desktop/import.md @@ -33,11 +33,17 @@ Use the [import wizard](#open-the-import-wizard) for your claude.ai conversation * Your administrator has turned import on by setting [`claudeAiImport`](https://claude.com/docs/third-party/claude-desktop/configuration#claudeaiimport) with `enabled` set to `true` in the managed configuration. The import wizard is off by default; until then, **Settings → Import & export** has no **Import…** button and reports that import isn't enabled for this deployment. The [automatic import of earlier third-party sessions](#automatic-import-of-earlier-third-party-sessions) doesn't depend on this setting. * If your administrator lists the claude.ai organizations you may import from, with `allowedOrganizationUuids` under [`claudeAiImport`](https://claude.com/docs/third-party/claude-desktop/configuration#claudeaiimport), you can import only by signing in to claude.ai, and only from a listed organization. A sign-in to any other organization or to a personal account is refused, and the wizard's options to import from a file or from earlier sessions on this computer are turned off. The [automatic import of earlier third-party sessions](#automatic-import-of-earlier-third-party-sessions) isn't affected by this list. * Claude Desktop is installed and running in third-party mode. See [Installation and setup](https://claude.com/docs/third-party/claude-desktop/installation.md). -* To bring history over from a claude.ai Team or Enterprise workspace, an owner of that workspace has enabled member data export (next section). Personal claude.ai accounts can always export. +* To bring history over from a claude.ai Team or Enterprise workspace, an owner of that workspace has [enabled member data export](#enable-member-data-export-admins), which isn't possible in a HIPAA-ready organization. Personal claude.ai accounts can always export. ## Enable member data export (admins) -On Team and Enterprise workspaces, member data export is off by default. A workspace owner enables it on claude.ai under **Settings → Organization → Data and privacy → Allow members to export their own data**. +On Team and Enterprise workspaces, member data export is off by default. + +> [!NOTE] +> +> In a [HIPAA-ready organization](https://support.claude.com/en/articles/13296973-hipaa-ready-enterprise-plans), member data export can't be turned on. Both ways to import claude.ai chats and projects in [step 1 of the import wizard](#step-1-claude-ai-chats-and-projects) need member data export, so neither works for members of that organization. If [`allowedOrganizationUuids`](https://claude.com/docs/third-party/claude-desktop/configuration#claudeaiimport) isn't set, they can still import Cowork and Claude Code sessions already on their computer in [step 2](#step-2-local-cowork-and-code-sessions). + +To enable member data export, a workspace owner goes to [**Organization settings > Data and privacy**](https://claude.ai/admin-settings/data-privacy-controls) on claude.ai and turns on the **Allow members to export their own data** toggle. ![claude.ai organization settings, Data and privacy page, with the Allow members to export their own data toggle turned on and a confirmation toast reading Member data export enabled.](https://mintcdn.com/claude-ai/HpR2FaaZXZXkiUcV/images/third-party/import/import-admin-toggle.png?fit=max\&auto=format\&n=HpR2FaaZXZXkiUcV\&q=85\&s=f1f4696a2124cd36ee9a7366cb1c4772) diff --git a/content/mcp/community/interest-groups/security.md b/content/mcp/community/interest-groups/security.md index a8e6228ec..562783392 100644 --- a/content/mcp/community/interest-groups/security.md +++ b/content/mcp/community/interest-groups/security.md @@ -12,13 +12,16 @@ ## Mission Statement -The Security Interest Group catalogs MCP-specific threats, reviews security-relevant proposals, and -scopes validated problems into focused Working Groups or [SEPs](https://modelcontextprotocol.io/community/sep-guidelines.md). +The Security Interest Group is the first stop for MCP-specific security topics. It vets incoming +threats, security-relevant proposals, and disclosure questions, then routes validated work to the +Working Group or [SEP](https://modelcontextprotocol.io/community/sep-guidelines.md) that owns it. ## Scope ### In Scope +* **Triage and routing**: receiving security topics raised on Discord or GitHub and handing them + to the owning group (Auth IG, Transports WG, Registry WG, Tool Annotations IG, SDK maintainers) * **Threat modeling**: developing and maintaining a shared, layered view of MCP attack surfaces spanning admission and identity, caller governance, runtime behavior, interception and enforcement, and auditability, to give individual proposals a common frame of reference @@ -92,17 +95,20 @@ scopes validated problems into focused Working Groups or [SEPs](https://modelcon | Stefano Ortolani | Broadcom | [@ostefano](https://github.com/ostefano) | `ostefano.` | Participant | Open to anyone. Join the `#security-ig` channel on the -[MCP Contributors Discord](https://modelcontextprotocol.io/community/communication.md#discord). Calls are open and active -participation is highly encouraged. The group is looking for contributors who will engage with -proposals and help drive work forward rather than observe. +[MCP Contributors Discord](https://modelcontextprotocol.io/community/communication.md#discord). Discussion runs asynchronously in +the channel between calls, and the agenda for each monthly call is assembled there. The group is +looking for contributors who will engage with proposals and help drive work forward rather than +observe. ## Operations | Meeting | Frequency | Duration | Purpose | | - | - | - | - | -| Office Hours | Every 2 weeks | 45 min | Threat review, proposal triage, deployment reports, WG-proposal scoping | +| Forum call | Monthly | 45 min | Triage and routing of topics on the published agenda, WG proposal scoping | +| Digest | Monthly | n/a | Summary of routed items, open topics, and advisories | -An agenda is shared in `#security-ig` ahead of each call. +The facilitators post a call for agenda in `#security-ig` ahead of each monthly call, and anyone +can add topics to it. Discord: [#security-ig](https://discord.com/channels/1358869848138059966/1379811011669921883) @@ -128,4 +134,5 @@ evolve as the group identifies new areas of interest. | Date | Change | | - | - | +| 2026-08-26 | Restructured as a routing group, replaced biweekly office hours with a monthly agenda-driven call and digest (core maintainer meeting, [discussion #3316](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/3316)) | | 2026-06-13 | Initial charter | diff --git a/content/mcp/community/security.md b/content/mcp/community/security.md index 25f4a437e..ab01d8ce5 100644 --- a/content/mcp/community/security.md +++ b/content/mcp/community/security.md @@ -65,6 +65,6 @@ boundary. The SDK's stdio transport is not a sandbox. ## Security Interest Group -The [Security Interest Group](https://modelcontextprotocol.io/community/interest-groups/security.md) is the venue for -discussing MCP-specific threats, reviewing security-relevant proposals, and routing -disclosure questions that don't fit a single repository. +The [Security Interest Group](https://modelcontextprotocol.io/community/interest-groups/security.md) is where you raise MCP-specific +security topics, including disclosure questions that don't fit a single repository, and where +facilitators route them to the group that owns the work. diff --git a/content/mcp/docs/2026-07-28/develop/build-client.md b/content/mcp/docs/2026-07-28/develop/build-client.md index 18dd110cd..0e9fc932f 100644 --- a/content/mcp/docs/2026-07-28/develop/build-client.md +++ b/content/mcp/docs/2026-07-28/develop/build-client.md @@ -824,6 +824,10 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > > [!NOTE] > > +> > This client uses MCP protocol version 2025-11-25, as supported by the latest stable release of the Java SDK. It connects to servers that accept that version, but not to servers that accept only 2026-07-28. See [backward compatibility](https://modelcontextprotocol.io/specification/2026-07-28/basic/versioning.md#backward-compatibility-with-initialization-based-versions). +> +> > [!NOTE] +> > > > This is a quickstart demo based on Spring AI MCP auto-configuration and boot starters. > > To learn how to create sync and async MCP Clients manually, consult the [Java SDK Client](https://java.sdk.modelcontextprotocol.io/) documentation. > @@ -854,7 +858,7 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > ```bash theme={null} > git clone https://github.com/spring-projects/spring-ai-examples.git -> cd model-context-protocol/web-search/brave-chatbot +> cd spring-ai-examples/model-context-protocol/web-search/brave-chatbot > ``` > > 3. Set up your API keys: @@ -920,7 +924,7 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > This activates the `spring-ai-starter-mcp-client` to create one or more `McpClient`s based on the provided server configuration. > The `spring.ai.mcp.client.toolcallback.enabled=true` property enables the tool callback mechanism, that automatically registers all MCP tool as spring ai tools. -> It is disabled by default. +> It is enabled by default. > > 3. MCP Server Configuration (`mcp-servers-config.json`): > @@ -945,8 +949,8 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > ```java theme={null} > var chatClient = chatClientBuilder > .defaultSystem("You are useful assistant, expert in AI and Java.") -> .defaultToolCallbacks((Object[]) mcpToolAdapter.toolCallbacks()) -> .defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory())) +> .defaultTools(SyncMcpToolCallbackProvider.builder().mcpClients(mcpSyncClients).build()) +> .defaultAdvisors(MessageChatMemoryAdvisor.builder(MessageWindowChatMemory.builder().build()).build()) > .build(); > ``` > @@ -954,7 +958,7 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > * Uses Claude AI model for natural language understanding > * Integrates Brave Search through MCP for real-time web search capabilities -> * Maintains conversation memory using InMemoryChatMemory +> * Maintains conversation memory using MessageWindowChatMemory > * Runs as an interactive command-line application > > ### Build and run @@ -2030,9 +2034,9 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > ## System Requirements > -> Before starting, ensure your Linux system meets these requirements: +> Before starting, ensure your system meets these requirements: > -> * Latest stable version of [Rust and Cargo](https://www.rust-lang.org/tools/install) +> * [Rust and Cargo](https://www.rust-lang.org/tools/install) 1.88 or newer > * Anthropic API key (Claude) > * A Python, Node.js, or executable MCP server to connect to > @@ -2054,18 +2058,24 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > edition = "2024" > > [dependencies] -> anyhow = "1.0.100" -> genai = "0.4.2" -> rmcp = { version = "0.8.0", features = ["server", "client", "transport-io", "transport-child-process"] } -> tokio = { version = "1.47.1", features = ["full"] } -> tracing = "0.1.41" -> tracing-subscriber = { version = "0.3", features = ["env-filter"] } -> serde_json = "1.0.128" +> anyhow = "1.0.104" +> jsonschema = "0.59" +> # Only the client half of rmcp is needed, over a child-process stdio transport. +> rmcp = { version = "3.4", features = [ +> "client", +> "transport-io", +> "transport-child-process", +> ], default-features = false } +> # The Messages API is called directly, which keeps the provider's content +> # blocks verbatim. That matters for signed thinking blocks; see request_model. +> reqwest = { version = "0.13", features = ["json"] } +> serde = { version = "1.0", features = ["derive"] } +> serde_json = "1.0.151" +> tokio = { version = "1.53", features = ["full"] } > dotenvy = "0.15.7" -> reqwest = "0.12.23" > ``` > -> The [`rmcp`](https://github.com/modelcontextprotocol/rust-sdk) crate provides the Rust MCP SDK and child-process transport. This example uses the [`genai`](https://github.com/jeremychone/rust-genai) crate to send requests to Claude and represent tools in the model request. +> The [`rmcp`](https://github.com/modelcontextprotocol/rust-sdk) crate provides the Rust MCP SDK and the child-process stdio transport. Only its client half is enabled. The client calls the [Messages API](https://docs.anthropic.com/en/api/messages) directly with [`reqwest`](https://docs.rs/reqwest). Calling the API directly keeps the content blocks of each reply verbatim, which matters when a reply contains a signed thinking block. The [`jsonschema`](https://docs.rs/jsonschema) crate validates structured tool results against the schema a tool declares. > > ## Setting Up Your API Key > @@ -2083,6 +2093,8 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > echo ".env" >> .gitignore > ``` > +> The client loads `.env` when the file exists. Exporting `ANTHROPIC_API_KEY` in the shell works as well. +> > > [!WARNING] > > > > Make sure you keep your `ANTHROPIC_API_KEY` secure! @@ -2093,272 +2105,492 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > ### Imports and Client Structure > -> First, add the imports, model constant, and basic client structure: +> First, add the imports and constants: > > ```rust theme={null} > use anyhow::{Context, Result, bail}; -> use genai::Client; -> use genai::chat::{ -> ChatMessage, ChatRequest, ChatResponse, ContentPart, Tool as GenaiTool, ToolResponse, +> use jsonschema::Validator; +> use rmcp::model::{ +> CallToolRequestParams, CallToolResult, ClientCapabilities, ClientConfig, Implementation, +> ProtocolVersion, Tool as McpTool, > }; -> use rmcp::model::{CallToolRequestParam, Tool as McpTool}; -> use rmcp::service::{RoleClient, RunningService, ServiceExt}; +> use rmcp::service::{ClientLifecycleMode, ClientServiceExt, RoleClient, RunningService}; > use rmcp::transport::TokioChildProcess; -> use serde_json::Value; +> use serde::{Deserialize, Serialize}; +> use serde_json::{Value, json}; +> use std::collections::HashMap; +> use std::time::Duration; > use tokio::io::{self, AsyncBufReadExt, BufReader}; > use tokio::process::Command; > > const MODEL_ANTHROPIC: &str = "claude-opus-5"; +> /// The model may think before answering, and max_tokens caps thinking +> /// plus the reply, so leave room for both. +> const MAX_TOKENS: u32 = 10000; +> const MAX_TOOL_TURNS: usize = 10; +> +> const ANTHROPIC_API_BASE: &str = "https://api.anthropic.com"; +> const ANTHROPIC_VERSION: &str = "2023-06-01"; +> const REQUEST_TIMEOUT: Duration = Duration::from_secs(120); +> ``` +> +> `MAX_TOKENS` caps the thinking and the reply together. `MAX_TOOL_TURNS` bounds how many rounds of tool calls one query may take. `REQUEST_TIMEOUT` applies to each request sent to the Messages API. +> +> Next, add the types for the Messages API and the client structure: +> +> ```rust theme={null} +> /// One turn of the conversation, as the Messages API takes it. +> /// +> /// `content` is a list of raw blocks rather than typed ones on purpose. An +> /// assistant turn is fed straight back on the next request, and Claude requires +> /// the blocks it sent to return unchanged -- a thinking block's `signature` +> /// included. Reserialising through a narrower type would drop whatever it does +> /// not model. +> #[derive(Serialize, Clone)] +> struct Message { +> role: &'static str, +> content: Vec, +> } +> +> impl Message { +> fn user(content: Vec) -> Self { +> Message { +> role: "user", +> content, +> } +> } +> +> fn assistant(content: Vec) -> Self { +> Message { +> role: "assistant", +> content, +> } +> } +> } +> +> /// A tool as the Messages API declares it, converted from an MCP tool. +> #[derive(Serialize, Clone)] +> struct ToolDefinition { +> name: String, +> #[serde(skip_serializing_if = "Option::is_none")] +> description: Option, +> input_schema: Value, +> } +> +> #[derive(Serialize)] +> struct MessagesRequest<'a> { +> model: &'a str, +> max_tokens: u32, +> messages: &'a [Message], +> tools: &'a [ToolDefinition], +> } +> +> #[derive(Deserialize)] +> struct MessagesResponse { +> content: Vec, +> } +> +> /// The `type` of a content block, when it has one. +> fn block_type(block: &Value) -> &str { +> block +> .get("type") +> .and_then(Value::as_str) +> .unwrap_or_default() +> } > > struct MCPClient { -> anthropic: Client, -> session: Option>, -> tools: Vec, +> http: reqwest::Client, +> session: Option>, +> tools: Vec, +> /// Compiled `outputSchema` per tool name. rmcp does not validate results, +> /// so this client does it with the `jsonschema` crate. +> output_schemas: HashMap, > } > ``` > -> The client keeps the model API client, the active MCP session, and the tools advertised by the connected server. +> `Message` holds the content blocks of one turn as raw `serde_json::Value`s. An assistant turn goes back to the API unchanged on the next request, with any thinking block and its `signature` intact. `ToolDefinition` is a tool as the Messages API declares it. `MCPClient` keeps the HTTP client, the active MCP session, the tools in Messages API form, and one compiled validator per tool that declares an `outputSchema`. > > ### Client Initialization > -> Next, initialize the model client and start without an MCP session or tools: +> Next, open the `impl MCPClient` block with the constructor. The methods in the following sections go inside this block, which closes after `cleanup`: > > ```rust theme={null} > impl MCPClient { > fn new() -> Result { > Ok(MCPClient { -> anthropic: Client::default(), +> http: reqwest::Client::builder() +> .timeout(REQUEST_TIMEOUT) +> .build() +> .context("Failed to build HTTP client")?, > session: None, > tools: Vec::new(), +> output_schemas: HashMap::new(), > }) > } -> -> // Additional methods will go here. -> } > ``` > -> `genai::Client::default()` reads the `ANTHROPIC_API_KEY` environment variable when it sends a request. +> `new` builds a `reqwest::Client` with the request timeout. The API key is read later, when a request is sent, so connecting to a server and listing its tools works without one. > -> ### Server Connection Management +> ### Validating Structured Tool Output > > Add this method inside the `impl MCPClient` block: > > ```rust theme={null} -> async fn connect_to_server(&mut self, server_args: &[String]) -> Result<()> { -> if self.session.is_some() { -> bail!("Client is already connected to a server"); +> /// Check a result against its tool's declared `outputSchema`. Error results +> /// are exempt: they carry a message, not data. +> fn validate_tool_output(&self, name: &str, result: &CallToolResult) -> Result<()> { +> let Some(validator) = self.output_schemas.get(name) else { +> return Ok(()); +> }; +> if result.is_error.unwrap_or(false) { +> return Ok(()); +> } +> let Some(structured) = &result.structured_content else { +> bail!("Tool {name} declares an output schema but returned no structured content"); +> }; +> if let Err(error) = validator.validate(structured) { +> bail!("Structured content from tool {name} does not match its output schema: {error}"); +> } +> Ok(()) > } +> ``` > -> let mut command = Command::new(&server_args[0]); -> command.args(&server_args[1..]); -> -> let process = TokioChildProcess::new(command) -> .with_context(|| format!("Failed to spawn server process for {:?}", server_args))?; +> A tool may declare an `outputSchema`, and the specification asks clients to validate `structuredContent` against it. rmcp does not do this, so the client keeps a compiled `jsonschema::Validator` per tool and checks each successful result. A result with `is_error` set carries a message, so it is exempt. A tool that declares a schema and returns no structured content is reported as an error. > -> let session = ().serve(process).await?; +> ### Server Connection Management > -> let rmcp_tools = session -> .list_all_tools() -> .await -> .context("Unable to list tools from server")?; +> Add this method inside the `impl MCPClient` block: > -> let tool_names: Vec = rmcp_tools -> .iter() -> .map(|tool| tool.name.to_string()) -> .collect(); +> ```rust theme={null} +> async fn connect_to_server(&mut self, server_args: &[String]) -> Result<()> { +> if self.session.is_some() { +> bail!("Client is already connected to a server"); +> } > -> println!("Connected to server with tools: {tool_names:?}"); +> let mut command = Command::new(&server_args[0]); +> command.args(&server_args[1..]); +> +> let process = TokioChildProcess::new(command) +> .with_context(|| format!("Failed to spawn server process for {:?}", server_args))?; +> +> // Without a ClientConfig the client would report rmcp's own crate name +> // and version rather than its own. +> let config = ClientConfig::new( +> ClientCapabilities::default(), +> Implementation::new("mcp-client-rust", "1.0.0"), +> ); +> +> // `Auto` probes server/discover and falls back to the 2025-11-25 +> // initialize handshake, matching the Python and TypeScript clients. +> // `serve` alone would only ever do the legacy handshake, under which a +> // server cannot offer this era's features -- an array-rooted +> // `outputSchema`, for one, which get_alerts uses. +> let session = config +> .serve_with_lifecycle( +> process, +> ClientLifecycleMode::Auto { +> preferred_versions: vec![ProtocolVersion::V_2026_07_28], +> legacy_version: Some(ProtocolVersion::V_2025_11_25), +> }, +> ) +> .await?; +> +> let rmcp_tools = session +> .list_all_tools() +> .await +> .context("Unable to list tools from server")?; +> +> let tool_names: Vec = rmcp_tools +> .iter() +> .map(|tool| tool.name.to_string()) +> .collect(); +> +> let protocol_version = session +> .peer_info() +> .map(|info| info.protocol_version.to_string()) +> .unwrap_or_else(|| "unknown".to_string()); +> println!("Connected over protocol {protocol_version} with tools: {tool_names:?}"); +> +> // An outputSchema root may be any JSON Schema, not just an object. +> for tool in &rmcp_tools { +> let Some(schema) = &tool.output_schema else { +> continue; +> }; +> let schema = Value::Object(schema.as_ref().clone()); +> let validator = Validator::new(&schema).with_context(|| { +> format!("Failed to compile output schema of tool {}", tool.name) +> })?; +> self.output_schemas.insert(tool.name.to_string(), validator); +> } > -> self.tools = convert_tools(&rmcp_tools); -> self.session = Some(session); -> Ok(()) -> } +> self.tools = convert_tools(&rmcp_tools); +> self.session = Some(session); +> Ok(()) +> } > ``` > > This method: > > 1. Starts the server as a child process using the command and arguments supplied on the command line -> 2. Establishes an MCP session over stdio -> 3. Lists all tools advertised by the server -> 4. Converts those tools into the format used in model requests +> 2. Names the client `mcp-client-rust` through a `ClientConfig` +> 3. Negotiates the protocol with `serve_with_lifecycle` and `ClientLifecycleMode::Auto`, which probes `server/discover` for `2026-07-28` and falls back to the `2025-11-25` `initialize` handshake +> 4. Lists all tools advertised by the server and prints the negotiated protocol version with the tool names +> 5. Compiles a validator from each tool's `outputSchema` +> 6. Converts the tools into the form used in model requests > -> ### Converting MCP Tools +> rmcp's `serve` method alone performs only the legacy handshake. The `Auto` mode makes the features of the current revision reachable, including an `outputSchema` whose root is an array. > -> Add this function outside the `impl MCPClient` block: +> ### Query Processing Logic +> +> Now add the core query-processing method inside `impl MCPClient`: > > ```rust theme={null} -> fn convert_tools(tools: &[McpTool]) -> Vec { -> tools -> .iter() -> .map(|tool| GenaiTool { -> name: tool.name.to_string(), -> description: tool.description.as_deref().map(str::to_string), -> schema: Some(Value::Object(tool.input_schema.as_ref().clone())), -> config: None, -> }) -> .collect() -> } -> ``` +> async fn process_query(&mut self, query: &str) -> Result { +> let session = self +> .session +> .as_ref() +> .context("Client is not connected to any server")?; +> +> let mut messages = vec![Message::user(vec![json!({"type": "text", "text": query})])]; +> let mut final_text = Vec::new(); +> +> // Initial Claude API call with tools +> let mut content = self.request_model(&messages).await?; +> +> // Keep calling tools until Claude answers without one, up to a cap. +> for _ in 0..MAX_TOOL_TURNS { +> let mut tool_uses = Vec::new(); +> for block in &content { +> match block_type(block) { +> "text" => { +> if let Some(text) = block.get("text").and_then(Value::as_str) { +> final_text.push(text.to_string()); +> } +> } +> "tool_use" => tool_uses.push(block.clone()), +> _ => {} +> } +> } > -> MCP and model APIs describe tools with similar information but different Rust types. `convert_tools` maps each MCP tool's name, description, and input schema into a `genai` tool definition. +> if tool_uses.is_empty() { +> return Ok(final_text.join("\n")); +> } > -> ### Sending Model Requests +> // Execute every tool call in this response and collect the results +> let mut tool_results = Vec::new(); +> for tool_use in &tool_uses { +> let name = tool_use +> .get("name") +> .and_then(Value::as_str) +> .context("tool_use block has no name")?; +> let id = tool_use +> .get("id") +> .and_then(Value::as_str) +> .context("tool_use block has no id")?; +> let input = tool_use.get("input").cloned().unwrap_or(json!({})); +> +> // Add information about the tool call to final text +> final_text.push(format!("[Calling tool {name} with args {input}]")); +> +> // Query the MCP server +> let mut params = CallToolRequestParams::new(name.to_string()); +> if let Some(arguments) = input.as_object().cloned() { +> params = params.with_arguments(arguments); +> } +> let tool_result = match session.call_tool(params).await { +> Ok(result) => result, +> // A rejected call is the model's mistake to correct, so it +> // goes back as a failed tool_result rather than ending the +> // query. Every tool_use still needs a matching result. +> Err(error) => { +> final_text.push(format!("[{name} failed: {error}]")); +> tool_results.push(json!({ +> "type": "tool_result", +> "tool_use_id": id, +> "content": format!("Tool call {name} failed: {error}"), +> "is_error": true, +> })); +> continue; +> } +> }; +> +> self.validate_tool_output(name, &tool_result)?; +> +> // structured_content is data the application can use directly. +> if let Some(Value::Array(items)) = &tool_result.structured_content { +> final_text.push(format!("[{name} returned {} items]", items.len())); +> } > -> Add this helper method inside `impl MCPClient`: +> // content is a list of block types; forward only the text ones. +> let mut payload = tool_result +> .content +> .iter() +> .filter_map(|block| block.as_text().map(|text| text.text.as_str())) +> .collect::>() +> .join("\n"); +> +> // A structured result SHOULD also carry serialized JSON in a text +> // block, but only SHOULD, so fall back to serializing it rather +> // than sending the model an empty result. +> if payload.is_empty() { +> if let Some(structured) = &tool_result.structured_content { +> payload = structured.to_string(); +> } +> } > -> ```rust theme={null} -> async fn request_model(&self, chat_req: &ChatRequest) -> Result { -> let response = self -> .anthropic -> .exec_chat(MODEL_ANTHROPIC, chat_req.clone(), None) -> .await -> .context("Anthropic chat request failed")?; -> -> Ok(response) -> } -> ``` +> tool_results.push(json!({ +> "type": "tool_result", +> "tool_use_id": id, +> "content": payload, +> "is_error": tool_result.is_error.unwrap_or(false), +> })); +> } > -> This keeps model request handling in one place and adds useful context if the API request fails. +> // Append the assistant's response and all tool results, in one user +> // message, to the history. Every tool_use needs a matching +> // tool_result, and the assistant's blocks go back as they arrived. +> messages.push(Message::assistant(content)); +> messages.push(Message::user(tool_results)); > -> ### Query Processing Logic +> content = self.request_model(&messages).await?; +> } > -> Now add the core query-processing method inside `impl MCPClient`: +> // The turn cap was hit. Keep the last response's text. If it asked for +> // more tools, say they were not run. +> let mut wants_tools = false; +> for block in &content { +> match block_type(block) { +> "text" => { +> if let Some(text) = block.get("text").and_then(Value::as_str) { +> final_text.push(text.to_string()); +> } +> } +> "tool_use" => wants_tools = true, +> _ => {} +> } +> } +> if wants_tools { +> final_text.push(format!("[Stopped after {MAX_TOOL_TURNS} tool-use turns]")); +> } > -> ```rust theme={null} -> async fn process_query(&mut self, query: &str) -> Result { -> let session = self -> .session -> .as_ref() -> .context("Client is not connected to any server")?; -> -> let mut messages = vec![ChatMessage::user(query)]; -> let mut final_text = Vec::new(); -> -> // Initial Claude API call with tools -> let mut chat_req = ChatRequest::new(messages.clone()).with_tools(self.tools.clone()); -> let mut chat_rsp = self.request_model(&chat_req).await?; -> -> // Process response content - collect text and handle tool calls -> for text in chat_rsp.texts() { -> final_text.push(text.to_string()); +> Ok(final_text.join("\n")) > } +> ``` > -> let tool_calls = chat_rsp.tool_calls(); -> if !tool_calls.is_empty() { -> // Append assistant's response to message history -> messages.push(ChatMessage::assistant(chat_rsp.content.clone())); -> -> // Execute each tool call and collect responses -> let mut tool_results = Vec::new(); -> for tool_call in tool_calls { -> // Add information about the tool call to final text -> let tool_args_str = serde_json::to_string(&tool_call.fn_arguments) -> .unwrap_or_else(|_| "{}".to_string()); -> -> final_text.push(format!( -> "[Calling tool {} with args {}]", -> tool_call.fn_name, tool_args_str -> )); -> -> // Query the MCP server -> let tool_result = session -> .call_tool(CallToolRequestParam { -> name: tool_call.fn_name.clone().into(), -> arguments: tool_call.fn_arguments.as_object().cloned(), -> }) -> .await -> .with_context(|| format!("Tool call {} failed", tool_call.fn_name))?; -> -> let payload = serde_json::to_string(&tool_result) -> .context("Failed to serialize tool result")?; -> -> tool_results.push(ContentPart::ToolResponse(ToolResponse::new( -> tool_call.call_id.clone(), -> payload, -> ))); -> } +> The method sends the user's query to Claude with the server's tools and then loops. Each pass collects the text blocks of the reply and gathers its `tool_use` blocks. When a reply contains no tool use, the collected text is returned. Otherwise the client calls each requested tool through the MCP session and builds one `tool_result` block per `tool_use`. A call the server rejects goes back with `is_error` set, so Claude can read the message and try something else. A successful result is checked against its output schema. Its text blocks are joined and forwarded to Claude, and when it has no text blocks the serialized `structured_content` is sent in their place. When `structured_content` is an array, the client prints the item count as an example of using structured data directly. The assistant's blocks are appended to the history exactly as they arrived, followed by one user message holding all tool results, and the next request is sent. The loop stops after `MAX_TOOL_TURNS` rounds. At that point the last reply's text is kept, and a note is added when Claude asked for more tools. > -> // Append tool responses to message history -> messages.push(ChatMessage::user(tool_results)); +> ### Sending Model Requests > -> // Build the next request and query model -> chat_req = ChatRequest::new(messages.clone()); -> chat_rsp = self.request_model(&chat_req).await?; +> Add this helper method inside `impl MCPClient`: > -> // Collect text from response -> for text in chat_rsp.texts() { -> final_text.push(text.to_string()); +> ```rust theme={null} +> /// Call Claude with the current history and return the content blocks of +> /// its reply, untouched. Tools are passed on every call so Claude can keep +> /// calling them across turns. +> async fn request_model(&self, messages: &[Message]) -> Result> { +> let api_key = std::env::var("ANTHROPIC_API_KEY").context("ANTHROPIC_API_KEY is not set")?; +> // The base URL is configurable so the client can point at a local stand-in. +> let base_url = +> std::env::var("ANTHROPIC_BASE_URL").unwrap_or_else(|_| ANTHROPIC_API_BASE.to_string()); +> +> let request = MessagesRequest { +> model: MODEL_ANTHROPIC, +> max_tokens: MAX_TOKENS, +> messages, +> tools: &self.tools, +> }; +> +> let response = self +> .http +> .post(format!("{}/v1/messages", base_url.trim_end_matches('/'))) +> .header("x-api-key", api_key) +> .header("anthropic-version", ANTHROPIC_VERSION) +> .json(&request) +> .send() +> .await +> .context("Anthropic request failed")?; +> +> let status = response.status(); +> let body = response +> .text() +> .await +> .context("Unable to read the Anthropic response")?; +> if !status.is_success() { +> bail!("Anthropic request failed with {status}: {body}"); > } -> } > -> Ok(final_text.join("\n")) -> } +> let parsed: MessagesResponse = +> serde_json::from_str(&body).context("Unable to parse the Anthropic response")?; +> Ok(parsed.content) +> } > ``` > -> The method first sends the user's query and available tools to Claude. When Claude requests tools, the client executes each request through the MCP session, sends the results back to Claude, and collects the final text response. +> `request_model` reads `ANTHROPIC_API_KEY` on each call and posts the history to `/v1/messages` with the `x-api-key` and `anthropic-version` headers. `ANTHROPIC_BASE_URL` overrides the endpoint, which allows pointing the client at a local stand-in. Tools are sent on every request so Claude can keep calling them across turns. A non-success status becomes an error that includes the response body. The reply's content blocks are returned untouched. > > ### Interactive Chat Interface > > Add the interactive terminal loop inside `impl MCPClient`: > > ```rust theme={null} -> async fn chat_loop(&mut self) -> Result<()> { -> println!("\nMCP Client Started!"); -> println!("Type your queries or 'quit' to exit."); +> async fn chat_loop(&mut self) -> Result<()> { +> println!("\nMCP Client Started!"); +> println!("Type your queries or 'quit' to exit."); > -> let mut stdin = BufReader::new(io::stdin()); -> let mut input = String::new(); +> let mut stdin = BufReader::new(io::stdin()); +> let mut input = String::new(); > -> loop { -> print!("\nQuery: "); -> std::io::Write::flush(&mut std::io::stdout())?; +> loop { +> print!("\nQuery: "); +> std::io::Write::flush(&mut std::io::stdout())?; > -> input.clear(); -> if stdin.read_line(&mut input).await? == 0 { -> break; // EOF -> } +> input.clear(); +> if stdin.read_line(&mut input).await? == 0 { +> break; // EOF +> } > -> let query = input.trim(); -> if query.eq_ignore_ascii_case("quit") { -> break; -> } -> if query.is_empty() { -> continue; -> } +> let query = input.trim(); +> if query.eq_ignore_ascii_case("quit") { +> break; +> } +> if query.is_empty() { +> continue; +> } > -> match self.process_query(query).await { -> Ok(response) => println!("\n{}", response), -> Err(err) => println!("\nError: {}", err), +> match self.process_query(query).await { +> Ok(response) => println!("\n{}", response), +> Err(err) => println!("\nError: {:#}", err), +> } > } -> } > -> Ok(()) -> } +> Ok(()) +> } > ``` > -> The loop accepts queries until the user types `quit` or closes standard input. Query errors are printed without terminating the client. +> The loop accepts queries until the user types `quit` or closes standard input. Query errors are printed without terminating the client. The `{:#}` format prints the whole `anyhow` context chain on one line. > > ### Cleanup > -> Add this method inside `impl MCPClient` to stop the MCP session and child process: +> Add this method inside `impl MCPClient` to stop the MCP session and child process. The closing brace ends the `impl MCPClient` block: > > ```rust theme={null} -> async fn cleanup(&mut self) -> Result<()> { -> if let Some(session) = self.session.take() { -> let _ = session.cancel().await; +> async fn cleanup(&mut self) -> Result<()> { +> if let Some(session) = self.session.take() { +> let _ = session.cancel().await; +> } +> Ok(()) > } -> Ok(()) > } > ``` > > ### Main Entry Point > -> Finally, add the asynchronous entry point outside the `impl MCPClient` block: +> Next, add the asynchronous entry point outside the `impl MCPClient` block: > > ```rust theme={null} > #[tokio::main] > async fn main() -> Result<()> { -> dotenvy::dotenv().context("Failed to load env file")?; +> // .env is optional; the key may come from the environment instead. +> let _ = dotenvy::dotenv(); > > let mut args = std::env::args(); > let _ = args.next(); @@ -2373,6 +2605,21 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > let result = async { > client.connect_to_server(&server_args).await?; +> +> // Connecting and listing tools needs no credentials; querying them +> // does. Matching the Python and TypeScript clients, report and exit +> // rather than failing, so the connection itself can be exercised +> // without a key. +> // Empty counts as unset, as it does in the other clients: `KEY= cmd` +> // is how the smoke test forces this path. +> if std::env::var("ANTHROPIC_API_KEY").map_or(true, |key| key.is_empty()) { +> println!( +> "\nNo ANTHROPIC_API_KEY found. To query these tools with Claude, set your API key:" +> ); +> println!(" export ANTHROPIC_API_KEY=your-api-key-here"); +> return Ok(()); +> } +> > client.chat_loop().await > } > .await; @@ -2386,14 +2633,34 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > } > ``` > -> The entry point loads `.env`, treats all remaining command-line arguments as the server command, connects the client, starts the chat loop, and ensures cleanup runs before exiting. +> The entry point loads `.env` when the file exists, treats all remaining command-line arguments as the server command, connects the client, and ensures cleanup runs before exiting. When `ANTHROPIC_API_KEY` is unset or empty, the client prints how to set the key and exits after listing the server's tools. This exercises the MCP connection without credentials. +> +> ### Describing Tools to the Model +> +> Finally, add this function outside the `impl MCPClient` block: +> +> ```rust theme={null} +> fn convert_tools(tools: &[McpTool]) -> Vec { +> tools +> .iter() +> .map(|tool| ToolDefinition { +> name: tool.name.to_string(), +> description: tool.description.as_deref().map(str::to_string), +> input_schema: Value::Object(tool.input_schema.as_ref().clone()), +> }) +> .collect() +> } +> ``` +> +> MCP and the Messages API describe tools with the same information in different Rust types. `convert_tools` copies each MCP tool's name, description, and input schema into a `ToolDefinition`, which serializes to the shape the `tools` parameter expects. The description is omitted when a tool has none. > > ### Verify the Complete File > > Before running the client, confirm the items in `src/main.rs` are placed at the correct scope: > -> * `new`, `connect_to_server`, `process_query`, `request_model`, `chat_loop`, and `cleanup` are methods inside the single `impl MCPClient` block. -> * `main` and `convert_tools` are functions outside the `impl MCPClient` block. +> * `new`, `validate_tool_output`, `connect_to_server`, `process_query`, `request_model`, `chat_loop`, and `cleanup` are methods inside the single `impl MCPClient` block, which opens in Client Initialization and closes after `cleanup`. +> * `user` and `assistant` are methods inside the `impl Message` block. +> * `block_type`, `main`, and `convert_tools` are functions outside both `impl` blocks. > > Rust does not require these items to appear in a particular order, but methods and free functions must be placed in the correct scope. Compare your file with the [complete `src/main.rs` example](https://github.com/modelcontextprotocol/quickstart-resources/blob/main/mcp-client-rust/src/main.rs), then check that it compiles: > @@ -2426,37 +2693,49 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > The client will: > > 1. Start and connect to the specified MCP server -> 2. List the tools available from that server +> 2. Print the negotiated protocol version and the tools available from that server > 3. Start an interactive chat session where you can: > * Enter queries > * See tool executions > * Get responses from Claude > +> Connecting to the weather server prints a line like: +> +> ```text theme={null} +> Connected over protocol 2026-07-28 with tools: ["get_alerts", "get_forecast"] +> ``` +> +> Without an `ANTHROPIC_API_KEY`, the client stops after this line and prints how to set the key. +> > ## How It Works > -> When you submit a query: +> When the user submits a query: > -> 1. The client sends your query and the server's available tools to Claude +> 1. The client sends the query and the server's tool definitions to Claude > 2. Claude decides which tools, if any, to use -> 3. The client executes requested tools through the MCP session -> 4. Tool results are sent back to Claude -> 5. Claude provides a natural language response -> 6. The response is displayed in the terminal +> 3. The client executes every requested tool through the MCP session and validates structured results against their output schemas +> 4. Tool results, including failures marked with `is_error`, are sent back to Claude together with Claude's own blocks, unchanged +> 5. Steps 2 through 4 repeat until Claude answers without a tool call or `MAX_TOOL_TURNS` is reached +> 6. The collected text is displayed in the terminal > > ## Best Practices > > 1. **Error Handling** -> * Add context to errors at process, MCP, model API, and serialization boundaries +> * Add context to errors at process, MCP, and model API boundaries +> * Send a rejected tool call back to Claude as a `tool_result` with `is_error` set, so every `tool_use` gets an answer > * Report individual query errors without terminating the interactive session -> * Validate server commands before running them -> 2. **Resource Management** +> 2. **Conversation History** +> * Feed assistant blocks back exactly as they arrived, thinking blocks and their signatures included +> * Pass the tool list on every request so Claude can keep calling tools across turns +> * Cap the number of tool turns per query +> 3. **Resource Management** > * Always cancel the MCP session during cleanup > * Ensure cleanup runs even when connection or chat-loop operations fail > * Avoid starting a second server while a session is active -> 3. **Security** -> * Store API keys securely in `.env` -> * Review the tools exposed by a server before allowing model-driven calls -> * Connect only to servers and executable commands you trust +> 4. **Security** +> * Store API keys securely in `.env` or the environment +> * Validate structured tool results against their declared output schemas +> * Connect only to trusted servers and executable commands > > ## Troubleshooting > @@ -2477,9 +2756,7 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > ### Environment File Issues > -> If you see `Failed to load env file`, ensure `.env` exists in the directory where you run the client. -> -> If the model request reports a missing API key, confirm that `.env` contains: +> The `.env` file is optional. When it is missing, the client reads `ANTHROPIC_API_KEY` from the environment. When the key is unset or empty, the client connects, prints the server's tools, and exits with instructions for setting the key. Export the key, or create a `.env` in the directory where the client runs that contains: > > ```text theme={null} > ANTHROPIC_API_KEY=your-api-key-goes-here @@ -2488,8 +2765,10 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > ### Tool and Response Errors > > * `Unable to list tools from server`: Verify the server starts successfully and communicates over stdio -> * `Tool call ... failed`: Verify the server tool's required arguments and environment variables -> * `Failed to serialize tool result`: Inspect the server's response for unsupported or malformed content +> * `[... failed: ...]` in the output: The server rejected the tool call. The message also goes to Claude as a failed `tool_result`, so Claude may retry with different arguments +> * `Tool ... declares an output schema but returned no structured content` or `Structured content from tool ... does not match its output schema`: The server's result does not satisfy its own `outputSchema` +> * `Anthropic request failed with ...`: The response body follows the status and names the cause, such as an invalid key or insufficient credits +> * `[Stopped after 10 tool-use turns]`: The query reached `MAX_TOOL_TURNS`. Raise the constant for workflows that need more rounds ## Next steps diff --git a/content/mcp/docs/2026-07-28/develop/build-server.md b/content/mcp/docs/2026-07-28/develop/build-server.md index 4b96c3a0d..cbf7926b7 100644 --- a/content/mcp/docs/2026-07-28/develop/build-server.md +++ b/content/mcp/docs/2026-07-28/develop/build-server.md @@ -779,6 +779,10 @@ This tutorial will primarily focus on tools. > > > [!NOTE] > > +> > This server uses MCP protocol version 2025-11-25, as supported by the latest stable release of the Java SDK. Clients that also support that version can connect to it, but clients that support only 2026-07-28 cannot. See [backward compatibility](https://modelcontextprotocol.io/specification/2026-07-28/basic/versioning.md#backward-compatibility-with-initialization-based-versions). +> +> > [!NOTE] +> > > > This is a quickstart demo based on Spring AI MCP auto-configuration and boot starters. > > To learn how to create sync and async MCP Servers, manually, consult the [Java SDK Server](https://java.sdk.modelcontextprotocol.io/) documentation. > @@ -804,7 +808,7 @@ This tutorial will primarily focus on tools. > ### System requirements > > * Java 17 or higher installed. -> * [Spring Boot 3.3.x](https://docs.spring.io/spring-boot/installing.html) or higher +> * [Spring Boot 4.1.x](https://docs.spring.io/spring-boot/installing.html) or higher > > ### Set up your environment > @@ -1016,7 +1020,7 @@ This tutorial will primarily focus on tools. > .args("-jar", "/ABSOLUTE/PATH/TO/PARENT/FOLDER/mcp-weather-stdio-server-0.0.1-SNAPSHOT.jar") > .build(); > -> var stdioTransport = new StdioClientTransport(stdioParams); +> var stdioTransport = new StdioClientTransport(stdioParams, McpJsonDefaults.getMapper()); > > var mcpClient = McpClient.sync(stdioTransport).build(); > @@ -1064,6 +1068,10 @@ This tutorial will primarily focus on tools. > [tab] Kotlin > +> > [!NOTE] +> > +> > This server uses MCP protocol version 2025-11-25, as supported by the latest stable release of the Kotlin SDK. Clients that also support that version can connect to it, but clients that support only 2026-07-28 cannot. See [backward compatibility](https://modelcontextprotocol.io/specification/2026-07-28/basic/versioning.md#backward-compatibility-with-initialization-based-versions). +> > Let's get started with building our weather server! [You can find the complete code for what we'll be building here.](https://github.com/modelcontextprotocol/kotlin-sdk/tree/main/samples/weather-stdio-server) > > ### Prerequisite knowledge @@ -1127,7 +1135,7 @@ This tutorial will primarily focus on tools. > > ```kotlin build.gradle.kts theme={null} > // Check latest versions at https://github.com/modelcontextprotocol/kotlin-sdk/releases -> val mcpVersion = "0.9.0" +> val mcpVersion = "0.16.0" > val ktorVersion = "3.2.3" > val slf4jVersion = "2.0.17" > @@ -1138,6 +1146,10 @@ This tutorial will primarily focus on tools. > application > } > +> repositories { +> mavenCentral() +> } +> > application { > mainClass.set("MainKt") > } @@ -1358,7 +1370,7 @@ This tutorial will primarily focus on tools. > > ```bash theme={null} > ./gradlew build -> java -jar build/libs/weather-0.1.0-all.jar +> java -jar build/libs/weather-all.jar > ``` > > Let's now test your server from an existing MCP host, Claude for Desktop. @@ -1398,7 +1410,7 @@ This tutorial will primarily focus on tools. > "command": "java", > "args": [ > "-jar", -> "/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-0.1.0-all.jar" +> "/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-all.jar" > ] > } > } @@ -1412,7 +1424,7 @@ This tutorial will primarily focus on tools. > "command": "java", > "args": [ > "-jar", -> "C:\\PATH\\TO\\PARENT\\FOLDER\\weather\\build\\libs\\weather-0.1.0-all.jar" +> "C:\\PATH\\TO\\PARENT\\FOLDER\\weather\\build\\libs\\weather-all.jar" > ] > } > } @@ -1422,7 +1434,7 @@ This tutorial will primarily focus on tools. > This tells Claude for Desktop: > > 1. There's an MCP server named "weather" -> 2. Launch it by running `java -jar /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-0.1.0-all.jar` +> 2. Launch it by running `java -jar /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-all.jar` > > Save the file, and restart **Claude for Desktop**. diff --git a/content/mcp/docs/2026-07-28/learn/client-concepts.md b/content/mcp/docs/2026-07-28/learn/client-concepts.md index b63e9168d..9b47441c7 100644 --- a/content/mcp/docs/2026-07-28/learn/client-concepts.md +++ b/content/mcp/docs/2026-07-28/learn/client-concepts.md @@ -238,7 +238,7 @@ The flow ensures security through multiple human-in-the-loop checkpoints. Users ], modelPreferences: { hints: [{ - name: "claude-sonnet-4-20250514" // Suggested model + name: "claude-sonnet" // Prefer Sonnet-class models }], costPriority: 0.3, // Less concerned about API cost speedPriority: 0.2, // Can wait for thorough analysis diff --git a/content/mcp/docs/2026-07-28/sdk.md b/content/mcp/docs/2026-07-28/sdk.md index c87a5c785..3dfe52768 100644 --- a/content/mcp/docs/2026-07-28/sdk.md +++ b/content/mcp/docs/2026-07-28/sdk.md @@ -27,7 +27,7 @@ See [SDK Tiering System](https://modelcontextprotocol.io/community/sdk-tiers.md) ## Getting Started -Each SDK provides the same functionality but follows the idioms and best practices of its language. All SDKs support: +Each SDK follows the idioms and best practices of its language. SDKs adopt new protocol revisions on their own schedules, so check each SDK's documentation for the revisions it supports. All SDKs support: * Creating MCP servers that expose tools, resources, and prompts * Building MCP clients that can connect to any MCP server diff --git a/content/mcp/docs/2026-07-28/tools/debugging.md b/content/mcp/docs/2026-07-28/tools/debugging.md index aa8b7f690..bb8d402d9 100644 --- a/content/mcp/docs/2026-07-28/tools/debugging.md +++ b/content/mcp/docs/2026-07-28/tools/debugging.md @@ -221,11 +221,16 @@ Log files are written to: * macOS: `~/Library/Logs/Claude` * Windows: `%APPDATA%\Claude\logs` +* Linux: `~/.config/Claude/logs` ```bash macOS theme={null} tail -n 20 -F ~/Library/Logs/Claude/mcp*.log ``` +```bash Linux theme={null} +tail -n 20 -F ~/.config/Claude/logs/mcp*.log +``` + ```powershell Windows theme={null} type "$env:AppData\Claude\logs\mcp*.log" ``` diff --git a/content/mcp/docs/2026-07-28/tools/inspector/cli.md b/content/mcp/docs/2026-07-28/tools/inspector/cli.md index a1a6f5d95..7604188b8 100644 --- a/content/mcp/docs/2026-07-28/tools/inspector/cli.md +++ b/content/mcp/docs/2026-07-28/tools/inspector/cli.md @@ -43,9 +43,9 @@ Later examples abbreviate whichever of these forms you use, along with its `--tr > [!NOTE] > > **The config file is the only durable way to give a run its -> [roots](https://modelcontextprotocol.io/specification/draft/client/roots.md):** there is no roots flag, and the -> CLI has no `roots/set` method. Roots configured for a server are advertised at -> connect, so a server that calls `roots/list` (as +> [roots](https://modelcontextprotocol.io/specification/2026-07-28/client/roots.md):** there is no roots flag, and +> the CLI has no `roots/set` method. Roots configured for a server are +> advertised at connect, so a server that calls `roots/list` (as > `@modelcontextprotocol/server-filesystem` does, to learn its allowed > directories) gets them. @@ -138,6 +138,8 @@ Every non-zero exit maps to a stable failure class, so a caller can branch on *w | `7` | `--verify` found a skill that violates SEP-2640 (conformance, digest, or size mismatch). | | `8` | `--verify` couldn't check every skill within its read bounds. | | `9` | `--verify --require-digests` found a skill that advertises no digests. | +| `10` | A `--load` run breached a `--load-max-error-rate` or `--load-max-p99` threshold. The summary is printed first, and the envelope `code` names the threshold: `load_error_rate_exceeded` or `load_p99_exceeded`. | +| `11` | The server answered HTTP 429 (envelope `code` `rate_limited`). The envelope also carries `method`, plus `retryAfter` (the `Retry-After` header as sent) and `retryAfterMs` when the server sent one that parses. | On any non-zero exit the CLI also writes a **single JSON line to stderr**: @@ -152,7 +154,7 @@ On any non-zero exit the CLI also writes a **single JSON line to stderr**: } ``` -The envelope carries `code` and `message` always, plus `cause` (the underlying error, such as a DNS failure), `status` (the HTTP status) and `url` when known. Query-string secrets in a URL are redacted. `code` is a stable name for the failure: `auth_required`, `unreachable`, `tool_not_found`, `tool_is_error`, `no_app`, `schema_unportable`, `store_unavailable`, `oauth_state_unrecognized`, or the catch-all `error`, among others. +The envelope carries `code` and `message` always, plus `cause` (the underlying error, such as a DNS failure), `status` (the HTTP status) and `url` when known. Query-string secrets in a URL are redacted. `code` is a stable name for the failure: `auth_required`, `unreachable`, `tool_not_found`, `tool_is_error`, `no_app`, `schema_unportable`, `store_unavailable`, `oauth_state_unrecognized`, `rate_limited`, or the catch-all `error`, among others. Because it's one line, a caller can parse it with `2>&1 | tail -1 | jq .error`. @@ -184,15 +186,17 @@ mcp-inspector --cli --config ./ci-servers.json --server my-server \ ### CI gates -Three flags turn a check into a non-zero exit, each with its own code so a job can tell the failures apart: +These flags turn a check into a non-zero exit, each with its own code so a job can tell the failures apart: * `--strict` (with `tools/list`): reports tool-schema portability problems in full on stderr (path, issue, suggested fix) and exits `6` if any is error-severity. Without it, `tools/list` prints only a one-line count. Under `--format json` the findings are folded into the output as `schemaFindings`. * `--verify` (with `skills/list` or `skills/get`): runs the SEP-2640 conformance and digest checks, writes one JSON report per skill on stdout, and exits `7` on a violation or `8` when the read bounds stopped it before every skill was checked. `--skill-catalog-max-skills` and `--skill-catalog-max-bytes` set those bounds. * `--require-digests` (with `--verify`): exits `9` for a skill that advertises no digests, instead of reporting it as unverifiable and exiting `0`. +* `--load-max-error-rate ` and `--load-max-p99 ` (with `--load`): turn a load run into a gate. The run prints its summary, then exits `10` when the share of failed calls is above the fraction (`0` to `1`, so `0` fails on any failed call), when the p99 latency is above the given milliseconds, or when no call completed. `--load` (with `tools/call --tool-name`) calls the tool repeatedly and concurrently and prints a latency and error-rate summary instead of a result, bounded by `--load-duration ` (default `10` when `--load-requests` is not set) and `--load-requests `, with in-flight calls still finishing. `--load-concurrency ` (default `10`) caps the calls in flight, `--load-connections ` (default `1`, at most `--load-concurrency`, HTTP and SSE servers only) spreads them over independent sessions opened before timing starts, and `--load-rate ` (default unlimited) caps the calls started per second. ```bash theme={null} mcp-inspector --cli --method tools/list --strict > /dev/null mcp-inspector --cli --method skills/list --verify --require-digests +mcp-inspector --cli --method tools/call --tool-name get_weather --load --load-requests 200 --load-max-p99 500 ``` ### Branch on the failure class diff --git a/content/mcp/docs/2026-07-28/tools/inspector/configuration.md b/content/mcp/docs/2026-07-28/tools/inspector/configuration.md index 80d38378a..eb3a707aa 100644 --- a/content/mcp/docs/2026-07-28/tools/inspector/configuration.md +++ b/content/mcp/docs/2026-07-28/tools/inspector/configuration.md @@ -14,6 +14,7 @@ The `mcp-inspector` binary is a launcher: it reads two flags of its own and forw | - | - | | `--web` / `--cli` / `--tui` | Selects the client, `--web` by default. Passing more than one fails with `Specify at most one of --web, --cli, or --tui.` Launcher flags must come first: parsing stops at the first argument the launcher does not own, and everything from that point on is forwarded to the client unchanged. | | `-h` / `--help` | With no mode flag, prints the launcher's own help and exits. With a mode flag it is forwarded, so `mcp-inspector --cli --help` prints the CLI's help. | +| `-V` / `--version` | Listed in the launcher's help, but the launcher does not act on it. The flag is forwarded to the selected client, which prints the Inspector version, so `mcp-inspector -V` prints it through the web client and `mcp-inspector --cli -V` through the CLI. | Everything below belongs to a client. @@ -143,6 +144,7 @@ The whole scripting surface belongs to the CLI. See [CLI client](https://modelco | - | - | | **What to invoke** | `--method`, `--tool-name`, `--tool-arg`, `--tool-args-json`, `--uri`, `--cursor`, `--prompt-name`, `--prompt-args`, `--log-level`, `--metadata`, `--tool-metadata`, `--rename` | | **How to run it** | `--connect-timeout`, `--format`, `-q` / `--quiet`, `--output`, `--output-format`, `--app-info`, `--advertise-apps`, `--strict`, `--verify`, `--require-digests`, `--completion ` (`bash`, `zsh`, or `fish`) | +| **Load test** | `--load`, `--load-concurrency`, `--load-connections`, `--load-duration`, `--load-requests`, `--load-rate`, `--load-max-error-rate`, `--load-max-p99` (see [CI gates](https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/cli.md#ci-gates)) | | **Auth** | `--use-stored-auth`, `--stored-auth-only`, `--relogin`, `--no-revoke`, `--wait-for-auth`, `--list-stored-auth`, `--print-handoff` | ## Environment variables @@ -156,18 +158,23 @@ Environment variables split the same way as flags: two are read by the launcher | `MCP_DEBUG` | Append the error stack to a top-level `--web` or `--tui` failure (a `--cli` failure always prints its [JSON error envelope](https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/cli.md#exit-codes-and-error-envelopes) instead). Only when set to a meaningful value: `0`, `false`, and empty read as off. | | `DEBUG` | Same, with the same meaningful-value rule, so a stray `DEBUG=0` doesn't turn stack traces on and `DEBUG` still works as the npm `debug` package's namespace filter. | +The TUI reads both variables itself, with the same rule, for its own top-level failure. + ### CLI and TUI -Some of these are read by the web backend too, as the **Read by** column shows. +Some of these are read by the web backend or by `mcpdo` too, as the **Read by** column shows. | Variable | Read by | Effect | | - | - | - | -| `MCP_CATALOG_PATH` | Web, CLI, TUI | Fallback for `--catalog`. The CLI honors it only when no ad-hoc target is given, so a shell that exports it can still run one-off ad-hoc invocations. The web client and TUI apply it regardless, so combining it with an ad-hoc target is rejected there. | -| `MCP_CLIENT_CONFIG_PATH` | CLI, TUI | Fallback for `--client-config`. | -| `MCP_OAUTH_CALLBACK_URL` | CLI, TUI | Fallback for `--callback-url`. | -| `MCP_STORAGE_DIR` | Web, CLI, TUI | Storage directory. Relocates the OAuth state file (`/oauth.json`) and the secrets file (`/secrets.json`). | -| `MCP_INSPECTOR_OAUTH_STATE_PATH` | CLI, TUI | Per-file override of the OAuth state path. Takes precedence over `MCP_STORAGE_DIR`. | -| `MCP_AUTO_OPEN_ENABLED` | Web, CLI | Controls browser auto-open. `false` never opens one. In the CLI, `true` forces auto-open and lets interactive OAuth run without a TTY, and unset opens only on a TTY. In the web client, unset opens the UI at launch. The TUI does not read it. | +| `MCP_CATALOG_PATH` | Web, CLI, TUI, mcpdo | Fallback for `--catalog`. The CLI honors it only when no ad-hoc target is given, so a shell that exports it can still run one-off ad-hoc invocations. The web client and TUI apply it regardless, so combining it with an ad-hoc target is rejected there. | +| `MCP_CLIENT_CONFIG_PATH` | CLI, TUI, mcpdo | Fallback for `--client-config`. | +| `MCP_OAUTH_CALLBACK_URL` | CLI, TUI, mcpdo | Fallback for `--callback-url`. | +| `MCP_STORAGE_DIR` | Web, CLI, TUI, mcpdo | Storage directory. Relocates the OAuth state file (`/oauth.json`) and the secrets file (`/secrets.json`). | +| `MCP_INSPECTOR_OAUTH_STATE_PATH` | CLI, TUI, mcpdo | Per-file override of the OAuth state path. Takes precedence over `MCP_STORAGE_DIR`. | +| `MCP_AUTO_OPEN_ENABLED` | Web, CLI, mcpdo | Controls browser auto-open. `false` never opens one. In the CLI, `true` forces auto-open and lets interactive OAuth run without a TTY, and unset opens only on a TTY. In the web client, unset opens the UI at launch. The TUI does not read it. | +| `MCP_INSPECTOR_LOG_DIR` | TUI | Directory of the TUI's `auth.log`. Defaults to `~/.mcp-inspector`. | +| `LOG_LEVEL` | TUI | Level of that log, as a pino level name. Defaults to `info`. | +| `NO_COLOR` | CLI, mcpdo | Any non-empty value disables ANSI styling in human-readable output: all of mcpdo's `--format text` output (the same as `--plain`), and the sign-in prompt the CLI writes to stderr. | ### Web backend environment variables @@ -179,6 +186,7 @@ Some of these are read by the web backend too, as the **Read by** column shows. | `CLIENT_PORT` | Web UI port. Defaults to `6274`. | | `DANGEROUSLY_BIND_ALL_INTERFACES` | Required opt-in to bind a wildcard host (`0.0.0.0`, `::`, or any equivalent spelling). | | `ALLOWED_ORIGINS` | Comma-separated origin allow-list. **Replaces** the default list rather than merging. | +| `MCP_INSPECTOR_ALLOWED_HOSTS` | Comma-separated extra hostnames accepted in the `Host` header, for a reverse proxy that rewrites `Host`. `localhost` and `*.localhost`, IPv4 and bracketed IPv6 literals, the bind host (unless it is a wildcard), and the hostname of every `ALLOWED_ORIGINS` entry are always accepted. An entry starting with `.` (`.example.com`) admits that domain and its subdomains. An entry with a scheme, port, path, wildcard, or whitespace is dropped with a warning. The port is not compared. Any other `Host` gets a `403`. | | `MCP_PROXY_AUTH_TOKEN` | Deprecated v1 name for `MCP_INSPECTOR_API_TOKEN`, used only when the new name is unset. | | `MCP_SANDBOX_PORT` | MCP Apps sandbox port. Defaults to `6275`; `0` asks the OS for a free port. | | `SERVER_PORT` | v1's proxy port, now only a fallback for the sandbox port when `MCP_SANDBOX_PORT` is unset or invalid. | @@ -186,6 +194,8 @@ Some of these are read by the web backend too, as the **Read by** column shows. | `MCP_SANDBOX_FULL_ADDRESS` | Public URL of the MCP Apps sandbox proxy, for running behind a reverse proxy. | | `MCP_APP_ORIGIN_FULL_ADDRESS` | Public origin that `_meta.ui.domain` app documents are served from, for running behind a reverse proxy. | | `MCP_LOG_FILE` | Append the backend's structured (JSON lines) log to this file. | +| `INSPECTOR_TLS_KEY_PATH` | PEM private key for the web UI listener. Set together with `INSPECTOR_TLS_CERT_PATH` to serve the UI over `https`. Setting one without the other, an unreadable file, or a key and certificate that are not a usable pair is a startup error. The listener does not fall back to `http`. A blank value counts as unset. Only the UI listener is covered. The sandbox and app-origin listeners stay `http`. The CLI's `--print-handoff` emits an `https://` deep link when both are set. | +| `INSPECTOR_TLS_CERT_PATH` | PEM certificate (or chain) for the key in `INSPECTOR_TLS_KEY_PATH`. | | `MCP_AUTO_OPEN_ENABLED` | `false` stops the browser from opening at launch. See [CLI and TUI](#cli-and-tui). | | `MCP_CATALOG_PATH`, `MCP_STORAGE_DIR` | As described under [CLI and TUI](#cli-and-tui). | | `HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY` | Standard proxy routing for outbound MCP connections. | @@ -296,6 +306,38 @@ A catalog or config file is the familiar MCP client config shape (a `mcpServers` } ``` -Fields that equal their default are omitted when the Inspector writes the file back, keeping diffs minimal. `protocolEra` (see [Protocol eras](https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/protocol-eras.md)) defaults to `legacy` and `modernLogLevel` to `debug`. +Fields that equal their default are omitted when the Inspector writes the file back, keeping diffs minimal. `protocolEra` (see [Protocol eras](https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/protocol-eras.md)) defaults to `legacy` and `modernLogLevel` to `debug`. `"type": "http"` is accepted as an alias of `"streamable-http"` and written back in the long form. + +The Inspector-specific fields and their defaults: + +| Field | Default | Meaning | +| - | - | - | +| `headers` | | HTTP headers for an SSE or Streamable HTTP server, as a flat object. | +| `metadata` | | Default `_meta` object merged into every outgoing request. Values may be any JSON. | +| `protocolEra` | `legacy` | `legacy`, `auto`, or `modern`. See [Protocol eras](https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/protocol-eras.md). | +| `elicitCapability` | `both` | Elicitation capability advertised to the server: `off`, `url`, `form`, or `both`. Read by `mcpdo` only. | +| `modernLogLevel` | `debug` | Per-request log level stamped on modern connections, or `off`. Legacy connections ignore it. | +| `connectionTimeout` | `30000` | Connect-time timeout in ms. `0` disables it. | +| `requestTimeout` | | Per-request timeout in ms. | +| `taskTtl` | `60000` | TTL in ms for tasks created with **Run as task**. | +| `autoRefreshOnListChanged` | `false` | Refresh the tools, resources, and prompts lists on `list_changed` instead of only flagging the indicator. | +| `paginatedLists` | `false` | Fetch the lists one page at a time instead of aggregating every page on load. | +| `suppressNotificationStream` | `false` | Legacy-era Streamable HTTP only: do not open the standalone `GET` notification stream. | +| `advertisedExtensions` | | Per-extension overrides of which extensions the Inspector advertises, keyed by extension id. | +| `maxFetchRequests` | `1000` | HTTP requests kept in the Network log for this server. `0` means unlimited. | +| `skillCatalogMaxSkills` | `256` | Most skills read in one skills verification run. A positive integer. | +| `skillCatalogMaxBytes` | `67108864` | Most bytes read across all skills in one skills verification run (64 MiB). A positive integer. | +| `roots` | | Roots advertised through the `roots` capability, each `{ "uri", "name" }`. | +| `oauth.clientId` | | OAuth client ID for a static client. | +| `oauth.clientSecret` | | OAuth client secret for a confidential client. | +| `oauth.scopes` | | Scopes to request, as one string. | +| `oauth.enterpriseManaged` | | `true` connects through the enterprise IdP (EMA) instead of standard OAuth. | +| `oauth.onInsufficientScope` | `reauthorize` | Step-up policy for `403 insufficient_scope`: `reauthorize` or `throw`. | +| `oauth.requestRefreshToken` | `true` | Whether the client declares the `refresh_token` grant when it registers. Only `false` is written. | +| `oauth.scopeOnRefresh` | `false` | Whether a refresh-token request carries `scope`. Only `true` is written. | +| `oauth.revokeOnClear` | `true` | Whether clearing this server's OAuth state also revokes the grant at the authorization server (RFC 7009). Only `false` is written. | +| `oauth.authorizationParams` | | Extra query parameters for the authorization request. Reserved keys are dropped with a warning. | +| `oauth.authorizationUrl` | | Overrides the `authorization_endpoint` the authorization server's metadata advertises. | +| `oauth.tokenUrl` | | Overrides the `token_endpoint` the authorization server's metadata advertises. | You do not have to hand-write these; the web client can [import an existing client config](https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/recipes.md#importing-an-existing-client-config) from Claude Desktop, Cursor, Cline, or VS Code, or a registry `server.json`. diff --git a/content/mcp/docs/2026-07-28/tools/inspector/mcpdo.md b/content/mcp/docs/2026-07-28/tools/inspector/mcpdo.md index 4d77aa75e..519fe645b 100644 --- a/content/mcp/docs/2026-07-28/tools/inspector/mcpdo.md +++ b/content/mcp/docs/2026-07-28/tools/inspector/mcpdo.md @@ -76,16 +76,20 @@ mcpdo --conn my-server tools/list Omitting the name falls back to the most recently used connection, but only on an interactive TTY. From a script or an agent, where stdin is not a TTY, an unqualified command is an error, so that a background job never acts on whichever server you last used. Set `MCP_ALLOW_DEFAULT_CONNECTION=1` to allow the fallback anyway. +`mcpdo connections/use ` sets the most recently used connection without sending anything to the server. + Connections **self-heal**: a dropped transport (an expired HTTP session, an exited stdio child) is re-dialed transparently on next use with the stored credentials. Only an `auth_required` error needs you to run `connect` again. A connection runs **one call at a time**. Commands against it from other shells queue behind the call in flight, and while a call is parked on an [elicitation](#elicitation), new calls on that connection are refused until it is answered. A long call does not block other connections. +`tools/call` also accepts the one-shot CLI's `--load` family (`--load`, `--load-concurrency`, `--load-connections`, `--load-duration`, `--load-requests`, `--load-rate`, `--load-max-error-rate`, `--load-max-p99`), with the same defaults and the same summary, run inside the daemon against the connection (see [CI gates](https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/cli.md#ci-gates)). `--load-connections` opens its extra sessions with stored credentials only. Later commands on the connection wait until the run ends. + ## Tasks -A tool that requires task support is refused by a plain `tools/call`; add `--task` to make a task-augmented call. It still **blocks** until the task finishes, then prints the final result: +On a legacy connection, a plain `tools/call` refuses a tool that requires task support. Add `--task` to make a task-augmented call. `--task` applies to legacy servers only. On a modern connection the server decides per request whether to return a task, and the flag changes nothing on the wire. The call still **blocks** until the task finishes, then prints the final result: ```bash theme={null} -mcpdo @my-server tools/call --task start_job size:=large +mcpdo @my-server tools/call --task start_job size:=large # task-augmented call on a legacy connection ``` If the task reaches `input_required`, its question is handled like any other [elicitation](#elicitation). @@ -111,7 +115,7 @@ Terminal-bound text (results, elicitation prompts, daemon errors) has control ch | `mcpdo disconnect --clear-auth` (`-c`) | Close the connection **and** clear its stored tokens, so the next `connect` signs in fresh. | | `mcpdo auth/list` | Stored credentials, each annotated with the catalog or connection names it is "known as", and `● live` when an open connection holds it. | | `mcpdo auth/clear ` | Clear one stored credential, by store URL or friendly name. `--all --yes` clears every one. | -| `mcpdo auth/ema-login` / `auth/ema-status` / `auth/ema-logout` | Enterprise-managed authorization: sign in to the IdP once, then connect to EMA servers silently. | +| `mcpdo auth/ema-login` / `auth/ema-status` / `auth/ema-logout` | Enterprise-managed authorization: sign in to the IdP once, then connect to EMA servers silently. `mcpdo connect --ema` treats a catalog entry as enterprise-managed for that connect, overriding its `oauth.enterpriseManaged`. It needs the entry's OAuth client ID and secret, so it cannot be used with an ad-hoc target. | When a browser sign-in is needed and neither stdin nor stderr is a TTY (and `MCP_AUTO_OPEN_ENABLED` is not forced on), `connect` exits `0` immediately with `pendingAuth: true` and an `authUrl`. Relay that URL to whoever will sign in. The connection completes on its own once they do: the next real command against it finishes the connection, and `connections/list` reports `pendingAuthSignedIn` in the meantime. Don't reconnect to fix a pending sign-in. @@ -173,4 +177,4 @@ Adjust the network and mount flags to what the server needs. HTTP and SSE server ## Using mcpdo from a coding agent -The package ships an agent skill that teaches an agent to drive `mcpdo`: connections it holds then extend the agent's toolset, and it knows to relay sign-in URLs and answer parked elicitations. `mcpdo agent-help` prints the guide, `mcpdo agent-help --skill-path` prints the path of the installable skill file, and `mcpdo agent-help --instructions` prints a block to append to a project's `CLAUDE.md` or `AGENTS.md`. +The package ships an agent skill that teaches an agent to drive `mcpdo`: connections it holds then extend the agent's toolset, and it knows to relay sign-in URLs and answer parked elicitations. `mcpdo agent-help` prints the guide, `mcpdo agent-help --skill-path` prints the path of the installable skill file, and `mcpdo agent-help --instructions` prints a block to append to a project's `CLAUDE.md` or `AGENTS.md`. The skill can also be installed with `npx skills add modelcontextprotocol/inspector --skill mcpdo`. diff --git a/content/mcp/docs/2026-07-28/tools/inspector/protocol-eras.md b/content/mcp/docs/2026-07-28/tools/inspector/protocol-eras.md index d7c0df00c..962fbcf0a 100644 --- a/content/mcp/docs/2026-07-28/tools/inspector/protocol-eras.md +++ b/content/mcp/docs/2026-07-28/tools/inspector/protocol-eras.md @@ -121,9 +121,9 @@ Tasks change the most between protocol eras, including *how the Inspector UI tab > > Tasks are an **extension** (`io.modelcontextprotocol/tasks`, [SEP-2663](https://modelcontextprotocol.io/seps/2663-tasks-extension.md)), so the tab is gated on the server *advertising that extension* rather than on `capabilities.tasks`. > -> Run a tool as a task and `tools/call` returns a `CreateTaskResult` (`resultType: "task"`, visible in the Protocol and Network tabs). The Inspector polls **`tasks/get`** only; there is no `tasks/list`, so **Refresh** re-polls the handles the client already knows about. A completed task **inlines its result**, with no blocking `tasks/result` call. +> There is no **Run as task** control on a modern connection. Task creation is server-directed, so the server decides per request whether `tools/call` returns a `CreateTaskResult` (`resultType: "task"`, visible in the Protocol and Network tabs). The Inspector polls **`tasks/get`** only; there is no `tasks/list`, so **Refresh** re-polls the handles the client already knows about. A completed task **inlines its result**, with no blocking `tasks/result` call. > -> A task that needs more information moves to `input_required` and surfaces an embedded [elicitation](https://modelcontextprotocol.io/specification/draft/client/elicitation.md) in the pending-request modal (the dialog the web client opens whenever a request is waiting on you). Answering it sends **`tasks/update`** carrying the `inputResponses`, and the next poll completes. +> A task that needs more information moves to `input_required` and surfaces an embedded [elicitation](https://modelcontextprotocol.io/specification/2026-07-28/client/elicitation.md) in the pending-request modal (the dialog the web client opens whenever a request is waiting on you). Answering it sends **`tasks/update`** carrying the `inputResponses`, and the next poll completes. > > Reproduce with `test-servers/configs/tasks-modern-http.json` (tools `modern_task` and `modern_input_task`). @@ -139,7 +139,7 @@ Modern: the client polls tasks/get on handles it already holds, and the complete ## Multi-round tool results (MRTR) -On the modern era a tool can return `input_required` instead of a final result, embedding an [elicitation](https://modelcontextprotocol.io/specification/draft/client/elicitation.md), a [sampling](https://modelcontextprotocol.io/specification/draft/client/sampling.md) request, or a [`roots/list`](https://modelcontextprotocol.io/specification/draft/client/roots) request. The client answers that embedded request and retries the `tools/call` under a fresh JSON-RPC id until the call reaches `complete`. +On the modern era a tool can return `input_required` instead of a final result, embedding an [elicitation](https://modelcontextprotocol.io/specification/2026-07-28/client/elicitation.md), a [sampling](https://modelcontextprotocol.io/specification/2026-07-28/client/sampling.md) request, or a [`roots/list`](https://modelcontextprotocol.io/specification/2026-07-28/client/roots) request. The client answers that embedded request and retries the `tools/call` under a fresh JSON-RPC id until the call reaches `complete`. The Inspector drives MRTR **manually**, so each round pauses at the **pending-request modal**, tagged `input_required`, for you to answer. The Protocol view groups the whole exchange as one MRTR conversation rather than as unrelated calls. diff --git a/content/mcp/docs/2026-07-28/tools/inspector/recipes.md b/content/mcp/docs/2026-07-28/tools/inspector/recipes.md index 384a67414..03116b017 100644 --- a/content/mcp/docs/2026-07-28/tools/inspector/recipes.md +++ b/content/mcp/docs/2026-07-28/tools/inspector/recipes.md @@ -246,7 +246,7 @@ The Inspector refuses to bind the **wildcard** all-interfaces addresses (`0.0.0. | Goal | What to do | | - | - | | **Reach it from another machine on the LAN** | `HOST=192.168.1.50`. The default origin allow-list follows the bind host, so `http://192.168.1.50:6274` is accepted with no further config. | -| **Behind TLS or a reverse proxy** | The browser's `Origin` becomes the public origin, which won't match the bind host. Set `ALLOWED_ORIGINS=https://inspector.example.com`, and for MCP Apps set `MCP_SANDBOX_FULL_ADDRESS` (see below). | +| **Behind TLS or a reverse proxy** | The browser's `Origin` becomes the public origin, which won't match the bind host. Set `ALLOWED_ORIGINS=https://inspector.example.com`, and for MCP Apps set `MCP_SANDBOX_FULL_ADDRESS` (see below). If the proxy rewrites `Host` to a name that is not in `ALLOWED_ORIGINS`, also set `MCP_INSPECTOR_ALLOWED_HOSTS=inspector.example.com` (or `.example.com` for a domain and its subdomains), or the backend answers `403`. Without a proxy, `INSPECTOR_TLS_KEY_PATH` and `INSPECTOR_TLS_CERT_PATH` serve the UI itself over `https`. | | **Wildcard bind (containers)** | Set `DANGEROUSLY_BIND_ALL_INTERFACES=true`. Loopback access still works out of the box; reaching it at a non-loopback address needs `ALLOWED_ORIGINS`. | > [!WARNING] @@ -273,7 +273,7 @@ When an exploration spans many calls (a multi-step flow over one session, a log ```bash theme={null} mcpdo connect my-server -mcpdo @my-server tools/call --task start_job size:=large # task-augmented; blocks until the task finishes +mcpdo @my-server tools/call --task start_job size:=large # task-augmented on a legacy connection, blocks until the task finishes mcpdo @my-server tools/call get_job_report mcpdo @my-server logging/tail # long-lived; Ctrl-C to stop mcpdo disconnect my-server diff --git a/content/mcp/docs/2026-07-28/tools/inspector/security.md b/content/mcp/docs/2026-07-28/tools/inspector/security.md index 907db9bb2..e7b93e3dd 100644 --- a/content/mcp/docs/2026-07-28/tools/inspector/security.md +++ b/content/mcp/docs/2026-07-28/tools/inspector/security.md @@ -21,7 +21,7 @@ The web client is a browser app backed by a Node server that owns the MCP connec What the token does and does not protect: -* **The token is the real guard for non-browser clients.** The origin allow-list (`ALLOWED_ORIGINS`) stops other web pages from driving the backend, but a request that arrives with **no** `Origin` header (curl, a script, any non-browser client) skips that check entirely. +* **The token is the real guard for non-browser clients.** The origin allow-list (`ALLOWED_ORIGINS`) stops other web pages from driving the backend, but a request that arrives with **no** `Origin` header (curl, a script, any non-browser client) skips that check entirely. A `Host` header allow-list runs ahead of every route, including `GET /`, and answers `403` to a request whose `Host` is not a loopback name, an IP literal, the bind host, an `ALLOWED_ORIGINS` hostname, or an entry of `MCP_INSPECTOR_ALLOWED_HOSTS`, so a DNS-rebinding page cannot load the page and read the token (see [Host binding and origins](https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/web.md#host-binding-and-origins)). * **`GET /` discloses the token.** The backend injects it into the served HTML so that a reload or a bookmark keeps working. Anyone who can load the page can therefore read the token, which is why the bind address matters more than the token's value. Pinning your own `MCP_INSPECTOR_API_TOKEN` does not change this, since a custom token is disclosed exactly like a generated one. * **`DANGEROUSLY_OMIT_AUTH=true` removes the guard completely.** Anything that can reach the port can then spawn processes as you and use any OAuth token the Inspector holds. Only `true` or `1` turns auth off; any other value, including `false`, keeps it on. * **Only `/api/*` is gated.** The page itself, its static assets and `GET /healthz` are served without the token. `/healthz` returns only `{"status":"ok"}`, for container and orchestrator probes. diff --git a/content/mcp/docs/2026-07-28/tools/inspector/web.md b/content/mcp/docs/2026-07-28/tools/inspector/web.md index 1e8d0bd3e..ef4f76478 100644 --- a/content/mcp/docs/2026-07-28/tools/inspector/web.md +++ b/content/mcp/docs/2026-07-28/tools/inspector/web.md @@ -129,7 +129,7 @@ A prompt rendered with the arguments supplied. * The sandbox listens on its own port, `6275` by default (set it with `MCP_SANDBOX_PORT`). An app whose UI resource declares `_meta.ui.domain` has its document served from a third listener, the app origin, on `6278` by default (`MCP_APP_ORIGIN_PORT`). Expose or forward both along with the web port. * The sandbox is gated by a `frame-ancestors` CSP, and a bracketed IPv6 literal is not a valid CSP host-source, so browse the Inspector at `localhost`, `127.0.0.1`, a hostname, or a LAN IPv4, **not** at a bare `http://[::1]:...`. -* By default the sandbox URL is plain `http` on the bind address, so an `https://` Inspector page blocks the frame as mixed content. Behind a TLS reverse proxy, set `MCP_SANDBOX_FULL_ADDRESS` (and `MCP_APP_ORIGIN_FULL_ADDRESS`) to the public `https://` address the browser reaches each listener at. Neither may share an origin with the Inspector UI; a value that does is ignored with a warning. +* By default the sandbox URL is plain `http` on the bind address, so an `https://` Inspector page blocks the frame as mixed content. That applies whether the page is `https` through a proxy or through `INSPECTOR_TLS_KEY_PATH` and `INSPECTOR_TLS_CERT_PATH`, which cover the UI listener only. Behind a TLS reverse proxy, set `MCP_SANDBOX_FULL_ADDRESS` (and `MCP_APP_ORIGIN_FULL_ADDRESS`) to the public `https://` address the browser reaches each listener at. Neither may share an origin with the Inspector UI; a value that does is ignored with a warning. See [Recipes](https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/recipes.md#reviewing-an-mcp-app) for the CLI-first automated review flow. @@ -171,6 +171,8 @@ Three further parameters land you on a *rendered app*: `openApp=` name By default the Inspector binds `127.0.0.1` and accepts requests only from the loopback origins for its port. Treat both defaults as security boundaries, since the backend spawns processes on your machine. +A `Host` header allow-list runs ahead of every route, including `GET /`. A request is answered `403` unless its `Host` is `localhost` or a `*.localhost` name, an IPv4 or bracketed IPv6 literal, the bind host, the hostname of an `ALLOWED_ORIGINS` entry, or an entry of `MCP_INSPECTOR_ALLOWED_HOSTS`. The port is not compared. A same-origin `GET /` carries no `Origin` header, so the origin allow-list never sees it, and the `Host` check is what stops a DNS-rebinding page from loading the page and reading the token out of it. + Binding all interfaces (`HOST=0.0.0.0`) is **refused** unless you set `DANGEROUSLY_BIND_ALL_INTERFACES=true`. Binding a *specific* non-loopback address is allowed with no opt-in, since that's a single deliberate exposure rather than every interface at once. See the [Hosting on a network](https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/recipes.md#hosting-on-a-network) recipe for the full matrix, and [Configuration](https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector/configuration.md#web-backend-environment-variables) for the variables. diff --git a/content/mcp/docs/draft/develop/build-client.md b/content/mcp/docs/draft/develop/build-client.md index 64b4dcfd6..ce0a0ebc8 100644 --- a/content/mcp/docs/draft/develop/build-client.md +++ b/content/mcp/docs/draft/develop/build-client.md @@ -824,6 +824,10 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > > [!NOTE] > > +> > This client uses MCP protocol version 2025-11-25, as supported by the latest stable release of the Java SDK. It connects to servers that accept that version, but not to servers that accept only 2026-07-28. See [backward compatibility](https://modelcontextprotocol.io/specification/draft/basic/versioning.md#backward-compatibility-with-initialization-based-versions). +> +> > [!NOTE] +> > > > This is a quickstart demo based on Spring AI MCP auto-configuration and boot starters. > > To learn how to create sync and async MCP Clients manually, consult the [Java SDK Client](https://java.sdk.modelcontextprotocol.io/) documentation. > @@ -854,7 +858,7 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > ```bash theme={null} > git clone https://github.com/spring-projects/spring-ai-examples.git -> cd model-context-protocol/web-search/brave-chatbot +> cd spring-ai-examples/model-context-protocol/web-search/brave-chatbot > ``` > > 3. Set up your API keys: @@ -920,7 +924,7 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > This activates the `spring-ai-starter-mcp-client` to create one or more `McpClient`s based on the provided server configuration. > The `spring.ai.mcp.client.toolcallback.enabled=true` property enables the tool callback mechanism, that automatically registers all MCP tool as spring ai tools. -> It is disabled by default. +> It is enabled by default. > > 3. MCP Server Configuration (`mcp-servers-config.json`): > @@ -945,8 +949,8 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > ```java theme={null} > var chatClient = chatClientBuilder > .defaultSystem("You are useful assistant, expert in AI and Java.") -> .defaultToolCallbacks((Object[]) mcpToolAdapter.toolCallbacks()) -> .defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory())) +> .defaultTools(SyncMcpToolCallbackProvider.builder().mcpClients(mcpSyncClients).build()) +> .defaultAdvisors(MessageChatMemoryAdvisor.builder(MessageWindowChatMemory.builder().build()).build()) > .build(); > ``` > @@ -954,7 +958,7 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > * Uses Claude AI model for natural language understanding > * Integrates Brave Search through MCP for real-time web search capabilities -> * Maintains conversation memory using InMemoryChatMemory +> * Maintains conversation memory using MessageWindowChatMemory > * Runs as an interactive command-line application > > ### Build and run @@ -2030,9 +2034,9 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > ## System Requirements > -> Before starting, ensure your Linux system meets these requirements: +> Before starting, ensure your system meets these requirements: > -> * Latest stable version of [Rust and Cargo](https://www.rust-lang.org/tools/install) +> * [Rust and Cargo](https://www.rust-lang.org/tools/install) 1.88 or newer > * Anthropic API key (Claude) > * A Python, Node.js, or executable MCP server to connect to > @@ -2054,18 +2058,24 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > edition = "2024" > > [dependencies] -> anyhow = "1.0.100" -> genai = "0.4.2" -> rmcp = { version = "0.8.0", features = ["server", "client", "transport-io", "transport-child-process"] } -> tokio = { version = "1.47.1", features = ["full"] } -> tracing = "0.1.41" -> tracing-subscriber = { version = "0.3", features = ["env-filter"] } -> serde_json = "1.0.128" +> anyhow = "1.0.104" +> jsonschema = "0.59" +> # Only the client half of rmcp is needed, over a child-process stdio transport. +> rmcp = { version = "3.4", features = [ +> "client", +> "transport-io", +> "transport-child-process", +> ], default-features = false } +> # The Messages API is called directly, which keeps the provider's content +> # blocks verbatim. That matters for signed thinking blocks; see request_model. +> reqwest = { version = "0.13", features = ["json"] } +> serde = { version = "1.0", features = ["derive"] } +> serde_json = "1.0.151" +> tokio = { version = "1.53", features = ["full"] } > dotenvy = "0.15.7" -> reqwest = "0.12.23" > ``` > -> The [`rmcp`](https://github.com/modelcontextprotocol/rust-sdk) crate provides the Rust MCP SDK and child-process transport. This example uses the [`genai`](https://github.com/jeremychone/rust-genai) crate to send requests to Claude and represent tools in the model request. +> The [`rmcp`](https://github.com/modelcontextprotocol/rust-sdk) crate provides the Rust MCP SDK and the child-process stdio transport. Only its client half is enabled. The client calls the [Messages API](https://docs.anthropic.com/en/api/messages) directly with [`reqwest`](https://docs.rs/reqwest). Calling the API directly keeps the content blocks of each reply verbatim, which matters when a reply contains a signed thinking block. The [`jsonschema`](https://docs.rs/jsonschema) crate validates structured tool results against the schema a tool declares. > > ## Setting Up Your API Key > @@ -2083,6 +2093,8 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > echo ".env" >> .gitignore > ``` > +> The client loads `.env` when the file exists. Exporting `ANTHROPIC_API_KEY` in the shell works as well. +> > > [!WARNING] > > > > Make sure you keep your `ANTHROPIC_API_KEY` secure! @@ -2093,272 +2105,492 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > ### Imports and Client Structure > -> First, add the imports, model constant, and basic client structure: +> First, add the imports and constants: > > ```rust theme={null} > use anyhow::{Context, Result, bail}; -> use genai::Client; -> use genai::chat::{ -> ChatMessage, ChatRequest, ChatResponse, ContentPart, Tool as GenaiTool, ToolResponse, +> use jsonschema::Validator; +> use rmcp::model::{ +> CallToolRequestParams, CallToolResult, ClientCapabilities, ClientConfig, Implementation, +> ProtocolVersion, Tool as McpTool, > }; -> use rmcp::model::{CallToolRequestParam, Tool as McpTool}; -> use rmcp::service::{RoleClient, RunningService, ServiceExt}; +> use rmcp::service::{ClientLifecycleMode, ClientServiceExt, RoleClient, RunningService}; > use rmcp::transport::TokioChildProcess; -> use serde_json::Value; +> use serde::{Deserialize, Serialize}; +> use serde_json::{Value, json}; +> use std::collections::HashMap; +> use std::time::Duration; > use tokio::io::{self, AsyncBufReadExt, BufReader}; > use tokio::process::Command; > > const MODEL_ANTHROPIC: &str = "claude-opus-5"; +> /// The model may think before answering, and max_tokens caps thinking +> /// plus the reply, so leave room for both. +> const MAX_TOKENS: u32 = 10000; +> const MAX_TOOL_TURNS: usize = 10; +> +> const ANTHROPIC_API_BASE: &str = "https://api.anthropic.com"; +> const ANTHROPIC_VERSION: &str = "2023-06-01"; +> const REQUEST_TIMEOUT: Duration = Duration::from_secs(120); +> ``` +> +> `MAX_TOKENS` caps the thinking and the reply together. `MAX_TOOL_TURNS` bounds how many rounds of tool calls one query may take. `REQUEST_TIMEOUT` applies to each request sent to the Messages API. +> +> Next, add the types for the Messages API and the client structure: +> +> ```rust theme={null} +> /// One turn of the conversation, as the Messages API takes it. +> /// +> /// `content` is a list of raw blocks rather than typed ones on purpose. An +> /// assistant turn is fed straight back on the next request, and Claude requires +> /// the blocks it sent to return unchanged -- a thinking block's `signature` +> /// included. Reserialising through a narrower type would drop whatever it does +> /// not model. +> #[derive(Serialize, Clone)] +> struct Message { +> role: &'static str, +> content: Vec, +> } +> +> impl Message { +> fn user(content: Vec) -> Self { +> Message { +> role: "user", +> content, +> } +> } +> +> fn assistant(content: Vec) -> Self { +> Message { +> role: "assistant", +> content, +> } +> } +> } +> +> /// A tool as the Messages API declares it, converted from an MCP tool. +> #[derive(Serialize, Clone)] +> struct ToolDefinition { +> name: String, +> #[serde(skip_serializing_if = "Option::is_none")] +> description: Option, +> input_schema: Value, +> } +> +> #[derive(Serialize)] +> struct MessagesRequest<'a> { +> model: &'a str, +> max_tokens: u32, +> messages: &'a [Message], +> tools: &'a [ToolDefinition], +> } +> +> #[derive(Deserialize)] +> struct MessagesResponse { +> content: Vec, +> } +> +> /// The `type` of a content block, when it has one. +> fn block_type(block: &Value) -> &str { +> block +> .get("type") +> .and_then(Value::as_str) +> .unwrap_or_default() +> } > > struct MCPClient { -> anthropic: Client, -> session: Option>, -> tools: Vec, +> http: reqwest::Client, +> session: Option>, +> tools: Vec, +> /// Compiled `outputSchema` per tool name. rmcp does not validate results, +> /// so this client does it with the `jsonschema` crate. +> output_schemas: HashMap, > } > ``` > -> The client keeps the model API client, the active MCP session, and the tools advertised by the connected server. +> `Message` holds the content blocks of one turn as raw `serde_json::Value`s. An assistant turn goes back to the API unchanged on the next request, with any thinking block and its `signature` intact. `ToolDefinition` is a tool as the Messages API declares it. `MCPClient` keeps the HTTP client, the active MCP session, the tools in Messages API form, and one compiled validator per tool that declares an `outputSchema`. > > ### Client Initialization > -> Next, initialize the model client and start without an MCP session or tools: +> Next, open the `impl MCPClient` block with the constructor. The methods in the following sections go inside this block, which closes after `cleanup`: > > ```rust theme={null} > impl MCPClient { > fn new() -> Result { > Ok(MCPClient { -> anthropic: Client::default(), +> http: reqwest::Client::builder() +> .timeout(REQUEST_TIMEOUT) +> .build() +> .context("Failed to build HTTP client")?, > session: None, > tools: Vec::new(), +> output_schemas: HashMap::new(), > }) > } -> -> // Additional methods will go here. -> } > ``` > -> `genai::Client::default()` reads the `ANTHROPIC_API_KEY` environment variable when it sends a request. +> `new` builds a `reqwest::Client` with the request timeout. The API key is read later, when a request is sent, so connecting to a server and listing its tools works without one. > -> ### Server Connection Management +> ### Validating Structured Tool Output > > Add this method inside the `impl MCPClient` block: > > ```rust theme={null} -> async fn connect_to_server(&mut self, server_args: &[String]) -> Result<()> { -> if self.session.is_some() { -> bail!("Client is already connected to a server"); +> /// Check a result against its tool's declared `outputSchema`. Error results +> /// are exempt: they carry a message, not data. +> fn validate_tool_output(&self, name: &str, result: &CallToolResult) -> Result<()> { +> let Some(validator) = self.output_schemas.get(name) else { +> return Ok(()); +> }; +> if result.is_error.unwrap_or(false) { +> return Ok(()); +> } +> let Some(structured) = &result.structured_content else { +> bail!("Tool {name} declares an output schema but returned no structured content"); +> }; +> if let Err(error) = validator.validate(structured) { +> bail!("Structured content from tool {name} does not match its output schema: {error}"); +> } +> Ok(()) > } +> ``` > -> let mut command = Command::new(&server_args[0]); -> command.args(&server_args[1..]); -> -> let process = TokioChildProcess::new(command) -> .with_context(|| format!("Failed to spawn server process for {:?}", server_args))?; +> A tool may declare an `outputSchema`, and the specification asks clients to validate `structuredContent` against it. rmcp does not do this, so the client keeps a compiled `jsonschema::Validator` per tool and checks each successful result. A result with `is_error` set carries a message, so it is exempt. A tool that declares a schema and returns no structured content is reported as an error. > -> let session = ().serve(process).await?; +> ### Server Connection Management > -> let rmcp_tools = session -> .list_all_tools() -> .await -> .context("Unable to list tools from server")?; +> Add this method inside the `impl MCPClient` block: > -> let tool_names: Vec = rmcp_tools -> .iter() -> .map(|tool| tool.name.to_string()) -> .collect(); +> ```rust theme={null} +> async fn connect_to_server(&mut self, server_args: &[String]) -> Result<()> { +> if self.session.is_some() { +> bail!("Client is already connected to a server"); +> } > -> println!("Connected to server with tools: {tool_names:?}"); +> let mut command = Command::new(&server_args[0]); +> command.args(&server_args[1..]); +> +> let process = TokioChildProcess::new(command) +> .with_context(|| format!("Failed to spawn server process for {:?}", server_args))?; +> +> // Without a ClientConfig the client would report rmcp's own crate name +> // and version rather than its own. +> let config = ClientConfig::new( +> ClientCapabilities::default(), +> Implementation::new("mcp-client-rust", "1.0.0"), +> ); +> +> // `Auto` probes server/discover and falls back to the 2025-11-25 +> // initialize handshake, matching the Python and TypeScript clients. +> // `serve` alone would only ever do the legacy handshake, under which a +> // server cannot offer this era's features -- an array-rooted +> // `outputSchema`, for one, which get_alerts uses. +> let session = config +> .serve_with_lifecycle( +> process, +> ClientLifecycleMode::Auto { +> preferred_versions: vec![ProtocolVersion::V_2026_07_28], +> legacy_version: Some(ProtocolVersion::V_2025_11_25), +> }, +> ) +> .await?; +> +> let rmcp_tools = session +> .list_all_tools() +> .await +> .context("Unable to list tools from server")?; +> +> let tool_names: Vec = rmcp_tools +> .iter() +> .map(|tool| tool.name.to_string()) +> .collect(); +> +> let protocol_version = session +> .peer_info() +> .map(|info| info.protocol_version.to_string()) +> .unwrap_or_else(|| "unknown".to_string()); +> println!("Connected over protocol {protocol_version} with tools: {tool_names:?}"); +> +> // An outputSchema root may be any JSON Schema, not just an object. +> for tool in &rmcp_tools { +> let Some(schema) = &tool.output_schema else { +> continue; +> }; +> let schema = Value::Object(schema.as_ref().clone()); +> let validator = Validator::new(&schema).with_context(|| { +> format!("Failed to compile output schema of tool {}", tool.name) +> })?; +> self.output_schemas.insert(tool.name.to_string(), validator); +> } > -> self.tools = convert_tools(&rmcp_tools); -> self.session = Some(session); -> Ok(()) -> } +> self.tools = convert_tools(&rmcp_tools); +> self.session = Some(session); +> Ok(()) +> } > ``` > > This method: > > 1. Starts the server as a child process using the command and arguments supplied on the command line -> 2. Establishes an MCP session over stdio -> 3. Lists all tools advertised by the server -> 4. Converts those tools into the format used in model requests +> 2. Names the client `mcp-client-rust` through a `ClientConfig` +> 3. Negotiates the protocol with `serve_with_lifecycle` and `ClientLifecycleMode::Auto`, which probes `server/discover` for `2026-07-28` and falls back to the `2025-11-25` `initialize` handshake +> 4. Lists all tools advertised by the server and prints the negotiated protocol version with the tool names +> 5. Compiles a validator from each tool's `outputSchema` +> 6. Converts the tools into the form used in model requests > -> ### Converting MCP Tools +> rmcp's `serve` method alone performs only the legacy handshake. The `Auto` mode makes the features of the current revision reachable, including an `outputSchema` whose root is an array. > -> Add this function outside the `impl MCPClient` block: +> ### Query Processing Logic +> +> Now add the core query-processing method inside `impl MCPClient`: > > ```rust theme={null} -> fn convert_tools(tools: &[McpTool]) -> Vec { -> tools -> .iter() -> .map(|tool| GenaiTool { -> name: tool.name.to_string(), -> description: tool.description.as_deref().map(str::to_string), -> schema: Some(Value::Object(tool.input_schema.as_ref().clone())), -> config: None, -> }) -> .collect() -> } -> ``` +> async fn process_query(&mut self, query: &str) -> Result { +> let session = self +> .session +> .as_ref() +> .context("Client is not connected to any server")?; +> +> let mut messages = vec![Message::user(vec![json!({"type": "text", "text": query})])]; +> let mut final_text = Vec::new(); +> +> // Initial Claude API call with tools +> let mut content = self.request_model(&messages).await?; +> +> // Keep calling tools until Claude answers without one, up to a cap. +> for _ in 0..MAX_TOOL_TURNS { +> let mut tool_uses = Vec::new(); +> for block in &content { +> match block_type(block) { +> "text" => { +> if let Some(text) = block.get("text").and_then(Value::as_str) { +> final_text.push(text.to_string()); +> } +> } +> "tool_use" => tool_uses.push(block.clone()), +> _ => {} +> } +> } > -> MCP and model APIs describe tools with similar information but different Rust types. `convert_tools` maps each MCP tool's name, description, and input schema into a `genai` tool definition. +> if tool_uses.is_empty() { +> return Ok(final_text.join("\n")); +> } > -> ### Sending Model Requests +> // Execute every tool call in this response and collect the results +> let mut tool_results = Vec::new(); +> for tool_use in &tool_uses { +> let name = tool_use +> .get("name") +> .and_then(Value::as_str) +> .context("tool_use block has no name")?; +> let id = tool_use +> .get("id") +> .and_then(Value::as_str) +> .context("tool_use block has no id")?; +> let input = tool_use.get("input").cloned().unwrap_or(json!({})); +> +> // Add information about the tool call to final text +> final_text.push(format!("[Calling tool {name} with args {input}]")); +> +> // Query the MCP server +> let mut params = CallToolRequestParams::new(name.to_string()); +> if let Some(arguments) = input.as_object().cloned() { +> params = params.with_arguments(arguments); +> } +> let tool_result = match session.call_tool(params).await { +> Ok(result) => result, +> // A rejected call is the model's mistake to correct, so it +> // goes back as a failed tool_result rather than ending the +> // query. Every tool_use still needs a matching result. +> Err(error) => { +> final_text.push(format!("[{name} failed: {error}]")); +> tool_results.push(json!({ +> "type": "tool_result", +> "tool_use_id": id, +> "content": format!("Tool call {name} failed: {error}"), +> "is_error": true, +> })); +> continue; +> } +> }; +> +> self.validate_tool_output(name, &tool_result)?; +> +> // structured_content is data the application can use directly. +> if let Some(Value::Array(items)) = &tool_result.structured_content { +> final_text.push(format!("[{name} returned {} items]", items.len())); +> } > -> Add this helper method inside `impl MCPClient`: +> // content is a list of block types; forward only the text ones. +> let mut payload = tool_result +> .content +> .iter() +> .filter_map(|block| block.as_text().map(|text| text.text.as_str())) +> .collect::>() +> .join("\n"); +> +> // A structured result SHOULD also carry serialized JSON in a text +> // block, but only SHOULD, so fall back to serializing it rather +> // than sending the model an empty result. +> if payload.is_empty() { +> if let Some(structured) = &tool_result.structured_content { +> payload = structured.to_string(); +> } +> } > -> ```rust theme={null} -> async fn request_model(&self, chat_req: &ChatRequest) -> Result { -> let response = self -> .anthropic -> .exec_chat(MODEL_ANTHROPIC, chat_req.clone(), None) -> .await -> .context("Anthropic chat request failed")?; -> -> Ok(response) -> } -> ``` +> tool_results.push(json!({ +> "type": "tool_result", +> "tool_use_id": id, +> "content": payload, +> "is_error": tool_result.is_error.unwrap_or(false), +> })); +> } > -> This keeps model request handling in one place and adds useful context if the API request fails. +> // Append the assistant's response and all tool results, in one user +> // message, to the history. Every tool_use needs a matching +> // tool_result, and the assistant's blocks go back as they arrived. +> messages.push(Message::assistant(content)); +> messages.push(Message::user(tool_results)); > -> ### Query Processing Logic +> content = self.request_model(&messages).await?; +> } > -> Now add the core query-processing method inside `impl MCPClient`: +> // The turn cap was hit. Keep the last response's text. If it asked for +> // more tools, say they were not run. +> let mut wants_tools = false; +> for block in &content { +> match block_type(block) { +> "text" => { +> if let Some(text) = block.get("text").and_then(Value::as_str) { +> final_text.push(text.to_string()); +> } +> } +> "tool_use" => wants_tools = true, +> _ => {} +> } +> } +> if wants_tools { +> final_text.push(format!("[Stopped after {MAX_TOOL_TURNS} tool-use turns]")); +> } > -> ```rust theme={null} -> async fn process_query(&mut self, query: &str) -> Result { -> let session = self -> .session -> .as_ref() -> .context("Client is not connected to any server")?; -> -> let mut messages = vec![ChatMessage::user(query)]; -> let mut final_text = Vec::new(); -> -> // Initial Claude API call with tools -> let mut chat_req = ChatRequest::new(messages.clone()).with_tools(self.tools.clone()); -> let mut chat_rsp = self.request_model(&chat_req).await?; -> -> // Process response content - collect text and handle tool calls -> for text in chat_rsp.texts() { -> final_text.push(text.to_string()); +> Ok(final_text.join("\n")) > } +> ``` > -> let tool_calls = chat_rsp.tool_calls(); -> if !tool_calls.is_empty() { -> // Append assistant's response to message history -> messages.push(ChatMessage::assistant(chat_rsp.content.clone())); -> -> // Execute each tool call and collect responses -> let mut tool_results = Vec::new(); -> for tool_call in tool_calls { -> // Add information about the tool call to final text -> let tool_args_str = serde_json::to_string(&tool_call.fn_arguments) -> .unwrap_or_else(|_| "{}".to_string()); -> -> final_text.push(format!( -> "[Calling tool {} with args {}]", -> tool_call.fn_name, tool_args_str -> )); -> -> // Query the MCP server -> let tool_result = session -> .call_tool(CallToolRequestParam { -> name: tool_call.fn_name.clone().into(), -> arguments: tool_call.fn_arguments.as_object().cloned(), -> }) -> .await -> .with_context(|| format!("Tool call {} failed", tool_call.fn_name))?; -> -> let payload = serde_json::to_string(&tool_result) -> .context("Failed to serialize tool result")?; -> -> tool_results.push(ContentPart::ToolResponse(ToolResponse::new( -> tool_call.call_id.clone(), -> payload, -> ))); -> } +> The method sends the user's query to Claude with the server's tools and then loops. Each pass collects the text blocks of the reply and gathers its `tool_use` blocks. When a reply contains no tool use, the collected text is returned. Otherwise the client calls each requested tool through the MCP session and builds one `tool_result` block per `tool_use`. A call the server rejects goes back with `is_error` set, so Claude can read the message and try something else. A successful result is checked against its output schema. Its text blocks are joined and forwarded to Claude, and when it has no text blocks the serialized `structured_content` is sent in their place. When `structured_content` is an array, the client prints the item count as an example of using structured data directly. The assistant's blocks are appended to the history exactly as they arrived, followed by one user message holding all tool results, and the next request is sent. The loop stops after `MAX_TOOL_TURNS` rounds. At that point the last reply's text is kept, and a note is added when Claude asked for more tools. > -> // Append tool responses to message history -> messages.push(ChatMessage::user(tool_results)); +> ### Sending Model Requests > -> // Build the next request and query model -> chat_req = ChatRequest::new(messages.clone()); -> chat_rsp = self.request_model(&chat_req).await?; +> Add this helper method inside `impl MCPClient`: > -> // Collect text from response -> for text in chat_rsp.texts() { -> final_text.push(text.to_string()); +> ```rust theme={null} +> /// Call Claude with the current history and return the content blocks of +> /// its reply, untouched. Tools are passed on every call so Claude can keep +> /// calling them across turns. +> async fn request_model(&self, messages: &[Message]) -> Result> { +> let api_key = std::env::var("ANTHROPIC_API_KEY").context("ANTHROPIC_API_KEY is not set")?; +> // The base URL is configurable so the client can point at a local stand-in. +> let base_url = +> std::env::var("ANTHROPIC_BASE_URL").unwrap_or_else(|_| ANTHROPIC_API_BASE.to_string()); +> +> let request = MessagesRequest { +> model: MODEL_ANTHROPIC, +> max_tokens: MAX_TOKENS, +> messages, +> tools: &self.tools, +> }; +> +> let response = self +> .http +> .post(format!("{}/v1/messages", base_url.trim_end_matches('/'))) +> .header("x-api-key", api_key) +> .header("anthropic-version", ANTHROPIC_VERSION) +> .json(&request) +> .send() +> .await +> .context("Anthropic request failed")?; +> +> let status = response.status(); +> let body = response +> .text() +> .await +> .context("Unable to read the Anthropic response")?; +> if !status.is_success() { +> bail!("Anthropic request failed with {status}: {body}"); > } -> } > -> Ok(final_text.join("\n")) -> } +> let parsed: MessagesResponse = +> serde_json::from_str(&body).context("Unable to parse the Anthropic response")?; +> Ok(parsed.content) +> } > ``` > -> The method first sends the user's query and available tools to Claude. When Claude requests tools, the client executes each request through the MCP session, sends the results back to Claude, and collects the final text response. +> `request_model` reads `ANTHROPIC_API_KEY` on each call and posts the history to `/v1/messages` with the `x-api-key` and `anthropic-version` headers. `ANTHROPIC_BASE_URL` overrides the endpoint, which allows pointing the client at a local stand-in. Tools are sent on every request so Claude can keep calling them across turns. A non-success status becomes an error that includes the response body. The reply's content blocks are returned untouched. > > ### Interactive Chat Interface > > Add the interactive terminal loop inside `impl MCPClient`: > > ```rust theme={null} -> async fn chat_loop(&mut self) -> Result<()> { -> println!("\nMCP Client Started!"); -> println!("Type your queries or 'quit' to exit."); +> async fn chat_loop(&mut self) -> Result<()> { +> println!("\nMCP Client Started!"); +> println!("Type your queries or 'quit' to exit."); > -> let mut stdin = BufReader::new(io::stdin()); -> let mut input = String::new(); +> let mut stdin = BufReader::new(io::stdin()); +> let mut input = String::new(); > -> loop { -> print!("\nQuery: "); -> std::io::Write::flush(&mut std::io::stdout())?; +> loop { +> print!("\nQuery: "); +> std::io::Write::flush(&mut std::io::stdout())?; > -> input.clear(); -> if stdin.read_line(&mut input).await? == 0 { -> break; // EOF -> } +> input.clear(); +> if stdin.read_line(&mut input).await? == 0 { +> break; // EOF +> } > -> let query = input.trim(); -> if query.eq_ignore_ascii_case("quit") { -> break; -> } -> if query.is_empty() { -> continue; -> } +> let query = input.trim(); +> if query.eq_ignore_ascii_case("quit") { +> break; +> } +> if query.is_empty() { +> continue; +> } > -> match self.process_query(query).await { -> Ok(response) => println!("\n{}", response), -> Err(err) => println!("\nError: {}", err), +> match self.process_query(query).await { +> Ok(response) => println!("\n{}", response), +> Err(err) => println!("\nError: {:#}", err), +> } > } -> } > -> Ok(()) -> } +> Ok(()) +> } > ``` > -> The loop accepts queries until the user types `quit` or closes standard input. Query errors are printed without terminating the client. +> The loop accepts queries until the user types `quit` or closes standard input. Query errors are printed without terminating the client. The `{:#}` format prints the whole `anyhow` context chain on one line. > > ### Cleanup > -> Add this method inside `impl MCPClient` to stop the MCP session and child process: +> Add this method inside `impl MCPClient` to stop the MCP session and child process. The closing brace ends the `impl MCPClient` block: > > ```rust theme={null} -> async fn cleanup(&mut self) -> Result<()> { -> if let Some(session) = self.session.take() { -> let _ = session.cancel().await; +> async fn cleanup(&mut self) -> Result<()> { +> if let Some(session) = self.session.take() { +> let _ = session.cancel().await; +> } +> Ok(()) > } -> Ok(()) > } > ``` > > ### Main Entry Point > -> Finally, add the asynchronous entry point outside the `impl MCPClient` block: +> Next, add the asynchronous entry point outside the `impl MCPClient` block: > > ```rust theme={null} > #[tokio::main] > async fn main() -> Result<()> { -> dotenvy::dotenv().context("Failed to load env file")?; +> // .env is optional; the key may come from the environment instead. +> let _ = dotenvy::dotenv(); > > let mut args = std::env::args(); > let _ = args.next(); @@ -2373,6 +2605,21 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > let result = async { > client.connect_to_server(&server_args).await?; +> +> // Connecting and listing tools needs no credentials; querying them +> // does. Matching the Python and TypeScript clients, report and exit +> // rather than failing, so the connection itself can be exercised +> // without a key. +> // Empty counts as unset, as it does in the other clients: `KEY= cmd` +> // is how the smoke test forces this path. +> if std::env::var("ANTHROPIC_API_KEY").map_or(true, |key| key.is_empty()) { +> println!( +> "\nNo ANTHROPIC_API_KEY found. To query these tools with Claude, set your API key:" +> ); +> println!(" export ANTHROPIC_API_KEY=your-api-key-here"); +> return Ok(()); +> } +> > client.chat_loop().await > } > .await; @@ -2386,14 +2633,34 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > } > ``` > -> The entry point loads `.env`, treats all remaining command-line arguments as the server command, connects the client, starts the chat loop, and ensures cleanup runs before exiting. +> The entry point loads `.env` when the file exists, treats all remaining command-line arguments as the server command, connects the client, and ensures cleanup runs before exiting. When `ANTHROPIC_API_KEY` is unset or empty, the client prints how to set the key and exits after listing the server's tools. This exercises the MCP connection without credentials. +> +> ### Describing Tools to the Model +> +> Finally, add this function outside the `impl MCPClient` block: +> +> ```rust theme={null} +> fn convert_tools(tools: &[McpTool]) -> Vec { +> tools +> .iter() +> .map(|tool| ToolDefinition { +> name: tool.name.to_string(), +> description: tool.description.as_deref().map(str::to_string), +> input_schema: Value::Object(tool.input_schema.as_ref().clone()), +> }) +> .collect() +> } +> ``` +> +> MCP and the Messages API describe tools with the same information in different Rust types. `convert_tools` copies each MCP tool's name, description, and input schema into a `ToolDefinition`, which serializes to the shape the `tools` parameter expects. The description is omitted when a tool has none. > > ### Verify the Complete File > > Before running the client, confirm the items in `src/main.rs` are placed at the correct scope: > -> * `new`, `connect_to_server`, `process_query`, `request_model`, `chat_loop`, and `cleanup` are methods inside the single `impl MCPClient` block. -> * `main` and `convert_tools` are functions outside the `impl MCPClient` block. +> * `new`, `validate_tool_output`, `connect_to_server`, `process_query`, `request_model`, `chat_loop`, and `cleanup` are methods inside the single `impl MCPClient` block, which opens in Client Initialization and closes after `cleanup`. +> * `user` and `assistant` are methods inside the `impl Message` block. +> * `block_type`, `main`, and `convert_tools` are functions outside both `impl` blocks. > > Rust does not require these items to appear in a particular order, but methods and free functions must be placed in the correct scope. Compare your file with the [complete `src/main.rs` example](https://github.com/modelcontextprotocol/quickstart-resources/blob/main/mcp-client-rust/src/main.rs), then check that it compiles: > @@ -2426,37 +2693,49 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > The client will: > > 1. Start and connect to the specified MCP server -> 2. List the tools available from that server +> 2. Print the negotiated protocol version and the tools available from that server > 3. Start an interactive chat session where you can: > * Enter queries > * See tool executions > * Get responses from Claude > +> Connecting to the weather server prints a line like: +> +> ```text theme={null} +> Connected over protocol 2026-07-28 with tools: ["get_alerts", "get_forecast"] +> ``` +> +> Without an `ANTHROPIC_API_KEY`, the client stops after this line and prints how to set the key. +> > ## How It Works > -> When you submit a query: +> When the user submits a query: > -> 1. The client sends your query and the server's available tools to Claude +> 1. The client sends the query and the server's tool definitions to Claude > 2. Claude decides which tools, if any, to use -> 3. The client executes requested tools through the MCP session -> 4. Tool results are sent back to Claude -> 5. Claude provides a natural language response -> 6. The response is displayed in the terminal +> 3. The client executes every requested tool through the MCP session and validates structured results against their output schemas +> 4. Tool results, including failures marked with `is_error`, are sent back to Claude together with Claude's own blocks, unchanged +> 5. Steps 2 through 4 repeat until Claude answers without a tool call or `MAX_TOOL_TURNS` is reached +> 6. The collected text is displayed in the terminal > > ## Best Practices > > 1. **Error Handling** -> * Add context to errors at process, MCP, model API, and serialization boundaries +> * Add context to errors at process, MCP, and model API boundaries +> * Send a rejected tool call back to Claude as a `tool_result` with `is_error` set, so every `tool_use` gets an answer > * Report individual query errors without terminating the interactive session -> * Validate server commands before running them -> 2. **Resource Management** +> 2. **Conversation History** +> * Feed assistant blocks back exactly as they arrived, thinking blocks and their signatures included +> * Pass the tool list on every request so Claude can keep calling tools across turns +> * Cap the number of tool turns per query +> 3. **Resource Management** > * Always cancel the MCP session during cleanup > * Ensure cleanup runs even when connection or chat-loop operations fail > * Avoid starting a second server while a session is active -> 3. **Security** -> * Store API keys securely in `.env` -> * Review the tools exposed by a server before allowing model-driven calls -> * Connect only to servers and executable commands you trust +> 4. **Security** +> * Store API keys securely in `.env` or the environment +> * Validate structured tool results against their declared output schemas +> * Connect only to trusted servers and executable commands > > ## Troubleshooting > @@ -2477,9 +2756,7 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > > ### Environment File Issues > -> If you see `Failed to load env file`, ensure `.env` exists in the directory where you run the client. -> -> If the model request reports a missing API key, confirm that `.env` contains: +> The `.env` file is optional. When it is missing, the client reads `ANTHROPIC_API_KEY` from the environment. When the key is unset or empty, the client connects, prints the server's tools, and exits with instructions for setting the key. Export the key, or create a `.env` in the directory where the client runs that contains: > > ```text theme={null} > ANTHROPIC_API_KEY=your-api-key-goes-here @@ -2488,8 +2765,10 @@ Before you begin, it helps to have gone through our [Build an MCP Server](https: > ### Tool and Response Errors > > * `Unable to list tools from server`: Verify the server starts successfully and communicates over stdio -> * `Tool call ... failed`: Verify the server tool's required arguments and environment variables -> * `Failed to serialize tool result`: Inspect the server's response for unsupported or malformed content +> * `[... failed: ...]` in the output: The server rejected the tool call. The message also goes to Claude as a failed `tool_result`, so Claude may retry with different arguments +> * `Tool ... declares an output schema but returned no structured content` or `Structured content from tool ... does not match its output schema`: The server's result does not satisfy its own `outputSchema` +> * `Anthropic request failed with ...`: The response body follows the status and names the cause, such as an invalid key or insufficient credits +> * `[Stopped after 10 tool-use turns]`: The query reached `MAX_TOOL_TURNS`. Raise the constant for workflows that need more rounds ## Next steps diff --git a/content/mcp/docs/draft/develop/build-server.md b/content/mcp/docs/draft/develop/build-server.md index 9405c5f42..0527a9ff2 100644 --- a/content/mcp/docs/draft/develop/build-server.md +++ b/content/mcp/docs/draft/develop/build-server.md @@ -779,6 +779,10 @@ This tutorial will primarily focus on tools. > > > [!NOTE] > > +> > This server uses MCP protocol version 2025-11-25, as supported by the latest stable release of the Java SDK. Clients that also support that version can connect to it, but clients that support only 2026-07-28 cannot. See [backward compatibility](https://modelcontextprotocol.io/specification/draft/basic/versioning.md#backward-compatibility-with-initialization-based-versions). +> +> > [!NOTE] +> > > > This is a quickstart demo based on Spring AI MCP auto-configuration and boot starters. > > To learn how to create sync and async MCP Servers, manually, consult the [Java SDK Server](https://java.sdk.modelcontextprotocol.io/) documentation. > @@ -804,7 +808,7 @@ This tutorial will primarily focus on tools. > ### System requirements > > * Java 17 or higher installed. -> * [Spring Boot 3.3.x](https://docs.spring.io/spring-boot/installing.html) or higher +> * [Spring Boot 4.1.x](https://docs.spring.io/spring-boot/installing.html) or higher > > ### Set up your environment > @@ -1016,7 +1020,7 @@ This tutorial will primarily focus on tools. > .args("-jar", "/ABSOLUTE/PATH/TO/PARENT/FOLDER/mcp-weather-stdio-server-0.0.1-SNAPSHOT.jar") > .build(); > -> var stdioTransport = new StdioClientTransport(stdioParams); +> var stdioTransport = new StdioClientTransport(stdioParams, McpJsonDefaults.getMapper()); > > var mcpClient = McpClient.sync(stdioTransport).build(); > @@ -1064,6 +1068,10 @@ This tutorial will primarily focus on tools. > [tab] Kotlin > +> > [!NOTE] +> > +> > This server uses MCP protocol version 2025-11-25, as supported by the latest stable release of the Kotlin SDK. Clients that also support that version can connect to it, but clients that support only 2026-07-28 cannot. See [backward compatibility](https://modelcontextprotocol.io/specification/draft/basic/versioning.md#backward-compatibility-with-initialization-based-versions). +> > Let's get started with building our weather server! [You can find the complete code for what we'll be building here.](https://github.com/modelcontextprotocol/kotlin-sdk/tree/main/samples/weather-stdio-server) > > ### Prerequisite knowledge @@ -1127,7 +1135,7 @@ This tutorial will primarily focus on tools. > > ```kotlin build.gradle.kts theme={null} > // Check latest versions at https://github.com/modelcontextprotocol/kotlin-sdk/releases -> val mcpVersion = "0.9.0" +> val mcpVersion = "0.16.0" > val ktorVersion = "3.2.3" > val slf4jVersion = "2.0.17" > @@ -1138,6 +1146,10 @@ This tutorial will primarily focus on tools. > application > } > +> repositories { +> mavenCentral() +> } +> > application { > mainClass.set("MainKt") > } @@ -1358,7 +1370,7 @@ This tutorial will primarily focus on tools. > > ```bash theme={null} > ./gradlew build -> java -jar build/libs/weather-0.1.0-all.jar +> java -jar build/libs/weather-all.jar > ``` > > Let's now test your server from an existing MCP host, Claude for Desktop. @@ -1398,7 +1410,7 @@ This tutorial will primarily focus on tools. > "command": "java", > "args": [ > "-jar", -> "/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-0.1.0-all.jar" +> "/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-all.jar" > ] > } > } @@ -1412,7 +1424,7 @@ This tutorial will primarily focus on tools. > "command": "java", > "args": [ > "-jar", -> "C:\\PATH\\TO\\PARENT\\FOLDER\\weather\\build\\libs\\weather-0.1.0-all.jar" +> "C:\\PATH\\TO\\PARENT\\FOLDER\\weather\\build\\libs\\weather-all.jar" > ] > } > } @@ -1422,7 +1434,7 @@ This tutorial will primarily focus on tools. > This tells Claude for Desktop: > > 1. There's an MCP server named "weather" -> 2. Launch it by running `java -jar /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-0.1.0-all.jar` +> 2. Launch it by running `java -jar /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-all.jar` > > Save the file, and restart **Claude for Desktop**. diff --git a/content/mcp/docs/draft/learn/client-concepts.md b/content/mcp/docs/draft/learn/client-concepts.md index 065734b22..845899392 100644 --- a/content/mcp/docs/draft/learn/client-concepts.md +++ b/content/mcp/docs/draft/learn/client-concepts.md @@ -238,7 +238,7 @@ The flow ensures security through multiple human-in-the-loop checkpoints. Users ], modelPreferences: { hints: [{ - name: "claude-sonnet-4-20250514" // Suggested model + name: "claude-sonnet" // Prefer Sonnet-class models }], costPriority: 0.3, // Less concerned about API cost speedPriority: 0.2, // Can wait for thorough analysis diff --git a/content/mcp/docs/draft/sdk.md b/content/mcp/docs/draft/sdk.md index 3a6d3f75e..e12b551b4 100644 --- a/content/mcp/docs/draft/sdk.md +++ b/content/mcp/docs/draft/sdk.md @@ -27,7 +27,7 @@ See [SDK Tiering System](https://modelcontextprotocol.io/community/sdk-tiers.md) ## Getting Started -Each SDK provides the same functionality but follows the idioms and best practices of its language. All SDKs support: +Each SDK follows the idioms and best practices of its language. SDKs adopt new protocol revisions on their own schedules, so check each SDK's documentation for the revisions it supports. All SDKs support: * Creating MCP servers that expose tools, resources, and prompts * Building MCP clients that can connect to any MCP server diff --git a/content/mcp/docs/draft/tools/debugging.md b/content/mcp/docs/draft/tools/debugging.md index 4e27cdf42..adfc0411e 100644 --- a/content/mcp/docs/draft/tools/debugging.md +++ b/content/mcp/docs/draft/tools/debugging.md @@ -221,11 +221,16 @@ Log files are written to: * macOS: `~/Library/Logs/Claude` * Windows: `%APPDATA%\Claude\logs` +* Linux: `~/.config/Claude/logs` ```bash macOS theme={null} tail -n 20 -F ~/Library/Logs/Claude/mcp*.log ``` +```bash Linux theme={null} +tail -n 20 -F ~/.config/Claude/logs/mcp*.log +``` + ```powershell Windows theme={null} type "$env:AppData\Claude\logs\mcp*.log" ``` diff --git a/content/mcp/docs/draft/tools/inspector/cli.md b/content/mcp/docs/draft/tools/inspector/cli.md index 7c93b0d29..d1d50f032 100644 --- a/content/mcp/docs/draft/tools/inspector/cli.md +++ b/content/mcp/docs/draft/tools/inspector/cli.md @@ -138,6 +138,8 @@ Every non-zero exit maps to a stable failure class, so a caller can branch on *w | `7` | `--verify` found a skill that violates SEP-2640 (conformance, digest, or size mismatch). | | `8` | `--verify` couldn't check every skill within its read bounds. | | `9` | `--verify --require-digests` found a skill that advertises no digests. | +| `10` | A `--load` run breached a `--load-max-error-rate` or `--load-max-p99` threshold. The summary is printed first, and the envelope `code` names the threshold: `load_error_rate_exceeded` or `load_p99_exceeded`. | +| `11` | The server answered HTTP 429 (envelope `code` `rate_limited`). The envelope also carries `method`, plus `retryAfter` (the `Retry-After` header as sent) and `retryAfterMs` when the server sent one that parses. | On any non-zero exit the CLI also writes a **single JSON line to stderr**: @@ -152,7 +154,7 @@ On any non-zero exit the CLI also writes a **single JSON line to stderr**: } ``` -The envelope carries `code` and `message` always, plus `cause` (the underlying error, such as a DNS failure), `status` (the HTTP status) and `url` when known. Query-string secrets in a URL are redacted. `code` is a stable name for the failure: `auth_required`, `unreachable`, `tool_not_found`, `tool_is_error`, `no_app`, `schema_unportable`, `store_unavailable`, `oauth_state_unrecognized`, or the catch-all `error`, among others. +The envelope carries `code` and `message` always, plus `cause` (the underlying error, such as a DNS failure), `status` (the HTTP status) and `url` when known. Query-string secrets in a URL are redacted. `code` is a stable name for the failure: `auth_required`, `unreachable`, `tool_not_found`, `tool_is_error`, `no_app`, `schema_unportable`, `store_unavailable`, `oauth_state_unrecognized`, `rate_limited`, or the catch-all `error`, among others. Because it's one line, a caller can parse it with `2>&1 | tail -1 | jq .error`. @@ -184,15 +186,17 @@ mcp-inspector --cli --config ./ci-servers.json --server my-server \ ### CI gates -Three flags turn a check into a non-zero exit, each with its own code so a job can tell the failures apart: +These flags turn a check into a non-zero exit, each with its own code so a job can tell the failures apart: * `--strict` (with `tools/list`): reports tool-schema portability problems in full on stderr (path, issue, suggested fix) and exits `6` if any is error-severity. Without it, `tools/list` prints only a one-line count. Under `--format json` the findings are folded into the output as `schemaFindings`. * `--verify` (with `skills/list` or `skills/get`): runs the SEP-2640 conformance and digest checks, writes one JSON report per skill on stdout, and exits `7` on a violation or `8` when the read bounds stopped it before every skill was checked. `--skill-catalog-max-skills` and `--skill-catalog-max-bytes` set those bounds. * `--require-digests` (with `--verify`): exits `9` for a skill that advertises no digests, instead of reporting it as unverifiable and exiting `0`. +* `--load-max-error-rate ` and `--load-max-p99 ` (with `--load`): turn a load run into a gate. The run prints its summary, then exits `10` when the share of failed calls is above the fraction (`0` to `1`, so `0` fails on any failed call), when the p99 latency is above the given milliseconds, or when no call completed. `--load` (with `tools/call --tool-name`) calls the tool repeatedly and concurrently and prints a latency and error-rate summary instead of a result, bounded by `--load-duration ` (default `10` when `--load-requests` is not set) and `--load-requests `, with in-flight calls still finishing. `--load-concurrency ` (default `10`) caps the calls in flight, `--load-connections ` (default `1`, at most `--load-concurrency`, HTTP and SSE servers only) spreads them over independent sessions opened before timing starts, and `--load-rate ` (default unlimited) caps the calls started per second. ```bash theme={null} mcp-inspector --cli --method tools/list --strict > /dev/null mcp-inspector --cli --method skills/list --verify --require-digests +mcp-inspector --cli --method tools/call --tool-name get_weather --load --load-requests 200 --load-max-p99 500 ``` ### Branch on the failure class diff --git a/content/mcp/docs/draft/tools/inspector/configuration.md b/content/mcp/docs/draft/tools/inspector/configuration.md index 4dd9efc5f..70cd204cb 100644 --- a/content/mcp/docs/draft/tools/inspector/configuration.md +++ b/content/mcp/docs/draft/tools/inspector/configuration.md @@ -14,6 +14,7 @@ The `mcp-inspector` binary is a launcher: it reads two flags of its own and forw | - | - | | `--web` / `--cli` / `--tui` | Selects the client, `--web` by default. Passing more than one fails with `Specify at most one of --web, --cli, or --tui.` Launcher flags must come first: parsing stops at the first argument the launcher does not own, and everything from that point on is forwarded to the client unchanged. | | `-h` / `--help` | With no mode flag, prints the launcher's own help and exits. With a mode flag it is forwarded, so `mcp-inspector --cli --help` prints the CLI's help. | +| `-V` / `--version` | Listed in the launcher's help, but the launcher does not act on it. The flag is forwarded to the selected client, which prints the Inspector version, so `mcp-inspector -V` prints it through the web client and `mcp-inspector --cli -V` through the CLI. | Everything below belongs to a client. @@ -143,6 +144,7 @@ The whole scripting surface belongs to the CLI. See [CLI client](https://modelco | - | - | | **What to invoke** | `--method`, `--tool-name`, `--tool-arg`, `--tool-args-json`, `--uri`, `--cursor`, `--prompt-name`, `--prompt-args`, `--log-level`, `--metadata`, `--tool-metadata`, `--rename` | | **How to run it** | `--connect-timeout`, `--format`, `-q` / `--quiet`, `--output`, `--output-format`, `--app-info`, `--advertise-apps`, `--strict`, `--verify`, `--require-digests`, `--completion ` (`bash`, `zsh`, or `fish`) | +| **Load test** | `--load`, `--load-concurrency`, `--load-connections`, `--load-duration`, `--load-requests`, `--load-rate`, `--load-max-error-rate`, `--load-max-p99` (see [CI gates](https://modelcontextprotocol.io/docs/draft/tools/inspector/cli.md#ci-gates)) | | **Auth** | `--use-stored-auth`, `--stored-auth-only`, `--relogin`, `--no-revoke`, `--wait-for-auth`, `--list-stored-auth`, `--print-handoff` | ## Environment variables @@ -156,18 +158,23 @@ Environment variables split the same way as flags: two are read by the launcher | `MCP_DEBUG` | Append the error stack to a top-level `--web` or `--tui` failure (a `--cli` failure always prints its [JSON error envelope](https://modelcontextprotocol.io/docs/draft/tools/inspector/cli.md#exit-codes-and-error-envelopes) instead). Only when set to a meaningful value: `0`, `false`, and empty read as off. | | `DEBUG` | Same, with the same meaningful-value rule, so a stray `DEBUG=0` doesn't turn stack traces on and `DEBUG` still works as the npm `debug` package's namespace filter. | +The TUI reads both variables itself, with the same rule, for its own top-level failure. + ### CLI and TUI -Some of these are read by the web backend too, as the **Read by** column shows. +Some of these are read by the web backend or by `mcpdo` too, as the **Read by** column shows. | Variable | Read by | Effect | | - | - | - | -| `MCP_CATALOG_PATH` | Web, CLI, TUI | Fallback for `--catalog`. The CLI honors it only when no ad-hoc target is given, so a shell that exports it can still run one-off ad-hoc invocations. The web client and TUI apply it regardless, so combining it with an ad-hoc target is rejected there. | -| `MCP_CLIENT_CONFIG_PATH` | CLI, TUI | Fallback for `--client-config`. | -| `MCP_OAUTH_CALLBACK_URL` | CLI, TUI | Fallback for `--callback-url`. | -| `MCP_STORAGE_DIR` | Web, CLI, TUI | Storage directory. Relocates the OAuth state file (`/oauth.json`) and the secrets file (`/secrets.json`). | -| `MCP_INSPECTOR_OAUTH_STATE_PATH` | CLI, TUI | Per-file override of the OAuth state path. Takes precedence over `MCP_STORAGE_DIR`. | -| `MCP_AUTO_OPEN_ENABLED` | Web, CLI | Controls browser auto-open. `false` never opens one. In the CLI, `true` forces auto-open and lets interactive OAuth run without a TTY, and unset opens only on a TTY. In the web client, unset opens the UI at launch. The TUI does not read it. | +| `MCP_CATALOG_PATH` | Web, CLI, TUI, mcpdo | Fallback for `--catalog`. The CLI honors it only when no ad-hoc target is given, so a shell that exports it can still run one-off ad-hoc invocations. The web client and TUI apply it regardless, so combining it with an ad-hoc target is rejected there. | +| `MCP_CLIENT_CONFIG_PATH` | CLI, TUI, mcpdo | Fallback for `--client-config`. | +| `MCP_OAUTH_CALLBACK_URL` | CLI, TUI, mcpdo | Fallback for `--callback-url`. | +| `MCP_STORAGE_DIR` | Web, CLI, TUI, mcpdo | Storage directory. Relocates the OAuth state file (`/oauth.json`) and the secrets file (`/secrets.json`). | +| `MCP_INSPECTOR_OAUTH_STATE_PATH` | CLI, TUI, mcpdo | Per-file override of the OAuth state path. Takes precedence over `MCP_STORAGE_DIR`. | +| `MCP_AUTO_OPEN_ENABLED` | Web, CLI, mcpdo | Controls browser auto-open. `false` never opens one. In the CLI, `true` forces auto-open and lets interactive OAuth run without a TTY, and unset opens only on a TTY. In the web client, unset opens the UI at launch. The TUI does not read it. | +| `MCP_INSPECTOR_LOG_DIR` | TUI | Directory of the TUI's `auth.log`. Defaults to `~/.mcp-inspector`. | +| `LOG_LEVEL` | TUI | Level of that log, as a pino level name. Defaults to `info`. | +| `NO_COLOR` | CLI, mcpdo | Any non-empty value disables ANSI styling in human-readable output: all of mcpdo's `--format text` output (the same as `--plain`), and the sign-in prompt the CLI writes to stderr. | ### Web backend environment variables @@ -179,6 +186,7 @@ Some of these are read by the web backend too, as the **Read by** column shows. | `CLIENT_PORT` | Web UI port. Defaults to `6274`. | | `DANGEROUSLY_BIND_ALL_INTERFACES` | Required opt-in to bind a wildcard host (`0.0.0.0`, `::`, or any equivalent spelling). | | `ALLOWED_ORIGINS` | Comma-separated origin allow-list. **Replaces** the default list rather than merging. | +| `MCP_INSPECTOR_ALLOWED_HOSTS` | Comma-separated extra hostnames accepted in the `Host` header, for a reverse proxy that rewrites `Host`. `localhost` and `*.localhost`, IPv4 and bracketed IPv6 literals, the bind host (unless it is a wildcard), and the hostname of every `ALLOWED_ORIGINS` entry are always accepted. An entry starting with `.` (`.example.com`) admits that domain and its subdomains. An entry with a scheme, port, path, wildcard, or whitespace is dropped with a warning. The port is not compared. Any other `Host` gets a `403`. | | `MCP_PROXY_AUTH_TOKEN` | Deprecated v1 name for `MCP_INSPECTOR_API_TOKEN`, used only when the new name is unset. | | `MCP_SANDBOX_PORT` | MCP Apps sandbox port. Defaults to `6275`; `0` asks the OS for a free port. | | `SERVER_PORT` | v1's proxy port, now only a fallback for the sandbox port when `MCP_SANDBOX_PORT` is unset or invalid. | @@ -186,6 +194,8 @@ Some of these are read by the web backend too, as the **Read by** column shows. | `MCP_SANDBOX_FULL_ADDRESS` | Public URL of the MCP Apps sandbox proxy, for running behind a reverse proxy. | | `MCP_APP_ORIGIN_FULL_ADDRESS` | Public origin that `_meta.ui.domain` app documents are served from, for running behind a reverse proxy. | | `MCP_LOG_FILE` | Append the backend's structured (JSON lines) log to this file. | +| `INSPECTOR_TLS_KEY_PATH` | PEM private key for the web UI listener. Set together with `INSPECTOR_TLS_CERT_PATH` to serve the UI over `https`. Setting one without the other, an unreadable file, or a key and certificate that are not a usable pair is a startup error. The listener does not fall back to `http`. A blank value counts as unset. Only the UI listener is covered. The sandbox and app-origin listeners stay `http`. The CLI's `--print-handoff` emits an `https://` deep link when both are set. | +| `INSPECTOR_TLS_CERT_PATH` | PEM certificate (or chain) for the key in `INSPECTOR_TLS_KEY_PATH`. | | `MCP_AUTO_OPEN_ENABLED` | `false` stops the browser from opening at launch. See [CLI and TUI](#cli-and-tui). | | `MCP_CATALOG_PATH`, `MCP_STORAGE_DIR` | As described under [CLI and TUI](#cli-and-tui). | | `HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY` | Standard proxy routing for outbound MCP connections. | @@ -296,6 +306,38 @@ A catalog or config file is the familiar MCP client config shape (a `mcpServers` } ``` -Fields that equal their default are omitted when the Inspector writes the file back, keeping diffs minimal. `protocolEra` (see [Protocol eras](https://modelcontextprotocol.io/docs/draft/tools/inspector/protocol-eras.md)) defaults to `legacy` and `modernLogLevel` to `debug`. +Fields that equal their default are omitted when the Inspector writes the file back, keeping diffs minimal. `protocolEra` (see [Protocol eras](https://modelcontextprotocol.io/docs/draft/tools/inspector/protocol-eras.md)) defaults to `legacy` and `modernLogLevel` to `debug`. `"type": "http"` is accepted as an alias of `"streamable-http"` and written back in the long form. + +The Inspector-specific fields and their defaults: + +| Field | Default | Meaning | +| - | - | - | +| `headers` | | HTTP headers for an SSE or Streamable HTTP server, as a flat object. | +| `metadata` | | Default `_meta` object merged into every outgoing request. Values may be any JSON. | +| `protocolEra` | `legacy` | `legacy`, `auto`, or `modern`. See [Protocol eras](https://modelcontextprotocol.io/docs/draft/tools/inspector/protocol-eras.md). | +| `elicitCapability` | `both` | Elicitation capability advertised to the server: `off`, `url`, `form`, or `both`. Read by `mcpdo` only. | +| `modernLogLevel` | `debug` | Per-request log level stamped on modern connections, or `off`. Legacy connections ignore it. | +| `connectionTimeout` | `30000` | Connect-time timeout in ms. `0` disables it. | +| `requestTimeout` | | Per-request timeout in ms. | +| `taskTtl` | `60000` | TTL in ms for tasks created with **Run as task**. | +| `autoRefreshOnListChanged` | `false` | Refresh the tools, resources, and prompts lists on `list_changed` instead of only flagging the indicator. | +| `paginatedLists` | `false` | Fetch the lists one page at a time instead of aggregating every page on load. | +| `suppressNotificationStream` | `false` | Legacy-era Streamable HTTP only: do not open the standalone `GET` notification stream. | +| `advertisedExtensions` | | Per-extension overrides of which extensions the Inspector advertises, keyed by extension id. | +| `maxFetchRequests` | `1000` | HTTP requests kept in the Network log for this server. `0` means unlimited. | +| `skillCatalogMaxSkills` | `256` | Most skills read in one skills verification run. A positive integer. | +| `skillCatalogMaxBytes` | `67108864` | Most bytes read across all skills in one skills verification run (64 MiB). A positive integer. | +| `roots` | | Roots advertised through the `roots` capability, each `{ "uri", "name" }`. | +| `oauth.clientId` | | OAuth client ID for a static client. | +| `oauth.clientSecret` | | OAuth client secret for a confidential client. | +| `oauth.scopes` | | Scopes to request, as one string. | +| `oauth.enterpriseManaged` | | `true` connects through the enterprise IdP (EMA) instead of standard OAuth. | +| `oauth.onInsufficientScope` | `reauthorize` | Step-up policy for `403 insufficient_scope`: `reauthorize` or `throw`. | +| `oauth.requestRefreshToken` | `true` | Whether the client declares the `refresh_token` grant when it registers. Only `false` is written. | +| `oauth.scopeOnRefresh` | `false` | Whether a refresh-token request carries `scope`. Only `true` is written. | +| `oauth.revokeOnClear` | `true` | Whether clearing this server's OAuth state also revokes the grant at the authorization server (RFC 7009). Only `false` is written. | +| `oauth.authorizationParams` | | Extra query parameters for the authorization request. Reserved keys are dropped with a warning. | +| `oauth.authorizationUrl` | | Overrides the `authorization_endpoint` the authorization server's metadata advertises. | +| `oauth.tokenUrl` | | Overrides the `token_endpoint` the authorization server's metadata advertises. | You do not have to hand-write these; the web client can [import an existing client config](https://modelcontextprotocol.io/docs/draft/tools/inspector/recipes.md#importing-an-existing-client-config) from Claude Desktop, Cursor, Cline, or VS Code, or a registry `server.json`. diff --git a/content/mcp/docs/draft/tools/inspector/mcpdo.md b/content/mcp/docs/draft/tools/inspector/mcpdo.md index 6f4de8ca4..5206291d4 100644 --- a/content/mcp/docs/draft/tools/inspector/mcpdo.md +++ b/content/mcp/docs/draft/tools/inspector/mcpdo.md @@ -76,16 +76,20 @@ mcpdo --conn my-server tools/list Omitting the name falls back to the most recently used connection, but only on an interactive TTY. From a script or an agent, where stdin is not a TTY, an unqualified command is an error, so that a background job never acts on whichever server you last used. Set `MCP_ALLOW_DEFAULT_CONNECTION=1` to allow the fallback anyway. +`mcpdo connections/use ` sets the most recently used connection without sending anything to the server. + Connections **self-heal**: a dropped transport (an expired HTTP session, an exited stdio child) is re-dialed transparently on next use with the stored credentials. Only an `auth_required` error needs you to run `connect` again. A connection runs **one call at a time**. Commands against it from other shells queue behind the call in flight, and while a call is parked on an [elicitation](#elicitation), new calls on that connection are refused until it is answered. A long call does not block other connections. +`tools/call` also accepts the one-shot CLI's `--load` family (`--load`, `--load-concurrency`, `--load-connections`, `--load-duration`, `--load-requests`, `--load-rate`, `--load-max-error-rate`, `--load-max-p99`), with the same defaults and the same summary, run inside the daemon against the connection (see [CI gates](https://modelcontextprotocol.io/docs/draft/tools/inspector/cli.md#ci-gates)). `--load-connections` opens its extra sessions with stored credentials only. Later commands on the connection wait until the run ends. + ## Tasks -A tool that requires task support is refused by a plain `tools/call`; add `--task` to make a task-augmented call. It still **blocks** until the task finishes, then prints the final result: +On a legacy connection, a plain `tools/call` refuses a tool that requires task support. Add `--task` to make a task-augmented call. `--task` applies to legacy servers only. On a modern connection the server decides per request whether to return a task, and the flag changes nothing on the wire. The call still **blocks** until the task finishes, then prints the final result: ```bash theme={null} -mcpdo @my-server tools/call --task start_job size:=large +mcpdo @my-server tools/call --task start_job size:=large # task-augmented call on a legacy connection ``` If the task reaches `input_required`, its question is handled like any other [elicitation](#elicitation). @@ -111,7 +115,7 @@ Terminal-bound text (results, elicitation prompts, daemon errors) has control ch | `mcpdo disconnect --clear-auth` (`-c`) | Close the connection **and** clear its stored tokens, so the next `connect` signs in fresh. | | `mcpdo auth/list` | Stored credentials, each annotated with the catalog or connection names it is "known as", and `● live` when an open connection holds it. | | `mcpdo auth/clear ` | Clear one stored credential, by store URL or friendly name. `--all --yes` clears every one. | -| `mcpdo auth/ema-login` / `auth/ema-status` / `auth/ema-logout` | Enterprise-managed authorization: sign in to the IdP once, then connect to EMA servers silently. | +| `mcpdo auth/ema-login` / `auth/ema-status` / `auth/ema-logout` | Enterprise-managed authorization: sign in to the IdP once, then connect to EMA servers silently. `mcpdo connect --ema` treats a catalog entry as enterprise-managed for that connect, overriding its `oauth.enterpriseManaged`. It needs the entry's OAuth client ID and secret, so it cannot be used with an ad-hoc target. | When a browser sign-in is needed and neither stdin nor stderr is a TTY (and `MCP_AUTO_OPEN_ENABLED` is not forced on), `connect` exits `0` immediately with `pendingAuth: true` and an `authUrl`. Relay that URL to whoever will sign in. The connection completes on its own once they do: the next real command against it finishes the connection, and `connections/list` reports `pendingAuthSignedIn` in the meantime. Don't reconnect to fix a pending sign-in. @@ -173,4 +177,4 @@ Adjust the network and mount flags to what the server needs. HTTP and SSE server ## Using mcpdo from a coding agent -The package ships an agent skill that teaches an agent to drive `mcpdo`: connections it holds then extend the agent's toolset, and it knows to relay sign-in URLs and answer parked elicitations. `mcpdo agent-help` prints the guide, `mcpdo agent-help --skill-path` prints the path of the installable skill file, and `mcpdo agent-help --instructions` prints a block to append to a project's `CLAUDE.md` or `AGENTS.md`. +The package ships an agent skill that teaches an agent to drive `mcpdo`: connections it holds then extend the agent's toolset, and it knows to relay sign-in URLs and answer parked elicitations. `mcpdo agent-help` prints the guide, `mcpdo agent-help --skill-path` prints the path of the installable skill file, and `mcpdo agent-help --instructions` prints a block to append to a project's `CLAUDE.md` or `AGENTS.md`. The skill can also be installed with `npx skills add modelcontextprotocol/inspector --skill mcpdo`. diff --git a/content/mcp/docs/draft/tools/inspector/protocol-eras.md b/content/mcp/docs/draft/tools/inspector/protocol-eras.md index d7c0df00c..86acbcf5c 100644 --- a/content/mcp/docs/draft/tools/inspector/protocol-eras.md +++ b/content/mcp/docs/draft/tools/inspector/protocol-eras.md @@ -121,7 +121,7 @@ Tasks change the most between protocol eras, including *how the Inspector UI tab > > Tasks are an **extension** (`io.modelcontextprotocol/tasks`, [SEP-2663](https://modelcontextprotocol.io/seps/2663-tasks-extension.md)), so the tab is gated on the server *advertising that extension* rather than on `capabilities.tasks`. > -> Run a tool as a task and `tools/call` returns a `CreateTaskResult` (`resultType: "task"`, visible in the Protocol and Network tabs). The Inspector polls **`tasks/get`** only; there is no `tasks/list`, so **Refresh** re-polls the handles the client already knows about. A completed task **inlines its result**, with no blocking `tasks/result` call. +> There is no **Run as task** control on a modern connection. Task creation is server-directed, so the server decides per request whether `tools/call` returns a `CreateTaskResult` (`resultType: "task"`, visible in the Protocol and Network tabs). The Inspector polls **`tasks/get`** only; there is no `tasks/list`, so **Refresh** re-polls the handles the client already knows about. A completed task **inlines its result**, with no blocking `tasks/result` call. > > A task that needs more information moves to `input_required` and surfaces an embedded [elicitation](https://modelcontextprotocol.io/specification/draft/client/elicitation.md) in the pending-request modal (the dialog the web client opens whenever a request is waiting on you). Answering it sends **`tasks/update`** carrying the `inputResponses`, and the next poll completes. > diff --git a/content/mcp/docs/draft/tools/inspector/recipes.md b/content/mcp/docs/draft/tools/inspector/recipes.md index 7f83b42d9..ae6c6f7ec 100644 --- a/content/mcp/docs/draft/tools/inspector/recipes.md +++ b/content/mcp/docs/draft/tools/inspector/recipes.md @@ -246,7 +246,7 @@ The Inspector refuses to bind the **wildcard** all-interfaces addresses (`0.0.0. | Goal | What to do | | - | - | | **Reach it from another machine on the LAN** | `HOST=192.168.1.50`. The default origin allow-list follows the bind host, so `http://192.168.1.50:6274` is accepted with no further config. | -| **Behind TLS or a reverse proxy** | The browser's `Origin` becomes the public origin, which won't match the bind host. Set `ALLOWED_ORIGINS=https://inspector.example.com`, and for MCP Apps set `MCP_SANDBOX_FULL_ADDRESS` (see below). | +| **Behind TLS or a reverse proxy** | The browser's `Origin` becomes the public origin, which won't match the bind host. Set `ALLOWED_ORIGINS=https://inspector.example.com`, and for MCP Apps set `MCP_SANDBOX_FULL_ADDRESS` (see below). If the proxy rewrites `Host` to a name that is not in `ALLOWED_ORIGINS`, also set `MCP_INSPECTOR_ALLOWED_HOSTS=inspector.example.com` (or `.example.com` for a domain and its subdomains), or the backend answers `403`. Without a proxy, `INSPECTOR_TLS_KEY_PATH` and `INSPECTOR_TLS_CERT_PATH` serve the UI itself over `https`. | | **Wildcard bind (containers)** | Set `DANGEROUSLY_BIND_ALL_INTERFACES=true`. Loopback access still works out of the box; reaching it at a non-loopback address needs `ALLOWED_ORIGINS`. | > [!WARNING] @@ -273,7 +273,7 @@ When an exploration spans many calls (a multi-step flow over one session, a log ```bash theme={null} mcpdo connect my-server -mcpdo @my-server tools/call --task start_job size:=large # task-augmented; blocks until the task finishes +mcpdo @my-server tools/call --task start_job size:=large # task-augmented on a legacy connection, blocks until the task finishes mcpdo @my-server tools/call get_job_report mcpdo @my-server logging/tail # long-lived; Ctrl-C to stop mcpdo disconnect my-server diff --git a/content/mcp/docs/draft/tools/inspector/security.md b/content/mcp/docs/draft/tools/inspector/security.md index a2308b162..2d694f7c2 100644 --- a/content/mcp/docs/draft/tools/inspector/security.md +++ b/content/mcp/docs/draft/tools/inspector/security.md @@ -21,7 +21,7 @@ The web client is a browser app backed by a Node server that owns the MCP connec What the token does and does not protect: -* **The token is the real guard for non-browser clients.** The origin allow-list (`ALLOWED_ORIGINS`) stops other web pages from driving the backend, but a request that arrives with **no** `Origin` header (curl, a script, any non-browser client) skips that check entirely. +* **The token is the real guard for non-browser clients.** The origin allow-list (`ALLOWED_ORIGINS`) stops other web pages from driving the backend, but a request that arrives with **no** `Origin` header (curl, a script, any non-browser client) skips that check entirely. A `Host` header allow-list runs ahead of every route, including `GET /`, and answers `403` to a request whose `Host` is not a loopback name, an IP literal, the bind host, an `ALLOWED_ORIGINS` hostname, or an entry of `MCP_INSPECTOR_ALLOWED_HOSTS`, so a DNS-rebinding page cannot load the page and read the token (see [Host binding and origins](https://modelcontextprotocol.io/docs/draft/tools/inspector/web.md#host-binding-and-origins)). * **`GET /` discloses the token.** The backend injects it into the served HTML so that a reload or a bookmark keeps working. Anyone who can load the page can therefore read the token, which is why the bind address matters more than the token's value. Pinning your own `MCP_INSPECTOR_API_TOKEN` does not change this, since a custom token is disclosed exactly like a generated one. * **`DANGEROUSLY_OMIT_AUTH=true` removes the guard completely.** Anything that can reach the port can then spawn processes as you and use any OAuth token the Inspector holds. Only `true` or `1` turns auth off; any other value, including `false`, keeps it on. * **Only `/api/*` is gated.** The page itself, its static assets and `GET /healthz` are served without the token. `/healthz` returns only `{"status":"ok"}`, for container and orchestrator probes. diff --git a/content/mcp/docs/draft/tools/inspector/web.md b/content/mcp/docs/draft/tools/inspector/web.md index 455ce5d1e..c798a1f1a 100644 --- a/content/mcp/docs/draft/tools/inspector/web.md +++ b/content/mcp/docs/draft/tools/inspector/web.md @@ -129,7 +129,7 @@ A prompt rendered with the arguments supplied. * The sandbox listens on its own port, `6275` by default (set it with `MCP_SANDBOX_PORT`). An app whose UI resource declares `_meta.ui.domain` has its document served from a third listener, the app origin, on `6278` by default (`MCP_APP_ORIGIN_PORT`). Expose or forward both along with the web port. * The sandbox is gated by a `frame-ancestors` CSP, and a bracketed IPv6 literal is not a valid CSP host-source, so browse the Inspector at `localhost`, `127.0.0.1`, a hostname, or a LAN IPv4, **not** at a bare `http://[::1]:...`. -* By default the sandbox URL is plain `http` on the bind address, so an `https://` Inspector page blocks the frame as mixed content. Behind a TLS reverse proxy, set `MCP_SANDBOX_FULL_ADDRESS` (and `MCP_APP_ORIGIN_FULL_ADDRESS`) to the public `https://` address the browser reaches each listener at. Neither may share an origin with the Inspector UI; a value that does is ignored with a warning. +* By default the sandbox URL is plain `http` on the bind address, so an `https://` Inspector page blocks the frame as mixed content. That applies whether the page is `https` through a proxy or through `INSPECTOR_TLS_KEY_PATH` and `INSPECTOR_TLS_CERT_PATH`, which cover the UI listener only. Behind a TLS reverse proxy, set `MCP_SANDBOX_FULL_ADDRESS` (and `MCP_APP_ORIGIN_FULL_ADDRESS`) to the public `https://` address the browser reaches each listener at. Neither may share an origin with the Inspector UI; a value that does is ignored with a warning. See [Recipes](https://modelcontextprotocol.io/docs/draft/tools/inspector/recipes.md#reviewing-an-mcp-app) for the CLI-first automated review flow. @@ -171,6 +171,8 @@ Three further parameters land you on a *rendered app*: `openApp=` name By default the Inspector binds `127.0.0.1` and accepts requests only from the loopback origins for its port. Treat both defaults as security boundaries, since the backend spawns processes on your machine. +A `Host` header allow-list runs ahead of every route, including `GET /`. A request is answered `403` unless its `Host` is `localhost` or a `*.localhost` name, an IPv4 or bracketed IPv6 literal, the bind host, the hostname of an `ALLOWED_ORIGINS` entry, or an entry of `MCP_INSPECTOR_ALLOWED_HOSTS`. The port is not compared. A same-origin `GET /` carries no `Origin` header, so the origin allow-list never sees it, and the `Host` check is what stops a DNS-rebinding page from loading the page and reading the token out of it. + Binding all interfaces (`HOST=0.0.0.0`) is **refused** unless you set `DANGEROUSLY_BIND_ALL_INTERFACES=true`. Binding a *specific* non-loopback address is allowed with no opt-in, since that's a single deliberate exposure rather than every interface at once. See the [Hosting on a network](https://modelcontextprotocol.io/docs/draft/tools/inspector/recipes.md#hosting-on-a-network) recipe for the full matrix, and [Configuration](https://modelcontextprotocol.io/docs/draft/tools/inspector/configuration.md#web-backend-environment-variables) for the variables. diff --git a/content/mcp/docs/draft/tutorials/security/authorization.md b/content/mcp/docs/draft/tutorials/security/authorization.md index e51a563aa..4d40eef75 100644 --- a/content/mcp/docs/draft/tutorials/security/authorization.md +++ b/content/mcp/docs/draft/tutorials/security/authorization.md @@ -926,6 +926,8 @@ For our testing purposes, we will create an extremely simple MCP server that exp > > To set up authorization in your MCP server using the MCP C# SDK, you can lean on the standard ASP.NET Core builder pattern. Instead of using the introspection endpoint provided by Keycloak, we will use built-in ASP.NET Core capabilities for token validation. > +> In the root of your server folder, create two files, `Program.cs` and `ProtectedMcpServer.csproj`, and a `Tools` folder. Fill `Program.cs` with: +> > ```csharp theme={null} > using Microsoft.AspNetCore.Authentication.JwtBearer; > using Microsoft.IdentityModel.Tokens; @@ -987,9 +989,9 @@ For our testing purposes, we will create an extremely simple MCP server that exp > { > options.ResourceMetadata = new() > { -> Resource = new Uri(serverUrl), -> ResourceDocumentation = new Uri("https://docs.example.com/api/math"), -> AuthorizationServers = { new Uri(authorizationServerUrl) }, +> Resource = serverUrl, +> ResourceDocumentation = "https://docs.example.com/api/math", +> AuthorizationServers = { authorizationServerUrl }, > ScopesSupported = ["mcp:tools"] > }; > }); @@ -1017,6 +1019,63 @@ For our testing purposes, we will create an extremely simple MCP server that exp > app.Run(serverUrl); > ``` > +> Fill `ProtectedMcpServer.csproj` with: +> +> ```xml theme={null} +> +> +> +> net9.0 +> enable +> enable +> +> local-authorization-mcp-server +> +> +> +> +> +> +> +> +> +> ``` +> +> In the `Tools` folder, create `MathTools.cs` and fill it with: +> +> ```csharp theme={null} +> using System.ComponentModel; +> using ModelContextProtocol.Server; +> +> namespace ProtectedMcpServer.Tools; +> +> [McpServerToolType] +> public sealed class MathTools +> { +> [McpServerTool, Description("Add two numbers together.")] +> public Task Add( +> [Description("First operand")] double a, +> [Description("Second operand")] double b) +> { +> return Task.FromResult(a + b); +> } +> +> [McpServerTool, Description("Multiply two numbers together.")] +> public Task Multiply( +> [Description("First operand")] double a, +> [Description("Second operand")] double b) +> { +> return Task.FromResult(a * b); +> } +> } +> ``` +> +> Then from the server's root, run: +> +> ```bash theme={null} +> dotnet run +> ``` +> > For more details, see the [C# SDK documentation](https://github.com/modelcontextprotocol/csharp-sdk). ## Testing the MCP Server diff --git a/content/mcp/extensions/auth/oauth-client-credentials.md b/content/mcp/extensions/auth/oauth-client-credentials.md index 147859475..40a048ccb 100644 --- a/content/mcp/extensions/auth/oauth-client-credentials.md +++ b/content/mcp/extensions/auth/oauth-client-credentials.md @@ -176,10 +176,10 @@ The official MCP SDKs provide built-in support for client credentials authentica **2. Create a provider and connect** -Choose the credential format that matches your setup: - Each sample pins the issuer of the authorization server that provisioned the credentials, so the client refuses to send them to any other authorization server the MCP server might advertise. +Choose the credential format that matches your setup: + #### Using a client secret > [tab] TypeScript diff --git a/content/support/10310342-how-do-i-log-out-of-all-active-sessions.md b/content/support/10310342-how-do-i-log-out-of-all-active-sessions.md index 7e98f64f0..10c7a2349 100644 --- a/content/support/10310342-how-do-i-log-out-of-all-active-sessions.md +++ b/content/support/10310342-how-do-i-log-out-of-all-active-sessions.md @@ -46,7 +46,7 @@ Logging out of all active sessions also logs you out of Claude Code. To log out If you used your Claude account to authenticate into Claude Code, you can see and log out of those sign-ins in **Settings > Account**, where they're listed with your other sessions. If they aren't listed there, manage your authorization tokens in **Settings > Claude Code**. To remove a token and log out of Claude Code, click the trash can icon. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1608263923/b4fa7d6f6f08f2adffb4ea63bc58/image+%287%29.png?expires=1793430000&signature=cbd3b02a0c0546dee2bf32984e268757ad181e0c289d48a8db3d7ab01ac6275b&req=dSYnHst4nohdWvMW1HO4zVuHix%2F51We7AQofdwM8qVea%2BRIJSkf%2FzzUJleBH%0AmnVSAvCzCM1aoFitNwc%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1608263923/b4fa7d6f6f08f2adffb4ea63bc58/image+%287%29.png?expires=1793464200&signature=63acd948236b8074b2cff3743b6cd2d12148230730adfdd093c99c6e813f074e&req=dSYnHst4nohdWvMW1HO4zVuHix%2F50GO5AQofdwM8qVc8wZFRECK%2BbvXBp5PN%0AwZqC3%2F99a2Ii5GObBRQ%3D%0A) ## Unable to access your account? diff --git a/content/support/10504844-manage-user-feedback-settings-on-team-and-enterprise-plans.md b/content/support/10504844-manage-user-feedback-settings-on-team-and-enterprise-plans.md index 0ebc8d5a2..8df19ec32 100644 --- a/content/support/10504844-manage-user-feedback-settings-on-team-and-enterprise-plans.md +++ b/content/support/10504844-manage-user-feedback-settings-on-team-and-enterprise-plans.md @@ -6,6 +6,6 @@ As a Primary Owner or Owner of a Team or Enterprise plan, you can manage the abi 2. Use the toggle to change the **Rate chats** setting for your organization: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2058292603/75752add0bed6a9f3ab217f01708/CleanShot%2B2026-02-12%2Bat%2B08_55_14-402x.png?expires=1793430000&signature=6994401d85490a57e42d361a5491e2c3909aa88799af41ab0dde0794bea529f1&req=diAiHst3n4dfWvMW1HO4zYGm8yQYE6jM085gFtEpvcQ1GOuY7%2Fih3AhgMCqE%0AchAubYz0e0JpaKcjeVg%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2058292603/75752add0bed6a9f3ab217f01708/CleanShot%2B2026-02-12%2Bat%2B08_55_14-402x.png?expires=1793464200&signature=a05a4481b01c120eaf3a8968e56fa4cefac738549fc679335245c4a26097a3b9&req=diAiHst3n4dfWvMW1HO4zYGm8yQYFqzO085gFtEpvcROWrs4tPALdaU0FyUx%0AnSLz65Y8IFRCGZY2%2Ftg%3D%0A) More information on how Anthropic collects, uses, and stores feedback data can be found in our Privacy Center: **[How long do you store my organization’s data?](https://privacy.claude.com/en/articles/7996866-how-long-do-you-store-my-organization-s-data)** \ No newline at end of file diff --git a/content/support/10949351-getting-started-with-local-mcp-servers-on-claude-desktop.md b/content/support/10949351-getting-started-with-local-mcp-servers-on-claude-desktop.md index 98c2fbe95..8f1595487 100644 --- a/content/support/10949351-getting-started-with-local-mcp-servers-on-claude-desktop.md +++ b/content/support/10949351-getting-started-with-local-mcp-servers-on-claude-desktop.md @@ -48,7 +48,7 @@ for specific instructions. Custom desktop extensions uploads allow Team and Enterprise plans to leverage organization-specific workflows that aren’t available in the public directory. After creating a custom desktop extension, Owners and Primary Owners can navigate to **Settings > Desktop app**, select "Manage" next to **Extensions** (or **Settings > Extensions** in the older Settings layout), and click "Advanced settings" to access the **Extension Developer** section: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1681607607/ba6e379d2769d190f0970a0adaed/AD_4nXd4aZkqjJFpiXMPF28Pih7HmSJ9pPsnoWAfVgiLdFRFiTkO92YtXteIjvDHaPl7T0tjfpRTBOlyrMbQ_aciCNDgfIuEvV3szmKvt72x5O51DMSClXOYWk1JIRIzylwkj3joXqZcLw?expires=1793430000&signature=d75d455384c9d15dd12b5817d87a26dc1c72d6020f962c5d93f4066f548cf832&req=dSYvF89%2BmodfXvMW1HO4zWbPxUN7ND0yHn9K2IaIG2Icd8fZP6ptgW0Is01E%0AODBSad2tLoAIx7Egzyg%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1681607607/ba6e379d2769d190f0970a0adaed/AD_4nXd4aZkqjJFpiXMPF28Pih7HmSJ9pPsnoWAfVgiLdFRFiTkO92YtXteIjvDHaPl7T0tjfpRTBOlyrMbQ_aciCNDgfIuEvV3szmKvt72x5O51DMSClXOYWk1JIRIzylwkj3joXqZcLw?expires=1793464200&signature=c409a7a85966d2911e6034ed0d0563f8e59e422b582de13e048793396de8bbe3&req=dSYvF89%2BmodfXvMW1HO4zWbPxUN7MTkwHn9K2IaIG2L0DM5m02zsCiPSYXXQ%0ANB505IYafo%2Bs0uaCf5g%3D%0A) Click “Install Extension…” and select the .mcpb file. Follow the prompts to install and configure your custom desktop extension. For more in-depth information, please refer to our [desktop extension developer documentation](https://github.com/anthropics/mcpb). diff --git a/content/support/11725453-set-up-the-claude-lti-in-canvas-by-instructure.md b/content/support/11725453-set-up-the-claude-lti-in-canvas-by-instructure.md index edea84188..6c64e7a92 100644 --- a/content/support/11725453-set-up-the-claude-lti-in-canvas-by-instructure.md +++ b/content/support/11725453-set-up-the-claude-lti-in-canvas-by-instructure.md @@ -44,7 +44,7 @@ This article provides information on how to enable the Claude LTI integration in 5. Click "Install" and refresh the course page. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1611422430/c8e0875feac1f2c7cb033be74fc9/AD_4nXfLU_bui3EXcCjQ0qm70HD97neqjGayKeDer_t76utlci8gZSUjYRhw6ZSOlDdqSEcwXBzd_shAh7pQEJ-8OoE0O21DM5coOgxmO_WD5hlwiuwtS2iYXcTavhIRyQT5zKFWvfn3NA?expires=1793430000&signature=a2c6f9b1a588ce6e3776a9fa21565ecc3a9a0d45a60608c72274ac9a9fc15875&req=dSYmF818n4VcWfMW1HO4zTEDa%2BgamPOBEv2ojHLMylbF%2BOW%2FZ17q36sjnDY1%0AgIp0xPW6HH0owUESc0w%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1611422430/c8e0875feac1f2c7cb033be74fc9/AD_4nXfLU_bui3EXcCjQ0qm70HD97neqjGayKeDer_t76utlci8gZSUjYRhw6ZSOlDdqSEcwXBzd_shAh7pQEJ-8OoE0O21DM5coOgxmO_WD5hlwiuwtS2iYXcTavhIRyQT5zKFWvfn3NA?expires=1793464200&signature=12b18508fb6c3d422c1a49de5ae52c745aad38a9391c4fa8a198817d6738c1cc&req=dSYmF818n4VcWfMW1HO4zTEDa%2BganfeDEv2ojHLMylYX%2Famgl6J8rKBC6USW%0A8VceiJy4%2Fk9DAfMNmuU%3D%0A) ## Turn on the Claude LTI Integration in Claude for Education organization settings diff --git a/content/support/11818288-why-am-i-being-asked-to-verify-my-payment-method.md b/content/support/11818288-why-am-i-being-asked-to-verify-my-payment-method.md index 1ae25cedf..6fb49b175 100644 --- a/content/support/11818288-why-am-i-being-asked-to-verify-my-payment-method.md +++ b/content/support/11818288-why-am-i-being-asked-to-verify-my-payment-method.md @@ -2,7 +2,7 @@ If you see the following pop-up when you log in to your Claude account, you’ll need to click the “Verify now” button to verify your payment method: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1631413861/42c3b13d7fc44a11a88ec2b9cd03/AD_4nXeMx8QXpeZZCkfAnVSwx8KZ9n4Vr2rvPdQddyE6ZNxch__F6ZqFs1G4ZmU52Wvb7gRlwRqquTLdw8IQv-gICDyP-MXqiQK_Oe7gX3SKsCKKt2IEpMx4qDeMeeZufMaJfv16XgOH5g?expires=1793430000&signature=313a53c1caf8bcfe860fa27fc2ca46b6cefc1e3ba45175719692ded2b5fd8e98&req=dSYkF81%2FnolZWPMW1HO4zf7%2BjUfq64Dyn6MrEicvimCbXV2AwaY%2BEz%2BND7Nt%0AWDrNvi%2FL6JvmkaE%2BoZM%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1631413861/42c3b13d7fc44a11a88ec2b9cd03/AD_4nXeMx8QXpeZZCkfAnVSwx8KZ9n4Vr2rvPdQddyE6ZNxch__F6ZqFs1G4ZmU52Wvb7gRlwRqquTLdw8IQv-gICDyP-MXqiQK_Oe7gX3SKsCKKt2IEpMx4qDeMeeZufMaJfv16XgOH5g?expires=1793464200&signature=dc9a8229820d9266b110048837c03e5ad062c6f069d802575626f756f1e76844&req=dSYkF81%2FnolZWPMW1HO4zf7%2BjUfq7oTwn6MrEicvimC0gvdD4hOsfIry8IcK%0AYWjw4NUTrhW6aHWh2X4%3D%0A) ## What happens if I click “Remind me later?” diff --git a/content/support/11869629-use-claude-with-android-apps.md b/content/support/11869629-use-claude-with-android-apps.md index d7f1216bc..4a50f7834 100644 --- a/content/support/11869629-use-claude-with-android-apps.md +++ b/content/support/11869629-use-claude-with-android-apps.md @@ -222,7 +222,7 @@ Permission requirements vary by feature: For features requiring permissions (like location or calendar access), Claude will request permission contextually with clear explanations of why the access is needed. You’ll be prompted to approve the action with three options: Allow once, Always allow, or Don't allow. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1707351614/ccb910e4b87b1e96ad9a11bbd835/b57b2130-d8d6-4499-89f6-6c12de236fd4?expires=1793430000&signature=9fbae6017565d109cf17a6aeba5f82ea936bbc4e43c1890a6ad0b86fcf7aa053&req=dScnEcp7nIdeXfMW1HO4zQe5G1yL2CX0S5x65TIld%2FBuSIg%2FE7SlMXyPaUXm%0Ay8WSJghZp0mHgcbz5Ec%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1707351614/ccb910e4b87b1e96ad9a11bbd835/b57b2130-d8d6-4499-89f6-6c12de236fd4?expires=1793464200&signature=00e75a001216d6eec4856fb1109113bb633a47745251849785c3ca44bdd9f5e0&req=dScnEcp7nIdeXfMW1HO4zQe5G1yL3SH2S5x65TIld%2FDmxMuN665UIo6LQTRb%0AoixKvAl5VucyYAQuBno%3D%0A) These permissions can be managed at any time in your device settings by going to Settings > Apps > Claude > Permissions. Click into each permission listed under **Allowed** and **Not allowed** to make changes. You can toggle between “Allow only while using the app” or “Ask every time” to change Claude’s access, or remove permissions by choosing “Don’t allow.” Claude will only request permissions if needed for specific features, and you can always choose to decline while still using other capabilities. diff --git a/content/support/12005970-manage-usage-credits-for-team-and-seat-based-enterprise-plans.md b/content/support/12005970-manage-usage-credits-for-team-and-seat-based-enterprise-plans.md index 2eaa847cd..89a5e8397 100644 --- a/content/support/12005970-manage-usage-credits-for-team-and-seat-based-enterprise-plans.md +++ b/content/support/12005970-manage-usage-credits-for-team-and-seat-based-enterprise-plans.md @@ -70,7 +70,7 @@ After navigating to **[Organization settings > Usage](https://claude.ai/admin-se The **Usage and spend limits** section will show the current limit (if any) or **Unlimited**. Clicking on "Adjust limit" opens a modal where you can either input an amount and click "Set spend limit," or click "Set to unlimited" to remove the organization-wide monthly spend limit. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2149347604/936ac4eb025d3ef1f00c3b8a26b0/image.png?expires=1793430000&signature=2a318e815ce546c9cdfedf345658119591e446732e3481ab6f54a0afc9b09bb8&req=diEjH8p6modfXfMW1HO4zQHwgqLTlS6m6DwhVVpk1mAlGMPhzqQQEw1%2F6rTH%0AW38ubPtTcWWJuXBYJNs%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2149347604/936ac4eb025d3ef1f00c3b8a26b0/image.png?expires=1793464200&signature=fb8f85b4f77a4a4a8f618c37ccac6a7cddfbb20b6d579438e715305fb646c6bd&req=diEjH8p6modfXfMW1HO4zQHwgqLTkCqk6DwhVVpk1mCT8XK2sudnM5Vo7Flx%0AdsBdT1IKnZH%2BKcGrSsI%3D%0A) Changes to your organization’s overall spend limit go into effect immediately. @@ -78,11 +78,11 @@ Changes to your organization’s overall spend limit go into effect immediately. Owners and Primary Owners on **seat-based Enterprise plans only** can set spend limits that apply to all users within a specific seat tier. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2149351600/c5b979c366ac2738f60ea84e85b3/CleanShot+2026-03-10+at+15_37_41%402x.png?expires=1793430000&signature=fc1fc6c407468a3b75667eb989ea51d2632aa370bac075033682ea767f8969c1&req=diEjH8p7nIdfWfMW1HO4zYnqMYaQIHCJ0wfO62ivdG%2FTtAfsLGFQ3bFZiRNy%0AiV2%2Fs7PUdBmMbEPCFlE%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2149351600/c5b979c366ac2738f60ea84e85b3/CleanShot+2026-03-10+at+15_37_41%402x.png?expires=1793464200&signature=2f9fd711226ff9d8194291fd870cc628e90ee88972e7f588bbd541905a41e472&req=diEjH8p7nIdfWfMW1HO4zYnqMYaQJXSL0wfO62ivdG90%2F5QZr3vUxBR5J0JG%0APQcwxNxROEf2RKX51DY%3D%0A) Select the "By group" tab to see **Standard seats** and **Premium seats** groups. Click the "..." icon next to the current limit, then "Edit limit." This opens a modal where you can either select "Set dollar amount" and input an amount, or click "Unlimited" to remove the limit for that seat type. Click "Set limit" to save your changes. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2149362056/44993661ca2db771fe924d0346f6/image.png?expires=1793430000&signature=054a2809b1779772fc41ddd1dd34c4dd58327253f5798100cd93dbe56f4bd369&req=diEjH8p4n4FaX%2FMW1HO4zRzvvYYPc01Gq7nEDCGq9G5%2BfvQaUQUYyZ%2FB7rQx%0AlNr8J4IN44XtP5BwR9U%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2149362056/44993661ca2db771fe924d0346f6/image.png?expires=1793464200&signature=d314f6a42001090aaf273e6720eeb30c4ac737d1df35b083237600c2d9a6c094&req=diEjH8p4n4FaX%2FMW1HO4zRzvvYYPdklEq7nEDCGq9G4NJF%2BaAjH6ImRlfDGG%0Axt9APKL0%2B2ZYEhzXTFI%3D%0A) --- @@ -90,11 +90,11 @@ Select the "By group" tab to see **Standard seats** and **Premium seats** groups Owners and Primary Owners can also set individual monthly spend limits for each member by finding **Spend limits by user** and clicking the "..." button next to the user, then "Edit limit." -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2149370853/db66f5cd03683b9cc119d0dcd6b8/image.png?expires=1793430000&signature=7da4f079aa4484403a42185a7ed9a941f2ff8cabd97ef61c951bc705d45ca28e&req=diEjH8p5nYlaWvMW1HO4zaPdGARTVi9Ge9HwvwG7ubh3vHFiHPkH%2Fw1XUKi6%0AbbrwX83aK9fKY9%2BT25M%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2149370853/db66f5cd03683b9cc119d0dcd6b8/image.png?expires=1793464200&signature=525805dcfd9c23c90a154718a1c22e615aeec58c3467ca08c4c57260638e5e09&req=diEjH8p5nYlaWvMW1HO4zaPdGARTUytEe9HwvwG7ubhjD%2BPtSyxDJ8zDzrhH%0AKKSWCh9AA9YZQmuc3fY%3D%0A) Enter the amount and click "Set limit." Alternatively, selecting "Set to unlimited" will remove that member's monthly spend limit (they will still be subject to any organization or seat-level spend limits). -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2149374028/97813fe3b515c2e839d8d92abd79/image.png?expires=1793430000&signature=7d4db6d7abaa3d4c07bac90c1eff188ca756b74529f51786ddfbda0d03f58117&req=diEjH8p5mYFdUfMW1HO4zevsA%2FSOMOuKw6z2wGSwkbs2hryReKoKEKboiB9p%0Ai6Htjs%2BOZ1fqqUbYHIo%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2149374028/97813fe3b515c2e839d8d92abd79/image.png?expires=1793464200&signature=0cf3ea6efb68a6f727f912326a42705e67f1ea4150d92a55531f963164813193&req=diEjH8p5mYFdUfMW1HO4zevsA%2FSONe%2BIw6z2wGSwkbvi9ml4KrOLAJO1xwLr%0A%2Bo%2BoS5Zk9CnUajAJ%2BZM%3D%0A) This allows owners fine control over usage credits, so you can set limits for different members based on their roles or individual needs. Once a user reaches their defined spend limit, this will automatically pause their usage credits until the end of the month. They will need to wait for their usage limits to reset before using Claude again. diff --git a/content/support/12157520-claude-code-usage-analytics.md b/content/support/12157520-claude-code-usage-analytics.md index d86c5b80d..3eba293ae 100644 --- a/content/support/12157520-claude-code-usage-analytics.md +++ b/content/support/12157520-claude-code-usage-analytics.md @@ -46,7 +46,7 @@ The **Usage** tab displays the following metrics for your organization. Data on - **Top commands**: The Claude Code commands used most often across your organization. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1717579277/46c512f4b3ed05c359cecd78ed5c/e0ce2c19-39e2-411f-9a1f-cb1d46439a42?expires=1793430000&signature=7cf3cf1737ea6f0c3c8e17fd8eb9449b186eaec747a5160a5dad2b55fd1ba077&req=dScmEcx5lINYXvMW1HO4zfiEPqVUjHnOCX9h5MbdDjNbDzfGNwoYOngtf%2FoJ%0AziQgJ6tVBqINxsVChIU%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1717579277/46c512f4b3ed05c359cecd78ed5c/e0ce2c19-39e2-411f-9a1f-cb1d46439a42?expires=1793464200&signature=bd777abb7562893bf77b5b0259f822dfc2b9324e676c164f6171dce0fae23d1e&req=dScmEcx5lINYXvMW1HO4zfiEPqVUiX3MCX9h5MbdDjNj%2FaHMdWha%2Bgx4opfp%0AVre5cthHU%2FX4Ut0oAJw%3D%0A) ### User-level metrics diff --git a/content/support/12260368-use-incognito-chats.md b/content/support/12260368-use-incognito-chats.md index cc0b8f3d3..907f63ff4 100644 --- a/content/support/12260368-use-incognito-chats.md +++ b/content/support/12260368-use-incognito-chats.md @@ -34,7 +34,7 @@ These differ from regular chats in several ways: When starting a new chat with Claude outside of a project, you'll see a ghost icon in the upper right corner of your screen: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1719768744/c7a2fa56cf284e48472f3b9c4dbf/030563f8-9f97-4891-a749-9ae95968a063?expires=1793430000&signature=680b29e3a2296245339f6ef1d8ae43e533195c3510e073b3aada277dfdde7692&req=dScmH854lYZbXfMW1HO4zeUcugG5beWLDCAt3Cx%2FSO1ZRpY3ef%2BYNzLsTTBw%0Af3sDu4IkVbF72XJA3e8%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1719768744/c7a2fa56cf284e48472f3b9c4dbf/030563f8-9f97-4891-a749-9ae95968a063?expires=1793464200&signature=c46730d7040e11be53770d948d0fa1e9d1547e8141d7f348ef49995cb4e9c9b5&req=dScmH854lYZbXfMW1HO4zeUcugG5aOGJDCAt3Cx%2FSO0zT7Ao1CsbGexeapvL%0AcU1DihYG3o5odU%2FBjRc%3D%0A) 1. Click the ghost icon to enable incognito mode. diff --git a/content/support/12592343-enabling-and-using-the-desktop-extension-allowlist.md b/content/support/12592343-enabling-and-using-the-desktop-extension-allowlist.md index cf0bc34c0..dd49f74c2 100644 --- a/content/support/12592343-enabling-and-using-the-desktop-extension-allowlist.md +++ b/content/support/12592343-enabling-and-using-the-desktop-extension-allowlist.md @@ -20,11 +20,11 @@ The desktop extension allowlist is disabled by default, so an organization Owner 4. Switch to the "Desktop" tab: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1781755172/63c92550571842577ad435860ec5/6f5cc4e1-ff7d-48de-863a-c4e6184d4605?expires=1793430000&signature=fc4aed6826ee33f0174d9c5931719925af0afa368697e9e46b2599bcf5810249&req=dScvF857mIBYW%2FMW1HO4zQ9pXEkO%2FHDb0ugSQm1MFW%2FvsVl7gxCNuwouA7wf%0AF8Y1%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1781755172/63c92550571842577ad435860ec5/6f5cc4e1-ff7d-48de-863a-c4e6184d4605?expires=1793464200&signature=ba9fa2006966354132fc5810f568c1e76164c035460607909905536f2e9fc8a4&req=dScvF857mIBYW%2FMW1HO4zQ9pXEkO%2BXTZ0ugSQm1MFW964tun%2F%2BmSJJsUTCGC%0AZ9em%0A) 5. Toggle **Allowlist** on: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1781755578/a6bafff5f084dc86ae463703fd3d/6cf0ee18-4e71-4129-98e8-cc08174e3c3a?expires=1793430000&signature=a003f8f867e7bb56197343774e7417fd13f052e1ff364591e5d94919d5fc9658&req=dScvF857mIRYUfMW1HO4zaj0BXIvSqcETAorLxpdoc%2F7Ja%2BFfQL%2BzqqxpSGo%0A2SPr%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1781755578/a6bafff5f084dc86ae463703fd3d/6cf0ee18-4e71-4129-98e8-cc08174e3c3a?expires=1793464200&signature=fe4f835765247cf029074a3b3e3dc8205c36b9974c5f7144e0c3a14804225ad6&req=dScvF857mIRYUfMW1HO4zaj0BXIvT6MGTAorLxpdoc%2BUCqeumBi%2BFcEIMRiU%0AKukK%0A) ## What happens after enabling the allowlist? @@ -42,7 +42,7 @@ Consider completing the allowlist setup during off-hours to minimize disruption **Important:** The allowlist requires Claude Desktop version 0.13.91 or higher, so users should update the desktop app by clicking “Claude”, then either “Check for updates” or “Restart to update to Claude 0.13.91”: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1781756960/ad18af50c83d35f2673656c23e00/a7ee450f-0c7d-42d6-a75f-fb1bc088cb52?expires=1793430000&signature=4cb8766bc4dfda471e28c0a5e2747eb2667804c63ca7d0fc5069171631cfa94a&req=dScvF857m4hZWfMW1HO4zYUJqICuCTLrCEDZ5AdBjIZFE9U3LPAs6rmlZpDN%0AphTOi%2B3bTdANlusdIb8%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1781756960/ad18af50c83d35f2673656c23e00/a7ee450f-0c7d-42d6-a75f-fb1bc088cb52?expires=1793464200&signature=bdec2dc1b870fbdd9ee526df57dd2483fb2c08e5d443d410fc2bd01a4c06f240&req=dScvF857m4hZWfMW1HO4zYUJqICuDDbpCEDZ5AdBjIZY7a7F%2BTb17TyMSccY%0A0c3Wap2pYJMIlmR%2Bq5k%3D%0A) ## Managing allowed extensions @@ -60,7 +60,7 @@ After enabling the allowlist, you can choose which extensions to allow: If you want to remove an extension from the allowlist, click the “...” button and “Remove from allowlist.” -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1781751250/6558c0f59aea7976bd44b0213d76/e750f02b-cd0d-437e-a83f-9ac362cdf456?expires=1793430000&signature=96d01ed9f23203fe541eeb482cbee4618a7b248a4bcb150e9342d0fbf05ab263&req=dScvF857nINaWfMW1HO4zTrxBKst%2FFeVqXridZhfx1IKx7AA408x38YYBj9w%0An%2B%2Bh44e4qy9KyjH1JYE%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1781751250/6558c0f59aea7976bd44b0213d76/e750f02b-cd0d-437e-a83f-9ac362cdf456?expires=1793464200&signature=f3673e16d5bf7e2915cacfb712728c8be8cbf796f004b658ad339cd05ecf4849&req=dScvF857nINaWfMW1HO4zTrxBKst%2BVOXqXridZhfx1I59Jci1XRDzUTwDg0k%0AmzwnX8Frf5W9czmU6CE%3D%0A) ## Uploading custom extensions diff --git a/content/support/12618689-use-claude-code-in-the-cloud.md b/content/support/12618689-use-claude-code-in-the-cloud.md index a3c37b57b..64b2f8240 100644 --- a/content/support/12618689-use-claude-code-in-the-cloud.md +++ b/content/support/12618689-use-claude-code-in-the-cloud.md @@ -10,7 +10,7 @@ This feature works with repositories you may not have on your local machine. You Cloud sessions enable asynchronous development workflows. In a local session in your terminal or editor, you typically work synchronously: you make a request, wait for Claude to respond, review the changes, then make another request. Synchronous work like this gives you fine-grained control but requires your attention throughout the process. A cloud session handles this differently: you can assign a larger task, let Claude work independently, and return later to review the completed work. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1786446157/07ec74cd46317f8278083a317841/6448f3ee-c6df-4417-8a13-90d8c2ca3d55?expires=1793430000&signature=511189f98625773a4e2ec7f8852f1e17cd311eb742d0cdbd7aae80293a7e9927&req=dScvEM16m4BaXvMW1HO4zR8%2BAVCEQZ127XrRA1YwWGt83j9e1BvY7I2epGMV%0AAoWZFVultH6SBrVwxFg%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1786446157/07ec74cd46317f8278083a317841/6448f3ee-c6df-4417-8a13-90d8c2ca3d55?expires=1793464200&signature=f03c153917c308ebbe869be69dcb240bcac8bc0f692843279bc4683ddc32d94c&req=dScvEM16m4BaXvMW1HO4zR8%2BAVCERJl07XrRA1YwWGsn0s04rNMqPAFcj6Ca%0A9ueb%2BHypU4i1jTx5XDA%3D%0A) You can also run multiple tasks in parallel. Since each task runs in its own isolated environment, you can have Claude working on several different issues or repositories simultaneously. Each task proceeds independently and creates its own pull request when complete. More than one task can work on the same repository at the same time. @@ -20,13 +20,13 @@ You can also run multiple tasks in parallel. Since each task runs in its own iso When you start a cloud session, Claude Code creates an isolated virtual machine for your work. Your GitHub repository is cloned into this environment, which comes pre-configured with common development tools and language ecosystems. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1786446158/c092f1383826cb871493f74169d4/97b7cb98-5da2-438e-a920-e170b8b9790e?expires=1793430000&signature=ea7a7fea1508df46cd7b383e7ffe4be7afd55f8270c5bd66be42072b656c8b3b&req=dScvEM16m4BaUfMW1HO4zcR0rJUwjOnA7DtpMiX%2FBYlKaJlXEhv8F2yd%2BtEl%0Agv%2BtIy7WAbXnuoklUVU%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1786446158/c092f1383826cb871493f74169d4/97b7cb98-5da2-438e-a920-e170b8b9790e?expires=1793464200&signature=22d2f64b6bfd51973129dd10f11e844ca2a9abde7f5626474427332e298c97ae&req=dScvEM16m4BaUfMW1HO4zcR0rJUwie3C7DtpMiX%2FBYlF8k5edATekAtRA%2Fa2%0AU%2FKpCZKWBmFk2wqc4RQ%3D%0A) Claude prepares the environment by running any setup commands you've defined in your repository's configuration. This includes installing dependencies, setting up databases, or running other initialization steps your project needs. If your task requires network access, maybe to install packages or fetch data, you can configure the level of internet access the environment has. Once the environment is ready, Claude begins working on your task. Claude reads your code, makes changes, writes tests, and runs commands to verify the work. You can monitor progress and provide guidance through the web interface if needed. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1786446156/83ecf0a5b98eddc9ffc9694c50f7/353589ce-b678-441d-8909-71b45fa2d065?expires=1793430000&signature=e7a0e29a258eb4c61c835d53a9f0a29edab0df318b6ed875185c2279880ecf47&req=dScvEM16m4BaX%2FMW1HO4zVbcTWCH4MTOUQl3YqgIJdZGmE%2FBz3MD3AKdhO5N%0AGd99FwiOiUj5Mf03qzw%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1786446156/83ecf0a5b98eddc9ffc9694c50f7/353589ce-b678-441d-8909-71b45fa2d065?expires=1793464200&signature=3745e880f049627888a095c81a19229c01a497c53ffd4db39c9a34f80536a768&req=dScvEM16m4BaX%2FMW1HO4zVbcTWCH5cDMUQl3YqgIJda7ik8UW%2FTbpvUb6wVK%0A8fP%2FFLeNcMnmxE0fVxk%3D%0A) When Claude completes the task, it pushes the changes to a new branch in your GitHub repository. You receive a notification and can review the changes, then create a pull request directly from the interface. The pull request includes all of Claude's work, ready for your review and any additional changes you want to make. diff --git a/content/support/12883420-view-usage-analytics-for-team-and-enterprise-plans.md b/content/support/12883420-view-usage-analytics-for-team-and-enterprise-plans.md index bb9ac5c69..8d43b7289 100644 --- a/content/support/12883420-view-usage-analytics-for-team-and-enterprise-plans.md +++ b/content/support/12883420-view-usage-analytics-for-team-and-enterprise-plans.md @@ -22,7 +22,7 @@ This page includes the following analytics: - Sessions in Cowork -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515895966/9f231a620f47d49e0ee648152189/848c1787-4eaa-4809-8fd2-1dbe2722560f?expires=1793430000&signature=2befc05a86e25fd3f4e768045fbecba915741e9f94cd2726393002af7089af9d&req=diUmE8F3mIhZX%2FMW1HO4zZL6wKV2mIVxExEG4dCAGDYvywu2cMEh6BD8k8bS%0AubfJYYt4yyneaem7Frg%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515895966/9f231a620f47d49e0ee648152189/848c1787-4eaa-4809-8fd2-1dbe2722560f?expires=1793464200&signature=0982d554deac03fa70bcb70991fb957ac4901b59589d9b1ebfa8474325888726&req=diUmE8F3mIhZX%2FMW1HO4zZL6wKV2nYFzExEG4dCAGDbPDn0K43u5lHljQJID%0A6bTc7l%2Bn2hSaTU2lTDg%3D%0A) ### Who’s using Claude? @@ -34,7 +34,7 @@ This page includes the following analytics: Use the dropdown on the **Active members and assigned seats** chart to filter by product, including Claude Design. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515896351/4d955858e6662c37489cc1470871/457cf159-8c2a-4403-ba22-cb92cb47e459?expires=1793430000&signature=34de6f80a5ec111024886de296766502eb6e24a5ca588cfbe736319c7c08a5b0&req=diUmE8F3m4JaWPMW1HO4zYEqezStQZCvYqPRsgaNdTxZ4tZg%2FCEEXE1snWp8%0ASNEBgSGsHSdq1lhuS7U%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515896351/4d955858e6662c37489cc1470871/457cf159-8c2a-4403-ba22-cb92cb47e459?expires=1793464200&signature=96bcd5ec4e8cf1d884112df6d1351bcc85e8625c6bd3dd82db5843f9f717ce6d&req=diUmE8F3m4JaWPMW1HO4zYEqezStRJStYqPRsgaNdTx92qkxRTIV3mztSgZ%2F%0ANc1Jt3YbvYH0m9r7ao4%3D%0A) ### How are they using Claude? @@ -48,9 +48,9 @@ Use the dropdown on the **Active members and assigned seats** chart to filter by - How agentic is their work? (beta) -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2583875713/e3cb3c329f3b643cb9a3809876b3/image.png?expires=1793430000&signature=fa9d969c5140b6bb9ea0d3e46c8f6d6ace0923043d698826b9acdcde8c238442&req=diUvFcF5mIZeWvMW1HO4zciS3Kvtmb5rDFD6TO7tG4h0DXiWeL9VlUreAKQP%0Aj1tSdTSIVy9nSVQWyK4%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2583875713/e3cb3c329f3b643cb9a3809876b3/image.png?expires=1793464200&signature=5d12e660b30a1c3c6bf7eb45eeb6b4b6efe8df15179f0be40fbb09f7ffd12878&req=diUvFcF5mIZeWvMW1HO4zciS3KvtnLppDFD6TO7tG4h0zKdiJUPKof9pYdNd%0ANCQHHRq0F1ytQji4LRc%3D%0A) -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515896563/abf008596ce5501297a609696362/fce5423c-4769-4b73-9a0a-c50f6407ebea?expires=1793430000&signature=da0928df2c3dc1aa085469af27323ba2132009927a381181b7eb6b1e9a5c8c46&req=diUmE8F3m4RZWvMW1HO4zR%2BID4Rqvvf3LS3kobW3ZgQwnLdvPKSBgLzyqAYv%0AjQCGlj5vf5SuQLbK%2FM4%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515896563/abf008596ce5501297a609696362/fce5423c-4769-4b73-9a0a-c50f6407ebea?expires=1793464200&signature=da894c4ff297578b2ed8360b599fa810aa76f6199fd2265ea56925cd14d3c3b9&req=diUmE8F3m4RZWvMW1HO4zR%2BID4Rqu%2FP1LS3kobW3ZgRQFV2w3jWlM0scP4gR%0A3OI1CuOPu6BWI0UYX0k%3D%0A) ### What are the results? @@ -66,7 +66,7 @@ Use the dropdown on the **Active members and assigned seats** chart to filter by - Estimated time saved -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515896943/dd415f03afe56ca38308ef987f86/189e8ebc-5594-4f4b-bd84-e3c11c824d5b?expires=1793430000&signature=b5aef116f6f64c8d9e8ff5686f0dfc75e1934fd42f6027f47e47e4a1a126b56f&req=diUmE8F3m4hbWvMW1HO4zfJThSc7qtxGiovaLYNN7Rn7yRdjx9lLbP45A3tz%0AeQKM%2BJcp3RfDCVSlCZY%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515896943/dd415f03afe56ca38308ef987f86/189e8ebc-5594-4f4b-bd84-e3c11c824d5b?expires=1793464200&signature=b4adfe442cdaaa1bb46c85b73f33b92f177dc8c504f8f0c4f81f8af0e8335a3e&req=diUmE8F3m4hbWvMW1HO4zfJThSc7r9hEiovaLYNN7RkFOj6hgzXdWmmud46t%0ANUBSf0XBxde%2BT7X%2Fkc8%3D%0A) ### How much is Claude costing? @@ -82,9 +82,9 @@ This section includes the following analytics: - Spend by model (month-to-date, quarter-to-date, year-to-date, 1 year) -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515896942/b403f2d216fc40b5195911020b8e/446b99f1-3187-4b79-b2be-9f17b1632ff8?expires=1793430000&signature=abd96a07e080a48b1b628f1aebfe065d1ceeabff035456de92dcbcea9338f5d8&req=diUmE8F3m4hbW%2FMW1HO4zYE%2BQt0G7zHdWbBLGZ4vBJX18uP7aVry%2BI5VzpPN%0AbAAVUKRA%2FP8CAUF14%2F0%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515896942/b403f2d216fc40b5195911020b8e/446b99f1-3187-4b79-b2be-9f17b1632ff8?expires=1793464200&signature=b1d3180ccfecc4572b7ee4e67f9894565443b6c27d8d5193fb217a7888c125d1&req=diUmE8F3m4hbW%2FMW1HO4zYE%2BQt0G6jXfWbBLGZ4vBJUYYTsJ6rwWq5f0CzNd%0AlsnBE54A%2FTeF9DrXP6I%3D%0A) -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515896941/2239ce38639df339b24d5af1cb50/f829bc2a-ee52-4135-9b13-09ef1b7d66d6?expires=1793430000&signature=cc0276a25e73a222e71144f3f1f93b675ca89148df380f2e0d6a5aecfe3ee354&req=diUmE8F3m4hbWPMW1HO4zTz0N%2BkGJMlQC%2BtvTPa1I7GuLtb%2FK%2F5V%2FQ82Vuyc%0A%2BskgS%2B72rePC%2FPoqGrU%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515896941/2239ce38639df339b24d5af1cb50/f829bc2a-ee52-4135-9b13-09ef1b7d66d6?expires=1793464200&signature=49ce7c3eeb1a1d9d1a550070d7d6b62976def373fd39b92aa6b9d6046c190804&req=diUmE8F3m4hbWPMW1HO4zTz0N%2BkGIc1SC%2BtvTPa1I7HvtO7YbAeRAhgjgXqt%0AJb8Ye%2Fkuh2QXNGbW6CE%3D%0A) **Note:** For a view of how spend limits are affecting your organization, you can also check the **Blocked by a spend limit** section at the top of **[Organization settings > Usage](https://claude.ai/admin-settings/usage)**. **Blocked by a spend limit** is built for usage-based Enterprise plans. Orgs without usage-based seats only see how many members are blocked or near their limit right now. Learn more about **[monitoring usage and spend on Enterprise plans](https://support.claude.com/en/articles/11526368-how-am-i-billed-for-my-enterprise-plan#h_ae17ec8236)**. @@ -162,7 +162,7 @@ Navigate to **[Analytics > Claude Chat](https://claude.ai/analytics/usage)** to - Top members by chats -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515898793/405db0c492da11886c28a2b82731/71a55afc-1cef-4c50-b7e1-86775cb9a168?expires=1793430000&signature=71aa3db15fdcfc551378e63dc109fab18cc0f59a1914c05835cc27c062890f1f&req=diUmE8F3lYZWWvMW1HO4zbhc8P6YYuQhTcfMEUwBBiXSBiLTkzUJQCc5MzT5%0AzKPiwLr5yF70SglL2QQ%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515898793/405db0c492da11886c28a2b82731/71a55afc-1cef-4c50-b7e1-86775cb9a168?expires=1793464200&signature=b3494e387eae4f7213f0705952574476e9df63c4ca2965109e7082078a847439&req=diUmE8F3lYZWWvMW1HO4zbhc8P6YZ%2BAjTcfMEUwBBiWIohRmYBOp%2FmcF9K%2B9%0AYftwEILAnOnQmM8K2Ss%3D%0A) ### Projects @@ -174,7 +174,7 @@ Navigate to **[Analytics > Claude Chat](https://claude.ai/analytics/usage)** to - Top members by project usage -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515899610/91d93108f0767e795fb9e488e882/71607d6d-dff1-4a13-a445-aa1d79850eed?expires=1793430000&signature=c886afe8aa79867d048358bb6572f07c8592f9171f80e1c22463ebd62a8da0d7&req=diUmE8F3lIdeWfMW1HO4zWhGoD%2BdmCOiExu5cYiHHN8mbiJ3C6mNnl1teKQD%0Ad8EjUrlwk5CkXMyDRpY%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515899610/91d93108f0767e795fb9e488e882/71607d6d-dff1-4a13-a445-aa1d79850eed?expires=1793464200&signature=f4ff91365098a78eafd30adf5f992de2ccebd0e2cc632ac6146a3e598d832897&req=diUmE8F3lIdeWfMW1HO4zWhGoD%2BdnSegExu5cYiHHN%2BG0tkqTVJaVhgO7BIp%0AzQ3RfcBaz4MsHlyN3Wc%3D%0A) ### Artifacts @@ -184,7 +184,7 @@ Navigate to **[Analytics > Claude Chat](https://claude.ai/analytics/usage)** to - Top 10 users by artifacts generated (month-to-date, quarter-to-date, year-to-date, 1 year) -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515899838/33d737f2357d6e485704669962ae/43faadc3-47da-4a93-bbb7-47a7983e7441?expires=1793430000&signature=f8b158865f88cc95efa9a3070a71c0b2e2254a0b8617761a07da766a6d1d33a7&req=diUmE8F3lIlcUfMW1HO4zcSk47nWfe7AjHDogqK0V%2BzjClTUWtq351%2B%2F69Ir%0A6qLk1U5xWOGx9cjLaxY%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515899838/33d737f2357d6e485704669962ae/43faadc3-47da-4a93-bbb7-47a7983e7441?expires=1793464200&signature=643031b48d8834e9159e62d7d2a9bca6ffd27e2dd28e3439573757118f368efd&req=diUmE8F3lIlcUfMW1HO4zcSk47nWeOrCjHDogqK0V%2BwryvH8p4dMqrA0j7YP%0AI1VTwBmGRAuYShQSkkg%3D%0A) --- @@ -280,7 +280,7 @@ Navigate to **[Analytics > Cowork](https://claude.ai/analytics/cowork)** to view - Daily, weekly, and monthly active Cowork users -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515901489/8005693d55b7fefbfe9233258d39/106c22a0-3f47-47a6-abbd-4788dd70f218?expires=1793430000&signature=1c6b022fb1015fc163643049a7f5d5721cf6bd9cea8a499e79d1f4ddcdfbf9fe&req=diUmE8B%2BnIVXUPMW1HO4zX7WE4u1XkGoFSi1Z3SzLLvHPmOLKhUr61Qmb50F%0A53%2BzCasD%2B8EvFHP3CS8%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2515901489/8005693d55b7fefbfe9233258d39/106c22a0-3f47-47a6-abbd-4788dd70f218?expires=1793464200&signature=d0513f051c4ab1b27da19cb9dcc26eb7f0a149b8371fe5227cf8d357a94e23e9&req=diUmE8B%2BnIVXUPMW1HO4zX7WE4u1W0WqFSi1Z3SzLLvz6%2F8MXm8IwaiJUm1M%0Aw4fMkXvnBHVYcDfkUbc%3D%0A) **Note:** Cowork analytics are available alongside Chat and Claude Code data in the **[Analytics API](https://platform.claude.com/docs/en/manage-claude/analytics-api)**. @@ -296,7 +296,7 @@ Navigate to **[Analytics > Surveys](https://claude.ai/analytics/surveys)** to as On Enterprise plans with usage-based billing, when your admin turns on individual usage analytics, any member of the organization can see their own usage broken down by product, model, and skill, along with where they stand against any spend limits set for them. Individual usage analytics are available in **[Settings > Usage](https://claude.ai/settings/usage)**. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2533906328/1f5cd0a57def40676410f8f379b4/member-usage-30d-model.png?expires=1793430000&signature=0a30445a8f113c019f2c33468445e18b5f7dedcb25aa734beeea3d752fff6924&req=diUkFcB%2Bm4JdUfMW1HO4zfveBqzBf%2BvaWGUKUw6QS4%2BHaZFPTM%2F4N4a9Aj2U%0AgGlB0r2dNeMxjMdHmcI%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2533906328/1f5cd0a57def40676410f8f379b4/member-usage-30d-model.png?expires=1793464200&signature=f087ab4f709a38cc4a78809e51322d17ea09f4235e894a25b24c59b9312353d1&req=diUkFcB%2Bm4JdUfMW1HO4zfveBqzBeu%2FYWGUKUw6QS4954%2BrvVY0EV4OCyGeb%0A0LQONfxNaofs4%2FFp7Yk%3D%0A) --- diff --git a/content/support/12997503-team-plan-billing-faqs.md b/content/support/12997503-team-plan-billing-faqs.md index 54d4674d7..1426d630d 100644 --- a/content/support/12997503-team-plan-billing-faqs.md +++ b/content/support/12997503-team-plan-billing-faqs.md @@ -18,7 +18,7 @@ Your organization's billing address determines where your invoices are sent. You If you want to use a name other than the one tied to your payment method, an organization Owner should check the "Use a different name on invoices" box when adding or updating your payment method in **[Organization settings > Billing](https://claude.ai/admin-settings/billing)**: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1922145253/f2e3d4e0fe43a2ea07e89244764c/image.png?expires=1793430000&signature=47f79e4ef9b18a907104098792266cab9b2301033bb9dfe9db1476bb6485d1b7&req=dSklFMh6mINaWvMW1HO4zRZTxVnFuMvTKAqLF4ERnlWgVtWJvjMw%2BmW0PNcR%0ArH%2BmetxPA%2BcihiOfiew%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1922145253/f2e3d4e0fe43a2ea07e89244764c/image.png?expires=1793464200&signature=346625f362bff75d89116eebb5c18b94ce46947b95a10b4ff75fa12bd6b5b167&req=dSklFMh6mINaWvMW1HO4zRZTxVnFvc%2FRKAqLF4ERnlXiuGtPUmG2dW8dDP%2Bx%0AvLxlCmmWjUOPYA%2BGLcc%3D%0A) ## When will I be billed? diff --git a/content/support/13132885-set-up-single-sign-on-sso.md b/content/support/13132885-set-up-single-sign-on-sso.md index 90a7aa114..4d22e0ec3 100644 --- a/content/support/13132885-set-up-single-sign-on-sso.md +++ b/content/support/13132885-set-up-single-sign-on-sso.md @@ -42,7 +42,7 @@ You can verify multiple domains for a single organization, but all domains must 3. Enter the domain(s) you want to verify in the **Update organization email domains** modal and click the “+” button: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2498843282/561d5ceb1c3a5df75bdfee8bfc3f/d2491145-362d-490b-bdcf-66a0a7656ddc?expires=1793430000&signature=44b84d01b9bdc2dc8611bd926004ceb10c5403c095861d8d7df52031bb289c77&req=diQuHsF6noNXW%2FMW1HO4zSdmH389%2BcSMe3H0OpmIzWFQaNFumOXFCBT5MvU1%0APcHt%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2498843282/561d5ceb1c3a5df75bdfee8bfc3f/d2491145-362d-490b-bdcf-66a0a7656ddc?expires=1793464200&signature=08b9e8643587b114f34fdb67f31313352bdadf50bf9e7fa49b52ac65de94e1a3&req=diQuHsF6noNXW%2FMW1HO4zSdmH389%2FMCOe3H0OpmIzWGQemPzhwRJ%2BVTge4JC%0A8RP3%0A) 4. Click “Save” when you’re finished adding domains. @@ -50,7 +50,7 @@ You can verify multiple domains for a single organization, but all domains must 6. Enter your domain in the text box and click “Continue”: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2047042630/0617a562cd28a7ff0e607d66a30b/6bd08e1d-2b65-40ab-bc79-a257153854c1?expires=1793430000&signature=8897a45cb4a4cdf350ec4c7cb783a7a57ce738c8dc61e3131406fa2dc4c1ce8e&req=diAjEcl6n4dcWfMW1HO4zWHctB6TlNGqyoyXAW0OlXrY5Dp4i8t2VOkJL0ni%0ANGKX%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2047042630/0617a562cd28a7ff0e607d66a30b/6bd08e1d-2b65-40ab-bc79-a257153854c1?expires=1793464200&signature=c1f2f4ac6bd2ea7b8543892d91e080148cf6f43376f3219ca0ab4d65773f3e2a&req=diAjEcl6n4dcWfMW1HO4zWHctB6TkdWoyoyXAW0OlXqwhXRpcX4%2B4c%2BysEmU%0AsaXC%0A) 7. The setup screen displays a TXT record. **Copy the full Value using the copy button**—it begins with `anthropic-domain-verification-` and is longer than what's visible in the box. In your DNS provider, add a TXT record to your domain and **Value** set to the copied string. The domain must match exactly what you entered in the previous step, including any subdomains. Add it alongside any existing TXT records; don't replace them. The value is case-sensitive, so paste it exactly. Please refer to your DNS provider's documentation on this topic. @@ -76,7 +76,7 @@ Clicking "Refresh" re-checks your DNS; it won't show Verified until the publishe If the record is correct and propagated but the status still shows Pending, contact Support. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2047044496/b8df54a0331784cc9ae8f00112aa/bf9609c1-dc93-4665-a066-4cae2fe4b002?expires=1793430000&signature=16af968f44230c06427a5d4827e9d4b4e3d63508c61f0079c090b95ef286015c&req=diAjEcl6mYVWX%2FMW1HO4zVjmWCoEbHS5PM2D8Zcdgrjfmdpgd3phLKulQgLy%0AVYhHNbsFsFRxRcQX0Ow%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2047044496/b8df54a0331784cc9ae8f00112aa/bf9609c1-dc93-4665-a066-4cae2fe4b002?expires=1793464200&signature=6d764e7ff4a32d7c2fb8891b009524d26159298d97365e2f98c0806e6d0e2633&req=diAjEcl6mYVWX%2FMW1HO4zVjmWCoEaXC7PM2D8Zcdgrherft3MhxJbPl%2FZhws%0AmF7PktKXWsWQby6pmqg%3D%0A) **Note:** Once your domain is verified, you'll see a **Restrict organization creation** toggle under **Security** on the Organization and access organization settings page. Enable this if you want to prevent users from creating new Claude or Console organizations—including personal accounts—using your verified domains. @@ -116,7 +116,7 @@ For IdP-specific setup instructions, see: You can now choose to toggle on **Require SSO for Console** and/or **Require SSO for Claude,** on the **Organization and access** page, under the **Authentication** section: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2312690200/bd2403586d4f6651ccd79e2a45af/b9f8d7ce-0def-49d9-bfb2-3a14352d7214?expires=1793430000&signature=3178512277a53e727aa9484602654f7514fa6b4b50b1449207f3145b5331af4b&req=diMmFM93nYNfWfMW1HO4zdAICgylAXwKItXtKivx6ZHtzxQeATa%2BxQcOcOlF%0A00nh4nbOUnoZUgOFlDY%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2312690200/bd2403586d4f6651ccd79e2a45af/b9f8d7ce-0def-49d9-bfb2-3a14352d7214?expires=1793464200&signature=19cd4367cdd995417ebe20ebb749f75974337d5c13cfb88267955c1f88b74d83&req=diMmFM93nYNfWfMW1HO4zdAICgylBHgIItXtKivx6ZEZJiXcR95Z4LzwUTu8%0AbR1p%2BmXE1AP384BYhro%3D%0A) When SSO is required, users must use the “Continue with SSO” option to log in to their Claude/Console accounts. When SSO is not required, they will have the option to choose “Continue with SSO” or “Continue with email.” diff --git a/content/support/13133195-set-up-jit-or-scim-provisioning.md b/content/support/13133195-set-up-jit-or-scim-provisioning.md index a461f51e6..43630f01b 100644 --- a/content/support/13133195-set-up-jit-or-scim-provisioning.md +++ b/content/support/13133195-set-up-jit-or-scim-provisioning.md @@ -40,7 +40,7 @@ Use this table to help decide which provisioning mode is right for your organiza Both JIT and SCIM can be combined with **Enable group mappings** to control role or seat tier assignment based on IdP group membership. If you select either of these options for your provisioning mode, **Enable group mappings** will appear within the **User provisioning** section: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2312706099/35d5d3ec149880a96bb7acec59f6/a4cfce55-86bf-40b0-b455-c8f412d48e9e?expires=1793430000&signature=2a21805d743181f3413226bd175463057d563308d54b3c6ea0f692603add5b8e&req=diMmFM5%2Bm4FWUPMW1HO4zXBDQqhQDlp2xFMG%2BIEvQScy%2FeJEVD5JHnixdmND%0AcA8ExIpG6H8kQo%2FxIW4%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2312706099/35d5d3ec149880a96bb7acec59f6/a4cfce55-86bf-40b0-b455-c8f412d48e9e?expires=1793464200&signature=a20768eff1bdd0c750f9efa827706c82579bd58b318f38339a7c4227b59d0b1a&req=diMmFM5%2Bm4FWUPMW1HO4zXBDQqhQC150xFMG%2BIEvQSdA5I3w00iowFDxE9Sv%0Avn7xJbdFLFoN%2Fz%2BaoaU%3D%0A) **Important:** Group mappings set a user’s role type and seat tier only. Users with the Custom role get their permissions from groups in Claude, and those groups sync from your IdP only when your provisioning mode is SCIM directory sync. With JIT, you need to create groups and add users to them manually in **[Organization settings > Groups](https://claude.ai/admin-settings/groups)**. If you map an IdP group to the Custom role under JIT without doing this, those users have no permissions when they log in. Learn more about **[managing groups on Enterprise plans](https://support.claude.com/en/articles/13799932)**. @@ -136,7 +136,7 @@ Learn more about **[setting up role-based permissions on Enterprise plans](https 4. Toggle **Enable group mappings** on (if it’s not already): - ![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2312714635/b57870b51e6511c8293637bceee2/da1ceabc-b6bc-451b-9cda-24ff6aa90d02?expires=1793430000&signature=3272200e58b05b282449e1e5480f3271db658452b94ee1ce3d35db544ef656af&req=diMmFM5%2FmYdcXPMW1HO4zeBEb8bclPpIyb72rapuHpNEe%2Bi%2Bi1BCcclzWcdt%0AN02w%0A) + ![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2312714635/b57870b51e6511c8293637bceee2/da1ceabc-b6bc-451b-9cda-24ff6aa90d02?expires=1793464200&signature=52f206b9493fe5cd1f40bb89f95f929190a6bcce9291986847c12e6378e258f6&req=diMmFM5%2FmYdcXPMW1HO4zeBEb8bckf5Kyb72rapuHpN%2B6Mtg%2FcIgBHPaoXSq%0AeN8F%0A) 5. In the **Enable group mappings** section, click “Add” next to each role and select the corresponding group from your IdP in the dropdown. @@ -188,7 +188,7 @@ Verify you have enough seats purchased and available to add members to your org. 4. **For SCIM:** Click "Sync" to prompt an immediate sync, or wait for the automatic sync cycle: - ![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2312717421/c97fce49ad17d4660880a05fbaaf/59fbfa2a-1072-4662-8ca5-102970d5a795?expires=1793430000&signature=67edf80d38e0d250e53fd514ecad8273bf6bf0b5fba7ad1e7bd23c85aeffc5f4&req=diMmFM5%2FmoVdWPMW1HO4zZ9Lal6pGsrC5hujYvMis4ds90oZVAPsPPGxRZ5g%0AgE6G%0A) + ![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2312717421/c97fce49ad17d4660880a05fbaaf/59fbfa2a-1072-4662-8ca5-102970d5a795?expires=1793464200&signature=07cce1ec13603e7b21bc32ff77b8a89c3ea6cfd8267e6f5d57ecbf08c58d2464&req=diMmFM5%2FmoVdWPMW1HO4zZ9Lal6pH87A5hujYvMis4eOCUGUjcNDVFJZUpge%0AMUD1%0A) ### Users mapped to the Custom role can't access anything after logging in diff --git a/content/support/13163631-configuring-session-security-settings.md b/content/support/13163631-configuring-session-security-settings.md index d74e47001..1b94d598b 100644 --- a/content/support/13163631-configuring-session-security-settings.md +++ b/content/support/13163631-configuring-session-security-settings.md @@ -18,7 +18,7 @@ Session duration controls allow Enterprise and Console Admins to set a maximum s 5. Confirm your selection by clicking “Enable.” -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1888469436/1725e63ea1a2615948faecf4ec73/9bd276a1-7329-414d-87a1-d04dac93fff7?expires=1793430000&signature=51d1ce779488e58821a5fafc6fddec8e4eb8135516f1258e89c66d3a74faf5cf&req=dSgvHs14lIVcX%2FMW1HO4zQNx6uEjQFpQg%2F6XaftFnjwVjlO%2BOBey5HkLnLhT%0Ao8WZesRYMpjKj3sxmK0%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1888469436/1725e63ea1a2615948faecf4ec73/9bd276a1-7329-414d-87a1-d04dac93fff7?expires=1793464200&signature=7debfccfc9ea703b2b06ad462cdee3d734e2d2561f34035a9d2923ee286da048&req=dSgvHs14lIVcX%2FMW1HO4zQNx6uEjRV5Sg%2F6XaftFnjwDju2bx5JspzYmTt%2Bd%0AOXTfw4wxJ6zsmNzpA1A%3D%0A) ### For Console Admins @@ -32,7 +32,7 @@ Session duration controls allow Enterprise and Console Admins to set a maximum s 5. Confirm your selection by clicking “Enable.” -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1888469435/7a766bbe02e61c7d8f05deb5b8f0/b0bda400-47c6-43dd-9907-131ebe180b36?expires=1793430000&signature=2e496d3b1239a0a373ba0f837ff9cb06d60c95f40a01bcf97cb60911f06ae3b5&req=dSgvHs14lIVcXPMW1HO4zWzx2boyJH8hXZ5D7eVpMtfI3lzz4lI1bVWO38Pw%0AINz%2BongDI65kczhW%2FE4%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1888469435/7a766bbe02e61c7d8f05deb5b8f0/b0bda400-47c6-43dd-9907-131ebe180b36?expires=1793464200&signature=6ba3a7ab692b5020c7bf3f45c20ec55b1d28c8b9ac5aa494b59e52ff7c5c9e98&req=dSgvHs14lIVcXPMW1HO4zWzx2boyIXsjXZ5D7eVpMtfnmfwMhbvnJ6nQMsWc%0Awi%2BR7yBCZ6KRnWr54b0%3D%0A) ### What happens after enabling shortened session length? @@ -50,7 +50,7 @@ You can change the session duration at any time by selecting a new value from th - Sessions scheduled to expire beyond the new duration will have their expiration shortened accordingly. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1888469437/46ac5bc55484ca01556d87a5ade7/b01a7651-ad65-4b32-93ff-16dbc9ca97c0?expires=1793430000&signature=c0b924d780ba062d2abbfffcab013e34d33c5aeac13f009f277a033171c6c0ac&req=dSgvHs14lIVcXvMW1HO4zZ7mW8uf5DmjA00cbyPOLDUqP26uA%2FCCuHOclzRL%0A80nkYoGI8%2FfMu%2Fm0jLg%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1888469437/46ac5bc55484ca01556d87a5ade7/b01a7651-ad65-4b32-93ff-16dbc9ca97c0?expires=1793464200&signature=13d1746185d7fd1a884659d636a0d5a290284fcaeef79d36281e74b1f2d461f4&req=dSgvHs14lIVcXvMW1HO4zZ7mW8uf4T2hA00cbyPOLDWUjYOpy3ZjXthSlLQd%0AUz6dOGmyhDIlKciuqig%3D%0A) ## Disabling session length settings diff --git a/content/support/13189465-log-in-to-your-claude-account.md b/content/support/13189465-log-in-to-your-claude-account.md index b7255a651..7292e34da 100644 --- a/content/support/13189465-log-in-to-your-claude-account.md +++ b/content/support/13189465-log-in-to-your-claude-account.md @@ -2,7 +2,7 @@ When you open Claude on a web browser ([claude.ai](https://claude.ai)), the desktop app, or a mobile app, you will see two different options for logging in to your Claude account. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1893216804/f2209c3ec6cf4fc2e803d13bbc9d/40520c9e-ff82-4a7c-adca-5a064fe18d8c?expires=1793430000&signature=e78d06192979d1028e44347897b7cd4cbb368c9134d6f7677db67af17d06e216&req=dSguFct%2Fm4lfXfMW1HO4zXg5B4GI4BK0zWhrqpWiTMmptedI%2B5HGCl6jfTLk%0AvlF1sTbV7XrMO5QWxJc%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1893216804/f2209c3ec6cf4fc2e803d13bbc9d/40520c9e-ff82-4a7c-adca-5a064fe18d8c?expires=1793464200&signature=62ff637b727322a658ad57dd8e0edc1e4789d2cf42d52dc8207b50a6a01b0732&req=dSguFct%2Fm4lfXfMW1HO4zXg5B4GI5Ra2zWhrqpWiTMkk2RRWlW%2FWYVimcwSr%0A4L3R6etNf36rL0oN3sw%3D%0A) ## Continue with Google diff --git a/content/support/13325567-account-management-faqs.md b/content/support/13325567-account-management-faqs.md index 28f17831f..d41ed2bdc 100644 --- a/content/support/13325567-account-management-faqs.md +++ b/content/support/13325567-account-management-faqs.md @@ -44,6 +44,6 @@ The email domain that was used to create your Team or Enterprise plan organizati Owners can remove domains by opening up the same modal and clicking the trash can icon to the right of the domain: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2053873852/1cbccea3b7067e03205f2ff8546b/CleanShot+2026-02-11+at+11_16_07%402x.png?expires=1793430000&signature=c40aebfab212b633eca573bd2881fe2566f07d7e36940864061744b500c5ac2b&req=diAiFcF5nolaW%2FMW1HO4zUrhF%2BicaggakeFUnrkrQZiZaimRDQgERa2rkK4J%0AxxdhUSC%2Bczo92IgWmZs%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2053873852/1cbccea3b7067e03205f2ff8546b/CleanShot+2026-02-11+at+11_16_07%402x.png?expires=1793464200&signature=c776c2bd0bc176ff128a222b7daf5285b935047285a0d05bd31aec65d4086fbb&req=diAiFcF5nolaW%2FMW1HO4zUrhF%2BicbwwYkeFUnrkrQZitj5lzVBvTJu9CsCzm%0Ao3okWK1o%2FHsMB2HvYOs%3D%0A) While the account creator must use a business email address, you can add public domains like @gmail.com, @yahoo.com, and @hotmail.com as allowed domains for other members of your organization. \ No newline at end of file diff --git a/content/support/13371040-log-in-to-your-console-account.md b/content/support/13371040-log-in-to-your-console-account.md index ea71fb6a4..e6d5433b2 100644 --- a/content/support/13371040-log-in-to-your-console-account.md +++ b/content/support/13371040-log-in-to-your-console-account.md @@ -2,7 +2,7 @@ When you navigate to the **[Claude Console](https://platform.claude.com)**, you will see two different options for logging in to your Console account. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1935026646/d90d1613a3dbe763fef5abb96e3c/image.png?expires=1793430000&signature=172654cef06235f73e688b650f2929d9d51984faeaa0cd8d56309942b73a4524&req=dSkkE8l8m4dbX%2FMW1HO4zcrI5oroo4AN8vUNcPt4%2B72AII8x1sidtyXKEg6h%0AsmNOGmECt7ZASGrjmGo%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1935026646/d90d1613a3dbe763fef5abb96e3c/image.png?expires=1793464200&signature=a4be1161be8f4e6be62b556643570f204abbe0a3f77b2e53d3d72eb41d9dfc5c&req=dSkkE8l8m4dbX%2FMW1HO4zcrI5oropoQP8vUNcPt4%2B71wQinK8ZNYLEGQZXgi%0AUB3w2zfXVooDxoAXckk%3D%0A) ## Continue with Google diff --git a/content/support/13641943-visual-and-interactive-content.md b/content/support/13641943-visual-and-interactive-content.md index f074c9807..025f53e3b 100644 --- a/content/support/13641943-visual-and-interactive-content.md +++ b/content/support/13641943-visual-and-interactive-content.md @@ -18,7 +18,7 @@ Claude can show current weather conditions and forecasts when you ask about the Claude automatically displays temperatures in Fahrenheit for US locations and Celsius for everywhere else. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2040544927/3a9c695b24df387ecdd766ad308c/8be9f393-dcb0-4ff8-89e8-5fa47bedaa38?expires=1793430000&signature=679bbbf3008e800cf04ad781f572fa0b47b9adf1e550c9ea603e4b2fe1b148f5&req=diAjFsx6mYhdXvMW1HO4zXlB7D2%2B1hiIdgndksVD5R1e5RsZ%2BTLSyh2JgbtK%0AMPfa%2Bo3VrUg%2FkHmrbxY%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2040544927/3a9c695b24df387ecdd766ad308c/8be9f393-dcb0-4ff8-89e8-5fa47bedaa38?expires=1793464200&signature=d5ef612c055c72bcafb49182293e2d5f77263029e339d4aa298e5705d514f099&req=diAjFsx6mYhdXvMW1HO4zXlB7D2%2B0xyKdgndksVD5R3O8sVHjWMJXO1YdwOw%0A7HnbwwGOPH5VmO%2Ff3Po%3D%0A) Weather is powered by Google Maps (). @@ -28,7 +28,7 @@ When you ask about recipes, Claude can display formatted recipe cards that are e **Note:** Visual recipe cards are available on web and desktop only. On mobile, Claude provides recipe information as text in the conversation. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2040544929/12f4c51eda7779d65d3ea2c7ab16/d0f4a314-cff8-421a-b401-10c2bf50374e?expires=1793430000&signature=675d7eb50ebcf0dd30d48c4a16439f16fea4719665538ab715ea62705522b51e&req=diAjFsx6mYhdUPMW1HO4zUQperMR0VSXrIPm%2FImZVg2MY6r8mhQRZqwcS8kA%0AUSUqedZAtUKKS277MpM%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2040544929/12f4c51eda7779d65d3ea2c7ab16/d0f4a314-cff8-421a-b401-10c2bf50374e?expires=1793464200&signature=da66c14ba2dbdbb8e3732de230dd60466b39363a9230211189d89592329e1d33&req=diAjFsx6mYhdUPMW1HO4zUQperMR1FCVrIPm%2FImZVg0InQ5I9HDEgSkHH6v0%0Aba0tFti3Obi9IlQ0jTY%3D%0A) ### Custom visuals @@ -76,7 +76,7 @@ For example, if you ask Claude to help you plan a trip, it might ask you to: This content appears at the bottom of the chat. You can still type a response if you prefer. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2040544930/9ad066e137d11e4b559b0217e12d/9bf30d2d-1715-42b3-9da5-2a9298f41f08?expires=1793430000&signature=8f4e9473abadecfe291082a806effb7cc8be4bb1430d2ebf8c1f116c1a500208&req=diAjFsx6mYhcWfMW1HO4zWmF5va6ah6ix4wz0C7CTAJ%2Fj1mSlP2QfufMpTIF%0AeP1HOr7VEEq0LK3QFy4%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2040544930/9ad066e137d11e4b559b0217e12d/9bf30d2d-1715-42b3-9da5-2a9298f41f08?expires=1793464200&signature=c09e15247d7a56b1fb935492489a78fb420204894fb6e3bedd5ab97fe0123b94&req=diAjFsx6mYhcWfMW1HO4zWmF5va6bxqgx4wz0C7CTAKwzWUnuWDRUm22rbpD%0AfMHgiEIhos3X1Mvsvk4%3D%0A) --- diff --git a/content/support/13837440-use-plugins-in-claude.md b/content/support/13837440-use-plugins-in-claude.md index 1a5cb26fa..47e2ada8b 100644 --- a/content/support/13837440-use-plugins-in-claude.md +++ b/content/support/13837440-use-plugins-in-claude.md @@ -58,7 +58,7 @@ In Cowork, open the "Cowork" tab first, then open **Customize**. You can also upload a custom plugin file if you built one yourself. On Team and Enterprise plans, a colleague can share a plugin with you directly instead of sending you the file. See **[Use a plugin shared with you](https://support.claude.com/en/articles/13837440-use-plugins-in-claude#h_ef985546b4)** below. Plugins you add in Claude on the web or in Claude Desktop are saved to your account, not to your computer, so they follow you to chat, Cowork, and Claude Code. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2100409211/fc01614dde1a616fa31ffaa9cb04/47bacf5b-a810-45b5-a468-9769f1a58ef8?expires=1793430000&signature=3ff82795cb4f61918a8cf74d8c41908e857269201320dd30994849b8b341f362&req=diEnFs1%2BlINeWPMW1HO4zZF3IxbZMPVVxakFVfq5WwwQ74vlbNkU3nOljryT%0AtfXsmmvWxALq53WAiZM%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2100409211/fc01614dde1a616fa31ffaa9cb04/47bacf5b-a810-45b5-a468-9769f1a58ef8?expires=1793464200&signature=0a08594814cd8bc55273ddf91473a712827b3043e82212d6ddab07e36cb650f7&req=diEnFs1%2BlINeWPMW1HO4zZF3IxbZNfFXxakFVfq5WwxJVGoIyg50MyjVHgtc%0A99twCqRjeUFdFmu4%2BiU%3D%0A) If you're on the Enterprise plan and your organization has skill scanning turned on, plugins are checked for malicious content when they're installed or updated. A plugin with malicious content is blocked, and one that may carry risk shows a caution banner. Learn more about **[skill and plugin scanning](https://support.claude.com/en/articles/15927065)**. @@ -68,7 +68,7 @@ If you're on the Enterprise plan and your organization has skill scanning turned Each plugin you add brings skills and commands you can use while working with Claude. Type "/" or click the "+" button to see the available skills from your plugins, in chat and in Cowork. In Cowork, you can also run a plugin's command by typing `/plugin-name:command`. Click any skill to see its details. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2157396844/4a790e10f5b88df770783df1d7e9/image.png?expires=1793430000&signature=166763b09212e3c1098f19e153d99a718324bb4e56571c388a9f1aa50565409d&req=diEiEcp3m4lbXfMW1HO4zf4NBfX4gECUmKUxugP2BQsSJacCTQS0wQDxgGe5%0Anqq3fF%2FDCfvpm4JKvNc%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2157396844/4a790e10f5b88df770783df1d7e9/image.png?expires=1793464200&signature=d11cd9ef088c3768091f793d191a67901d4069536fa172fdbe506a4d8b55702c&req=diEiEcp3m4lbXfMW1HO4zf4NBfX4hUSWmKUxugP2BQulFarkDhiLR5kNWjco%0AXwcSb8%2BZ1lvEMqFsxEE%3D%0A) --- diff --git a/content/support/14499648-how-scim-sync-works-for-enterprise-organizations.md b/content/support/14499648-how-scim-sync-works-for-enterprise-organizations.md index 8fdfa9667..4b6b8e46a 100644 --- a/content/support/14499648-how-scim-sync-works-for-enterprise-organizations.md +++ b/content/support/14499648-how-scim-sync-works-for-enterprise-organizations.md @@ -50,7 +50,7 @@ You can trigger a manual sync from two places in your admin settings. 2. Click "Check for updates" under **SCIM sync**: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2312613548/44cd5970ee3c3b2c7f8dcd592d71/image+%2824%29.png?expires=1793430000&signature=4a823756ebdeacfc8a63efcc4eb0c169edae6f4a4587370f72baad8ac647be30&req=diMmFM9%2FnoRbUfMW1HO4zW4gbTapNs20rgfl7PnOiuk%2B9hZDSQDeFVp0Mbou%0AwtAx%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2312613548/44cd5970ee3c3b2c7f8dcd592d71/image+%2824%29.png?expires=1793464200&signature=032babd7b5e4a4daa1ab1bb25f56ad278c2ed75e37d0758b101289a5ebee2f88&req=diMmFM9%2FnoRbUfMW1HO4zW4gbTapM8m2rgfl7PnOiunIfOeX4RmBF15KGzKO%0ADZoH%0A) 3. Select whether to sync members, groups, or both. @@ -62,7 +62,7 @@ You can trigger a manual sync from two places in your admin settings. 3. Select whether to sync members, groups, or both: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2312608119/e4b0ef4f309f3c4eac8311a6ef47/image.png?expires=1793430000&signature=1d2e4c58d55eccd9d4d6bee208cd492eeed1f765e9b09a1ed40af14f4781584e&req=diMmFM9%2BlYBeUPMW1HO4zX%2F4f7n0yDsf43OpyTHzM9QZ3S5kkq%2FgargVhAIE%0Ad855%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2312608119/e4b0ef4f309f3c4eac8311a6ef47/image.png?expires=1793464200&signature=d391b56712286e41c1d9b6c293fde7bcf500e52b1446992d825f4f732f20cbc4&req=diMmFM9%2BlYBeUPMW1HO4zX%2F4f7n0zT8d43OpyTHzM9RifCQQ%2FMD49AcU7wjw%0AVhif%0A) **Note:** If you trigger a manual sync while background changes are processing, your organization takes the most recent change for each member or group. If multiple changes are queued for the same member or group, you may need to resync again to make sure everything applies correctly. diff --git a/content/support/15330088-set-a-default-model-for-your-organization.md b/content/support/15330088-set-a-default-model-for-your-organization.md index e217eb6e6..3cb7dcb48 100644 --- a/content/support/15330088-set-a-default-model-for-your-organization.md +++ b/content/support/15330088-set-a-default-model-for-your-organization.md @@ -50,7 +50,7 @@ The organization default applies to every member. To set it: 4. Click “Save changes.” -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2514722139/d05c94072a41ea9090ecf386c53e/c32ee31d-954a-4551-a2da-91677fbd0b6f?expires=1793430000&signature=c3326ad039465fc390e22197b200de4fef3bff8826370bb3dd12bb5499f51def&req=diUmEs58n4BcUPMW1HO4zelOdjFELkhHfdGVZ664dGH%2FxfGt5ZkxVB6XOLIt%0AAuZTZhpbpAK7BBWV72E%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2514722139/d05c94072a41ea9090ecf386c53e/c32ee31d-954a-4551-a2da-91677fbd0b6f?expires=1793464200&signature=6ba23954dbfcbbc502ed18a43587fca72a347397c2477891825e205253559889&req=diUmEs58n4BcUPMW1HO4zelOdjFEK0xFfdGVZ664dGFMdVGRJbY0VxmfKTLx%0AODVk3nNc8MdIoEfB4Ig%3D%0A) --- diff --git a/content/support/15694740-manage-model-access-for-your-organization.md b/content/support/15694740-manage-model-access-for-your-organization.md index 9f5943dad..0c3471f3d 100644 --- a/content/support/15694740-manage-model-access-for-your-organization.md +++ b/content/support/15694740-manage-model-access-for-your-organization.md @@ -42,9 +42,9 @@ The organization setting is the ceiling. A role can't grant access to a model th If any custom role uses the model you’re disabling as its default, you’ll be prompted to change that role’s default before the change can be saved. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2514693921/02ea72756f5163f14e5d158516dc/69102088-cd86-498e-97aa-c8a6e0004419?expires=1793430000&signature=77541ef63ddcfa4017b95c13a88d0d6888c7eed9f2deedab40fd985773e9f5eb&req=diUmEs93nohdWPMW1HO4zXlxE%2BS9VNFXQf5Pb7M2Q0tAmQ8diR0Q7wycZAYA%0AbB0VD7QWdRKOBUXUlUg%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2514693921/02ea72756f5163f14e5d158516dc/69102088-cd86-498e-97aa-c8a6e0004419?expires=1793464200&signature=91105ba1fbb602b0d3eabeeb55ce731b35253d63939958036273a26e7e320a67&req=diUmEs93nohdWPMW1HO4zXlxE%2BS9UdVVQf5Pb7M2Q0tYHZQoyfhBeiYR2NuE%0A1ya0OJQd0%2F8dgF6YcOg%3D%0A) -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2514693922/bfc5de6626eb19dca1d7caf818ca/c3cd8bb6-f86c-4d01-92da-6ae4ca966662?expires=1793430000&signature=7a13cdac8ceb7e2e52f1720f5d24ab91bc774dbceaf8e01cb9cfcdbbab568c17&req=diUmEs93nohdW%2FMW1HO4zTqNsIrBRVhXAod9uc510lzGCv%2ByQyRzFUx0CxSi%0AEDfNh81tY4FCtwFtP7s%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2514693922/bfc5de6626eb19dca1d7caf818ca/c3cd8bb6-f86c-4d01-92da-6ae4ca966662?expires=1793464200&signature=95b61e7ae38ac7bf94f4696bd3f2b6be444f13215de8df9ac78697a10acd41f8&req=diUmEs93nohdW%2FMW1HO4zTqNsIrBQFxVAod9uc510lxP4R0b5ksgM5LJr0lY%0AjKI4fJZWyI%2BjvnRRQB4%3D%0A) --- @@ -78,7 +78,7 @@ If any custom role has an effort cap higher than the new organization cap for th Only models the role grants access to can be selected as that role’s default model. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2514693923/880665a87dbd4776cf19d6063a37/29d30c6d-f9fc-408c-8c72-4320c6d88d14?expires=1793430000&signature=8ff347b5d7838c2da371b748eaa136c5543307c8cb104f9e9e3e85adf42b1261&req=diUmEs93nohdWvMW1HO4zYj9SPYH7oG9XsqpNqvyFRIx0ir2OYVZvZlor89a%0AyKh5qqKeCBTn90ZFqP8%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2514693923/880665a87dbd4776cf19d6063a37/29d30c6d-f9fc-408c-8c72-4320c6d88d14?expires=1793464200&signature=8715a366851288aceb41929bd35efc940030288a7357cbdb0423104d153d3acd&req=diUmEs93nohdWvMW1HO4zYj9SPYH64W%2FXsqpNqvyFRLlB07YoyM1p7IUtnE5%0AWHMcbxfavw17G2zDs6o%3D%0A) --- @@ -96,7 +96,7 @@ Effort limits determine how much computation members on a role can apply per res 5. Click "Save" to save your changes. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2514693927/7a25673b3b075d72adb3cdc371e3/d2d7cd8d-a713-4e91-a706-f589ac46a9fe?expires=1793430000&signature=71d35415c8639c216d3d331679f031d5f3cc59abb1c78f2bf4e4834c0a31f71a&req=diUmEs93nohdXvMW1HO4ze1xBzC4cLkZDeA1RkowXUE6uFDjxpe01aT7ZWoy%0AkrGUPexxSwBlE1eRI7w%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2514693927/7a25673b3b075d72adb3cdc371e3/d2d7cd8d-a713-4e91-a706-f589ac46a9fe?expires=1793464200&signature=8d17847cbe0b316f19b4b56a48f81f49e0ca0b6ecc9745e101e125c4ae85c643&req=diUmEs93nohdXvMW1HO4ze1xBzC4db0bDeA1RkowXUHjpRmGMmW53SZ9mrv7%0AZ%2BIm8c4GamlYLn1z5BQ%3D%0A) Members on the role see only effort levels at or below the cap in their model menu. Note that available effort levels differ depending on the model, and some models don’t support effort level settings at all. For an explanation of each level, see **[Change the model, effort, and thinking settings](https://support.claude.com/en/articles/8664678)**. diff --git a/content/support/15936181-get-started-with-1password-for-claude.md b/content/support/15936181-get-started-with-1password-for-claude.md index 87195086f..73798b58a 100644 --- a/content/support/15936181-get-started-with-1password-for-claude.md +++ b/content/support/15936181-get-started-with-1password-for-claude.md @@ -52,7 +52,7 @@ Once the requirements are in place, you can set up 1Password from a few places i 4. Toggle on **Password managers**: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2546126596/ba71ca47e2df21cec62c243831f8/5b1c67e1-607d-4c73-8f61-d1ceb081082a?expires=1793430000&signature=e14c3dc927746489bdda052db4bc34507333270b5839ca326f77ed876b7c8903&req=diUjEMh8m4RWX%2FMW1HO4zU5ln2hqrsVjGkiu4hEpcPUV5EInTXZgdkXY%2FW9z%0At3XtrIoGeWgzFROVYKw%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2546126596/ba71ca47e2df21cec62c243831f8/5b1c67e1-607d-4c73-8f61-d1ceb081082a?expires=1793464200&signature=bad1cfbd6aed9b840593cb164088983757960389c52f17aaf50e624791c150ae&req=diUjEMh8m4RWX%2FMW1HO4zU5ln2hqq8FhGkiu4hEpcPXeZBZ7u5UiBXTP2S%2Fg%0AwXZs%2BAnaUKutSwg%2Bolg%3D%0A) Once enabled, eligible users will see the discovery options above. Users still need to install and set up the required apps and extensions themselves. diff --git a/content/support/16607638-understanding-your-pro-max-or-ultra-plan-invoices.md b/content/support/16607638-understanding-your-pro-max-or-ultra-plan-invoices.md index 2037e476a..b0d1557d4 100644 --- a/content/support/16607638-understanding-your-pro-max-or-ultra-plan-invoices.md +++ b/content/support/16607638-understanding-your-pro-max-or-ultra-plan-invoices.md @@ -40,7 +40,7 @@ You can also open any invoice from your account: **Amount due.** The invoice total minus any applied balance. This is what your payment method was charged. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2629072970/c514f489b65072ccad08e803864f/e8c7a7de-905f-4a40-815f-c9c66edcdbf6?expires=1793430000&signature=8c02bab7814e4d08f01cbbf3cd7a5fe1705ae57eac0b4beb6c29adb0d7086af8&req=diYlH8l5n4hYWfMW1HO4zdWraRI77VQePZYKVlMiWEUbIj5oFhAvDd9%2Bdw1J%0AAUnZ%2Frs926cw3a2nUm0%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2629072970/c514f489b65072ccad08e803864f/e8c7a7de-905f-4a40-815f-c9c66edcdbf6?expires=1793464200&signature=d9f0156f782850afcb7f6a12a0d534919c71ac8de975e5fd0d7aaf643e35a57f&req=diYlH8l5n4hYWfMW1HO4zdWraRI76FAcPZYKVlMiWEX4DdPxoZKox81488rq%0AWjald6sS0NQLnp5fJaY%3D%0A) ## Billing details on your invoice diff --git a/content/support/16893491-get-started-with-smart-reports.md b/content/support/16893491-get-started-with-smart-reports.md index 5a19b72af..b07119e66 100644 --- a/content/support/16893491-get-started-with-smart-reports.md +++ b/content/support/16893491-get-started-with-smart-reports.md @@ -28,13 +28,13 @@ Each report includes the following sections: Workstreams shows what the group used Claude for most, by sessions and by spend, side by side. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2671030907/7b62b605189fe8e9474a20c1eaf2/image.png?expires=1793430000&signature=c60206d1fc109d4774cf3cd73ebc42599292b695d269a35e6819c0c54fed2ead&req=diYgF8l9nYhfXvMW1HO4zZse%2BmGYSAgMVa%2FWhnGS4Gm4S%2FPV4L7JLfpa0dwz%0AyVueflS3B3eGCgtpLlo%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2671030907/7b62b605189fe8e9474a20c1eaf2/image.png?expires=1793464200&signature=cdac55d0084b4e9f414ab3487ee81c58346f191a915d86e0e04b8b532406b39b&req=diYgF8l9nYhfXvMW1HO4zZse%2BmGYTQwOVa%2FWhnGS4GnbvbWf%2FFZAGuHTHxGZ%0A1yTPauPM4Vo0q7p%2FmE0%3D%0A) ### Deliverables produced Deliverables produced groups sessions by the type of output that was produced. For example, analysis, documentation, content drafts, and code. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2671035220/2a582bc047a6ba46e7dbd6f05d9f/e17881ac-874c-4747-94ca-8679e0301455?expires=1793430000&signature=eeebd20a25437c6f6c4e92a2ad39f2759342018ee90ab8e0ab4994896ead11b4&req=diYgF8l9mINdWfMW1HO4zelj06RfkN3yYDEFlKbF9Y%2Bh8wKPNCuVbJo3DP3b%0AoG3gFfSuYnUc8IT8AbU%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2671035220/2a582bc047a6ba46e7dbd6f05d9f/e17881ac-874c-4747-94ca-8679e0301455?expires=1793464200&signature=02c3f0dd0881f170a5fd94bdc12bc5b2abf7f6517c1edaca117e5e4210144553&req=diYgF8l9mINdWfMW1HO4zelj06RfldnwYDEFlKbF9Y8ajoOwinJlEFp44qzS%0AnUkVlvhw1QkCczpISQc%3D%0A) ### Cost per session by type of output @@ -48,23 +48,23 @@ Task outcomes shows what each session produced. Most common pain points shows what got in the way, by category. For example, a connector that wasn’t set up, output that didn’t match the ask, approval or sign-in gating, tool failures, or rework loops. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2671052365/b69f22b75729e5587563e7ab6830/b1647659-a7ea-403b-89fc-0b150ee97675?expires=1793430000&signature=eff71c98cf687aeff5e1e54c5a1c2daa45a1842e65f9bfdc12a7ff70595f35d9&req=diYgF8l7n4JZXPMW1HO4zdDitrkxV91RjFK5P3Uf7RjGOlynhCvuVeP0OPhB%0AzTgjvVCaKNRZfT2HtNk%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2671052365/b69f22b75729e5587563e7ab6830/b1647659-a7ea-403b-89fc-0b150ee97675?expires=1793464200&signature=06ceadae422db73e7ee0e69c9d7cad08853ac989e5fa459be748899b37dd3af4&req=diYgF8l7n4JZXPMW1HO4zdDitrkxUtlTjFK5P3Uf7RgudMlJ9es9aEVRytcf%0A341J10rvxnnQQXD2hz4%3D%0A) Click into a category to see more information: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2671053199/b68936dd5d590c5fbcbbc092b332/5ec247b2-cd67-4f3f-97b5-23479b87a5c6?expires=1793430000&signature=9c7f8dd0614f0e199c39c99ec3d6af0fe484eacb563ab664fc507273622e3604&req=diYgF8l7noBWUPMW1HO4zbuGO4gsJbkcodOVMLl17PVTnH3c0xaqx2hiTFW1%0AM%2BZ0ruSFKzh4UCILJB0%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2671053199/b68936dd5d590c5fbcbbc092b332/5ec247b2-cd67-4f3f-97b5-23479b87a5c6?expires=1793464200&signature=83c6f6e8f993f40485d96f4115521e5223e6025547a39d9774fa73e09f38eaa5&req=diYgF8l7noBWUPMW1HO4zbuGO4gsIL0eodOVMLl17PWt%2B3vc%2FEbnTje%2B3ram%0AgONQrKURNrzeSw2I2qM%3D%0A) ### Inefficiencies Inefficiencies counts sessions that produced nothing usable and sessions that were personal or off-topic, with their cost (shown only as an aggregate count and cost, with no summaries or drilldown). -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2671036122/90dc848a7adf371a872bd89a2f5e/de86945b-ccfe-4e0f-892d-abacc475c5c4?expires=1793430000&signature=9d132cdf43d5a355d31cd0fb6fcff85063713cb1c73ad9c4ed23ed350931c2c5&req=diYgF8l9m4BdW%2FMW1HO4zcYfhgySDvQaBas8rgXn%2Fb3mLTtncik5jiAvUpNx%0AzNsXKCJSX67NfvnPG7A%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2671036122/90dc848a7adf371a872bd89a2f5e/de86945b-ccfe-4e0f-892d-abacc475c5c4?expires=1793464200&signature=509526945ff047b0141ab8bf414dcde2301600a53c001e391ee56bf1509eb068&req=diYgF8l9m4BdW%2FMW1HO4zcYfhgySC%2FAYBas8rgXn%2Fb36cIXIFOwzW%2F%2FxJWz%2F%0A%2FQMRQ4shSLY4M7Is96Y%3D%0A) ### Complex, autonomous work Complex, autonomous work shows sessions scoring highest on task complexity, time saved, how long Claude worked on its own, and the expertise required. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2771304819/746adaaa5ae3196304f0af43cbdd/image.png?expires=1793430000&signature=e9c111b23a332e4cb1cf8107128a1239d9ece4254ec05559d1d3fe9358fc7219&req=dicgF8p%2BmYleUPMW1HO4zRKi0HWHjk5mhdMrWDTaChW4vePB%2BXzWlX6qHq%2FJ%0AG3OoBtroyJ0wefFjG2M%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2771304819/746adaaa5ae3196304f0af43cbdd/image.png?expires=1793464200&signature=373e5a04d5fa698df3a9978bfd00b8ed50492c145e3971339908f4c15c4de73e&req=dicgF8p%2BmYleUPMW1HO4zRKi0HWHi0pkhdMrWDTaChU9ReZg4DS6Cjt4g5NY%0Am893Y7xPz0gTfQBa2bg%3D%0A) ### New to the organization @@ -78,7 +78,7 @@ This section shows work that people have automated for themselves. Most expensive sessions lists where spend concentrates. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2671032083/2b075387a4a3473f884a8ba26436/image.png?expires=1793430000&signature=2ef247b5a4c1b565c52e4a83656ff6b00efa47fd8c18c283229376c8a1cb4246&req=diYgF8l9n4FXWvMW1HO4zdLkImyh6UYpnUoxuhUXEhg1ltOqFUx54P97cdBs%0AHjOHcCA7rQN8Bgg6jpM%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2671032083/2b075387a4a3473f884a8ba26436/image.png?expires=1793464200&signature=a95d0b2c7072f1163ba6999589931f2ef2cdf05efc53262d66155eb3db19f672&req=diYgF8l9n4FXWvMW1HO4zdLkImyh7EIrnUoxuhUXEhiO%2BvdRihMB%2FxB3KUCd%0AZ6kSRIGESeEs5JtYbUk%3D%0A) ### Answers to custom questions diff --git a/content/support/16951679-use-claude-in-google-docs-sheets-and-slides.md b/content/support/16951679-use-claude-in-google-docs-sheets-and-slides.md index 624889925..334c47631 100644 --- a/content/support/16951679-use-claude-in-google-docs-sheets-and-slides.md +++ b/content/support/16951679-use-claude-in-google-docs-sheets-and-slides.md @@ -28,11 +28,11 @@ If your organization already allows Marketplace apps, this takes about two minut 2. Open a Google Docs, Sheets, or Slides file and go to Extensions > Claude > “Open Claude": -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2707281468/abc0497defca04936c9a4b97d147/8b17d05f-3fb1-4e49-8d1f-65364ac3f496?expires=1793430000&signature=9af7f0cd78fb9523871ac80e506ea3bb876f17f8cfa3953ca71e47ca3dd4e62a&req=dicnEct2nIVZUfMW1HO4zRwmJT9oV%2BRPaAKM49NdBLP%2FluzLiqr8br9GTx6Z%0ASGO3%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2707281468/abc0497defca04936c9a4b97d147/8b17d05f-3fb1-4e49-8d1f-65364ac3f496?expires=1793464200&signature=db15b1f6555b004eb42cffb3d0a2bb209a4bf8e7f7b7a85ea053ae5e470ad663&req=dicnEct2nIVZUfMW1HO4zRwmJT9oUuBNaAKM49NdBLOfQgesfJWiEodX%2FkAL%0AIp5V%0A) 3. The first time, Google asks you to allow two permissions. Review them and click "Allow": - ![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2707282342/f583a396098ff16e3cbd156d4a2a/112c6459-79c6-4fbb-9bc0-748fda6f592f?expires=1793430000&signature=1b4a3d42e7f6f843a4ae4b871ddd3ef7cbd224df48891bfddab2a547b0cb8ee6&req=dicnEct2n4JbW%2FMW1HO4zeKY3p8Cgw7weBfHlrCfDWerjTkqBG0rj8ayFSSC%0AswKE%0A) + ![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2707282342/f583a396098ff16e3cbd156d4a2a/112c6459-79c6-4fbb-9bc0-748fda6f592f?expires=1793464200&signature=7473e0e69ead41535bdc5ffdf0df08392b13f2d9c1067d8bba2f23f1e6d765c1&req=dicnEct2n4JbW%2FMW1HO4zeKY3p8ChgryeBfHlrCfDWesBbqMUDvUy4Mb8cJ0%0Atyqt%0A) 4. Sign in with your Claude account in the sidebar, and optionally enable your connectors. diff --git a/content/support/17005973-manage-pooled-group-budgets-on-enterprise-plans.md b/content/support/17005973-manage-pooled-group-budgets-on-enterprise-plans.md index 65e56b2f3..0f3f9ba41 100644 --- a/content/support/17005973-manage-pooled-group-budgets-on-enterprise-plans.md +++ b/content/support/17005973-manage-pooled-group-budgets-on-enterprise-plans.md @@ -80,7 +80,7 @@ If a user belongs to more than one group with a pooled budget, the largest poole With a custom order, the first pooled budget in your list with budget remaining pays. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2719736736/a4ec8e92af4975a87891357e5dbd/6f58b496-432d-4069-ba18-72a6390ab2ea?expires=1793430000&signature=c2c23fc81d6c3fb4799a67ec9d2e57c04e8aaae0d8b30f99e553cd69da81e3e8&req=dicmH859m4ZcX%2FMW1HO4zU9wBwccUogzTLR6JppsyjQsvVJCh%2FSv1%2Fxz6ob6%0A750PRJVTrbU7KkLpz1I%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2719736736/a4ec8e92af4975a87891357e5dbd/6f58b496-432d-4069-ba18-72a6390ab2ea?expires=1793464200&signature=003acea745a2817dbb8b97a7b7de6b754b76a148b6b424cd9eac272fd9b122e1&req=dicmH859m4ZcX%2FMW1HO4zU9wBwccV4wxTLR6JppsyjSk5QVJxGDuCH8aFWKD%0AIbgwUC6Ox1Kevz7z9iM%3D%0A) **Note:** Budget priority only decides the order in which pooled budgets pay. To choose which group's member monthly limit applies to a user in more than one group, use the **Member limit from groups** setting under **Spending defaults**. diff --git a/content/support/17203415-set-up-claude-for-intune.md b/content/support/17203415-set-up-claude-for-intune.md index c0a1af2fc..1f0ea51ad 100644 --- a/content/support/17203415-set-up-claude-for-intune.md +++ b/content/support/17203415-set-up-claude-for-intune.md @@ -70,25 +70,25 @@ To add Claude for Intune for enrolled company-owned devices: 1. In the Microsoft Intune admin center, select "Apps" from the left side navigation panel: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700192269/ce2bf95a18aba11042da50f4c1ad/dda0f9a2-d585-4b09-ae4f-a1ff70b1e010?expires=1793430000&signature=16062c880ae0d9cf2fe7a868df07c89e87d6b6b3a4ceafd02f3e120322519da6&req=dicnFsh3n4NZUPMW1HO4ze7khjLV4WtgAMLV2Uu0R4UKpskymTrwm7LvdQPN%0ADo1o%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700192269/ce2bf95a18aba11042da50f4c1ad/dda0f9a2-d585-4b09-ae4f-a1ff70b1e010?expires=1793464200&signature=986004a1bcf80ce88224f7ea8d6efb9b6629ebbbf7331b3528bb058a698ebcfb&req=dicnFsh3n4NZUPMW1HO4ze7khjLV5G9iAMLV2Uu0R4U83BSKIqNcsYfcLzX4%0ASSqy%0A) 2. Under Platforms, select "iOS/iPadOS": -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700195036/b70c6c0bdeff5f2b72568ef4943b/67cc834c-5e91-42da-9d3b-1f32c8dd8c05?expires=1793430000&signature=efe5e7fd381f13c976435a380789ba66db8bbb397e079a1d19d4e6c541b4b3dd&req=dicnFsh3mIFcX%2FMW1HO4zeH1oU7jsnOUQ7hR7Wh%2Bi70zcvN%2F0I9o6rkEjD4w%0APQPh%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700195036/b70c6c0bdeff5f2b72568ef4943b/67cc834c-5e91-42da-9d3b-1f32c8dd8c05?expires=1793464200&signature=05b9093b22c83c5e7a6424512fcb379634c02ea1fe19aaf01a1c159c67ea94c7&req=dicnFsh3mIFcX%2FMW1HO4zeH1oU7jt3eWQ7hR7Wh%2Bi70P%2FrvVXCPnJd0QP1dO%0AmnkM%0A) 3. Click "+ Create." For the App type, select the "iOS store app," and click the "Select" button on the bottom: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700195791/9a01290b4189e6a39c473af0a448/cfed06da-f35a-4b22-b687-286ea48864c1?expires=1793430000&signature=1df831006fd7e3d35acf757f943e785776ed054676cea54d78068794487e316f&req=dicnFsh3mIZWWPMW1HO4zTni3cUtYZ4s2SRx6amjj9FQdnLBcPGFpJaKWbZI%0AtoPF%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700195791/9a01290b4189e6a39c473af0a448/cfed06da-f35a-4b22-b687-286ea48864c1?expires=1793464200&signature=b3ce3dc88c87e9fd387ab238099438999142c9384b1499ff6a2f805ed90da401&req=dicnFsh3mIZWWPMW1HO4zTni3cUtZJou2SRx6amjj9GXzAvsqU37DmDxkpdA%0ApGv0%0A) 4. Search "Claude for Intune" and click the "Select" button on the bottom. 5. In **App Information**, set **Minimum operating system** to iOS 18, then click the "Next" button: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700196458/588327ab209e9524c45111a244a1/258697c2-2f82-471b-9104-2bccb1b01614?expires=1793430000&signature=a8bb79cae41971d925aed16df18a133af320bf8ac2c64e327269066b5f2ab410&req=dicnFsh3m4VaUfMW1HO4zbxl5YtTdDIuDNNSLAHCCFq%2BS8KaWWYpCnsN2LIc%0AGRqf%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700196458/588327ab209e9524c45111a244a1/258697c2-2f82-471b-9104-2bccb1b01614?expires=1793464200&signature=56afd978ce30781338fb3c7f9e487c58105074550500ccad1ce1d95f8bf1aaf1&req=dicnFsh3m4VaUfMW1HO4zbxl5YtTcTYsDNNSLAHCCFrREf33zqLPq6CEO%2B77%0AYSz0%0A) 6. For **Assignments**, add the groups that should get the app: under Required to install it automatically, or under Available for enrolled devices so employees can install it from Company Portal. You can use user groups or device groups. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2741107114/8f15b0d179a54c2ca4effaad8577/55bed25a-4b20-47b0-9e89-7f8adc86c04f?expires=1793430000&signature=d3066a57bad95c9987ab66fdcf307ac5593de3fd49a66e3c8793fdff80d3449d&req=dicjF8h%2BmoBeXfMW1HO4zYaZMeu4evOemN%2B6UXepdg%2FfvgzMqspPz4Ac8LPd%0ANhbI%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2741107114/8f15b0d179a54c2ca4effaad8577/55bed25a-4b20-47b0-9e89-7f8adc86c04f?expires=1793464200&signature=e571eb4f2683d35bb116597a313f4292e983ea4e1d73d73dc25c67e7810f6c10&req=dicjF8h%2BmoBeXfMW1HO4zYaZMeu4f%2FecmN%2B6UXepdg9K0NjszSbz6ylHOq2k%0AGJQd%0A) 7. Click "Next," review and create. @@ -98,27 +98,27 @@ To add Claude for Intune for enrolled company-owned devices: 1. In the Microsoft Intune admin center, select "Apps" from the left side navigation panel: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700190760/9f6412fe68632cffee29826f7d30/42fdeb30-64af-4089-a976-5094bb6b8292?expires=1793430000&signature=880ea10b750577920054971824933f0b2fd0f45f6f592db84e7ab372a8d8dfe5&req=dicnFsh3nYZZWfMW1HO4zQwrZIkGUNI8LtTCoSp4D6ofI0Tf6V45uB8Xi9O3%0ArlXC%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700190760/9f6412fe68632cffee29826f7d30/42fdeb30-64af-4089-a976-5094bb6b8292?expires=1793464200&signature=0ab5b91f5a379ddcce5b6ea689e0df4d6d720cd84ef2afdb693db57e01517dac&req=dicnFsh3nYZZWfMW1HO4zQwrZIkGVdY%2BLtTCoSp4D6osiKfuAhEmm9uaScdQ%0ATufL%0A) 2. Under **Manage apps**, select "Protection": -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700200858/a7ddd4265aeb6d61a7a096297cd5/fc9a1fe2-3d0e-4038-9b2c-f96bd19e4020?expires=1793430000&signature=d29b50596c8e516ca96ba929218435d2c51878cba3e98a5e404cd64de6b4b91b&req=dicnFst%2BnYlaUfMW1HO4zeBHXBw59v3tnJWY0xu8hzLXOAPbAtkGtKShuWlD%0AuSRR%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700200858/a7ddd4265aeb6d61a7a096297cd5/fc9a1fe2-3d0e-4038-9b2c-f96bd19e4020?expires=1793464200&signature=810d6d82bdf109c5d72eeca421f898b9dea8b36cdbc0a35632b0ceeb4c08248a&req=dicnFst%2BnYlaUfMW1HO4zeBHXBw58%2FnvnJWY0xu8hzIEBDKXD9cNxv9ldYKh%0AXS3m%0A) 3. Click "+ Create" and then select "iOS/iPadOS": -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700201382/6240e257b2b498b5fa5ac1111561/11ef4f59-aba1-4d2b-ac58-9aec1dd60a4d?expires=1793430000&signature=15945fa46e5df1987b55c9f1d17ce553fb238497f27f2c7c05390ff60931e3ec&req=dicnFst%2BnIJXW%2FMW1HO4zc89y0hSAXpOV2VWh%2B9zzEoCXe4GkvAYxNBcZf%2Bw%0A4hnX%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700201382/6240e257b2b498b5fa5ac1111561/11ef4f59-aba1-4d2b-ac58-9aec1dd60a4d?expires=1793464200&signature=1e1733e74c81534574449e31c794b6a8ec0851339865a0b369ffd202121937c3&req=dicnFst%2BnIJXW%2FMW1HO4zc89y0hSBH5MV2VWh%2B9zzErqq6%2Bsi5yk23Q4l5kv%0A%2Fyt3%0A) 4. Enter Name in the **Basics** tab, then click "Next" to **Apps**. Set **Target policy to** "Selected apps." Click "+ Select custom apps": -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700201929/2edf45cedc0bc03204f86d01a49e/4d96c12d-962b-43f6-8b3f-668e3247d4c1?expires=1793430000&signature=24de32046f3ee897b9d62ba552fd33693ffadf26f689bbadd9ce03ac075da7ff&req=dicnFst%2BnIhdUPMW1HO4zVmMRJIQUD0IKETwku7gMsvj9BkBydSSR27InvhC%0AScIr%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700201929/2edf45cedc0bc03204f86d01a49e/4d96c12d-962b-43f6-8b3f-668e3247d4c1?expires=1793464200&signature=084c3efa91f4213324e3464db7b2fc1fa9027ef0eb7cb2d72c2aaf52bd12db32&req=dicnFst%2BnIhdUPMW1HO4zVmMRJIQVTkKKETwku7gMsvj4Tb9%2BdHFjsSlu1PB%0AOngI%0A) 5. Type in the bundle ID `com.anthropic.claudeforintune`. Select it so it appears under **Selected Apps** before clicking "Select": -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700202816/3565aea2d1b9c22a5f8d105825c5/3de6d241-6259-463e-a503-a6ca9f2095e0?expires=1793430000&signature=a96cbde04741cafd0e310b0085419ca5df497c81c03936be4f04456e6e44e76e&req=dicnFst%2Bn4leX%2FMW1HO4zf6tYiAsy6p312LT9vQL0W5sLbnVV3QWNZKTsXmA%0AEav7%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700202816/3565aea2d1b9c22a5f8d105825c5/3de6d241-6259-463e-a503-a6ca9f2095e0?expires=1793464200&signature=a45f90e60b0c4b530def2eac0705174da7c73eb8be5c651cea0a641e09754225&req=dicnFst%2Bn4leX%2FMW1HO4zf6tYiAszq5112LT9vQL0W6MeGE1Tamv9LfwTc5F%0AELKM%0A) 6. In Apps, confirm the bundle ID now appears under **Custom apps** before clicking "Next": -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700203780/24ed354ef0de87bf0a0c1bc129a1/46eed662-f488-48ee-a4d1-8a9a76079884?expires=1793430000&signature=a8496fd1865027794bb4d4f73b31329bbb0822febf3ce7fd8979a41e6ce41dba&req=dicnFst%2BnoZXWfMW1HO4zQd95NaO2Mjf8F6Cfy2R7u9ItJFJAMShEbaBGGdO%0Aa5%2FZ%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2700203780/24ed354ef0de87bf0a0c1bc129a1/46eed662-f488-48ee-a4d1-8a9a76079884?expires=1793464200&signature=a59a3e8b3051e4f09e536b0ec18aa14f43abfd418631d69ce04a4aed8e8accdd&req=dicnFst%2BnoZXWfMW1HO4zQd95NaO3czd8F6Cfy2R7u%2F7HhPx9pN7Icv7C%2BkL%0AJQPN%0A) 7. Configure the Data protection, Access requirements, and Conditional launch settings as needed. diff --git a/content/support/17444462-set-up-and-manage-the-new-unified-claude-experience-for-your-enterprise-organization.md b/content/support/17444462-set-up-and-manage-the-new-unified-claude-experience-for-your-enterprise-organization.md index 80fc9d11f..dff3d4284 100644 --- a/content/support/17444462-set-up-and-manage-the-new-unified-claude-experience-for-your-enterprise-organization.md +++ b/content/support/17444462-set-up-and-manage-the-new-unified-claude-experience-for-your-enterprise-organization.md @@ -184,11 +184,11 @@ The new unified Claude experience gets its own line in your reports. When a memb **A page of its own.** Admins who can view analytics will find a Chat and Cowork unified page under Apps. It shows daily active users. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2719814921/59cd7abb6c99192d741223dd2016/f2fadd45-8cb0-49db-a9a2-c8f367f29c91?expires=1793430000&signature=447048db4358bff696a1b405fbb71a2535c707b001ff5302b970b54636b750cb&req=dicmH8F%2FmYhdWPMW1HO4zdLa5QxsY66Af83E7E4Kt4Ww6bmde0tXI3pTH3%2B6%0AUsUypxNSTBMhUhkpAF4%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2719814921/59cd7abb6c99192d741223dd2016/f2fadd45-8cb0-49db-a9a2-c8f367f29c91?expires=1793464200&signature=d0ac6a41d769cfc472281ad27f8d33cee03ec06a180b975184925c67a5dfc09f&req=dicmH8F%2FmYhdWPMW1HO4zdLa5QxsZqqCf83E7E4Kt4WRgMqZcfU4NNJqNvk6%0AR5sDUfFgomaCYjgiHeU%3D%0A) **Across the dashboard.** You can pick "Chat and Cowork unified" in the Active users, Active members, Total spend, and Spend by model charts. The See all members table on the Overview page has a "Messages in Chat and Cowork unified" column. The Top connectors and Top skills cards don't include it yet. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2719816289/17e3ba22d470c32e8df9b3c20251/385c6be9-7019-451d-85f8-025a6e12a34c?expires=1793430000&signature=a64f6eb4169a8597f191585f4b65ec7af75305658d2722fee4bb125b4329ae8f&req=dicmH8F%2Fm4NXUPMW1HO4zRXO8AwVQ4W5JG9o4WcdeVCQGV5GllsX%2B4cjYHDA%0AO9X%2BfdPQPWwdXFnIpcA%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2719816289/17e3ba22d470c32e8df9b3c20251/385c6be9-7019-451d-85f8-025a6e12a34c?expires=1793464200&signature=b295411cab510618595bae366062bbcc3499cfd5d2507562df3394e8e05f74f5&req=dicmH8F%2Fm4NXUPMW1HO4zRXO8AwVRoG7JG9o4WcdeVBMl9Z9%2Bx%2BgXTxY9gqZ%0A%2FzaIci41DMLGX19UzsE%3D%0A) **Who sees it.** The page appears for every organization that can turn on the new unified Claude experience, whether or not it is on yet. diff --git a/content/support/8114491-get-started-with-claude.md b/content/support/8114491-get-started-with-claude.md index a812a5cd4..46aa1f4c0 100644 --- a/content/support/8114491-get-started-with-claude.md +++ b/content/support/8114491-get-started-with-claude.md @@ -36,7 +36,7 @@ You use **prompts** to communicate with Claude. The best approach is to speak to Type your prompt into the chat interface and click the submit button to start a conversation with Claude. You can click the "+" button in the lower left or type "/" to view additional options and commands: -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1916208578/2cf2ea52f1f884084b57983a8805/image.png?expires=1793430000&signature=9c340f9469a14229cf4bb6ea4c2b41fd07bfea998116ae34dc99d6b73a3a4495&req=dSkmEMt%2BlYRYUfMW1HO4zV2J7CzOt4eB9crMELaMZPzQJMdsg6ehdMauSQO%2B%0A%2FKMif4wcm%2B%2FaEu%2F6kbU%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1916208578/2cf2ea52f1f884084b57983a8805/image.png?expires=1793464200&signature=a363386c04d0d50aa176cfde157760bf8595c9deab0b6644baf6a7884b8a21bc&req=dSkmEMt%2BlYRYUfMW1HO4zV2J7CzOsoOD9crMELaMZPz21AneuruvPk4UX6Cg%0AbYT7bZlzMuI7J1IiT1s%3D%0A) --- diff --git a/content/support/8230524-delete-or-rename-a-conversation.md b/content/support/8230524-delete-or-rename-a-conversation.md index 8cdd28291..4f94013cb 100644 --- a/content/support/8230524-delete-or-rename-a-conversation.md +++ b/content/support/8230524-delete-or-rename-a-conversation.md @@ -44,15 +44,15 @@ These steps apply to Claude for iOS, listed on the App Store as Claude by Anthro 4. If deleting, tap "Delete" again in the confirmation prompt. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599501318/75c28edc693efbe8befd21e4da64/d18a921a-df4b-4788-833c-12c966a32527?expires=1793430000&signature=c55c1f1f7acb7667c0f9371060f7558250822e91e3c79768cf4ec8c2f0bb09dd&req=diUuH8x%2BnIJeUfMW1HO4zSc12K1ei2Cr1DBI29QsIlGebFHOdhMO9s5cYb8u%0AR3%2B4JL0EcLy9E%2FC6wyY%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599501318/75c28edc693efbe8befd21e4da64/d18a921a-df4b-4788-833c-12c966a32527?expires=1793464200&signature=76df96ea1a50ca1a972a544434a0fbd08a3a3a25c9a8f5de07c05360b61d22a3&req=diUuH8x%2BnIJeUfMW1HO4zSc12K1ejmSp1DBI29QsIlEpUYyoX4Um9pvGjwUs%0ALQ9SDeaKI8rW%2BY0I03U%3D%0A) -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599493852/2e58b92d18f307bb79ae30650f26/1bbe52f3-202b-4d5d-9f9a-eeda4d6952c3?expires=1793430000&signature=e0355a60e18b1be69fedeb59b00ea1960ffd73e4ff2b9901e6a49acaf110bd27&req=diUuH813nolaW%2FMW1HO4zTjXM%2BSILcDlj7blKEDtUI3X5T5GNWbbV8kCtK3Y%0ABKqmjMzDooOHbehO1Ko%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599493852/2e58b92d18f307bb79ae30650f26/1bbe52f3-202b-4d5d-9f9a-eeda4d6952c3?expires=1793464200&signature=42a2e40af3d574ed7b9bd4f42978671472ac54dbe23ed23f77d191377ddc8d78&req=diUuH813nolaW%2FMW1HO4zTjXM%2BSIKMTnj7blKEDtUI0Ic2t%2BeD56FoqpdWv6%0ABgus75MrK9clUYgNTfk%3D%0A) You can also delete the conversation you have open: tap the "⋯" button in the top right corner, tap "Delete," then confirm. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599493848/997184c386d0e6fb0bd2d7c1f2b6/5d2bc394-25fc-4814-8c2a-2f54d004f83f?expires=1793430000&signature=14d57806b3caae0b7ab2fab620dde43bc14979a66c9e896794500e7c3a90b4d2&req=diUuH813nolbUfMW1HO4zVCIq5nLyNxGzQl%2BKgU984xcXrjLShHitikIhnzI%0AwDuiCzxPmzInPImE%2F20%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599493848/997184c386d0e6fb0bd2d7c1f2b6/5d2bc394-25fc-4814-8c2a-2f54d004f83f?expires=1793464200&signature=0ec4fc18fb5f1e4300ec63f7308b0e0d1c934d40f1cdfa79a65f5ccb1966f77b&req=diUuH813nolbUfMW1HO4zVCIq5nLzdhEzQl%2BKgU984zFI5KFxJw3nq0r3P%2BF%0AnqPtCBBgD4cN8aBpskk%3D%0A) -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599493856/799041da9fa918e90068c5ebf5bd/2e8d5cee-c45a-41d7-a14b-486e50a37f88?expires=1793430000&signature=54caa6a76e0f06d14eb368a570048fc4268de014eba4856c23dc090c3d9595a9&req=diUuH813nolaX%2FMW1HO4zVCl4Qv20mVNEDIU8RT6jk1smsFdvzBZmY7Ilgwl%0AWg2LnkYgGYaHEkatlxM%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599493856/799041da9fa918e90068c5ebf5bd/2e8d5cee-c45a-41d7-a14b-486e50a37f88?expires=1793464200&signature=6d8abbf179eebd12b8bb073a8060c1fd215570de52483b18875ad0e0aa2c164b&req=diUuH813nolaX%2FMW1HO4zVCl4Qv212FPEDIU8RT6jk3b0Opy31sIEU34Wph2%0AcTEq97ZOCmBoepCxDw4%3D%0A) ## Delete or rename a conversation on Claude for Android @@ -66,9 +66,9 @@ These steps apply to the Claude for Android, listed on Google Play as Claude by 3. If deleting, tap "Delete" again in the confirmation prompt. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599493850/a64e6561222d535f2f5bd03e71f0/5de429c2-d8ed-4e8a-89e8-a13ccaa49767?expires=1793430000&signature=74912750b3748028efac504158a95879a6e9f75bd6f55503322489631ad7eb3d&req=diUuH813nolaWfMW1HO4zVTddtEowVB1rqtc0YNNUtJS13q%2BiTflkDtkcvVQ%0Ab6%2FgsLAhkLQaUOY%2BJPQ%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599493850/a64e6561222d535f2f5bd03e71f0/5de429c2-d8ed-4e8a-89e8-a13ccaa49767?expires=1793464200&signature=384b693b5ab5c50fc4af4ba98dd2f110a911d5ba9d3f8098182bb2dc4fbe1e90&req=diUuH813nolaWfMW1HO4zVTddtEoxFR3rqtc0YNNUtJkTRh55zVPcl4%2BGHA4%0Aa0kCfHKP9DGopUAN%2BWs%3D%0A) -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599493851/f21b39c60e88050d4b0745325f0d/0a8c0d08-dc53-4ef1-8d9f-2b995242c1f9?expires=1793430000&signature=09dff8cf29bcd8ac1cee33fe0d0b1c618aecfd525117e5b49b6ca2e118d967e4&req=diUuH813nolaWPMW1HO4zUYvwlYPoT5c%2FjekULCQNzXUDi4k0jde2910t3GK%0A6BnxL32tr4dhz9LHkO4%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599493851/f21b39c60e88050d4b0745325f0d/0a8c0d08-dc53-4ef1-8d9f-2b995242c1f9?expires=1793464200&signature=d0bad1d28b007dc5734678bc3eda1075ea1394d4d8135a706d18e774aa567af8&req=diUuH813nolaWPMW1HO4zUYvwlYPpDpe%2FjekULCQNzUXYRE0oq03isOxkBRo%0AvZME24WG%2F6S%2FQrJnQQg%3D%0A) **To delete multiple conversations at once:** @@ -78,9 +78,9 @@ These steps apply to the Claude for Android, listed on Google Play as Claude by 3. Tap the trash icon, then tap "Delete" in the confirmation prompt. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599493849/3013a0ab921337b4544f7ffeffa6/e828ec14-fb52-4205-a840-707b6f2a848d?expires=1793430000&signature=39085bebaa119fa44964f5bd90e4a62c7d5177127051ca9cbaad7ff6b0bfbd5d&req=diUuH813nolbUPMW1HO4zWGamcRweY3f4AqhTnZa84VQD2BQwwZztiF81jn5%0A8w6jwCTdls7oTkvIiCY%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599493849/3013a0ab921337b4544f7ffeffa6/e828ec14-fb52-4205-a840-707b6f2a848d?expires=1793464200&signature=d02dc00a0de8ee43fec563b389c81e8838f991fe746a4033bd8cff74ba9f69ce&req=diUuH813nolbUPMW1HO4zWGamcRwfInd4AqhTnZa84WTh6zbnWZSqkfWAMP2%0AltdVYNzWlpAw%2Btxz4eU%3D%0A) -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599493853/e2507f53cce8a26776a22a457b1a/bd79bb8a-b078-420f-a4e1-75590367aa80?expires=1793430000&signature=7e4e4d14fdafec6fc924b60489e11eedbfd6bd1abc87fbf06c3a8ea8579334ca&req=diUuH813nolaWvMW1HO4zQTtEhb1x0A4SBGfF3I2bRigd%2BzqJDm1PXYmB%2BSf%0AEuN0TAwV1feEP7AIdH4%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2599493853/e2507f53cce8a26776a22a457b1a/bd79bb8a-b078-420f-a4e1-75590367aa80?expires=1793464200&signature=ace91bd8e5727fdbcd50adcd2cd16306ba4f136544b2826b8d365eb1acf24c2c&req=diUuH813nolaWvMW1HO4zQTtEhb1wkQ6SBGfF3I2bRhkI9PAeVlcV1BY%2BpNi%0AjfiF05%2Brqe0wzlD1YyQ%3D%0A) ## What happens when you delete a conversation diff --git a/content/support/8325618-paid-plan-billing-faqs.md b/content/support/8325618-paid-plan-billing-faqs.md index 0af40d0bc..7ff378954 100644 --- a/content/support/8325618-paid-plan-billing-faqs.md +++ b/content/support/8325618-paid-plan-billing-faqs.md @@ -50,7 +50,7 @@ There's no separate option to remove a card, and updating to a new card replaces If you want to use a name other than the one tied to your payment method, check the "Use a different name on invoices" box when adding or updating your payment method in **[Settings > Billing](https://claude.ai/settings/billing)**. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1922141785/666191101c11030b05f03a668a74/image.png?expires=1793430000&signature=bb02f0c6e1e7e2e13d427531b053004c5f293604168db0facb2e61abfc3f4af1&req=dSklFMh6nIZXXPMW1HO4zVXW8W6vaDPMQoNvNFTb5cdCm7Yfo6OzJyFEmMbA%0AFY9eZQrfuy64oeHPh5A%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1922141785/666191101c11030b05f03a668a74/image.png?expires=1793464200&signature=7cf358e43b72940d8018e0193872b62c47add710634a5e828ebbdd8ae403a5d3&req=dSklFMh6nIZXXPMW1HO4zVXW8W6vbTfOQoNvNFTb5ccJSpOkCIrfyK1QLpG0%0AE2VM3M1cA7BKFOE9ERM%3D%0A) ## How can I edit a paid invoice? diff --git a/content/support/8887527-customizing-your-appearance-settings.md b/content/support/8887527-customizing-your-appearance-settings.md index 9390ddc7c..31f502698 100644 --- a/content/support/8887527-customizing-your-appearance-settings.md +++ b/content/support/8887527-customizing-your-appearance-settings.md @@ -8,7 +8,7 @@ 3. Select from Light, Match System, and Dark under **Color mode**. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1648260417/d478c757c7115ad58a12026d4caf/AD_4nXc__Qop4X9hknWGfGj_y_DCpLutLruhxIclJIfir0ilsgNMg7X8ksIVnqk1Oce5FKlGIOYu9CKbVsu8DqD7iIY2aC0ZfXMyFTeAdNq-Cao2mXcj_WUpNF0kM2HoYR_dEx6N_cuJow?expires=1793430000&signature=5f5eefeb83ec713f44c17066d59c537e5e67a8ea490cfee70ecad77510a70046&req=dSYjHst4nYVeXvMW1HO4zc2jJqE5g4vkSBkgeTglJrpXQPSXWZN6QGHdx0CQ%0AqByEQsj0fd25n1cOcpM%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1648260417/d478c757c7115ad58a12026d4caf/AD_4nXc__Qop4X9hknWGfGj_y_DCpLutLruhxIclJIfir0ilsgNMg7X8ksIVnqk1Oce5FKlGIOYu9CKbVsu8DqD7iIY2aC0ZfXMyFTeAdNq-Cao2mXcj_WUpNF0kM2HoYR_dEx6N_cuJow?expires=1793464200&signature=51e62c73340081a7381a2f979b729bd2d863d8960e7a2f44b8c27fbaaa8835bc&req=dSYjHst4nYVeXvMW1HO4zc2jJqE5ho%2FmSBkgeTglJrp6em0fU4kx6Xm8FRnC%0AXqNVm6XJtR1OOfAMZy0%3D%0A) ## How to change your font @@ -16,10 +16,10 @@ 2. Select from Default, Match System, and Dyslexic Friendly. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1648260416/7fc0803d44d8de40f8e6636b2eb6/AD_4nXf0UEDa1i2QmqlQtoB5BgpQ-FfZVzss_7wMVQdvkmEDSfoTxixnG0GSxC6qrOs21HdkXH-I2Yn_GHDAf8yjd6FJtoh9FadALozvIErFp9r8LychDGLPb7OpN1CN4PRcgVAYNCre?expires=1793430000&signature=c14d33435f4a352f859d5faed989678c178849385ebba68f0a8399cf02490098&req=dSYjHst4nYVeX%2FMW1HO4zc896mPhXnE8QtNFlF5%2FHEdXNmx9oB5f8l%2FMB6qN%0Akhat2%2FiZTj2BsF6MbJ0%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1648260416/7fc0803d44d8de40f8e6636b2eb6/AD_4nXf0UEDa1i2QmqlQtoB5BgpQ-FfZVzss_7wMVQdvkmEDSfoTxixnG0GSxC6qrOs21HdkXH-I2Yn_GHDAf8yjd6FJtoh9FadALozvIErFp9r8LychDGLPb7OpN1CN4PRcgVAYNCre?expires=1793464200&signature=9dde7672eebbe28659ff1c61b255f3b6501d9753df37830979f40e2ea2a53113&req=dSYjHst4nYVeX%2FMW1HO4zc896mPhW3U%2BQtNFlF5%2FHEdLeSJ5jbXjuMTZ7FK8%0AiIVYuIug6XIh1UTjyn8%3D%0A) ## Can I disable the sidebar? It's not currently possible to completely disable the sidebar. You can click the button on the top right of the sidebar to open or close it. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1941108004/5217903737ddd9bb62fe5d7a904c/CleanShot+2026-01-14+at+09_12_58.png?expires=1793430000&signature=e6706ea960bf0f561f31ca5cf417bbf9bbff8a41183d06c52bbc7479780bfc9c&req=dSkjF8h%2BlYFfXfMW1HO4zUS%2BBlzyWnvvylfYa7uDb9k9E6XqZ4tmzh%2Fn82Zv%0AY3ir8HGwiFSDvB7WfBI%3D%0A) \ No newline at end of file +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/1941108004/5217903737ddd9bb62fe5d7a904c/CleanShot+2026-01-14+at+09_12_58.png?expires=1793464200&signature=474aa68b0ae1ce09afd715d6ecc01d69fdcbeb0a3a9ec7f99e24cb67cda857aa&req=dSkjF8h%2BlYFfXfMW1HO4zUS%2BBlzyX3%2FtylfYa7uDb9lvCPnjjiE9CGKPLCMX%0ANYocjvucaCm0PIfq2Wk%3D%0A) \ No newline at end of file diff --git a/content/support/9267400-move-your-personal-claude-account-to-a-team-or-enterprise-organization.md b/content/support/9267400-move-your-personal-claude-account-to-a-team-or-enterprise-organization.md index aaa5e62d4..d733b82f5 100644 --- a/content/support/9267400-move-your-personal-claude-account-to-a-team-or-enterprise-organization.md +++ b/content/support/9267400-move-your-personal-claude-account-to-a-team-or-enterprise-organization.md @@ -132,7 +132,7 @@ For the full walkthrough of your options, deadlines, and what happens to your su You may have both a personal account and an organization account tied to the same email address. You can switch between them by clicking your initials or name in the lower left corner of the screen. -![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2312193347/712f763fc290b2488c103849f20c/0c135a6f-3442-4ee1-9ab7-98673f03ef6e?expires=1793430000&signature=e9f31a93c09c0b246a1146f05b4d2a35a1d311d8f11b7101e1694a6c7a776336&req=diMmFMh3noJbXvMW1HO4zXhPnNMyyx9hufhmlOXMdYZila6QM9kVkEk1rqd5%0AwTTv4aL%2BKWZM8dm3PUQ%3D%0A) +![](https://downloads.intercomcdn.com/i/o/lupk8zyo/2312193347/712f763fc290b2488c103849f20c/0c135a6f-3442-4ee1-9ab7-98673f03ef6e?expires=1793464200&signature=e3c9455ea91acda542dae05de5f08a011b3fa2feaa876d0db3a7687e18e74b5e&req=diMmFMh3noJbXvMW1HO4zXhPnNMyzhtjufhmlOXMdYaaYiuwTuP1gGYU%2Btvi%0Ams3OidB%2Fs8ptHjPfCvg%3D%0A) A blue checkmark shows which account you're currently using. Click the other account to switch to it and access its separate conversations and projects.