Serve resources and prompts
Expose readable context through URIs and templates, and reusable prompts with arguments - safely.
- List, read and template resources by URI
- Use annotations to guide which context matters
- Return prompt messages, and prevent path traversal
A resource is data identified by a URI - file:///project/README.md, git://repo/main, or your own scheme like crm://customers/42. Clients find them with resources/list and fetch them with resources/read. A read can return text or base64 binary (blob), and several items at once (say, every file in a folder).
When there are too many resources to list, a server offers resource templates using URI templates: file:///{path} or weather://{city}/today. The client fills in the variables to build a concrete URI.
1{
2 "jsonrpc": "2.0",
3 "id": 2,
4 "result": {
5 "resultType": "complete",
6 "contents": [
7 {
8 "uri": "file:///project/src/main.rs",
9 "mimeType": "text/x-rust",
10 "text": "fn main() {\n println!(\"Hello world!\");\n}"
11 }
12 ],
13 "ttlMs": 60000,
14 "cacheScope": "private"
15 }
16}Resources and content can carry annotations that help the host decide what to include: audience ("user", "assistant" or both), priority from 0 (optional) to 1 (effectively required), and lastModified.
Prompts
A prompt has a name, a description and optional arguments. prompts/get with argument values returns a list of messages (each with a role of user or assistant and some content), ready to start a conversation. Hosts often show prompts as slash commands.
1{
2 "jsonrpc": "2.0",
3 "id": 2,
4 "result": {
5 "resultType": "complete",
6 "description": "Code review prompt",
7 "messages": [
8 {
9 "role": "user",
10 "content": {
11 "type": "text",
12 "text": "Please review this Python code:\ndef hello():\n print('world')"
13 }
14 }
15 ]
16 }
17}Key takeaways
Resources are URI-addressed context:
resources/list,resources/read, and templates for parameterized URIs.Annotations (
audience,priority,lastModified) help hosts pick context.Prompts return ready-made messages; resource servers must block path traversal.
Lesson quiz
6 questions · pass with 5 correct · up to 50 XP
Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.
Practice: write Python
Write Python in the editor and run it against sample inputs. Python runs locally in your browser using a WebAssembly runtime.
Expand a URI template
The first line is a URI template with {name} variables. The second line is a JSON object of values. Replace every variable with its value and print the URI. If any variable has no value, print missing NAME for the first such variable instead.
- Two variables
- Missing value
Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.
Block path traversal
The first line is the server’s root folder (an absolute POSIX path). Each following line is a requested relative path. For each, print allow FULL_PATH if the normalized path stays inside the root, otherwise deny REQUESTED. Use posixpath.normpath(posixpath.join(root, requested)) and treat a path as inside when it equals the root or starts with the root followed by /.
- Normal and escaping
- Sibling folder and absolute path
Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.
Questions about this lesson
Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.
Loading posts…