DEV Community

Cover image for Micimici MCP: 11 Tools for Teachers — Multimedia Search + Notion, All in One MCP Server
Francesca Bertolini
Francesca Bertolini

Posted on

Micimici MCP: 11 Tools for Teachers — Multimedia Search + Notion, All in One MCP Server

Notion MCP Challenge Submission 🧠

This is a submission for the Notion MCP Challenge

What I Built

Micimici MCP is a Model Context Protocol server that gives AI assistants (Claude, ChatGPT, Cursor) 11 tools to search educational multimedia from 7 free sources and manage a Notion workspace — all through natural language.

Teachers can't afford stock photo subscriptions. Students deserve beautiful learning materials. So I built a single MCP server that solves both problems:

7 Multimedia Search Tools:

  • web_search_images — Web image search with advanced filters (size, color, type, layout, license)
  • pixabay_search — CC0 photos, illustrations, vectors, and videos
  • pexels_search — Professional photos and videos, free to use
  • unsplash_search — High-quality HD photography
  • wikimedia_search — Scientific diagrams, maps, educational media (CC/Public Domain)
  • europeana_search — European cultural heritage: artworks, manuscripts, historical photos
  • openclipart_search — Public domain SVG clipart

3 Notion Tools:

  • notion_search — Search pages and databases in the teacher's workspace
  • notion_save_page — Create pages with full Markdown content
  • notion_create_database — Build structured databases with typed columns (text, number, select, multi_select, date, checkbox, url, email)

1 Publishing Tool:

  • publish_html_page — Publish complete HTML pages to a public URL (24h), optionally saving the link to Notion. This solves the problem of Notion filtering external images — the teacher gets a direct link to a page with all images intact.

The Flow

A teacher types one prompt:

"Search for images of the water cycle on Pexels and Wikimedia, create an educational page with those images, publish it, and save the link in my Notion."

Claude automatically:

  1. Searches Pexels and Wikimedia for relevant images
  2. Builds a complete, styled HTML page
  3. Publishes it to a shareable URL
  4. Saves the link in the teacher's Notion workspace

No copy-pasting. No manual uploads. No subscriptions.

Privacy by Design

Each teacher configures their own Notion integration token. Student data stays in the teacher's own Notion workspace — never on our servers. The teacher has full control over their data.

Video Demo

Show us the code

GitHub Repository: github.com/francy2222/micimici-MCP

Live MCP Server: https://micimici-mcp.vercel.app/api/mcp

The entire server is a single JavaScript file — no frameworks, no complexity. Here's how the Notion integration works:

Saving a page to Notion via MCP

// Markdown → Notion blocks converter
function mdToBlocks(md) {
    return md.split('\n').filter(l => l.trim()).map(t => {
        t = t.trim();
        if (t.startsWith('# '))  return { object:'block', type:'heading_1', 
            heading_1: { rich_text:[{text:{content:t.slice(2)}}] } };
        if (t.startsWith('- '))  return { object:'block', type:'bulleted_list_item', 
            bulleted_list_item: { rich_text:[{text:{content:t.slice(2)}}] } };
        return { object:'block', type:'paragraph', 
            paragraph: { rich_text:[{text:{content:t}}] } };
    });
}

// MCP tool: notion_save_page
server.tool("notion_save_page", 
    "Create a page in Notion with markdown content.",
    { title: z.string(), content: z.string(), 
      parent_page_id: z.string(), icon_emoji: z.string().optional() },
    async ({ title, content, parent_page_id, icon_emoji }) => {
        const body = {
            parent: { page_id: parent_page_id },
            properties: { title: { title: [{ text: { content: title } }] } },
            children: mdToBlocks(content)
        };
        if (icon_emoji) body.icon = { type: 'emoji', emoji: icon_emoji };
        const data = await (await fetch('https://api.notion.com/v1/pages', {
            method: 'POST', headers: notionHeaders(), body: JSON.stringify(body)
        })).json();
        return { content: [{ type: "text", 
            text: `Page created: ${data.url}` }] };
    }
);
Enter fullscreen mode Exit fullscreen mode

