Serves Oracle Forms module content (.fmb/.mmb/.pll/.olb) from a directory to MCP clients.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Inspect callable tools, capabilities, and parameters exposed to AI agents by Oracle Forms MCP.
list_modulesModules in the forms dir with type, size, and cache status; filter by `pattern`/`regex`, `type`, `status` and page via `limit`/`cursor
fetch_moduleConverts + indexes one module (idempotent; progress notifications)
get_module_overviewNames of every section + counts β the first call after a fetch (`verbosity=detailed` adds window and canvas objects)
list_blocksBlocks with base table, item count, trigger count
get_blockOne block: items with type, property class, prompt and trigger names (`verbosity=detailed` adds data type, column, canvas, visible/required/LOV); flags subclassed blocks/items
list_triggersTriggers with level/scope; filter by block, item, or level (`verbosity=detailed` adds a PL/SQL preview)
An MCP server that serves the content of Oracle Forms modules
(.fmb forms, .mmb menus, .pll PL/SQL libraries, .olb object libraries) found in a
directory, so AI assistants can inspect blocks, items, triggers, program units, and raw object
XML without opening Forms Builder.
Built as a Kotlin Multiplatform core (pure @Serializable models and ports) with a JVM MCP
server on top: declarative tool adapters over a single FormsService, stdio and HTTP transports,
and a fingerprint-based on-disk cache. Oracle tool conversion feeds a streaming StAX parser that
turns Forms XML into a structured index.
Oracle Forms applications from the 1990sβ2000s are still running critical business processes, but
their logic is locked inside binary .fmb/.pll modules that only Forms Builder can open. That
makes them opaque to modern AI tooling and painful to review, document, or migrate.
Oracle Forms MCP turns those modules into structured, queryable content so an AI assistant can:
It is aimed at developers and teams doing Oracle Forms modernization, reverse engineering, code review, and documentation β anyone who needs to read Forms logic faster than opening it by hand.
A typical session against the bundled sample-forms directory:
list_modules scans the configured --forms-dir (non-recursive) and reports each module's
cache status: NOT_CACHED, CACHED, STALE (source changed on disk), or SOURCE_MISSING.
A production forms directory holds thousands of modules, so the answer is filtered and paged:
narrow with pattern/type/status, follow nextCursor for the rest, and read
countsByStatus for the shape of the whole match.fetch_module produces the module's text form in the cache and indexes it:
ORACLE_HOME set β binaries are converted with the Oracle tools in
%ORACLE_HOME%\bin: frmf2xml for .fmb/.mmb/.olb (XML), frmcmp_batch
(Module_Type=LIBRARY Script=YES) for .pll (a .pld text dump).ORACLE_HOME not set β pre-converted files are expected next to the modules
(orders_fmb.xml, dupes_fmb.xml, picker_fmb.xml, toolbar_fmb.xml,
mainmenu_mmb.xml, objects_olb.xml, utils.pld) and copied into the cache..sql sidecar files; every named XML element gets a line-range reference so
get_object_xml can slice it back out of the converted file.STALE and read tools ask for a re-fetch.annotate_element and relate_elements let the assistant write durable meta-information back
about individual elements (notes, tags, summaries, classifications, cross-references). This is
kept in a separate store β not the derived index β so it survives re-fetching, and the read
tools surface it inline. An annotation made before a source change is flagged, never dropped.| Tool | What it returns |
|---|---|
list_modules | Modules in the forms dir with type, size, and cache status; filter by pattern/regex, type, status and page via limit/cursor |
fetch_module | Converts + indexes one module (idempotent; progress notifications) |
get_module_overview | Names of every section + counts β the first call after a fetch (verbosity=detailed adds window and canvas objects) |
list_blocks | Blocks with base table, item count, trigger count |
get_block | One block: items with type, property class, prompt and trigger names, and its master-detail relations (verbosity=detailed adds data type, column, canvas, size, visible/required/LOV and the DML properties resolved through each item's property class; columns=true adds the base table's columns and the ones no item supplies); flags subclassed blocks/items |
list_triggers | Triggers with level/scope; filter by block, item, or level (verbosity=detailed adds a PL/SQL preview) |
get_trigger | One trigger's decoded PL/SQL body (same-named triggers told apart by ownerPath or level); resolve follows a subclassing pointer into a cached parent module |
list_program_units | Procedures, functions, package specs/bodies with line counts |
get_program_unit | One program unit's PL/SQL (disambiguate spec/body via unitType); resolve as for get_trigger |
search_source | Line search over one fetched module: extracted PL/SQL (plsql), the raw XML (xml), or both; paginated via offset/nextOffset |
search_modules | The same search across every cached module β cross-form calls, shared :GLOBALs, subclassing pointers; reports the modules it could not reach; paged via an opaque cursor |
read_source | A line range of a cached file, by uri (which names its module) or module + file β the converted XML or an extracted PL/SQL sidecar |
get_object_xml | The raw XML fragment of any named object β the escape hatch |
Every tool checks its arguments against its own input schema before running. An argument it does not have is never silently dropped: the call fails with every problem listed at once (unknown arguments with the name most likely meant, missing ones with their permitted values, values outside an enum), plus an example call where the tool has one.
Two Forms properties carry more meaning than anything else in a module, and both used to be
reachable only one get_object_xml call at a time.
An item's property class is usually its role: Forms shops name their classes for what the
object does, so a push button is an LOV button and a text item is a filter field only because
of the class it inherits. get_block reports propertyClass on every item and block, confirmed
against the classes the module actually declares.
A window's modality decides how a form is read β a modal window is a dialog, so the code that
fills it and the code that consumes the result sit on opposite sides of one interaction.
get_module_overview(verbosity: "detailed") returns the window and canvas objects behind two of
its name lists: modality, size, toolbar canvases, and the window each canvas sits on.
A property Forms did not write comes back as null, meaning the object keeps the Forms default β
never false. On an item that has a property class it does not even mean the default: the class
supplies the value, and in a real form that is where most of an item's behaviour lives. So
get_block(verbosity: "detailed") returns both β items[].dml, what the item itself wrote, and
effectiveDml, the same properties with the class applied (item, then class, then whatever that
class is based on, followed into other modules that are already fetched). An item is listed in
effectiveDml only when that chain resolved to the end, so a null there really is the Forms
default. Every other item is a row of unresolvedItems, with the reason and β when fetching fixes
it β the module to fetch; propertyClasses and the result's hint give the same account per class
and name the fetch_module call. items: [...] narrows all of it to the items a question is about.
Factual signals from GitHub, npm, and our automated checks β not a rating.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/oracle-forms-mcp)<a href="https://allmcps.com/mcp/oracle-forms-mcp"><img src="https://allmcps.com/api/badge/oracle-forms-mcp?style=directory" alt="Oracle Forms MCP on AllMCPs" /></a>