Skip to main content
Glama
pythia-the-oracle

pythia-oracle-mcp

Official

get_integration_guide

Get Solidity code to integrate Pythia on-chain indicators into a smart contract. Select tier: discovery, analysis, speed, or complete.

Instructions

Get Solidity code to integrate Pythia into a smart contract.

Args: tier: 'discovery' (single value), 'analysis', 'speed', or 'complete'.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
tierNodiscovery

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The get_integration_guide tool handler function. Registered as @mcp.tool() with FastMCP. Accepts a 'tier' parameter (default 'discovery') and returns Solidity code for integrating Pythia into smart contracts. Fetches live contract data from feed-status.json and returns Solidity code for either Discovery (single indicator) or bundle tiers (Analysis/Speed/Complete).
    @mcp.tool()
    async def get_integration_guide(tier: str = "discovery") -> str:
        """Get Solidity code to integrate Pythia into a smart contract.
    
        Args:
            tier: 'discovery' (single value), 'analysis', 'speed', or 'complete'.
        """
        tier = tier.lower()
        if tier not in _JOB_IDS:
            return f"Unknown tier '{tier}'. Choose: discovery, analysis, speed, complete"
    
        data = await _fetch_data()
        mainnet = _get_mainnet(data)
        consumer_addr = mainnet["consumers"].get(tier, "CHECK_WEBSITE")
        job_id = _JOB_IDS[tier]
        operator = mainnet["operator"]
        link_token = mainnet["link_token"]
        fee_str = _get_tier_fee(data, tier)
    
        if tier == "discovery":
            fee_num = _get_tier_fees(data).get("discovery", 0.01)
            return f"""Pythia Integration — Discovery Tier (Single Indicator)
    
    Consumer: {consumer_addr}
    Fee: {fee_str}
    Job ID: {job_id}
    
    ```solidity
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.19;
    
    import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";
    import "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
    
    contract MyPythiaConsumer is ChainlinkClient, ConfirmedOwner {{
        using Chainlink for Chainlink.Request;
    
        uint256 public lastValue;
        bytes32 private jobId = {job_id};
        uint256 private fee = {fee_num} ether; // {fee_str}
        address private oracle = {operator};
    
        constructor() ConfirmedOwner(msg.sender) {{
            _setChainlinkToken({link_token});
            _setChainlinkOracle(oracle);
        }}
    
        /// @notice Request a single indicator value
        /// @param feed Feed name, e.g. "bitcoin_RSI_1H_14" or "solana_EMA_5M_20"
        function requestIndicator(string memory feed) public onlyOwner returns (bytes32) {{
            Chainlink.Request memory req = _buildChainlinkRequest(
                jobId, address(this), this.fulfill.selector
            );
            req._add("feed", feed);
            return _sendChainlinkRequest(req, fee);
        }}
    
        function fulfill(bytes32 requestId, uint256 value) public recordChainlinkFulfillment(requestId) {{
            lastValue = value;
        }}
    
        function withdrawLink() public onlyOwner {{
            LinkTokenInterface link = LinkTokenInterface(_chainlinkTokenAddress());
            require(link.transfer(msg.sender, link.balanceOf(address(this))));
        }}
    }}
    ```
    
    Steps:
    1. Deploy this contract on Polygon mainnet
    2. Fund it with ERC-677 LINK (use PegSwap if you have bridged LINK)
    3. Call requestIndicator("bitcoin_RSI_1H_14") — result arrives in fulfill()
    4. Read lastValue — it's the indicator x 1e18
    
    Free trial: Use PythiaFaucet ({FAUCET_ADDRESS}) instead — no LINK needed."""
    
        else:
            fee_num = _get_tier_fees(data).get(tier, 0.10)
            return f"""Pythia Integration — {tier.upper()} Tier (Bundle)
    
    Consumer: {consumer_addr}
    Fee: {fee_str}
    Job ID: {job_id}
    
    ```solidity
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.19;
    
    import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";
    import "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
    
    contract MyPythiaBundleConsumer is ChainlinkClient, ConfirmedOwner {{
        using Chainlink for Chainlink.Request;
    
        uint256[] public lastBundle;
        bytes32 private jobId = {job_id};
        uint256 private fee = {fee_num} ether; // {fee_str}
        address private oracle = {operator};
    
        constructor() ConfirmedOwner(msg.sender) {{
            _setChainlinkToken({link_token});
            _setChainlinkOracle(oracle);
        }}
    
        /// @notice Request a bundle of indicators for a token
        /// @param engineId Token engine ID, e.g. "bitcoin", "solana", "aave"
        function requestBundle(string memory engineId) public onlyOwner returns (bytes32) {{
            Chainlink.Request memory req = _buildChainlinkRequest(
                jobId, address(this), this.fulfillBundle.selector
            );
            req._add("feed", engineId);
            req._add("bundle", "true");
            return _sendChainlinkRequest(req, fee);
        }}
    
        function fulfillBundle(bytes32 requestId, uint256[] memory values)
            public recordChainlinkFulfillment(requestId)
        {{
            lastBundle = values;
        }}
    
        function getBundleValue(uint256 index) public view returns (uint256) {{
            require(index < lastBundle.length, "Index out of bounds");
            return lastBundle[index];
        }}
    
        function withdrawLink() public onlyOwner {{
            LinkTokenInterface link = LinkTokenInterface(_chainlinkTokenAddress());
            require(link.transfer(msg.sender, link.balanceOf(address(this))));
        }}
    }}
    ```
    
    Steps:
    1. Deploy on Polygon mainnet (gasLimit: 1,000,000 — bundles need more gas)
    2. Fund with ERC-677 LINK
    3. Call requestBundle("bitcoin") — bundle arrives in fulfillBundle()
    4. Read lastBundle[i] — each slot is an indicator x 1e18
    
    Bundle contents vary by tier:
      Analysis = 1H + 1D + 1W indicators
      Speed = all 5M indicators
      Complete = everything
    
    Docs: {WEBSITE_URL}"""
  • The tool is registered as an MCP tool using the @mcp.tool() decorator on the async function get_integration_guide. The mcp instance is created as FastMCP('Pythia Oracle') on line 17.
    @mcp.tool()
    async def get_integration_guide(tier: str = "discovery") -> str:
  • Input schema / parameter definition for get_integration_guide: accepts a 'tier' string parameter with choices 'discovery', 'analysis', 'speed', 'complete'. Default is 'discovery'.
    async def get_integration_guide(tier: str = "discovery") -> str:
        """Get Solidity code to integrate Pythia into a smart contract.
    
        Args:
            tier: 'discovery' (single value), 'analysis', 'speed', or 'complete'.
  • _JOB_IDS dict and _TIER_RETURNS dict used by get_integration_guide to map tier names to Chainlink job IDs and return type descriptions.
    _JOB_IDS = {
        "discovery": "0x8920841054eb4082b5910af84afa005e00000000000000000000000000000000",
        "analysis": "0xa1ecae215cd9471a95095ab52e2f403600000000000000000000000000000000",
        "speed": "0x8a50dfe4645f41a993a175b486d9840600000000000000000000000000000000",
        "complete": "0x48d135697ade4c8faec5fe67bbc3f65b00000000000000000000000000000000",
    }
    
    _TIER_RETURNS = {
        "discovery": "uint256 (single indicator)",
        "analysis": "uint256[] (1H/1D/1W bundle)",
        "speed": "uint256[] (5M bundle)",
        "complete": "uint256[] (all indicators)",
    }
  • _get_tier_fee helper used by get_integration_guide to fetch the live fee for a tier from feed-status.json.
    def _get_tier_fee(data: dict, tier: str) -> str:
        """Get fee string like '0.01 LINK' for a tier from live data."""
        fees = _get_tier_fees(data)
        if tier not in fees:
            raise RuntimeError(f"Tier '{tier}' not found in live pricing data. Available: {list(fees)}")
        return f"{fees[tier]} LINK"
Behavior2/5

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

No annotations provided, so description carries full burden. It does not disclose any behavioral traits like read-only nature, side effects, or permissions. Only states the output, not behavior.

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

Conciseness4/5

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

Very concise, one sentence plus arg list. No filler, but could be more structured with explicit separation. Still efficient.

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

Completeness3/5

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

Adequate for a simple tool with output schema; explains purpose and parameter. Lacks context on prerequisites or relation to other guides. Not incomplete but not rich.

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

Parameters4/5

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

Schema has 0% description coverage; description adds meaning by listing possible values for 'tier'. Although phrasing is slightly ambiguous, it provides guidance beyond the schema's bare type string.

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 tool returns Solidity code for integrating Pythia into a smart contract, specific verb and resource, and distinguishes from sibling guide tools by mentioning Pythia and Solidity code.

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

Usage Guidelines2/5

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

No guidance on when to use this tool over siblings like get_events_guide or get_visions_guide. The description only states what it does, not context or exclusions.

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/pythia-the-oracle/pythia-oracle-mcp'

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