import {
DocsTitle,
DocsLead,
DocsH2,
DocsP,
DocsList,
DocsLi,
DocsCode,
Mono,
} from '@/components/docs-page';
export const metadata = { title: 'Authoring tools — BuildMyMCPServer docs' };
export default function Authoring() {
return (
<>
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:
{
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.
>
);
}