feat(mcp): add MCP resources for sample pipelines#384
Conversation
|
✅ Reviewed on |
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
| async fn list_resource_templates( | ||
| &self, | ||
| _request: Option<PaginatedRequestParams>, | ||
| _ctx: RequestContext<RoleServer>, | ||
| ) -> Result<ListResourceTemplatesResult, McpError> { | ||
| let raw = RawResourceTemplate::new("streamkit://samples/{mode}/{id}", "Sample Pipeline") | ||
| .with_description( | ||
| "A curated sample pipeline template. Modes: 'oneshot' (batch processing), \ | ||
| 'dynamic' (real-time streaming), 'demo', or 'user'.", | ||
| ) | ||
| .with_mime_type("application/x-yaml"); | ||
|
|
||
| let template = Annotated::new(raw, None); | ||
|
|
||
| Ok(ListResourceTemplatesResult::with_all_items(vec![template])) |
There was a problem hiding this comment.
📝 Info: list_resource_templates skips auth, unlike sibling resource handlers
list_resources (apps/skit/src/mcp/mod.rs:732) checks perms.list_samples and read_resource (apps/skit/src/mcp/mod.rs:768) checks perms.read_samples, but list_resource_templates (apps/skit/src/mcp/mod.rs:822-837) has no auth or permission check at all. This is consistent with get_info() which also returns static metadata without auth, and the template only reveals the URI pattern (streamkit://samples/{mode}/{id}) — not actual sample names or content. So this is defensible, but worth noting the asymmetry in case the team prefers uniform auth enforcement across all resource-related handlers.
Was this helpful? React with 👍 or 👎 to provide feedback.
Debug
There was a problem hiding this comment.
This is intentional — the template is static schema metadata (URI pattern, description, MIME type) that doesn't expose any sample data. It's useful for MCP clients to discover the resource URI pattern even before authenticating. Adding an auth check here would prevent agents from knowing how to request resources.
The list_samples tool mode filter only accepted 'oneshot' and 'dynamic', but the sample system also supports 'demo' and 'user' modes. This updates the filter to accept all four modes, matching the modes used in samples.rs:list_samples and the resource handler in PR #384. Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com>
Enable the MCP resources capability and expose sample/template pipelines as browsable MCP resources. - Enable `resources` capability in ServerCapabilities builder - Override `list_resources` to enumerate all sample pipelines (oneshot, dynamic, demo, user) with streamkit:// URIs - Override `read_resource` to return pipeline YAML by URI - Override `list_resource_templates` with a single URI template - Make `list_samples`, `get_sample`, and `SamplesError` pub for cross-module use from the MCP handler - Add 4 integration tests: list_resources, read_resource, read_resource_not_found, list_resource_templates Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com>
…ad_resource - Check perms.read_samples (not list_samples) in read_resource, matching the HTTP handler's access control - Validate resource ID against path traversal characters (.., /, \) - Add mcp_read_resource_rejects_path_traversal integration test Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com>
Defense-in-depth: validate the filename portion of the sample ID directly in get_sample so future callers cannot skip validation. Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com>
978a937 to
efa1f0d
Compare
MCP Comprehensive Test ReportDate: 2026-04-25 | Branch: Summary
Overall: ALL 89 TESTS PASS PR #384 Specific Results (MCP Resources)
Security: All path traversal vectors properly blocked. No regressions. Full report: https://staging.itsdev.in/sessions/c0e3bffbfefe401daa6aeeb33d9c2e89 |
Summary
Enable the MCP
resourcescapability and expose sample/template pipelines as browsable MCP resources. LLM agents can now discover and read curated pipeline templates viaresources/list,resources/read, andresources/templates/list.Changes
apps/skit/src/mcp/mod.rs: Enableresourcescapability inServerCapabilitiesbuilder. Overridelist_resources(enumerates all sample pipelines withstreamkit://samples/{mode}/{id}URIs),read_resource(returns pipeline YAML by URI with defensive URI parsing and path traversal validation), andlist_resource_templates(returns a single URI template describing available modes).apps/skit/src/samples.rs: Makelist_samples,get_sample, andSamplesErrorpubfor cross-module access from the MCP handler. Add# Errorsdoc sections to satisfy clippy.apps/skit/tests/mcp_integration_test.rs: Add 5 integration tests with a dedicatedstart_mcp_server_with_sampleshelper that creates temp sample files:mcp_list_resources_returns_samplesmcp_read_resource_returns_yamlmcp_read_resource_not_foundmcp_list_resource_templatesmcp_read_resource_rejects_path_traversalSecurity
read_resourcechecksperms.read_samples(matching the HTTP handler's access control)..,/,\)Review & Testing Checklist for Human
read_resourcepermission check usesread_samples(notlist_samples) — mirrorsget_sample_handlerinsamples.rs:294..,/, and\in resource IDsresources/listreturns correct URIs and metadata for actual sample pipelinesresources/readwith a valid URI returns the expected YAML contentjust skit, connect an MCP client, and exerciseresources/list→ pick a URI →resources/readNotes
plugin_integration_testfailures are pre-existing onmain(native plugin tests) and unrelated to this change.list_resource_templatesintentionally skips auth — it returns only static schema metadata (URI pattern, description, MIME type), not sample data.Link to Devin session: https://staging.itsdev.in/sessions/d635c6317c6640348fbaecb4b0cf1184
Requested by: @streamer45