Skip to main content
Glama

ris_dokument

Retrieve complete legal document text from Austria's official legal database. Use after searching to load full laws or decisions, with options for markdown or JSON output.

Instructions

Retrieve full text of a legal document.

Use this after searching to load the complete text of a specific law or decision.

Note: For long documents, content may be truncated. Use specific searches to narrow down.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
dokumentnummerNoRIS document number (e.g., "NOR40052761") - from search results
urlNoDirect URL to document content
response_formatNo"markdown" (default) or "json"markdown

Implementation Reference

  • The handler function for `ris_dokument` tool, which handles document retrieval by number or URL, including fallback to search APIs and content fetching.
    async (args) => {
      const { dokumentnummer, url: inputUrl, response_format } = args;
    
      if (!dokumentnummer && !inputUrl) {
        return createMcpResponse(
          '**Fehler:** Bitte gib entweder eine `dokumentnummer` oder eine `url` an.\n\n' +
            'Die Dokumentnummer findest du in den Suchergebnissen von `ris_bundesrecht`, ' +
            '`ris_landesrecht` oder `ris_judikatur`.',
        );
      }
    
      // SSRF protection: validate user-supplied URLs against domain allowlist
      if (inputUrl && !isAllowedUrl(inputUrl)) {
        return createMcpResponse(
          '**Fehler:** Die angegebene URL ist nicht erlaubt.\n\n' +
            'Nur HTTPS-URLs zu offiziellen RIS-Domains sind zulaessig ' +
            '(data.bka.gv.at, www.ris.bka.gv.at, ris.bka.gv.at).',
        );
      }
    
      try {
        let contentUrl = inputUrl;
        let htmlContent: string | undefined;
        let metadata: DocumentMetadata;
    
        if (dokumentnummer && !inputUrl) {
          // Strategy: Try direct URL construction first, fallback to search API
          const directResult = await getDocumentByNumber(dokumentnummer);
    
          if (directResult.success) {
            // Direct fetch succeeded - use minimal metadata
            htmlContent = directResult.html;
            contentUrl = directResult.url;
            metadata = {
              dokumentnummer,
              applikation: 'Unbekannt',
              titel: dokumentnummer,
              kurztitel: null,
              citation: {},
              dokument_url: directResult.url,
            };
          } else {
            // Direct fetch failed - fallback to search API
            let apiResponse;
    
            if (dokumentnummer.startsWith('NOR')) {
              apiResponse = await searchBundesrecht({
                Applikation: 'BrKons',
                Dokumentnummer: dokumentnummer,
                DokumenteProSeite: 'Ten',
              });
            } else if (
              dokumentnummer.startsWith('LBG') ||
              dokumentnummer.startsWith('LNO') ||
              dokumentnummer.startsWith('LST') ||
              dokumentnummer.startsWith('LTI') ||
              dokumentnummer.startsWith('LVO') ||
              dokumentnummer.startsWith('LWI') ||
              dokumentnummer.startsWith('LSB') ||
              dokumentnummer.startsWith('LOO') ||
              dokumentnummer.startsWith('LKT')
            ) {
              apiResponse = await searchLandesrecht({
                Applikation: 'LrKons',
                Dokumentnummer: dokumentnummer,
                DokumenteProSeite: 'Ten',
              });
            } else if (dokumentnummer.startsWith('JFR') || dokumentnummer.startsWith('JFT')) {
              apiResponse = await searchJudikatur({
                Applikation: 'Vfgh',
                Dokumentnummer: dokumentnummer,
                DokumenteProSeite: 'Ten',
              });
            } else if (dokumentnummer.startsWith('JWR') || dokumentnummer.startsWith('JWT')) {
              apiResponse = await searchJudikatur({
                Applikation: 'Vwgh',
                Dokumentnummer: dokumentnummer,
                DokumenteProSeite: 'Ten',
              });
            } else if (dokumentnummer.startsWith('BVWG')) {
              apiResponse = await searchJudikatur({
                Applikation: 'Bvwg',
                Dokumentnummer: dokumentnummer,
                DokumenteProSeite: 'Ten',
              });
            } else if (dokumentnummer.startsWith('LVWG')) {
              apiResponse = await searchJudikatur({
                Applikation: 'Lvwg',
                Dokumentnummer: dokumentnummer,
                DokumenteProSeite: 'Ten',
              });
            } else if (dokumentnummer.startsWith('DSB')) {
              apiResponse = await searchJudikatur({
                Applikation: 'Dsk',
                Dokumentnummer: dokumentnummer,
                DokumenteProSeite: 'Ten',
              });
            } else if (dokumentnummer.startsWith('GBK')) {
              apiResponse = await searchJudikatur({
                Applikation: 'Gbk',
                Dokumentnummer: dokumentnummer,
                DokumenteProSeite: 'Ten',
              });
            } else if (dokumentnummer.startsWith('PVAK')) {
              apiResponse = await searchJudikatur({
                Applikation: 'Pvak',
                Dokumentnummer: dokumentnummer,
                DokumenteProSeite: 'Ten',
              });
            } else if (dokumentnummer.startsWith('ASYLGH')) {
              apiResponse = await searchJudikatur({
                Applikation: 'AsylGH',
                Dokumentnummer: dokumentnummer,
                DokumenteProSeite: 'Ten',
              });
            } else if (dokumentnummer.startsWith('BGBLA') || dokumentnummer.startsWith('BGBL')) {
              // Bundesgesetzblätter - use Bundesrecht endpoint
              const applikation = dokumentnummer.startsWith('BGBLA') ? 'BgblAuth' : 'BgblAlt';
              apiResponse = await searchBundesrecht({
                Applikation: applikation,
                Dokumentnummer: dokumentnummer,
                DokumenteProSeite: 'Ten',
              });
            } else if (dokumentnummer.startsWith('REGV')) {
              // Regierungsvorlagen - use Bundesrecht endpoint
              apiResponse = await searchBundesrecht({
                Applikation: 'RegV',
                Dokumentnummer: dokumentnummer,
                DokumenteProSeite: 'Ten',
              });
            } else if (dokumentnummer.startsWith('MRP') || dokumentnummer.startsWith('ERL')) {
              // Sonstige Sammlungen - use Sonstige endpoint
              apiResponse = await searchSonstige({
                Applikation: dokumentnummer.startsWith('MRP') ? 'Mrp' : 'Erlaesse',
                Dokumentnummer: dokumentnummer,
                DokumenteProSeite: 'Ten',
              });
            } else {
              // Default to Justiz for unknown prefixes
              apiResponse = await searchJudikatur({
                Applikation: 'Justiz',
                Dokumentnummer: dokumentnummer,
                DokumenteProSeite: 'Ten',
              });
            }
    
            // Find the document with matching dokumentnummer (don't blindly take first result)
            const findResult = findDocumentByDokumentnummer(apiResponse.documents, dokumentnummer);
    
            if (!findResult.success) {
              // Both direct fetch and search failed - provide helpful error
              const directError = directResult.error;
              if (findResult.error === 'no_documents') {
                return createMcpResponse(
                  `**Fehler:** Kein Dokument mit der Nummer \`${dokumentnummer}\` gefunden.\n\n` +
                    `Direkter Abruf: ${directError}\n` +
                    `Suche: Keine Ergebnisse.\n\n` +
                    'Bitte pruefe die Dokumentnummer oder verwende eine Suche, ' +
                    'um das gewuenschte Dokument zu finden.',
                );
              } else {
                return createMcpResponse(
                  `**Fehler:** Dokument \`${dokumentnummer}\` nicht gefunden.\n\n` +
                    `Direkter Abruf: ${directError}\n` +
                    `Suche: ${findResult.totalResults} Ergebnisse, aber keines mit dieser Dokumentnummer.\n\n` +
                    `Bitte verwende eine alternative Suche oder die direkte URL.`,
                );
              }
            }
    
            const doc = findResult.document;
            contentUrl = doc.content_urls.html ?? undefined;
    
            if (!contentUrl) {
              return createMcpResponse(
                `**Fehler:** Keine Inhalts-URL fuer Dokument \`${dokumentnummer}\` verfuegbar.\n\n` +
                  'Das Dokument hat moeglicherweise keinen abrufbaren Volltext.',
              );
            }
    
            // Build metadata from search result
            metadata = {
              dokumentnummer: doc.dokumentnummer,
              applikation: doc.applikation,
              titel: doc.titel,
              kurztitel: doc.kurztitel,
              citation: {
                kurztitel: doc.citation.kurztitel,
                langtitel: doc.citation.langtitel,
                kundmachungsorgan: doc.citation.kundmachungsorgan,
                paragraph: doc.citation.paragraph,
                eli: doc.citation.eli,
                inkrafttreten: doc.citation.inkrafttreten,
                ausserkrafttreten: doc.citation.ausserkrafttreten,
              },
              dokument_url: doc.dokument_url,
              gesamte_rechtsvorschrift_url: doc.gesamte_rechtsvorschrift_url,
            };
          }
        } else {
          // Only URL provided - minimal metadata
          metadata = {
            dokumentnummer: dokumentnummer ?? 'Unbekannt',
            applikation: 'Unbekannt',
            titel: inputUrl ?? '',
            kurztitel: null,
            citation: {},
            dokument_url: inputUrl,
          };
        }
    
        if (!contentUrl) {
          return createMcpResponse('**Fehler:** Keine gueltige URL zum Abrufen des Dokuments.');
        }
    
        // Fetch document content if not already fetched via direct URL
        if (!htmlContent) {
          htmlContent = await getDocumentContent(contentUrl);
        }
    
        // Format the document
        const formatted = formatDocument(htmlContent, metadata, response_format);
        const result = truncateResponse(formatted);
    
        return createMcpResponse(result);
      } catch (e) {
        return createMcpResponse(formatErrorResponse(e));
      }
    },
  • Schema definitions for the `ris_dokument` tool inputs.
    {
      dokumentnummer: z
        .string()
        .optional()
        .describe('RIS document number (e.g., "NOR40052761") - from search results'),
      url: z.string().optional().describe('Direct URL to document content'),
      response_format: z
        .enum(['markdown', 'json'])
        .default('markdown')
        .describe('"markdown" (default) or "json"'),
    },
  • Registration function for the `ris_dokument` tool.
    export function registerDokumentTool(server: McpServer): void {
      server.tool(
        'ris_dokument',
        `Retrieve full text of a legal document.
    
    Use this after searching to load the complete text of a specific law or decision.
    
    Note: For long documents, content may be truncated. Use specific searches to narrow down.`,
        {
          dokumentnummer: z
            .string()
            .optional()
            .describe('RIS document number (e.g., "NOR40052761") - from search results'),
          url: z.string().optional().describe('Direct URL to document content'),
          response_format: z
            .enum(['markdown', 'json'])
            .default('markdown')
            .describe('"markdown" (default) or "json"'),
        },
        async (args) => {
          const { dokumentnummer, url: inputUrl, response_format } = args;
    
          if (!dokumentnummer && !inputUrl) {
            return createMcpResponse(
              '**Fehler:** Bitte gib entweder eine `dokumentnummer` oder eine `url` an.\n\n' +
                'Die Dokumentnummer findest du in den Suchergebnissen von `ris_bundesrecht`, ' +
                '`ris_landesrecht` oder `ris_judikatur`.',
            );
          }
    
          // SSRF protection: validate user-supplied URLs against domain allowlist
          if (inputUrl && !isAllowedUrl(inputUrl)) {
            return createMcpResponse(
              '**Fehler:** Die angegebene URL ist nicht erlaubt.\n\n' +
                'Nur HTTPS-URLs zu offiziellen RIS-Domains sind zulaessig ' +
                '(data.bka.gv.at, www.ris.bka.gv.at, ris.bka.gv.at).',
            );
          }
    
          try {
            let contentUrl = inputUrl;
            let htmlContent: string | undefined;
            let metadata: DocumentMetadata;
    
            if (dokumentnummer && !inputUrl) {
              // Strategy: Try direct URL construction first, fallback to search API
              const directResult = await getDocumentByNumber(dokumentnummer);
    
              if (directResult.success) {
                // Direct fetch succeeded - use minimal metadata
                htmlContent = directResult.html;
                contentUrl = directResult.url;
                metadata = {
                  dokumentnummer,
                  applikation: 'Unbekannt',
                  titel: dokumentnummer,
                  kurztitel: null,
                  citation: {},
                  dokument_url: directResult.url,
                };
              } else {
                // Direct fetch failed - fallback to search API
                let apiResponse;
    
                if (dokumentnummer.startsWith('NOR')) {
                  apiResponse = await searchBundesrecht({
                    Applikation: 'BrKons',
                    Dokumentnummer: dokumentnummer,
                    DokumenteProSeite: 'Ten',
                  });
                } else if (
                  dokumentnummer.startsWith('LBG') ||
                  dokumentnummer.startsWith('LNO') ||
                  dokumentnummer.startsWith('LST') ||
                  dokumentnummer.startsWith('LTI') ||
                  dokumentnummer.startsWith('LVO') ||
                  dokumentnummer.startsWith('LWI') ||
                  dokumentnummer.startsWith('LSB') ||
                  dokumentnummer.startsWith('LOO') ||
                  dokumentnummer.startsWith('LKT')
                ) {
                  apiResponse = await searchLandesrecht({
                    Applikation: 'LrKons',
                    Dokumentnummer: dokumentnummer,
                    DokumenteProSeite: 'Ten',
                  });
                } else if (dokumentnummer.startsWith('JFR') || dokumentnummer.startsWith('JFT')) {
                  apiResponse = await searchJudikatur({
                    Applikation: 'Vfgh',
                    Dokumentnummer: dokumentnummer,
                    DokumenteProSeite: 'Ten',
                  });
                } else if (dokumentnummer.startsWith('JWR') || dokumentnummer.startsWith('JWT')) {
                  apiResponse = await searchJudikatur({
                    Applikation: 'Vwgh',
                    Dokumentnummer: dokumentnummer,
                    DokumenteProSeite: 'Ten',
                  });
                } else if (dokumentnummer.startsWith('BVWG')) {
                  apiResponse = await searchJudikatur({
                    Applikation: 'Bvwg',
                    Dokumentnummer: dokumentnummer,
                    DokumenteProSeite: 'Ten',
                  });
                } else if (dokumentnummer.startsWith('LVWG')) {
                  apiResponse = await searchJudikatur({
                    Applikation: 'Lvwg',
                    Dokumentnummer: dokumentnummer,
                    DokumenteProSeite: 'Ten',
                  });
                } else if (dokumentnummer.startsWith('DSB')) {
                  apiResponse = await searchJudikatur({
                    Applikation: 'Dsk',
                    Dokumentnummer: dokumentnummer,
                    DokumenteProSeite: 'Ten',
                  });
                } else if (dokumentnummer.startsWith('GBK')) {
                  apiResponse = await searchJudikatur({
                    Applikation: 'Gbk',
                    Dokumentnummer: dokumentnummer,
                    DokumenteProSeite: 'Ten',
                  });
                } else if (dokumentnummer.startsWith('PVAK')) {
                  apiResponse = await searchJudikatur({
                    Applikation: 'Pvak',
                    Dokumentnummer: dokumentnummer,
                    DokumenteProSeite: 'Ten',
                  });
                } else if (dokumentnummer.startsWith('ASYLGH')) {
                  apiResponse = await searchJudikatur({
                    Applikation: 'AsylGH',
                    Dokumentnummer: dokumentnummer,
                    DokumenteProSeite: 'Ten',
                  });
                } else if (dokumentnummer.startsWith('BGBLA') || dokumentnummer.startsWith('BGBL')) {
                  // Bundesgesetzblätter - use Bundesrecht endpoint
                  const applikation = dokumentnummer.startsWith('BGBLA') ? 'BgblAuth' : 'BgblAlt';
                  apiResponse = await searchBundesrecht({
                    Applikation: applikation,
                    Dokumentnummer: dokumentnummer,
                    DokumenteProSeite: 'Ten',
                  });
                } else if (dokumentnummer.startsWith('REGV')) {
                  // Regierungsvorlagen - use Bundesrecht endpoint
                  apiResponse = await searchBundesrecht({
                    Applikation: 'RegV',
                    Dokumentnummer: dokumentnummer,
                    DokumenteProSeite: 'Ten',
                  });
                } else if (dokumentnummer.startsWith('MRP') || dokumentnummer.startsWith('ERL')) {
                  // Sonstige Sammlungen - use Sonstige endpoint
                  apiResponse = await searchSonstige({
                    Applikation: dokumentnummer.startsWith('MRP') ? 'Mrp' : 'Erlaesse',
                    Dokumentnummer: dokumentnummer,
                    DokumenteProSeite: 'Ten',
                  });
                } else {
                  // Default to Justiz for unknown prefixes
                  apiResponse = await searchJudikatur({
                    Applikation: 'Justiz',
                    Dokumentnummer: dokumentnummer,
                    DokumenteProSeite: 'Ten',
                  });
                }
    
                // Find the document with matching dokumentnummer (don't blindly take first result)
                const findResult = findDocumentByDokumentnummer(apiResponse.documents, dokumentnummer);
    
                if (!findResult.success) {
                  // Both direct fetch and search failed - provide helpful error
                  const directError = directResult.error;
                  if (findResult.error === 'no_documents') {
                    return createMcpResponse(
                      `**Fehler:** Kein Dokument mit der Nummer \`${dokumentnummer}\` gefunden.\n\n` +
                        `Direkter Abruf: ${directError}\n` +
                        `Suche: Keine Ergebnisse.\n\n` +
                        'Bitte pruefe die Dokumentnummer oder verwende eine Suche, ' +
                        'um das gewuenschte Dokument zu finden.',
                    );
                  } else {
                    return createMcpResponse(
                      `**Fehler:** Dokument \`${dokumentnummer}\` nicht gefunden.\n\n` +
                        `Direkter Abruf: ${directError}\n` +
                        `Suche: ${findResult.totalResults} Ergebnisse, aber keines mit dieser Dokumentnummer.\n\n` +
                        `Bitte verwende eine alternative Suche oder die direkte URL.`,
                    );
                  }
                }
    
                const doc = findResult.document;
                contentUrl = doc.content_urls.html ?? undefined;
    
                if (!contentUrl) {
                  return createMcpResponse(
                    `**Fehler:** Keine Inhalts-URL fuer Dokument \`${dokumentnummer}\` verfuegbar.\n\n` +
                      'Das Dokument hat moeglicherweise keinen abrufbaren Volltext.',
                  );
                }
    
                // Build metadata from search result
                metadata = {
                  dokumentnummer: doc.dokumentnummer,
                  applikation: doc.applikation,
                  titel: doc.titel,
                  kurztitel: doc.kurztitel,
                  citation: {
                    kurztitel: doc.citation.kurztitel,
                    langtitel: doc.citation.langtitel,
                    kundmachungsorgan: doc.citation.kundmachungsorgan,
                    paragraph: doc.citation.paragraph,
                    eli: doc.citation.eli,
                    inkrafttreten: doc.citation.inkrafttreten,
                    ausserkrafttreten: doc.citation.ausserkrafttreten,
                  },
                  dokument_url: doc.dokument_url,
                  gesamte_rechtsvorschrift_url: doc.gesamte_rechtsvorschrift_url,
                };
              }
            } else {
              // Only URL provided - minimal metadata
              metadata = {
                dokumentnummer: dokumentnummer ?? 'Unbekannt',
                applikation: 'Unbekannt',
                titel: inputUrl ?? '',
                kurztitel: null,
                citation: {},
                dokument_url: inputUrl,
              };
            }
    
            if (!contentUrl) {
              return createMcpResponse('**Fehler:** Keine gueltige URL zum Abrufen des Dokuments.');
            }
    
            // Fetch document content if not already fetched via direct URL
            if (!htmlContent) {
              htmlContent = await getDocumentContent(contentUrl);
            }
    
            // Format the document
            const formatted = formatDocument(htmlContent, metadata, response_format);
            const result = truncateResponse(formatted);
    
            return createMcpResponse(result);
          } catch (e) {
            return createMcpResponse(formatErrorResponse(e));
          }
        },
      );
    }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden and adds valuable behavioral context: it warns about content truncation for long documents and suggests using specific searches to narrow down. This goes beyond what the input schema provides about the tool's operational behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is perfectly structured with three sentences that each earn their place: purpose statement, usage guidance, and behavioral warning. It's front-loaded with the core purpose and wastes no words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a retrieval tool with no annotations and no output schema, the description provides good context about the tool's purpose, usage timing, and truncation behavior. However, it doesn't describe what the output looks like (format, structure) which would be helpful given the lack of output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The description doesn't add any additional parameter semantics beyond what's in the schema descriptions, which is acceptable given the high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Retrieve full text') and resource ('legal document'), distinguishing it from sibling tools that appear to search or list documents rather than retrieve full content. It explicitly mentions 'law or decision' to clarify the type of document.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool ('after searching to load the complete text'), but doesn't explicitly state when NOT to use it or name specific alternatives among the sibling tools. The guidance is helpful but could be more comprehensive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Honeyfield-Org/ris-mcp-ts'

If you have feedback or need assistance with the MCP directory API, please join our Discord server