Skip to main content

List Resources

Discovers all available resources on an MCP server. This node returns a list of resources with their URIs, names, descriptions, and MIME types, enabling dynamic resource discovery.

Common Properties

  • Name - The custom name of the node.
  • Color - The custom color of the node.
  • Delay Before (sec) - Waits in seconds before executing the node.
  • Delay After (sec) - Waits in seconds after executing node.
  • Continue On Error - Automation will continue regardless of any error. The default value is false.

Inputs

  • Client Id - The MCP client connection identifier from the Connect node.

Options

  • Timeout - Timeout in seconds for the operation (default: 30).

Outputs

  • Resources - Array of resource objects, each containing uri, name, description (optional), and mimeType (optional).

How It Works

  1. Client Lookup - Retrieves the MCP client using the provided Client ID
  2. List Request - Sends a ListResourcesRequest to the MCP server
  3. Response Processing - Extracts resource information from the server response
  4. Array Creation - Converts resources to an array of objects
  5. Output - Returns the resources array

Output Format

Each resource in the array contains:

{
"uri": "resource://path",
"name": "Resource Name",
"description": "What the resource contains",
"mimeType": "text/plain"
}

The description and mimeType fields are optional.

Examples

Example 1: List All Resources

Inputs:

  • Client Id: file-server

Resources Output:

[
{
"uri": "docs://readme",
"name": "Project README",
"description": "Project documentation",
"mimeType": "text/markdown"
},
{
"uri": "users://{id}/profile",
"name": "User Profile",
"description": "User profile data by ID",
"mimeType": "application/json"
},
{
"uri": "config://app-settings",
"name": "Application Settings",
"mimeType": "application/json"
}
]

Example 2: Filter Resources

JavaScript processing:

const resources = msg.resources;

// Get JSON resources only
msg.json_resources = resources.filter(r =>
r.mimeType === 'application/json'
);

// Get template resources (with {placeholders})
msg.template_resources = resources.filter(r =>
r.uri.includes('{') && r.uri.includes('}')
);

// Extract all URIs
msg.resource_uris = resources.map(r => r.uri);

Example 3: Find Specific Resource

Flow:

List Resources → Find by pattern → Read Resource

JavaScript:

// Find README resource
const readme = msg.resources.find(r =>
r.name.toLowerCase().includes('readme') ||
r.uri.includes('readme')
);

if (readme) {
msg.readme_uri = readme.uri;
}

Example 4: Build Resource Catalog

Flow:

List Resources → Group by type → Store catalog

JavaScript:

const catalog = {
documents: [],
configs: [],
data: [],
templates: []
};

msg.resources.forEach(resource => {
if (resource.mimeType?.includes('markdown')) {
catalog.documents.push(resource);
} else if (resource.uri.startsWith('config://')) {
catalog.configs.push(resource);
} else if (resource.uri.includes('{')) {
catalog.templates.push(resource);
} else {
catalog.data.push(resource);
}
});

msg.resource_catalog = catalog;

Best Practices

  1. Discovery:

    • List resources at initialization to know what's available
    • Cache the list if resources don't change frequently
    • Use to validate URIs before Read Resource
  2. Processing:

    • Filter resources by MIME type or URI pattern
    • Identify template resources (with placeholders)
    • Group resources by category or scheme
  3. Error Handling:

    • Check if resources array is not empty
    • Handle servers with no resources gracefully
    • Validate server connection before listing
  4. Performance:

    • Cache resource lists to reduce server calls
    • Only refresh when needed
    • Use for initialization, not every operation

Common Errors and Solutions

Error: "Client Id cannot be empty"

Solution:

  • Ensure Connect node executed successfully
  • Pass Client Id from Connect node
  • Verify client connection is active

Error: "Failed to list resources"

Solution:

  • Check server is running and accessible
  • Verify Client Id is correct
  • Check server logs for errors
  • Ensure server has ListResources capability enabled

Empty Resources Array

Cause: Server has no resources registered.

Solution:

  • Verify server has resources configured
  • Check server is properly initialized
  • Ensure resources are registered correctly on server

Tips for Effective Use

  1. Initial Discovery - Use at flow start to discover capabilities
  2. Validation - Validate URIs exist before Read Resource
  3. Documentation - Generate resource documentation automatically
  4. Dynamic Selection - Select resources based on context
  5. Caching - Store resource list to avoid repeated calls
  6. Filtering - Filter by MIME type or URI patterns
  7. Template Detection - Identify templated URIs for parameter substitution

Integration Patterns

Pattern 1: Resource Discovery and Reading

Connect → List Resources → Select Resource → Read Resource → Use

Pattern 2: Validation Before Reading

List Resources → Check if exists → Read Resource
↓ (if not exists)
Error Handler

Pattern 3: Build Catalog

List Resources → Format → Store in Database → Display to Users

Pattern 4: Dynamic Selection

List Resources → Filter by criteria → Read multiple → Process

Processing Examples

Extract Resource URIs Only

const uris = msg.resources.map(r => r.uri);
// ["docs://readme", "users://{id}/profile", "config://app-settings"]

Find Resources by MIME Type

const jsonResources = msg.resources.filter(r =>
r.mimeType === 'application/json'
);

Identify Template Resources

const templates = msg.resources.filter(r => {
const uri = r.uri;
return uri.includes('{') && uri.includes('}');
});

// Extract template variables
templates.forEach(t => {
const matches = t.uri.match(/\{(\w+)\}/g);
t.variables = matches?.map(m => m.slice(1, -1)) || [];
});

Create Lookup Map

const resourceMap = {};
msg.resources.forEach(r => {
resourceMap[r.uri] = {
name: r.name,
description: r.description,
mimeType: r.mimeType
};
});
msg.resource_lookup = resourceMap;

Group by Scheme

const byScheme = {};
msg.resources.forEach(r => {
const scheme = r.uri.split('://')[0];
if (!byScheme[scheme]) {
byScheme[scheme] = [];
}
byScheme[scheme].push(r);
});
msg.resources_by_scheme = byScheme;
// { "docs": [...], "users": [...], "config": [...] }

Check Resource Availability

const requiredUri = "docs://readme";
const exists = msg.resources.some(r => r.uri === requiredUri);
if (!exists) {
throw new Error(`Required resource ${requiredUri} not available`);
}