Publishing HTML to bypass Notion's image filtering

// Publish HTML to a public URL, then save the link to Notion
server.tool("publish_html_page",
    "Publish HTML to a public URL (24h). Optionally save link to Notion.",
    { html: z.string(), title: z.string().optional(),
      save_to_notion: z.boolean().default(false),
      parent_page_id: z.string().optional() },
    async ({ html, title, save_to_notion, parent_page_id }) => {
        // Publish to Netlify function
        const pub = await publishHtml(html);

        // Optionally save link to Notion
        if (save_to_notion && parent_page_id) {
            const content = `# ${title}\n\n🔗 ${pub.url}`;
            await notionSavePage(title, content, parent_page_id, '🌐');
        }
        return { content: [{ type: "text", 
            text: `Published: ${pub.url}` }] };
    }
);
Enter fullscreen mode Exit fullscreen mode

Tool registration with MCP SDK

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from 
    "@modelcontextprotocol/sdk/server/streamableHttp.js";

// Each serverless invocation gets a fresh instance
function createServer() {
    const s = new McpServer({ name: "Micimici MCP", version: "2.0.0" });
    // ... register all 11 tools ...
    return s;
}

export default async function handler(req, res) {
    const server = createServer();
    const transport = new StreamableHTTPServerTransport({ 
        sessionIdGenerator: undefined  // stateless mode for serverless
    });
    await server.connect(transport);
    await transport.handleRequest(req, res, req.body);
}
Enter fullscreen mode Exit fullscreen mode

Tech Stack

  • Runtime: Vercel Serverless Functions (Node.js 18+)
  • MCP SDK: @modelcontextprotocol/sdk with Streamable HTTP transport
  • Notion API: REST API v2022-06-28 with Internal Integration Token
  • Image Sources: Pexels API, Pixabay API, Unsplash API, Europeana API, Wikimedia API, OpenClipart API, web scraping
  • Publishing: Netlify Functions with Netlify Blobs for temporary storage

How I Used Notion MCP

Notion MCP is the backbone of Micimici's content management layer. Here's what it unlocks:

1. Search-driven content discovery

Teachers ask Claude to find content in their Notion workspace. The notion_search tool uses Notion's Search API to find pages and databases by keyword. This lets the AI understand what materials the teacher already has before creating new ones.

2. AI-generated educational content → Notion

When Claude creates a lesson, worksheet, or game, it can save it directly to the teacher's Notion using notion_save_page. The page is created with full Markdown formatting — headings, lists, quotes, dividers — converted to Notion blocks.

3. Structured tracking with databases

The notion_create_database tool lets Claude build complete databases with typed columns. A teacher can say "create a database to track my students' reading progress" and get a fully structured Notion database with Name, Book Title (text), Pages Read (number), Completed (checkbox), Genre (select), and Date (date) columns — all in one prompt.

4. HTML Publishing as a Notion companion

Notion filters many external image URLs, which breaks image-heavy educational pages. The publish_html_page tool solves this by publishing the full HTML to a temporary public URL and saving just the link in Notion. The teacher's Notion workspace becomes an organized index of all their published materials.

Why this architecture?

I chose to build a custom MCP server rather than just connecting to Notion's hosted MCP (mcp.notion.com) because I needed to combine Notion with multimedia search in a single, unified tool. A teacher shouldn't need to switch between "search for images" and "save to Notion" — it should be one seamless flow.

The server runs on Vercel's free tier. The Notion token is configured as an environment variable. The teacher's data stays in their own workspace. Zero cost, full control.


About me

I'm a special needs teacher from Italy with no computer science degree. I've been building free educational tools for my students for twenty years. In Italy, teachers earn about €1,200/month — we can't afford commercial subscriptions. So I build what we need.

Micimici is named after one of the cats in the school community's cat colony. Because every good project needs a cat. 🐱

Top comments (0)