+3  A: 

I changed a little bit of your code in the process, but this worked for me:

<?php

/**
* Plugin Name:   MyPlugin Example
* Version:       1.0.1
**/
class MyPlugin {

    function activate() {
        global $wp_rewrite;
        $this->flush_rewrite_rules();
    }

    // Took out the $wp_rewrite->rules replacement so the rewrite rules filter could handle this.
    function create_rewrite_rules($rules) {
        global $wp_rewrite;
        $newRule = array('MyPlugin/(.+)' => 'index.php?MyPlugin='.$wp_rewrite->preg_index(1));
        $newRules = $newRule + $rules;
        return $newRules;
    }

    function add_query_vars($qvars) {
        $qvars[] = 'MyPlugin';
        return $qvars;
    }

    function flush_rewrite_rules() {
        global $wp_rewrite;
        $wp_rewrite->flush_rules();
    }

    function template_redirect_intercept() {
        global $wp_query;
        if ($wp_query->get('MyPlugin')) {
            $this->pushoutput($wp_query->get('MyPlugin'));
            exit;
        }
    }

    function pushoutput($message) {
        $this->output($message);
    }

    function output( $output ) {
        header( 'Cache-Control: no-cache, must-revalidate' );
        header( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' );

        // Commented to display in browser.
        // header( 'Content-type: application/json' );

        echo json_encode( $output );
    }
}

$MyPluginCode = new MyPlugin();
register_activation_hook( __file__, array($MyPluginCode, 'activate') );

// Using a filter instead of an action to create the rewrite rules.
// Write rules -> Add query vars -> Recalculate rewrite rules
add_filter('rewrite_rules_array', array($MyPluginCode, 'create_rewrite_rules'));
add_filter('query_vars',array($MyPluginCode, 'add_query_vars'));

// Recalculates rewrite rules during admin init to save resourcees.
// Could probably run it once as long as it isn't going to change or check the
// $wp_rewrite rules to see if it's active.
add_filter('admin_init', array($MyPluginCode, 'flush_rewrite_rules'));
add_action( 'template_redirect', array($MyPluginCode, 'template_redirect_intercept') );

I've commented the important parts, but what I did was basically to move your hooks over to use_filter rather than add_action. I also moved the filters into the order that they are actually used in Wordpress. Seemed the thing to do at the time.

Finally, make sure that your permalinks are set to use pretty URLs. I had an issue where mine were set to default, which makes Wordpress ignore any rewrite conditions that it would otherwise need to parse. Change over to some pretty URLs and your conditions will refresh.

Let me know if that works for you. Hope that helps.

Thanks, Joe

Joseph Mastey
Thanks for this, I'm testing it now! One question, what would be a proper way of testing the $wp_rewrite rules to see if it's active?
Brad
Usually it's enough to invoke your URL w/o rewrite and with it (/index.php?MyPlugin=foo and /MyPlugin/foo) and use a little trial and error. If not, the rewrite code is in wp-includes/rewrite.php. It's not pretty nor easy to debug with the code in that file, though.
Joseph Mastey