Build

Authoring tools

What you write in the prompt is what Claude turns into TypeScript. Better prompts mean better tools. These patterns cover 80% of the common asks.

Anatomy of a tool

Each generated tool ends up looking like this:

generated TypeScript
server.registerTool(
  'search_pages',
  {
    title: 'search_pages',
    description: 'Search Notion pages matching a query.',
    inputSchema: {
      query: z.string().describe('search terms'),
    },
  },
  async (args) => {
    try {
      const res = await fetch('https://api.notion.com/v1/search', {
        method: 'POST',
        signal: AbortSignal.timeout(10000),
        headers: {
          'Authorization': `Bearer ${process.env.NOTION_API_KEY}`,
          'Notion-Version': '2022-06-28',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ query: args.query }),
      });
      const data = await res.json();
      return { content: [{ type: 'text', text: JSON.stringify(data.results) }] };
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      return { content: [{ type: 'text', text: 'Error: ' + msg }], isError: true };
    }
  },
);

Rules the generator enforces

  • No eval, no new Function, no child_process. The static check rejects the build.
  • No import statements in tool bodies — the runtime injects fetch, pg, z.
  • Secrets live in process.env. Never embedded literally.
  • External HTTP calls must use AbortSignal.timeout. Default 10s.
  • Database access via pg with parameterized queries only.
  • Errors return as MCP error-content, not thrown exceptions.

Prompt patterns that work

Be explicit about tool names. "Tool: search_pages(query)" beats "give me a search tool".

Name the credentials. "Auth: NOTION_API_KEY" tells the generator what to put in requiredSecrets. Saves an iteration.

Say if a tool is destructive. "Tool: delete_page(page_id) — destructive, permanently removes the page" surfaces the warning to the AI client.

One server per integration, not per tool. A Notion server with five tools is cleaner than five Notion servers each with one tool.

Iterate on a live server

Open the server detail page, click the Iterate tab, describe what you want to add. A new build version is queued, rolling-deployed, the old version stays live until the new one is healthy.