Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
ee39601
Add MCP Apps support for static_map_image_tool
mattpodwysocki Feb 2, 2026
79fd113
Enhance static map UI with click-to-zoom and better layout
mattpodwysocki Feb 2, 2026
aff8950
Update CHANGELOG with MCP Apps support details
mattpodwysocki Feb 4, 2026
4d7a35d
Fix registerAppResource call to include required _meta.ui CSP config
mattpodwysocki Feb 18, 2026
e74332f
Fix registerAppResource config: cast type instead of adding _meta
mattpodwysocki Feb 18, 2026
5a2d160
Add viewUUID to static_map_image_tool response _meta
mattpodwysocki Feb 18, 2026
b7a39e2
Add size-changed and fullscreen support to static map UI
mattpodwysocki Feb 18, 2026
cd89e9e
Fix HTML entity rendering and black space in static map UI
mattpodwysocki Feb 18, 2026
8b9b9b3
Remove height:100vh to eliminate black padding below map image
mattpodwysocki Feb 18, 2026
84ade5e
Measure actual rendered height for size-changed, not natural dimensions
mattpodwysocki Feb 18, 2026
aa76a33
Add screenshots of MCP Apps static map preview
mattpodwysocki Feb 18, 2026
c78367a
Remove screenshots from docs (will attach directly to PR)
mattpodwysocki Feb 18, 2026
7b972ad
Sync manifest/server versions after rebase onto main
mattpodwysocki Feb 18, 2026
c0f34aa
Restore package.json from main and add ext-apps dependency
mattpodwysocki Feb 18, 2026
1226e11
Document breaking change: static_map_image_tool returns URL not base64
mattpodwysocki Feb 23, 2026
8c3c705
Upgrade @modelcontextprotocol/ext-apps to 1.1.0
mattpodwysocki Feb 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,33 @@

## 0.8.3

### Breaking Changes

- **`static_map_image_tool`**: Tool now returns the map URL as `text` content instead of a base64-encoded image
- Before: `content: [{ type: "image", data: "...base64...", mimeType: "image/png" }]`
- After: `content: [{ type: "text", text: "https://api.mapbox.com/styles/v1/..." }]`
- In MCP Apps-capable hosts the image is rendered interactively via `StaticMapUIResource`; in other hosts the model receives the URL and can present or use it directly

### Features Added

- **MCP Apps Support for StaticMapImageTool** (#109)
- Added interactive map preview in compatible MCP clients (VS Code, Claude Code, Goose)
- Implemented `StaticMapUIResource` serving interactive HTML with inline MCP Apps SDK
- Added `@modelcontextprotocol/ext-apps@^1.0.1` dependency
- Enhanced `BaseTool` with `meta` property for MCP Apps metadata
- Configured CSP for `api.mapbox.com` domains
- Sends `ui/notifications/size-changed` to fit panel to rendered image height
- Fullscreen toggle using `ui/request-display-mode`
- Uses proper `RESOURCE_MIME_TYPE` ("text/html;profile=mcp-app") per MCP Apps specification

### Security

- **CVE-2026-0621**: Updated `@modelcontextprotocol/sdk` to 1.25.3 to fix ReDoS vulnerability in UriTemplate regex patterns
- Regenerated SDK patch for version 1.25.3

### Dependencies

- Added `@modelcontextprotocol/ext-apps@^1.0.1`
- Updated `@modelcontextprotocol/sdk` from 1.17.5 to 1.25.3

## 0.8.2
Expand Down
47 changes: 45 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
],
"dependencies": {
"@mcp-ui/server": "^5.13.1",
"@modelcontextprotocol/ext-apps": "^1.1.0",
"@modelcontextprotocol/sdk": "^1.26.0",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@modelcontextprotocol/sdk 1.26.0 / package.json

Total vulnerabilities: 1

Critical: 0 High: 0 Medium: 0 Low: 1
Vulnerability IDSeverityCVSSFixed inStatus
GHSA-gq3j-xvxp-8hrf LOW LOW 1 - Open

"@opentelemetry/api": "^1.9.0",
"@opentelemetry/auto-instrumentations-node": "^0.56.0",
Expand Down
30 changes: 28 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import { SpanStatusCode } from '@opentelemetry/api';

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
registerAppResource,
RESOURCE_MIME_TYPE
} from '@modelcontextprotocol/ext-apps/server';
import {
ListPromptsRequestSchema,
GetPromptRequestSchema
Expand Down Expand Up @@ -109,8 +113,30 @@ enabledCoreTools.forEach((tool) => {
tool.installTo(server);
});

// Register all resources to the server
allResources.forEach((resource) => {
// Separate MCP Apps UI resources from regular resources
const uiResources = allResources.filter((r) => r.uri.startsWith('ui://'));
const regularResources = allResources.filter((r) => !r.uri.startsWith('ui://'));

// Register MCP Apps UI resources using registerAppResource
// IMPORTANT: Use RESOURCE_MIME_TYPE which is "text/html;profile=mcp-app"
// This tells clients (like Claude Desktop) that this is an MCP App
uiResources.forEach((resource) => {
registerAppResource(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
server as any,
resource.name,
resource.uri,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
{ mimeType: RESOURCE_MIME_TYPE, description: resource.description } as any,
async () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return await resource.read(resource.uri, {} as any);
}
);
});

// Register regular resources using standard registration
regularResources.forEach((resource) => {
resource.installTo(server);
});

Expand Down
4 changes: 3 additions & 1 deletion src/resources/resourceRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
// INSERT NEW RESOURCE IMPORT HERE
import { CategoryListResource } from './category-list/CategoryListResource.js';
import { TemporaryDataResource } from './temporary/TemporaryDataResource.js';
import { StaticMapUIResource } from './ui-apps/StaticMapUIResource.js';
import { httpRequest } from '../utils/httpPipeline.js';

// Central registry of all resources
export const ALL_RESOURCES = [
// INSERT NEW RESOURCE INSTANCE HERE
new CategoryListResource({ httpRequest }),
new TemporaryDataResource()
new TemporaryDataResource(),
new StaticMapUIResource()
] as const;

export type ResourceInstance = (typeof ALL_RESOURCES)[number];
Expand Down
Loading