Build a local TypeScript server

Add the get_note tool

Return one complete note by stable ID with structured output and an explicit not-found result.

8 minute lesson

~~~

Search returns stable IDs. A second tool can now read one complete note without making every search result large.

Add it below search_notes:

  const noteSchema = z.object({
    id: z.string(),
    title: z.string(),
    tags: z.array(z.string()),
    body: z.string()
  })

  server.registerTool(
    'get_note',
    {
      description: 'Read one project note by its exact ID',
      inputSchema: z.object({ id: z.string().trim().min(1).max(100) }),
      outputSchema: z.object({ note: noteSchema }),
      annotations: {
        readOnlyHint: true,
        destructiveHint: false
      }
    },
    async ({ id }) => {
      const note = notes.find(candidate => candidate.id === id)

      if (!note) {
        return {
          content: [{ type: 'text', text: `No note found with ID: ${id}` }],
          isError: true
        }
      }

      const output = { note }
      return {
        content: [{ type: 'text', text: JSON.stringify(output, null, 2) }],
        structuredContent: output
      }
    }
  )

There are two kinds of failure here.

An empty or malformed id fails schema validation before the handler runs. A valid-looking ID that is absent reaches the handler and returns a tool execution error with isError: true.

That distinction gives the model a useful correction path. It can fix the argument shape, or it can search again for a valid ID. Returning an empty success would hide the difference.

Do not include every known ID in the error. On a private server, that would turn one failed lookup into data discovery. The separate search tool is the authorized discovery path.

Test deploy-checklist, missing-note, and an empty string. Confirm that only the successful call contains structuredContent matching the output schema.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →