diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index bfc7f07e5..1a1017092 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -11,6 +11,6 @@ jobs: label: runs-on: ubuntu-latest steps: - - uses: actions/labeler@v6 + - uses: actions/labeler@v7 with: sync-labels: false diff --git a/blog/assets/css/extended/quotes.css b/blog/assets/css/extended/quotes.css new file mode 100644 index 000000000..f081b9fb8 --- /dev/null +++ b/blog/assets/css/extended/quotes.css @@ -0,0 +1,256 @@ +/* ─── Quote cards (quotes / quote shortcodes) ────────────────────────────── */ +/* A row of testimonial cards separated by hairline dividers. The track is a + scroll-snap carousel; nav controls are injected by the shortcode's script + and stay hidden when everything fits one view. */ + +/* The strip breaks out of the prose column: symmetric negative margins grow + it toward the viewport edges, capped at 1200px so it stays sane on wide + monitors. The viewport bound is 50vw - 50% - 32px per side. 100vw includes + the page scrollbar, so the 32px gutter both absorbs the scrollbar width + and keeps a visible margin, which is what prevents a page-level horizontal + scrollbar. The prose column is centered in the viewport, so symmetric + margins keep the strip centered too. */ +.mcp-quotes { + --mcp-quotes-bleed: max(0px, min((1200px - 100%) / 2, 50vw - 50% - 32px)); + margin: 40px calc(-1 * var(--mcp-quotes-bleed)); +} + +/* A lone quote is a pull quote, not a strip: it stays in the prose column. */ +.mcp-quotes:has(.mcp-quote:only-child) { + --mcp-quotes-bleed: 0px; +} + +.mcp-quotes-track { + display: grid; + grid-auto-flow: column; + grid-auto-columns: 100%; + overflow-x: auto; + scroll-snap-type: x mandatory; + overscroll-behavior-x: contain; + scrollbar-width: none; +} + +.mcp-quotes-track::-webkit-scrollbar { + display: none; +} + +/* When more cards exist than fit one view, they are sized a bit narrower so + a slice of the next card peeks at the right edge, signaling that the strip + scrolls. Sets that fit exactly (1, 2, or 3 cards per breakpoint) keep the + full division and no peek. */ +@media (max-width: 599px) { + .mcp-quotes-track:has(> .mcp-quote + .mcp-quote) { + grid-auto-columns: calc(100% - 44px); + } +} + +@media (min-width: 600px) { + .mcp-quotes-track { + grid-auto-columns: 50%; + } +} + +@media (min-width: 600px) and (max-width: 899px) { + .mcp-quotes-track:has(> .mcp-quote:nth-child(3)) { + grid-auto-columns: calc((100% - 56px) / 2); + } +} + +@media (min-width: 900px) { + .mcp-quotes-track { + grid-auto-columns: calc(100% / 3); + } + + .mcp-quotes-track:has(> .mcp-quote:nth-child(4)) { + grid-auto-columns: calc((100% - 72px) / 3); + } +} + +.post-content .mcp-quote { + display: flex; + flex-direction: column; + min-width: 0; + margin: 0; + padding: 8px 24px; + border-inline-start: 1px solid var(--border); + scroll-snap-align: start; +} + +.post-content .mcp-quote:first-child { + padding-inline-start: 0; + border-inline-start: none; +} + +/* A lone quote reads as a pull quote: full track width, capped measure. */ +.mcp-quotes-track:has(> .mcp-quote:only-child) { + grid-auto-columns: 100%; +} + +.post-content .mcp-quote:only-child { + padding-inline-end: 0; +} + +.post-content .mcp-quote:only-child .mcp-quote-text { + max-width: 640px; +} + +/* 1-up mobile: tighter padding, but keep the hairline so the peeking next + card reads as a separate card. */ +@media (max-width: 599px) { + .post-content .mcp-quote { + padding-inline: 16px; + } +} + +/* Logos render at a common cap height regardless of the SVG's own aspect + ratio. Inline SVGs inherit currentColor so they track the theme. */ +.mcp-quote-logo { + display: block; + height: 28px; + margin-bottom: 20px; + color: var(--primary); +} + +.mcp-quote-logo svg, +.mcp-quote-logo img { + display: block; + height: 100%; + width: auto; + max-width: 100%; +} + +.mcp-quote-logo-text { + font-size: 18px; + font-weight: 400; + line-height: 28px; + letter-spacing: -0.01em; + color: var(--primary); +} + +/* Reset PaperMod's blockquote treatment (left bar, italic-ish inset). */ +.post-content .mcp-quote-text { + margin: 0; + padding: 0; + border: none; + font-size: 16px; + font-style: normal; + line-height: 1.6; + color: var(--content); +} + +.post-content .mcp-quote-text p { + display: inline; + margin: 0; + font-size: inherit; +} + +/* Attribution: the name bold on one line, the title regular and muted on the + next. PaperMod bolds figure > figcaption wholesale, so the figcaption is + reset to 400 and only the name span re-bolds (700, matching the blog's + strong text). Both lines share one tight line-height so the pair reads as + a unit, not two paragraphs. */ +.post-content .mcp-quote-attrib { + margin-top: auto; + padding-top: 16px; + font-size: 14px; + font-weight: 400; + line-height: 1.45; + color: var(--secondary); +} + +.mcp-quote-attrib-name { + display: block; + font-weight: 700; + color: var(--content); +} + +.mcp-quote-attrib-title { + display: block; +} + +/* Attributions start on the same line in every card. The track exposes three + explicit rows (logo / quote / attribution) and each card adopts them via + subgrid, so the quote row is sized by the longest quote in the set and + every attribution starts at the same y, on every carousel page. Long + quotes spill downward inside that row; short cards keep the open space. + Browsers without subgrid keep the flex column above, where attributions + bottom-align instead. Skipped under 600px, where cards show one per view + and cross-card alignment would only add empty space. */ +@media (min-width: 600px) { + @supports (grid-template-rows: subgrid) { + .mcp-quotes-track { + grid-template-rows: auto auto auto; + } + + .post-content .mcp-quote { + display: grid; + grid-template-rows: subgrid; + grid-row: span 3; + } + + .post-content .mcp-quote .mcp-quote-attrib { + margin-top: 0; + align-self: start; + } + } +} + +/* ─── Carousel controls ──────────────────────────────────────────────────── */ +.mcp-quotes-nav { + display: flex; + align-items: center; + justify-content: center; + gap: 16px; + margin-top: 28px; +} + +.mcp-quotes-nav[hidden] { + display: none; +} + +.mcp-quotes-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + padding: 0; + color: var(--primary); + background: var(--code-bg); + border: 1px solid var(--border); + border-radius: 50%; + cursor: pointer; + transition: border-color 0.15s ease; +} + +@media (hover: hover) { + .mcp-quotes-btn:not(:disabled):hover { + border-color: var(--primary); + } +} + +.mcp-quotes-btn:disabled { + opacity: 0.35; + cursor: default; +} + +.mcp-quotes-dots { + display: flex; + align-items: center; + gap: 8px; +} + +.mcp-quotes-dot { + width: 8px; + height: 8px; + padding: 0; + background: var(--tertiary); + border: none; + border-radius: 50%; + cursor: pointer; + transition: background 0.15s ease; +} + +.mcp-quotes-dot[aria-current="true"] { + background: var(--primary); +} diff --git a/blog/content/posts/2026-05-21-mcp-2026-07-28-rc.md b/blog/content/posts/2026-05-21-mcp-2026-07-28-rc.md index 5348f6861..fbc4686ba 100644 --- a/blog/content/posts/2026-05-21-mcp-2026-07-28-rc.md +++ b/blog/content/posts/2026-05-21-mcp-2026-07-28-rc.md @@ -145,7 +145,7 @@ change how those prompts are delivered. Instead of holding a Server-Sent Events ```json { - "resultType": "inputRequired", + "resultType": "input_required", "inputRequests": { "confirm": { "type": "elicitation", diff --git a/blog/layouts/shortcodes/quote.html b/blog/layouts/shortcodes/quote.html new file mode 100644 index 000000000..c2516bd29 --- /dev/null +++ b/blog/layouts/shortcodes/quote.html @@ -0,0 +1,39 @@ +{{- /* + A single testimonial card. Use inside a `quotes` block. + + Params: + name - person's name + title - person's role, shown on its own line under the name + company - company name, used as the logo's accessible label + (and shown as text when no logo is given) + logo - filename of an SVG in the post's page bundle, or a static path. + Bundle SVGs are inlined so currentColor tracks the theme. + + The quote text goes in the shortcode body. Markdown is supported. +*/ -}} +{{- $name := .Get "name" -}} +{{- $title := .Get "title" -}} +{{- $company := .Get "company" -}} +{{- $logo := .Get "logo" -}} +
+ {{- with $logo -}} + {{- with $.Page.Resources.GetMatch . -}} + {{- if eq .MediaType.SubType "svg" -}} + + {{- else -}} + + {{- end -}} + {{- else -}} + + {{- end -}} + {{- else -}} + + {{- end }} +
“{{ trim .Inner " \n" | .Page.RenderString }}”
+
+ {{ $name }} + {{- with $title }} + {{ . }} + {{- end }} +
+
diff --git a/blog/layouts/shortcodes/quotes.html b/blog/layouts/shortcodes/quotes.html new file mode 100644 index 000000000..76920767b --- /dev/null +++ b/blog/layouts/shortcodes/quotes.html @@ -0,0 +1,107 @@ +{{- /* + Testimonial quote row. Wraps one or more inner `quote` shortcodes in a + scroll-snap carousel. Nav controls stay hidden unless the quotes overflow + one view, so 1-3 quotes render as a plain static row. + + Usage: + {{< quotes >}} + {{< quote name="Ada Person" title="CTO" company="Acme" logo="acme.svg" >}} + Quote text, markdown allowed. + {{< /quote >}} + {{< /quotes >}} +*/ -}} +{{- $label := .Get "label" | default "Testimonials" -}} +
+
+ {{ .Inner }} +
+ +
+{{- if not (.Page.Store.Get "mcp-quotes-js") -}} +{{- .Page.Store.Set "mcp-quotes-js" true }} + +{{- end -}} diff --git a/docs/community/working-groups/mcp-apps.mdx b/docs/community/working-groups/mcp-apps.mdx new file mode 100644 index 000000000..c1c53160c --- /dev/null +++ b/docs/community/working-groups/mcp-apps.mdx @@ -0,0 +1,183 @@ +--- +title: MCP Apps Charter +description: Charter for the MCP Apps Working Group. +--- + +## Group Type + +**Working Group** + +## Mission Statement + +The MCP Apps Working Group defines how MCP servers deliver interactive user +interfaces to hosts. The group emerged from the convergence of MCP-UI and the +OpenAI Apps SDK into a single open standard via +[SEP-1865](/seps/1865-mcp-apps-interactive-user-interfaces-for-mcp) +(Extensions Track, Final), which introduces predeclared UI resources (the +`ui://` URI scheme), tool-to-UI association through metadata, and +bi-directional host/UI communication over MCP's JSON-RPC base protocol. The WG +produces specification extensions, SDKs, reference implementations, and host +guidance because interactive UI touches the protocol spec, SDK surface, host +security model, and client rendering behavior across the ecosystem (Claude, +ChatGPT, VS Code, Goose, Postman, and others). + +## Scope + +### In Scope + +- **Specification Work**: The MCP Apps Extension + ([modelcontextprotocol/ext-apps](https://github.com/modelcontextprotocol/ext-apps)) + and related SEPs, including UI resource declaration, tool metadata, lifecycle + and messaging (`ui/*` methods and notifications), and content-type profiles + (initially `text/html;profile=mcp-app`) under the + `io.modelcontextprotocol/ui` namespace. +- **Future Content Types & Rendering Targets**: Non-HTML view mimetypes, + container-agnostic rendering, and declarative or generative UI directions, + including A2UI interoperability. +- **SDKs & Reference Implementations**: The MCP Apps SDK + (`@modelcontextprotocol/ext-apps`), example servers, the reference host, and + host integration references demonstrating secure rendering and + bi-directional communication. +- **Security Model**: Sandboxing, origin isolation, CSP guidance, auditability + of UI-initiated actions, and threat-model documentation for host + implementers. +- **Conformance**: Host compatibility tests, an official MCP App validator, and + the definition of what "spec-conformant" means for both apps and hosts. +- **Cross-Cutting Concerns**: Coordination with the Registry WG (app + discoverability and metadata), Agents WG (UI in agentic loops), Security IG + (sandboxing and UI-initiated tool calls), SDK WG and SDK maintainers + (per-language support), and external projects (A2UI, AG-UI, and community + frameworks). +- **Documentation**: Specification sections and guidance for app authors and + host implementers. + +### Out of Scope + +- **Host-specific design systems**: Hosts control final look-and-feel. The WG + standardizes the contract, not visual design. +- **Client implementation mandates**: We document rendering and security + patterns but cannot require specific host behavior beyond spec conformance. +- **General agent orchestration**: Agent loops and sub-agent coordination + belong to the Agents WG. This WG covers only the UI surface. +- **Core protocol changes**: Changes to base MCP semantics are proposed through + the [SEP process](/community/sep-guidelines) and owned by the relevant group + or Core Maintainers. This WG owns the Apps extension, not the base protocol. + +### Related Groups + +- **Agents WG**: interactive UI within agentic flows and task lifecycles. +- **[Registry WG](/community/working-groups/registry)**: app metadata, + discovery, and distribution. +- **[Security IG](/community/interest-groups/security)**: sandboxing model and + review of UI-initiated actions. +- **[SDK WG](/community/working-groups/sdk)**: per-language MCP Apps support + and SDK consistency. + +## Leadership + +| Role | Name | Organization | GitHub | Term | +| ---- | ----------- | ------------ | ------------------------------------ | ------- | +| Lead | Ido Salomon | MCP-UI | [@idosal](https://github.com/idosal) | Initial | +| Lead | Liad Yosef | MCP-UI / Ora | [@liady](https://github.com/liady) | Initial | + +## Authority & Decision Rights + +| Decision Type | Authority Level | +| ----------------------------------- | ------------------------------------------------------ | +| Meeting logistics & scheduling | WG Leads (autonomous) | +| Proposal prioritization within WG | WG Leads (autonomous) | +| SEP triage & closure (in scope) | WG Leads (autonomous, with documented rationale) | +| Technical design within scope | WG consensus | +| Spec changes (additive) | WG consensus → Core Maintainer approval | +| Spec changes (breaking/fundamental) | WG consensus → Core Maintainer approval + wider review | +| Scope expansion | Core Maintainer approval required | +| WG Member approval | WG Member sponsors | + +## Membership + +| Name | Organization | GitHub | Discord | Level | +| ------------------ | -------------------------- | ---------------------------------------------------------- | ------- | ----------- | +| Ido Salomon | MCP-UI | [@idosal](https://github.com/idosal) | | Lead | +| Liad Yosef | MCP-UI / Ora | [@liady](https://github.com/liady) | | Lead | +| Olivier Chafik | Anthropic / MCP Maintainer | [@ochafik](https://github.com/ochafik) | | WG Member | +| Jonathan Hefner | MCP Maintainer | [@jonathanhefner](https://github.com/jonathanhefner) | | WG Member | +| Anton Pidkuiko | MCP Maintainer | [@antonpk1](https://github.com/antonpk1) | | WG Member | +| Nick Cooper | OpenAI | [@nickcoai](https://github.com/nickcoai) | | WG Member | +| Max Stoiber | OpenAI | [@mstoiber-oai](https://github.com/mstoiber-oai) | | Participant | +| Dominic Farolino | Google / Chromium | [@domfarolino](https://github.com/domfarolino) | | Participant | +| Cameron Yick | Datadog | [@hydrosquall](https://github.com/hydrosquall) | | Participant | +| Frédéric Barthelet | Alpic | [@fredericbarthelet](https://github.com/fredericbarthelet) | | Participant | +| Ola Hungerford | Nordstrom | [@olaservo](https://github.com/olaservo) | | Participant | +| Yann Jouanin | | [@yannj-fr](https://github.com/yannj-fr) | | Participant | + +## Operations + +| Meeting | Frequency | Duration | Purpose | +| --------------- | -------------------------------- | -------- | ------------------------------------------------------------------------ | +| Working Session | Tri-weekly (Wednesday, 08:00 PT) | 60 min | Spec review, SDK coordination, host implementation feedback; open to all | +| Office Hours | Monthly (planned) | 30 min | Open Q&A for app authors, host implementers, and newcomers | + +Meetings are published at +[meet.modelcontextprotocol.io](https://meet.modelcontextprotocol.io) under the +`#mcp-apps-wg` tag. Agendas and notes are maintained as a public rolling +document, the +[MCP Apps Workgroup Agenda](https://docs.google.com/document/d/103S6IjN9D80ntbPIcK3mP_ZWdeFom2Mq8qpkpIsXRVI/edit), +and are posted per the MCP meeting policy. The group has met since +2025-12-17. + +Discord: `#mcp-apps-wg` + +## Resources + +- Extension specification & SDK: + [modelcontextprotocol/ext-apps](https://github.com/modelcontextprotocol/ext-apps) + (npm: `@modelcontextprotocol/ext-apps`) +- SEP: [SEP-1865](/seps/1865-mcp-apps-interactive-user-interfaces-for-mcp) +- Ecosystem docs: [MCP Apps overview](/extensions/apps/overview) and + [Build an MCP App](/extensions/apps/build) +- Documentation & API reference: + [apps.extensions.modelcontextprotocol.io](https://apps.extensions.modelcontextprotocol.io/) +- Issue tracker: + [ext-apps issues](https://github.com/modelcontextprotocol/ext-apps/issues) + +## Deliverables & Success Metrics + +### Active Work Items + +Live tracking is in +[ext-apps issues](https://github.com/modelcontextprotocol/ext-apps/issues) and +pull requests. Headline workstreams: + +| Item | Status | Target Date | Champion | +| ---------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ----------- | -------------------------------------------------------------------------------------- | +| Spec maintenance & next revision (current: 2026-01-26) | In Progress | | [@idosal](https://github.com/idosal), [@liady](https://github.com/liady) | +| MCP Apps SDK (`@modelcontextprotocol/ext-apps`, stable 1.x) | Maintained | | MCP Apps SDK maintainers | +| Host compatibility & conformance test suite ([#674](https://github.com/modelcontextprotocol/ext-apps/issues/674)) | In Progress | | [@idosal](https://github.com/idosal) | +| Reusable views & view session identity ([#430](https://github.com/modelcontextprotocol/ext-apps/issues/430)) | In Progress | | [@mstoiber-oai](https://github.com/mstoiber-oai), [@idosal](https://github.com/idosal) | +| Rendering architecture: decouple requirements from the double-sandboxed iframe ([#716](https://github.com/modelcontextprotocol/ext-apps/issues/716)) | In Review | | [@domfarolino](https://github.com/domfarolino) | +| Dynamic View Content via embedded resources ([#699](https://github.com/modelcontextprotocol/ext-apps/pull/699)) | Proposal | | [@liady](https://github.com/liady) | +| Views not tied to a specific tool call ([#672](https://github.com/modelcontextprotocol/ext-apps/issues/672)) | In Progress | | [@mstoiber-oai](https://github.com/mstoiber-oai), [@liady](https://github.com/liady) | +| Authoring toolkit: Agent Skills, reference host (`basic-host`), example suite | Maintained | | TBD | + +### Success Criteria + +- Published, stable extension specification (2026-01-26 revision shipped) with + a maintained SDK and reference host, and responsive triage of spec and SDK + issues. +- A conformance suite that host implementers can run, with results published so + app authors know what works where. +- Interoperable MCP Apps running unmodified across multiple major hosts, with + the documented security model adopted by those hosts. +- A clear, specified path for content types beyond HTML. +- MCP Apps established as the standard UI layer of the agentic web: a single + app implementation reaching every MCP host. + +## Changelog + +| Date | Change | +| ---------- | ------------------------------------------------------------------------------------------ | +| 2025-11-21 | SEP-1865 proposed; MCP-UI and OpenAI Apps SDK approaches unified under the MCP Apps banner | +| 2025-12-17 | First MCP Apps Working Group meeting | +| 2026-01-26 | MCP Apps extension specification revision 2026-01-26 published | +| 2026-01-28 | SEP-1865 marked Final and merged | +| 2026-07-26 | Initial charter | diff --git a/docs/docs.json b/docs/docs.json index 74bcb9caa..0360e197c 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -497,6 +497,7 @@ "community/working-groups/file-uploads", "community/working-groups/inspector-v2", "community/working-groups/interceptors", + "community/working-groups/mcp-apps", "community/working-groups/registry", "community/working-groups/sdk", "community/working-groups/server-card", diff --git a/docs/docs/tutorials/security/authorization.mdx b/docs/docs/tutorials/security/authorization.mdx index 572d3e806..6de531d04 100644 --- a/docs/docs/tutorials/security/authorization.mdx +++ b/docs/docs/tutorials/security/authorization.mdx @@ -648,8 +648,8 @@ class Config: AUTH_REALM: str = os.getenv("AUTH_REALM", "master") # OAuth client settings - OAUTH_CLIENT_ID: str = os.getenv("OAUTH_CLIENT_ID", "mcp-server") - OAUTH_CLIENT_SECRET: str = os.getenv("OAUTH_CLIENT_SECRET", "UO3rmozkFFkXr0QxPTkzZ0LMXDidIikB") + OAUTH_CLIENT_ID: str = os.getenv("OAUTH_CLIENT_ID", "test-client") + OAUTH_CLIENT_SECRET: str = os.getenv("OAUTH_CLIENT_SECRET", "") # Server settings MCP_SCOPE: str = os.getenv("MCP_SCOPE", "mcp:tools") @@ -869,8 +869,11 @@ class IntrospectionTokenVerifier(TokenVerifier): form_data = { "token": token, "client_id": self.client_id, - "client_secret": self.client_secret, } + # Only send client_secret when one is configured + # Public clients authenticate with client_id alone. + if self.client_secret: + form_data["client_secret"] = self.client_secret headers = {"Content-Type": "application/x-www-form-urlencoded"} response = await client.post( @@ -894,7 +897,13 @@ class IntrospectionTokenVerifier(TokenVerifier): client_id=data.get("client_id", "unknown"), scopes=data.get("scope", "").split() if data.get("scope") else [], expires_at=data.get("exp"), - resource=data.get("aud"), # Include resource in token + # AccessToken.resource is `str | None`. Keycloak returns `aud` + # as a *list* here (e.g. ["test-client", "http://localhost:3000", + # "account"]); passing that list straight in raises a pydantic + # ValidationError that the broad `except` below turns into a + # silent 401. We already confirmed this server's resource is a + # valid audience in `_validate_resource`, so record that. + resource=self.resource_url, ) except Exception as e: @@ -923,7 +932,51 @@ class IntrospectionTokenVerifier(TokenVerifier): return check_resource_allowed(self.resource_url, resource) ``` -For more details, see the [Python SDK documentation](https://github.com/modelcontextprotocol/python-sdk). +For more details, see below or the [Python SDK documentation](https://github.com/modelcontextprotocol/python-sdk). + +**Python MCP Server** + +In the server's root have a `pyproject.toml` file and a `mcp_server` folder. Put all the Python files in the `mcp_server` folder, and fill the `pyproject.toml` file like: + +```toml +[project] +name = "mcp-simple-auth" +version = "0.1.0" +description = "A simple MCP server demonstrating OAuth authentication" +requires-python = ">=3.10" +authors = [{ name = "Model Context Protocol a Series of LF Projects, LLC." }] +license = { text = "MIT" } +dependencies = [ + "anyio>=4.5", + "click>=8.2.0", + "httpx>=0.27", + "mcp", + "pydantic>=2.0", + "pydantic-settings>=2.5.2", + "sse-starlette>=1.6.1", + "uvicorn>=0.23.1; sys_platform != 'emscripten'", +] + +[project.scripts] +mcp-simple-auth-rs = "mcp_server.server:main" + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["mcp_server"] + +[dependency-groups] +dev = ["pyright>=1.1.391", "pytest>=8.3.4", "ruff>=0.8.5"] +``` + +Then run the commands below to start the server. + +```bash +uv sync +uv run mcp-simple-auth-rs --port=3000 --auth-server=http://localhost:8080 --transport=streamable-http +``` diff --git a/package-lock.json b/package-lock.json index 3d05de693..0bee3de3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,16 +13,16 @@ "ajv": "^8.20.0", "ajv-formats": "^3.0.1", "cheerio": "^1.2.0", - "eslint": "^10.7.0", + "eslint": "^10.8.0", "eslint-config-prettier": "^10.1.8", "glob": "^13.0.6", - "prettier": "^3.9.5", + "prettier": "^3.9.6", "remark-mdx": "^3.1.1", "remark-parse": "^11.0.0", "tsx": "^4.23.1", "typedoc": "^0.28.20", "typescript": "^6.0.3", - "typescript-eslint": "^8.64.0", + "typescript-eslint": "^8.65.0", "typescript-json-schema": "0.68.0", "unified": "^11.0.5" }, @@ -543,9 +543,9 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz", - "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.7.0.tgz", + "integrity": "sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -870,17 +870,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.64.0.tgz", - "integrity": "sha512-CGvQPBxN3wZLu6Rz2kFUpZeoCm78xUic92ck39KPePkO1NPOwjCqdQnm5Q87tpWw9vcBvW8XLrDXjH9PWYtJ3Q==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.65.0.tgz", + "integrity": "sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.64.0", - "@typescript-eslint/type-utils": "8.64.0", - "@typescript-eslint/utils": "8.64.0", - "@typescript-eslint/visitor-keys": "8.64.0", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/type-utils": "8.65.0", + "@typescript-eslint/utils": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -893,7 +893,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.64.0", + "@typescript-eslint/parser": "^8.65.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -909,16 +909,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.64.0.tgz", - "integrity": "sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.65.0.tgz", + "integrity": "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.64.0", - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/typescript-estree": "8.64.0", - "@typescript-eslint/visitor-keys": "8.64.0", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3" }, "engines": { @@ -934,14 +934,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.64.0.tgz", - "integrity": "sha512-tk4WpOJ6IEbGrVHaNmM0YRrwAD3exZlIK3iadQNAxh4YKk6jvUQ4ecq18n+v7+meh+cJ3j+D8nbk8sRKhlwLQg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.65.0.tgz", + "integrity": "sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.64.0", - "@typescript-eslint/types": "^8.64.0", + "@typescript-eslint/tsconfig-utils": "^8.65.0", + "@typescript-eslint/types": "^8.65.0", "debug": "^4.4.3" }, "engines": { @@ -956,14 +956,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.64.0.tgz", - "integrity": "sha512-CXEaFdYXjSTgKhisNkwCcJwTP8Pl+fmRrEQrri4nm3vU743bALrxzLmq7fHG/7e6a5xO0lDYeURpZmBuhHk54w==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.65.0.tgz", + "integrity": "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/visitor-keys": "8.64.0" + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -974,9 +974,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.64.0.tgz", - "integrity": "sha512-2yo8rRNKuzbVWQp5kslhANqZ2uDAeROQHBRZNPu8JDsHmeFNj/XJJhX/FhNUWmkHHvoNsKa6+tHJiig87EzsQw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.65.0.tgz", + "integrity": "sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==", "dev": true, "license": "MIT", "engines": { @@ -991,15 +991,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.64.0.tgz", - "integrity": "sha512-XWG4Fmmv/6SvyS9nH8jWrKs6terwJvE8cyRt1CzYYqzp9OrPhCT4cMc/f7C6RZCwG+qMmiffJS1/qJP8G1URtg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.65.0.tgz", + "integrity": "sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/typescript-estree": "8.64.0", - "@typescript-eslint/utils": "8.64.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -1016,9 +1016,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.64.0.tgz", - "integrity": "sha512-qjhfuTfLXjA4IOzXvz0rTjT01BqEiIgPoUeMwiEjnaHKJMTNo8rH5pYW1a2L/0Dnux2fPC85AeyJoWaGa8WxTA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.65.0.tgz", + "integrity": "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==", "dev": true, "license": "MIT", "engines": { @@ -1030,16 +1030,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.64.0.tgz", - "integrity": "sha512-Pztpsn1aCE1oWDvDEfUk31nngvvF7vUB5SwHFEaZIFpvw7WJtqUHHL4plBZDA9HfWJJjL13BdG0YrJInTUvoVA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.65.0.tgz", + "integrity": "sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.64.0", - "@typescript-eslint/tsconfig-utils": "8.64.0", - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/visitor-keys": "8.64.0", + "@typescript-eslint/project-service": "8.65.0", + "@typescript-eslint/tsconfig-utils": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -1058,16 +1058,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.64.0.tgz", - "integrity": "sha512-aJUGVB3+U0htrrCjoA8qukw8cm8fNCGAxK/tVoS70k8aeb7DETKeFozRiVFIwEeN9WJLsjaP3ph8I60tY2XZoQ==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.65.0.tgz", + "integrity": "sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.64.0", - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/typescript-estree": "8.64.0" + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1082,13 +1082,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.64.0.tgz", - "integrity": "sha512-mrtuL8Nsn6gi2H4mo5KMTp823M+3Q19Ew/i+Zlikq20tIMm99C3Ez0dCmkWWnxut20esQvTg8aUSEhMcAOXhEw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.65.0.tgz", + "integrity": "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/types": "8.65.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -1649,9 +1649,9 @@ } }, "node_modules/eslint": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.7.0.tgz", - "integrity": "sha512-GVTD7s1vdIl6UYvAfriOPeY1Df8LIZjfofLvHwde+erDHGGuHyuM6xoxRxmHiebhYuD2p1vN4wWh0XzPARSGDQ==", + "version": "10.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.8.0.tgz", + "integrity": "sha512-nuKKvN+oIBO0koN7Tm7dlkmnkc21mtt0QJLwAKzjLq14y6lRTdVG36MZHJ8eQHwdJMwZbQNMlPOYedMq/oVJvQ==", "dev": true, "license": "MIT", "workspaces": [ @@ -1661,7 +1661,7 @@ "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.5", - "@eslint/config-helpers": "^0.6.0", + "@eslint/config-helpers": "^0.7.0", "@eslint/core": "^1.2.1", "@eslint/plugin-kit": "^0.7.2", "@humanfs/node": "^0.16.6", @@ -1685,7 +1685,7 @@ "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "minimatch": "^10.2.4", + "minimatch": "^10.2.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -3392,9 +3392,9 @@ } }, "node_modules/prettier": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.5.tgz", - "integrity": "sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg==", + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", + "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", "dev": true, "license": "MIT", "bin": { @@ -3727,16 +3727,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.64.0.tgz", - "integrity": "sha512-0qg+pDNMnqYzqH9AnNK+39tejHvsShUOUUoRUgtnTGE7QuMZhiFDnozq8nHJVq+Wae6NMLKNWLg5WmkcC/ndyQ==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.65.0.tgz", + "integrity": "sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.64.0", - "@typescript-eslint/parser": "8.64.0", - "@typescript-eslint/typescript-estree": "8.64.0", - "@typescript-eslint/utils": "8.64.0" + "@typescript-eslint/eslint-plugin": "8.65.0", + "@typescript-eslint/parser": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" diff --git a/package.json b/package.json index 96aed177f..9f1943a36 100644 --- a/package.json +++ b/package.json @@ -49,16 +49,16 @@ "ajv": "^8.20.0", "ajv-formats": "^3.0.1", "cheerio": "^1.2.0", - "eslint": "^10.7.0", + "eslint": "^10.8.0", "eslint-config-prettier": "^10.1.8", "glob": "^13.0.6", - "prettier": "^3.9.5", + "prettier": "^3.9.6", "remark-mdx": "^3.1.1", "remark-parse": "^11.0.0", "tsx": "^4.23.1", "typedoc": "^0.28.20", "typescript": "^6.0.3", - "typescript-eslint": "^8.64.0", + "typescript-eslint": "^8.65.0", "typescript-json-schema": "0.68.0", "unified": "^11.0.5" }, diff --git a/tools/sep-automation/package-lock.json b/tools/sep-automation/package-lock.json index ba4ea8f72..6ce2d5132 100644 --- a/tools/sep-automation/package-lock.json +++ b/tools/sep-automation/package-lock.json @@ -2017,9 +2017,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "dev": true, "funding": [ { @@ -2120,9 +2120,9 @@ "license": "MIT" }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", "dev": true, "funding": [ { @@ -2140,7 +2140,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" },