Skip to main content
Glama

Docva — Canva Education Document Generator

Headless MCP server that generates teacher verification documents — employment letters, teacher ID cards, teaching licenses, payslips, and more — across 13 countries.

License: MIT Python MCP Platform

Portable, self-contained, and installable anywhere.


Table of Contents


Related MCP server: office-worker-mcp

Sample outputs

Documents are rendered as high-resolution PNGs. Examples generated by this tool:

Teacher ID (US)

Employment letter (US)

US teacher ID

US letter

Teacher ID (UK)

Employment letter (UK)

UK teacher ID

UK letter


Features

  • Headless MCP server — document generation exposed as agent-callable tools over stdio.

  • 13 countries, each with its own document types and local conventions.

  • Real school databases with street addresses, districts, and contact info.

  • Consistent profile photos per person — hash-based selection from a bundled, gender-aware photo pool.

  • Cross-platform fonts — DejaVu Sans bundled; no system-font dependency.

  • Packaged & portable — ships as a self-contained wheel (code + photos + fonts) installable with one command.


Supported countries

Code

Country

Document types

uk

United Kingdom

employment_letter, teacher_id, teaching_license

us

United States

employment_letter, teacher_id, teaching_license

france

France

installation_statement, iprof_screenshot, bylaws_extract, teaching_certificate

netherlands

Netherlands

employment_contract, teacher_registration, duo_declaration, school_id

indonesia

Indonesia

payslip, teaching_experience_letter, nuptk_card, appointment_letter

australia

Australia

signed_school_letter, school_id, teaching_license

canada

Canada

oct_card, teaching_license, signed_school_letter

spain

Spain

teaching_id, signed_school_letter, employment_contract

argentina

Argentina

payslip, employment_certificate, signed_school_letter

slovakia

Slovakia

payslip, employment_letter, signed_school_letter

mexico

Mexico

teaching_id, signed_school_letter, employment_certificate

philippines

Philippines

teaching_id, employment_certificate, teaching_license

thailand

Thailand

payslip, letter_of_employment


Requirements

  • Python 3.10+

  • Dependencies (installed automatically): Pillow, mcp


Installation

From the built wheel

pip install dist/docva_doc_generator-0.1.0-py3-none-any.whl

From source (editable)

pip install -e .

Via uv

uvx --from . docva-mcp

Usage — MCP server

The server speaks MCP over stdio — the transport used by most agent runtimes (Hermes, Claude Desktop, and any MCP client). Connect it, discover the tools, then call them.

Step 1 — Install & verify

# from the built wheel
pip install dist/docva_doc_generator-0.1.0-py3-none-any.whl

# or editable from source
pip install -e .

Verify the install and that bundled assets resolve:

python -c "from countries.utils import load_font, get_profile_photo; \
print(load_font(30).getname()); print(get_profile_photo((280,340), person_id='x', gender='Male') is not None)"
# ('DejaVu Sans', 'Book')   <-- bundled font, not system
# True                      <-- bundled photo found

Step 2 — Run the server

# After install:
docva-mcp

# Or from source:
python mcp_server.py

It blocks and waits for MCP requests over stdin/stdout — don't run it as a foreground terminal app expecting prompts.

Step 3 — Register in your agent runtime

Point your MCP client at the docva-mcp command:

{
  "mcpServers": {
    "docva": {
      "command": "docva-mcp",
      "args": []
    }
  }
}

If docva-mcp isn't on your PATH, use the absolute path to your interpreter and module instead:

{
  "mcpServers": {
    "docva": {
      "command": "/path/to/python",
      "args": ["-m", "mcp_server"]
    }
  }
}

Tools

Tool

Description

list_countries_tool

List available countries, display names, and their document types.

list_schools(country)

List all schools for a country code.

generate_documents(...)

Render one or more documents to PNG and return their paths.

list_countries_tool()

No arguments. Returns one result item per country — { code, name, document_types }. (Because a list return is split into one MCP content item per entry, iterate content to see them all.)

list_schools(country: str)

  • country (required) — country code from list_countries_tool (e.g. "us").

  • Returns one result item per school — { name, address, town, postcode, state, phone, lea }. Iterate content to see them all.

generate_documents(...)

Parameter

Type

Required

Default

Description

country

string

✅

—

Country code (e.g. "us", "uk").

first_name

string

✅

—

Teacher's first name.

last_name

string

✅

—

Teacher's last name.

school_name

string

✅

—

