---
title: "Resources"
description: "Managing static and dynamic resources in MCP servers"
icon: "folder-open"
---

Resources in MCP provide a way to expose data, files, and content that clients can discover and read. Unlike tools which execute functions, resources represent accessible content with URIs.

<Tip>
**Response Helpers**: This guide uses response helpers like `text()`, `object()`, and `markdown()` for cleaner resource implementations. See [Response Helpers](./response-helpers) for the complete reference.
</Tip>

## Understanding Resources

Resources are:
- **Discoverable**: Clients can list and browse available resources
- **Readable**: Content can be retrieved via URI
- **Typed**: Each resource has a MIME type
- **Annotated**: Metadata helps clients understand resource purpose

## Resources

Fixed content that doesn't change based on parameters. Use response helpers for cleaner code:

<CodeGroup>

```typescript Helper
import { object } from 'mcp-use/server';

server.resource(
  {
    name: 'app_config',
    uri: 'config://application',
    title: 'Application Configuration',
    description: 'Current application settings'
  },
  async () => object({
    version: '1.0.0',
    environment: 'production',
    features: ['auth', 'api', 'ui']
  })
)
```

```typescript Expanded
server.resource({
  name: 'app_config',
  uri: 'config://application',
  title: 'Application Configuration',
  description: 'Current application settings',
  mimeType: 'application/json',
  readCallback: async () => ({
    contents: [{
      uri: 'config://application',
      mimeType: 'application/json',
      text: JSON.stringify({
        version: '1.0.0',
        environment: 'production',
        features: ['auth', 'api', 'ui']
      }, null, 2)
    }]
  })
})
```

</CodeGroup>

You can use any mime type you want.
To help you defining resources, you can use the response helpers to create the resource content.
Here are some of the helpers you can use:

```typescript
import { 
  text, markdown, html, xml, css, javascript, object, array,
  image, audio, binary, mix, 
} from 'mcp-use/server';
```

## Resource Templates

Resources with parameterized URIs for dynamic content:

```typescript
server.resourceTemplate({
  name: 'user_data',
  uriTemplate: 'user://{userId}/name',
}, async (uri, { userId }) => {
  
  // userId is automatically extracted from the URI and typed
  const userData = await fetchUserData(userId)
  return text(`User name: ${userData.name}`)

})
```

### Autocomplete for template variables

Provide completion suggestions for URI template variables so clients can autocomplete values:

```typescript
server.resourceTemplate({
  name: 'user_data',
  uriTemplate: 'user://{userId}/profile',
  callbacks: {
    complete: {
      // List of string values (prefix-filtered)
      userId: ['user-1', 'user-2', 'user-3'],
      // Or a callback for dynamic suggestions
      // userId: async (value) => (await fetchUserIds(value)).map(u => u.id),
    },
  },
}, async (uri, { userId }) => {
  const userData = await fetchUserData(userId)
  return text(`User name: ${userData.name}`)
})
```


## Resource Annotations

Provide metadata to help clients use resources effectively:

```typescript
server.resource({
  ...
  annotations: {
    // Target audience
    audience: ['user'],  // 'user' or 'assistant'

    // Priority (0.0 to 1.0)
    priority: 0.9,

    // Last modified timestamp
    lastModified: new Date().toISOString()
  }
},
  async () => { ... }
)
```

<Tip>
Learn more about resource annotations in the [MCP resources specification](https://modelcontextprotocol.io/specification/2025-06-18/server/resources#annotations).
</Tip>


## Multiple Content Items

Resources can return multiple content items:

<CodeGroup>
```typescript Helper
server.resource(
  {
    name: 'report_bundle',
    uri: 'reports://latest',
    title: 'Latest Reports Bundle'
  },
  async () => {
    const reportData = await getReportData();
    const chartImage = await generateChart(reportData);

    return mix(
      text('Executive Summary...'),
      object(reportData),
      image(chartImage, 'image/png')
    );
  }
)
```

```typescript Expanded
server.resource({
  name: 'report_bundle',
  uri: 'reports://latest',
  title: 'Latest Reports Bundle',
  mimeType: 'multipart/mixed',
  readCallback: async () => {
    const reportData = await getReportData();
    const chartImage = await generateChart(reportData);

    return {
      contents: [
        {
          uri: 'reports://latest/summary',
          mimeType: 'text/plain',
          text: 'Executive Summary...'
        },
        {
          uri: 'reports://latest/data',
          mimeType: 'application/json',
          text: JSON.stringify(reportData, null, 2)
        },
        {
          uri: 'reports://latest/chart',
          mimeType: 'image/png',
          blob: chartImage
        }
      ]
    }
  }
})
```

</CodeGroup>


## Callback Signature Variations

Resource templates support multiple callback signatures. Use the simplest one that meets your needs:

```typescript
import { text, object } from 'mcp-use/server';

// No parameters - for static templates
server.resource({
    name: 'welcome',
    uri: 'app://welcome'
  }, async () => text('Welcome to our API!')
)

// Just URI - when you need the full URI
server.resource({
    name: 'echo',
    uri: 'echo://{path}'
  }, async (uri) => text(`You requested: ${uri.toString()}`)
)

// URI and params - most common pattern
server.resourceTemplate({
    name: 'user',
    uriTemplate: 'user://{userId}'
  },
  async (uri, { userId }) => {
    const user = await fetchUser(userId);
    return object(user);
  }
)

// With context - for auth or request access
server.resourceTemplate(
  {
    name: 'private',
    resourceTemplate: { uriTemplate: 'private://{id}' }
  },
  async (uri, { id }, ctx) => {
    // Access authenticated user
    const user = ctx.auth;
    const data = await getPrivateData(id, user);
    return object(data);
  }
)
```


## Notifying Clients of Resource Changes

When dynamically adding or removing resources, notify clients to refresh their resources cache:

```typescript
// Register a new resource dynamically
server.resource({
  name: 'new_resource',
  uri: 'app://new',
  description: 'A dynamically added resource'
}, async () => text('New resource content'));

// Notify all connected clients
await server.sendResourcesListChanged();
```

See [Notifications](./notifications) for more details.


### Testing 

1. Start server with inspector
2. Navigate to Resources tab
3. Browse available resources
4. Click to read resource content
5. Verify content and MIME type

---


<Tip>
You can read more about resources in the [MCP resources specification](https://modelcontextprotocol.io/specification/2025-06-18/server/resources).
</Tip>



## Next Steps

- [Response Helpers](./response-helpers) - Utility functions for creating responses
- [Tools Guide](./tools) - Building executable tools
- [UI Widgets](./mcp-apps) - Creating interactive UI components
- [Examples](https://github.com/mcp-use/mcp-use/tree/main/examples) - Real-world resource implementations