Resources
Resources expose data to clients. They are primarily for providing information without significant computation or side effects (like GET requests). Use server.AddResource
. Dynamic URIs with {placeholders}
are supported.
package main
import (
"fmt"
"net/url"
"time"
"github.com/localrivet/gomcp/protocol"
"github.com/localrivet/gomcp/server"
// ... other imports
)
// Static resource handler
func handleAppVersion(uri *url.URL) (protocol.Content, error) {
return server.Text("1.2.3"), nil
}
// Dynamic resource handler (extracting part from URI)
func handleUserData(uri *url.URL) (protocol.Content, error) {
// Example URI: user://data/123/profile
// We need to parse the user ID from the path
userID := "" // Extract from uri.Path, e.g., using strings.Split
// Fetch user data...
userData := map[string]interface{}{
"id": userID,
"email": fmt.Sprintf("user%s@example.com", userID),
"lastLogin": time.Now().Format(time.RFC3339),
}
return server.JSON(userData) // Helper for JSON responses
}
func registerResources(srv *server.Server) error {
// Register a static resource
err := srv.AddResource(protocol.ResourceDefinition{
URI: "app://info/version",
Description: "Get the application version.",
Handler: handleAppVersion,
})
if err != nil { return err }
// Register a dynamic resource template
err = srv.AddResource(protocol.ResourceDefinition{
URI: "user://data/{userID}/profile", // Template URI
Description: "Get user profile data.",
IsTemplate: true, // Mark as template
Handler: handleUserData,
})
return err
}
- Method:
"resources/subscribe"
- Parameters:
protocol.SubscribeResourceParams
- Result:
protocol.SubscribeResourceResult
(currently empty)
type SubscribeResourceParams struct {
URIs []string `json:"uris"` // List of resource URIs to subscribe to
}
type SubscribeResourceResult struct{} // Currently empty
Clients provide a list of resource URIs they want to subscribe to. The server tracks these subscriptions per session.
resources/unsubscribe
Request
Clients can unsubscribe from resource updates.
- Method:
"resources/unsubscribe"
- Parameters:
protocol.UnsubscribeResourceParams
- Result:
protocol.UnsubscribeResourceResult
(currently empty)
type UnsubscribeResourceParams struct {
URIs []string `json:"uris"` // List of resource URIs to unsubscribe from
}
type UnsubscribeResourceResult struct{} // Currently empty
Clients provide a list of resource URIs they no longer wish to receive updates for.
resources/read
Request
Clients can request the content of a specific resource.
- Method:
"resources/read"
- Parameters:
protocol.ReadResourceRequestParams
- Result:
protocol.ReadResourceResult
type ReadResourceRequestParams struct {
URI string `json:"uri"`
Version string `json:"version,omitempty"` // Optional version to request a specific version
}
type ReadResourceResult struct {
Resource protocol.Resource `json:"resource"` // The resource metadata (should match the request URI/version)
Contents protocol.ResourceContents `json:"contents"` // The actual content (Text, Blob, or Audio)
}
Clients specify the uri
of the resource they want to read. Optionally, they can provide a version
to request a specific version of the resource. The server responds with the resource’s metadata and its content, which can be text, binary (blob), or audio, represented by the ResourceContents
interface and its concrete types (TextResourceContents
, BlobResourceContents
, AudioResourceContents
).
notifications/resources/updated
Notification
Servers send the notifications/resources/updated
notification to inform subscribed clients that a specific resource has been updated.
- Method:
"notifications/resources/updated"
- Parameters:
protocol.ResourceUpdatedParams
type ResourceUpdatedParams struct {
Resource Resource `json:"resource"` // The updated resource metadata
}
The server includes the updated protocol.Resource
metadata in the notification. Clients can then decide whether to re-read the resource content using resources/read
.
notifications/resources/list_changed
Notification
Servers can send the notifications/resources/list_changed
notification to inform clients that the list of available resources has changed (resources added or removed).
- Method:
"notifications/resources/list_changed"
- Parameters:
protocol.ResourcesListChangedParams
(currently empty)
type ResourcesListChangedParams struct{} // Currently empty
This notification does not include the updated list itself, only signals that a change has occurred. Clients must send a resources/list
request to get the new list.
Resource Updates and Subscriptions
Clients can subscribe to resource updates using the resources/subscribe
request. This allows them to receive notifications when a resource’s content or metadata changes without constantly polling the server.
The server tracks which sessions have subscribed to which resource URIs. When a resource is updated in your application, you can notify subscribed clients by calling server.NotifyResourceUpdated(updatedResource)
.
// Assume srv is your initialized *server.Server instance
// Assume updatedResource is the protocol.Resource with the new metadata/version
func updateResourceAndNotify(srv *server.Server, updatedResource protocol.Resource) {
// First, update the resource's metadata in the server's registry.
// RegisterResource also updates if a resource with the same URI already exists.
err := srv.RegisterResource(updatedResource)
if err != nil {
log.Printf("Failed to update resource '%s': %v", updatedResource.URI, err)
return
}
log.Printf("Updated resource metadata: %s", updatedResource.URI)
// Then, notify subscribed clients about the update.
// The server will automatically send a notifications/resources/updated
// message to all sessions that subscribed to this resource's URI.
srv.NotifyResourceUpdated(updatedResource)
log.Printf("Sent resources/updated notification for: %s", updatedResource.URI)
// Note: Clients receiving this notification will typically then send a
// resources/read request to get the new content if they need it.
}
Clients can unsubscribe from resource updates using the resources/unsubscribe
request.
Next Steps
- Implement the server-side logic to handle
resources/read
requests and provide resource content. This is a key step to make your resources fully functional. - Explore the
protocol
package for the differentResourceContents
types you can use to represent various data formats. - Integrate resource definition, registration, and update notification into your server application’s data management logic.