Exact or partial school name (matched against that country's school list).

position

string

✅

—

Teaching position/title.

date_of_birth

string

✅

—

DOB string, printed on the teacher ID (e.g. "12/05/1988").

gender

string

—

"Random"

"Random", "Male", or "Female" — selects the profile-photo pool.

document_types

string[]

—

all types

Which documents to render, e.g. ["employment_letter", "teacher_id"].

output_dir

string

—

output/

Where to save PNGs (relative to the server's working dir).

Returns { country, school, document_types, files, count, output_dir } — files are absolute PNG paths.

Connect from a Python client

Minimal working client (requires pip install mcp):

import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

async def main():
    params = StdioServerParameters(command="docva-mcp", args=[])
    async with stdio_client(params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            countries = await session.call_tool("list_countries_tool", {})
            # A list return is split into one content item per entry:
            for item in countries.content:
                print(item.text)

            res = await session.call_tool("generate_documents", {
                "country": "us",
                "first_name": "John",
                "last_name": "Smith",
                "school_name": "Valley High",
                "position": "Head of Science Department",
                "date_of_birth": "12/05/1988",
                "gender": "Male",
            })
            print(res.content[0].text)

asyncio.run(main())

Typical agent workflow

  1. Call list_countries_tool to see what's available.

  2. Call list_schools("us") to pick a real school.

  3. Call generate_documents(...) with the chosen country, school, and person details.

  4. Read the returned PNG paths and use the files.

Generated PNGs are written to output/ (or the output_dir you pass).


Legacy GUI

A tkinter (CustomTkinter) GUI is still available for manual use. The core generation logic is shared.

python main_gui.py        # on Windows, use run.bat (sets TCL_LIBRARY)

The MCP server is the primary, headless interface. The GUI is optional and not required for the skill.


Project structure

docva/
├── countries/            # Document generation core (package)
│   ├── base.py           # CountryGenerator ABC (contract)
│   ├── utils.py          # Fonts, profile photos, shared helpers
│   ├── foto/             # Bundled profile photos (package data)
│   ├── fonts/            # Bundled DejaVu fonts (package data)
│   └── <country>/        # One package per country
├── mcp_server.py         # MCP server exposing tools
├── main_gui.py           # Legacy tkinter GUI
├── docs/examples/        # Sample rendered documents
├── pyproject.toml        # Packaging, deps, entry point
├── output/               # Generated documents (git-ignored)
└── run.bat               # Windows GUI launcher

Adding a new country

  1. Create countries/<code>/__init__.py with a class inheriting countries.base.CountryGenerator.

  2. Implement the abstract methods: get_country_name, get_country_code, get_schools_data, get_first_names, get_last_names, get_positions, get_document_types, generate_document.

  3. Register it in countries/__init__.py via register_country("<code>", <Name>Generator).

  4. Optionally add a display label in main_gui.py (get_country_list / on_country_change).

The new country is automatically picked up by the MCP list_countries_tool and list_schools.


License

MIT

Available Tools

3 tools
generate_documentsA

Generate teacher verification documents (employment letter, teacher ID, teaching license).

Args: country: Country code from list_countries (e.g. 'us', 'uk'). first_name / last_name: The teacher's name. school_name: Exact or partial school name (matched against that country's school list). position: Teaching position/title. date_of_birth: Display date of birth string (shown on the teacher ID). gender: 'Random', 'Male', or 'Female' — selects which photo pool is used. document_types: Which documents to render. Omit for all. e.g. ['employment_letter', 'teacher_id']. output_dir: Where to save PNGs (relative to project root). Defaults to 'output'.

Returns: Dict with 'files' (absolute paths), 'count', and 'output_dir'.

Inputs: country (required), position (required), last_name (required), first_name (required), +5 more.

list_countries_toolA

List all available countries, their display names, and the document types each can generate.

Inputs: no named parameters. Returns: result

list_schoolsA

List all schools for a given country code (e.g. 'us', 'uk'). Each entry has name/address/town/postcode/state/phone/lea.

Inputs: country (required). Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.3/5.0

    Scored across 3 tools

    Disambiguation5/5

    Each tool serves a clearly distinct purpose: listing countries, listing schools, and generating documents. There is no overlap or ambiguity between the three tools.

    Naming Consistency4/5

    Two tools follow a list_ prefix pattern and generate_documents uses verb_noun style, which is mostly consistent. The '_tool' suffix on list_countries_tool is a minor deviation but does not cause confusion.

    Tool Count5/5

    Three tools is a well-scoped set for the server's purpose: discovery (countries/schools) and document generation. Each tool earns its place with no unnecessary bloat.

    Completeness5/5

    The tool surface covers the full workflow: listing supported countries and document types, retrieving schools for a country, and generating the requested teacher documents. There are no obvious dead ends or missing operations.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      A
      maintenance
      Enables AI agents to create and process office documents locally, including generating branded PDF, Word, Excel, and editable PowerPoint files from templates and themes, plus reading, OCR, form-filling, manipulation, and conversion of PDFs.
      1
      MIT
    • A
      license
      A
      quality
      Not graded
      maintenance
      Enables generating realistic teacher verification documents such as employment letters, teacher ID cards, teaching licenses, and payslips across 13 countries via MCP.
      16
      3
      225
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Reads passports, ID cards and driver's licences from a photo or scan and returns the printed fields and MRZ as structured JSON. One credit ($0.01) per recognised document; nothing is charged when no document is found.
      6
      222 npm
      MIT