Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Oracle Forms

БесплатноНе проверен

Serves Oracle Forms module content (.fmb/.mmb/.pll/.olb) from a directory to MCP clients.

GitHubEmbed

Описание

Serves Oracle Forms module content (.fmb/.mmb/.pll/.olb) from a directory to MCP clients.

README

CI CodeQL Release License Kotlin

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.

Why

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:

  • Understand a legacy app — enumerate blocks, items, triggers, and program units without a Forms IDE.
  • Review & document PL/SQL — pull decoded trigger and program-unit bodies straight into the model's context.
  • Assist modernization — feed decades-old business logic to an assistant for migration to APEX, Java, or a rewrite, and search across every module's source.

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.

See it work

A typical session against the bundled sample-forms directory:

You:  What does ORDERS.fmb do?
AI →  list_modules                 → ORDERS.fmb (NOT_CACHED), MAIN.mmb, UTILS.pll …
AI →  fetch_module ORDERS.fmb      → converted + indexed (12 blocks, 47 triggers, 9 program units)
AI →  get_module_overview ORDERS   → blocks, triggers, LOVs, record groups, windows, canvases …
You:  Show me the validation logic on the ORDER_ITEMS block.
AI →  list_triggers block=ORDER_ITEMS  → WHEN-VALIDATE-ITEM, WHEN-NEW-RECORD-INSTANCE …
AI →  get_trigger ORDER_ITEMS WHEN-VALIDATE-ITEM  → the decoded PL/SQL body
You:  Where else is the ADD_TAX procedure called?
AI →  search_source "ADD_TAX" scope=plsql  → hits across triggers and program units

How it works

  1. 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.
  2. 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, main_mmb.xml, objects_olb.xml, utils.pld) and copied into the cache.
  3. A single StAX pass parses the XML into a structured index (blocks with items, triggers with decoded PL/SQL, program units, LOVs, record groups, windows, canvases, …). PL/SQL bodies are extracted to .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.
  4. The other tools read the cached index. Caching is fingerprint-based (size + mtime + sha256 of the source file): editing a module marks it STALE and read tools ask for a re-fetch.

Tools

Tool What it returns
list_modules Every module in the forms dir with type, size, and cache status
fetch_module Converts + indexes one module (idempotent; progress notifications)
get_module_overview Names of every section + counts — the first call after a fetch
list_blocks Blocks with base table, item count, trigger count
get_block One block in full: items (type, column, canvas, prompt) + trigger names
list_triggers Triggers with level/scope/preview; filter by block, item, or level
get_trigger One trigger's decoded PL/SQL body
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)
search_source Line search over extracted PL/SQL (plsql), the raw XML (xml), or both
get_object_xml The raw XML fragment of any named object — the escape hatch

Plus a resource per cached module (oracleforms://ORDERS.fmb/index), a oracleforms://{module}/index resource template, and an explain_module prompt.

Quick start

Requires a JRE 21+. Build and install:

gradlew :server:installDist

Register with Claude Code (stdio):

claude mcp add oracle-forms -- server/build/install/server/bin/server --forms-dir C:\path\to\forms
Other MCP clients (Claude Desktop, Cursor, VS Code) — via the Docker image

The published image runs the server over stdio with no local build. Point the volume mount at your forms directory (copy-mode: the pre-converted *_fmb.xml/*.pld files must sit next to the modules — see Docker).

Claude Desktop (claude_desktop_config.json) and Cursor (~/.cursor/mcp.json) use the same shape:

{
  "mcpServers": {
    "oracle-forms": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "-v", "/path/to/forms:/forms",
               "ghcr.io/aoreshkov/oracle-forms-mcp", "--forms-dir", "/forms"]
    }
  }
}

VS Code (.vscode/mcp.json) uses a servers key instead:

{
  "servers": {
    "oracle-forms": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "-v", "${workspaceFolder}/forms:/forms",
               "ghcr.io/aoreshkov/oracle-forms-mcp", "--forms-dir", "/forms"]
    }
  }
}

Prefer the native launcher? Swap "command": "docker", "args": [...] for "command": "/abs/path/to/server/build/install/server/bin/server", "args": ["--forms-dir", "/abs/path/to/forms"].

Try it without any Oracle installation using the bundled fixtures:

server --forms-dir sample-forms

HTTP transport:

server --forms-dir C:\forms --transport http --port 3000   # endpoint: http://127.0.0.1:3000/mcp

Docker (copy-mode only)

A container image is published to ghcr.io/aoreshkov/oracle-forms-mcp. Oracle's frmf2xml / frmcmp_batch binaries are proprietary and not bundled, so the image works only in copy-mode: the modules you mount must already have their pre-converted text form (*_fmb.xml/*_mmb.xml/*_olb.xml/*.pld) sitting next to them. For live .fmb/.pll conversion, run the server on a host with an Oracle Forms installation (ORACLE_HOME set).

docker run -i -v /path/to/forms:/forms ghcr.io/aoreshkov/oracle-forms-mcp --forms-dir /forms

Options

--forms-dir <path>          Directory containing the Forms modules (or pass it positionally)
--transport stdio|http      Transport (default: stdio)
--port <int>                HTTP port (default: 3000)
--allowed-host / --allowed-origin   Extra HTTP hosts/origins (localhost-only by default)
--cache-dir <path>          Cache override (default: OS cache dir + /oracle-forms-mcp)
--conversion-timeout <sec>  Kill a stuck conversion (default: 120)

Cache

%LOCALAPPDATA%\oracle-forms-mcp (Windows), ~/Library/Caches/oracle-forms-mcp (macOS), $XDG_CACHE_HOME/oracle-forms-mcp (Linux). One directory per module:

ORDERS.fmb/
  converted/orders_fmb.xml      converted (or copied) text form
  plsql/triggers/*.sql          decoded trigger bodies
  plsql/program-units/*.sql     decoded program units
  index.json                    the structured index

Safe to delete at any time; modules are simply re-fetched.

Notes on the Oracle tools

  • frmf2xml writes its output into the process working directory; the server runs it with the module's cache dir as cwd and passes OVERWRITE=YES USE_PROPERTY_IDS=NO.
  • frmcmp_batch is preferred over frmcmp (headless); the server passes Script=YES Batch=YES Logon=NO and augments FORMS_PATH with the forms dir so attached libraries resolve.
  • Forms tools have unreliable exit codes — success is judged by the output file existing, being non-empty, and being newer than the invocation; failures surface the tool's output tail.
  • .pld files may be written in the client NLS charset; the parser reads UTF-8 with a windows-1252 fallback (set NLS_LANG accordingly if you see mojibake).

Development

gradlew build          # compile + all tests (no Oracle installation needed)
gradlew apiDump        # refresh the binary-compatibility dump after public API changes
gradlew :server:run --args="--forms-dir sample-forms"

Converter behavior is tested against a fake ORACLE_HOME (stub scripts); the full copy-mode pipeline is covered end-to-end by FormsServiceIntegrationTest against the bundled fixtures.

from github.com/aoreshkov/oracle-forms-mcp

Установка Oracle Forms

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/aoreshkov/oracle-forms-mcp

FAQ

Oracle Forms MCP бесплатный?

Да, Oracle Forms MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Oracle Forms?

Нет, Oracle Forms работает без API-ключей и переменных окружения.

Oracle Forms — hosted или self-hosted?

Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.

Как установить Oracle Forms в Claude Desktop, Claude Code или Cursor?

Открой Oracle Forms на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Oracle Forms with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории development