[MCP] Recourse Link and Embedded resource
Embedded resource:
In Tools, you can also embed the resouce as additional information.
https://modelcontextprotocol.io/specification/2025-06-18/server/tools#embedded-resources
Linked resource:
Sometime when you call a tool to get list of resources, if the list is huge, instead of returning the full content, you can using linked resource to save token
https://modelcontextprotocol.io/specification/2025-06-18/server/tools#resource-links
import { invariant } from '@epic-web/invariant'
import { type CallToolResult } from '@modelcontextprotocol/sdk/types.js'
import {
createEntryInputSchema,
createTagInputSchema,
entryIdSchema,
entryTagIdSchema,
tagIdSchema,
updateEntryInputSchema,
updateTagInputSchema,
} from './db/schema.ts'
import { type EpicMeMCP } from './index.ts'
export async function initializeTools(agent: EpicMeMCP) {
agent.server.registerTool(
'create_entry',
{
title: 'Create Entry',
description: 'Create a new journal entry',
inputSchema: createEntryInputSchema,
},
async (entry) => {
const createdEntry = await agent.db.createEntry(entry)
if (entry.tags) {
for (const tagId of entry.tags) {
await agent.db.addTagToEntry({
entryId: createdEntry.id,
tagId,
})
}
}
return {
content: [
createText(
`Entry "${createdEntry.title}" created successfully with ID "${createdEntry.id}"`,
),
createEntryEmbeddedResource(createdEntry),
],
}
},
)
agent.server.registerTool(
'get_entry',
{
title: 'Get Entry',
description: 'Get a journal entry by ID',
inputSchema: entryIdSchema,
},
async ({ id }) => {
const entry = await agent.db.getEntry(id)
invariant(entry, `Entry with ID "${id}" not found`)
return {
content: [createEntryEmbeddedResource(entry)],
}
},
)
agent.server.registerTool(
'list_entries',
{
title: 'List Entries',
description: 'List all journal entries',
},
async () => {
const entries = await agent.db.getEntries()
const entryLinks = entries.map((entry) => {
return {
// 🐨 change this to 'resource_link'
type: 'resource_link',
uri: `epicme://entries/${entry.id}`,
name: entry.title,
description: `Journal Entry: "${entry.title}"`,
mimeType: 'application/json',
} satisfies ResourceContent
})
return {
content: [
createText(`Found ${entries.length} entries.`),
...entryLinks,
],
}
},
)
agent.server.registerTool(
'update_entry',
{
title: 'Update Entry',
description:
'Update a journal entry. Fields that are not provided (or set to undefined) will not be updated. Fields that are set to null or any other value will be updated.',
inputSchema: updateEntryInputSchema,
},
async ({ id, ...updates }) => {
const existingEntry = await agent.db.getEntry(id)
invariant(existingEntry, `Entry with ID "${id}" not found`)
const updatedEntry = await agent.db.updateEntry(id, updates)
return {
content: [
createText(
`Entry "${updatedEntry.title}" (ID: ${id}) updated successfully`,
),
createEntryEmbeddedResource(updatedEntry),
],
}
},
)
agent.server.registerTool(
'delete_entry',
{
title: 'Delete Entry',
description: 'Delete a journal entry',
inputSchema: entryIdSchema,
},
async ({ id }) => {
const existingEntry = await agent.db.getEntry(id)
invariant(existingEntry, `Entry with ID "${id}" not found`)
await agent.db.deleteEntry(id)
return {
content: [
createText(
`Entry "${existingEntry.title}" (ID: ${id}) deleted successfully`,
),
createEntryEmbeddedResource(existingEntry),
],
}
},
)
agent.server.registerTool(
'create_tag',
{
title: 'Create Tag',
description: 'Create a new tag',
inputSchema: createTagInputSchema,
},
async (tag) => {
const createdTag = await agent.db.createTag(tag)
return {
content: [
createText(
`Tag "${createdTag.name}" created successfully with ID "${createdTag.id}"`,
),
createTagEmbeddedResource(createdTag),
],
}
},
)
agent.server.registerTool(
'get_tag',
{
title: 'Get Tag',
description: 'Get a tag by ID',
inputSchema: tagIdSchema,
},
async ({ id }) => {
const tag = await agent.db.getTag(id)
invariant(tag, `Tag ID "${id}" not found`)
return {
content: [createTagEmbeddedResource(tag)],
}
},
)
agent.server.registerTool(
'list_tags',
{
title: 'List Tags',
description: 'List all tags',
},
async () => {
const tags = await agent.db.getTags()
const tagLinks = tags.map((tag) => {
// 🐨 change this to a linked resource to not send more than is necessary
return {
type: 'resource_link',
uri: `epicme://tags/${tag.id}`,
name: tag.name,
mimeType: 'application/json',
description: `Tag: "${tag.name}"`,
} satisfies ResourceContent
})
return {
content: [createText(`Found ${tags.length} tags.`), ...tagLinks],
}
},
)
agent.server.registerTool(
'update_tag',
{
title: 'Update Tag',
description: 'Update a tag',
inputSchema: updateTagInputSchema,
},
async ({ id, ...updates }) => {
const updatedTag = await agent.db.updateTag(id, updates)
return {
content: [
createText(
`Tag "${updatedTag.name}" (ID: ${id}) updated successfully`,
),
createTagEmbeddedResource(updatedTag),
],
}
},
)
agent.server.registerTool(
'delete_tag',
{
title: 'Delete Tag',
description: 'Delete a tag',
inputSchema: tagIdSchema,
},
async ({ id }) => {
const existingTag = await agent.db.getTag(id)
invariant(existingTag, `Tag ID "${id}" not found`)
await agent.db.deleteTag(id)
return {
content: [
createText(
`Tag "${existingTag.name}" (ID: ${id}) deleted successfully`,
),
createTagEmbeddedResource(existingTag),
],
}
},
)
agent.server.registerTool(
'add_tag_to_entry',
{
title: 'Add Tag to Entry',
description: 'Add a tag to an entry',
inputSchema: entryTagIdSchema,
},
async ({ entryId, tagId }) => {
const tag = await agent.db.getTag(tagId)
const entry = await agent.db.getEntry(entryId)
invariant(tag, `Tag ${tagId} not found`)
invariant(entry, `Entry with ID "${entryId}" not found`)
const entryTag = await agent.db.addTagToEntry({
entryId,
tagId,
})
return {
content: [
createText(
`Tag "${tag.name}" (ID: ${entryTag.tagId}) added to entry "${entry.title}" (ID: ${entryTag.entryId}) successfully`,
),
createTagEmbeddedResource(tag),
createEntryEmbeddedResource(entry),
],
}
},
)
}
function createText(text: unknown): CallToolResult['content'][number] {
if (typeof text === 'string') {
return { type: 'text', text }
} else {
return { type: 'text', text: JSON.stringify(text) }
}
}
type ResourceContent = CallToolResult['content'][number]
function createEntryEmbeddedResource(entry: { id: number }): ResourceContent {
return {
type: 'resource',
resource: {
uri: `epicme://entries/${entry.id}`,
mimeType: 'application/json',
text: JSON.stringify(entry),
},
}
}
function createTagEmbeddedResource(tag: { id: number }): ResourceContent {
return {
type: 'resource',
resource: {
uri: `epicme://tags/${tag.id}`,
mimeType: 'application/json',
text: JSON.stringify(tag),
},
}
}

浙公网安备 33010602011771号