Jaspers

Jaspers Terminal

Summary

Professional investors, quantitative researchers, and traders face a common set of requirements when introducing agents into their research process. Agents must be configured with minimal setup and assigned repeatable, scheduled, and multi-step tasks. Agents require control of the internal environment, meaning the local files, applications, and command line in which the existing work is stored and executed. Agents require direct and uniform access to data vendors without a separate integration for each source. The interface must be finance-native, with live price and news feeds operated by agents, and a coordinating layer must accept direction by voice and text, with voice output of a quality suitable for daily use.

Jaspers Terminal is an open-source desktop application for macOS and Windows designed around these requirements. It runs natively on the user's machine and combines agentic access to data vendors through MCP with local file access, command execution, and a workspace designed for parallel analysis and real-time data visualization. The following outlines how each requirement is addressed.

Tasks are defined as repeatable and scheduled jobs that execute in the background, including while the application is closed. Background tasks have the same capabilities as the interactive agent, covering the range from monitoring a single price to workflows that retrieve and process data and generate PDF reports. Users explicitly grant folder access, which permits the agent to read and write local files and incorporate them into analyses, and command execution permits the agent to operate local applications.

The Terminal connects agents to any MCP server and includes a directory of financial data-feed integrations through which users locate data sources and services. It also implements the MCP Apps specification, which allows external MCP servers to display their own interfaces within the Terminal. The Jaspers Terminal SDK extends this: developers register plugins, fetch and process data, run LLM calls, and build custom UI elements, and combine these capabilities into applications that run inside the Terminal.

Quantitative research often involves several analyses and agent workflows running concurrently, and the workspace is arranged for this as a grid of panes that split horizontally and vertically, similar to a terminal multiplexer or a trading screen. Live feeds and scheduled updates keep data and visualizations current. Users direct the work through a coordinating agent, the superagent, by text or voice. The superagent has access to the underlying data and visibility into the workspace layout, and coordinates agents in the context of what the user currently sees.

SDK & Plugins

The app ships no plugins of its own: market data, filings, and screeners all arrive as plugins, and built-in views such as a table, a chart, and a single number render whatever any of them returns. Plugins are TypeScript packages written against one MIT-licensed SDK, @jaspers-ai/sdk. The main process owns the app's state, runs the assistant, and keeps the keys. Plugin code sits in three places around it: views inside the window, the plugin's own process, and any local MCP server the plugin ships.

A plugin is a folder whose plugin.tsx exports one declaration, definePlugin(...), listing everything the plugin offers. Three parts of the app read that one object: main runs its schemas and its summarize, the plugin's own process runs its sources and start, and the window mounts its views.

Here is the whole plugin.tsx of a watchlist backed by a small local MCP server that needs an API key.

import { defineConnection, definePlugin, defineSource, defineView } from '@jaspers-ai/sdk'
import { z } from 'zod'
import { WatchlistView } from './WatchlistView'

const quotes = defineSource({ mcp: 'server', tool: 'quotes' })

export default definePlugin({
  id: 'watchlist',
  secrets: { apikey: { label: 'Quotes API key' } },
  connections: {
    server: defineConnection({
      command: ['node', 'server.ts'],
      env: { QUOTES_API_KEY: '${secret:apikey}' },
    }),
  },
  sources: { quotes },
  views: {
    watchlist: defineView(WatchlistView, {
      title: 'Watchlist',
      state: z.object({ tickers: z.array(z.string()).max(50).default([]) }),
      output: z.object({ tickers: z.array(z.string()), count: z.number() }),
      instructions: 'A list of companies to watch. Set state.tickers to ticker symbols, up to 50.',
      renders: [quotes],
    }),
  },
})

The SDK exposes the following functions to plugin developers to interact with the Terminal:

fetch HTTP to the source's declared hosts only, each redirect checked again
live Values the plugin's views read as they change, held in memory
jobs Background work that outlives the call that started it
notify A line in the assistant's answer box, labelled with the plugin
llm Completions on the user's configured model; the key never reaches the plugin
tools The tools on the app's MCP connections, to list and call
files Its own data folder, read and write; its install folder, read only
state The app's state, read only, with no path to a credential
skills The skills the assistant may load, for the plugin's own model

Views

A view is a React component the assistant can drive, because it declares two schemas. state is what the assistant may set, and main checks every write against it, whole. output is what the view reports about what it shows, for the assistant to read back.

That pair is what lets a plain request land on a view. Asked to “put a watchlist with Apple, Microsoft, and Nvidia on the left half”, the assistant places the view with those tickers as its state. Each view sits in an element, a panel on the grid with its own command line.

A simple example definition of a View.

function List({ panel, tickers }: { panel: PanelRef; tickers: string[] }) {
  const { data, error } = useData('watchlist/quotes', { tickers })
  const rows = (data ?? []) as Quote[]
  usePublish(panel, { tickers: rows.map((row) => row.ticker), count: rows.length })
  if (error) return <p className="wl-note">{error}</p>
  return <QuoteTable rows={rows} />
}

Each view runs in its own sandboxed iframe with no network of its own and no direct access to the app. It acts only through the SDK bridge. Through it, a view reads the app's public state, runs sources, writes panel state in its workspace (checked by main against each view's schema), and asks the app to open an https link or copy text. A view that embeds a site, as the TradingView plugin does, names the site's exact https origin, and only that site loads.

Data Sources & Backends

A source is a named data call that views and the assistant both run through main. It takes one of two forms: one tool on an MCP server, or a function the plugin runs itself. A source that returns a list of records produces rows, and anything else comes back as text. The same rows feed the plugin's own views, the built-in table and chart, and the assistant. Rows are kept for the source's ttl, and a later run with the same arguments reuses them instead of calling again.

Every run is also filed in one local SQLite file. The source, the arguments, the workspace, the time, the rows, any prose, and the error if it failed. The assistant reads across it with SQL, so it can compare two providers or look back a week without fetching again. The file stays on your machine and opens in sqlite3, DuckDB, or pandas.

The MCP-native layer

The Terminal's integration layer is MCP. Everything an agent can reach is an MCP server, and the Terminal is the client that connects to each server, lists its tools, and allows agents to call them. The same interface applies uniformly to external vendors and to the user's own machine. A market data vendor and the local filesystem are each registered as a named server with a set of tools and a description of what each tool does.

An MCP server is added either through a managed selection of MCPs within the Terminal or through custom endpoints that can be configured. Users can add vendors through custom plugin development, and the Terminal can connect to locally running MCP servers on the user's machine.

Agents in the Terminal run against the registered servers. An agent given a task decides which servers to call, in what order, and with what arguments, and the Terminal records each call, its arguments, and its result. Adding a data source therefore changes what every agent can do, with no change to the application.

The pane grid

Quantitative research usually proceeds along multiple tasks and agentic workflows at once. The Terminal reflects that pattern of work by laying the workspace out as a grid of panes, split horizontally and vertically in the way a terminal multiplexer or a trading screen is arranged. Each pane is an independent agent session with its own conversation, its own working state, and its own log.

Sessions in different panes run concurrently. Panes share the same registered servers, so a session in one pane can pick up a dataset another pane produced, and a result can be dragged from a pane into a file or into another session's context.

A pane is also the unit of persistence. A session can be named, saved, and reopened with its full history and the artifacts it produced, so a piece of work on a name from last quarter is a pane to reopen. Layouts can be saved as well, which lets a user keep one arrangement for screening and another for reading through a single company.

Market and alternative data

Connecting a new data source involves authentication, pagination, rate limits, field naming, and the join keys that let one vendor's rows line up with another's. In the Terminal, that work is done once in the connector.

Market data arrives through vendor connectors the user registers. Alternative data is handled the same way, whether it is a commercial feed the manager already licenses, a web source, or a dataset the researcher deploys internally. A connector for a vendor is usually a thin wrapper over the vendor's own API, and because the interface is MCP, a vendor that publishes its own server connects directly.

The Jaspers research engine is a connector like the others. The connector exposes Discover, a proprietary Jaspers data feed, which covers the universe of US SEC registrants with fundamentals, valuation, ownership, a qualitative reading of filing text, and a knowledge graph that links filing text and XBRL data to a risk factor ontology. To the Terminal, Discover and Research by Jaspers are two more servers, registered and called in the same way as a market data vendor.

Because every source sits behind the same interface, a superagent can join sources within one request.

Operating the shell

The Terminal has a “Pro” mode, which allows it to treat the user's local shell as a registered server. In Pro mode, an agent in a pane can run shell commands, read and write files, execute scripts, and inspect their output as part of a research task. Flexible setup options are available.

Models, logging, and observability

The Terminal is bring-your-own-model by design. The user supplies API keys for the providers they use, and each step of an agent's work is routed to a model chosen by the task and its cost. The user can set which providers are available and pin a session to a specific model where a workflow depends on it. The economics of model routing changed during 2026, as several providers reset pricing, and the routing design lets the Terminal take advantage of lower prices without manual intervention by the user.

Every session is logged in full to an append-only log. The log holds each model call with its inputs and outputs, each MCP tool call with its arguments and result, each shell command with its output, and the timing and cost of each. A result in a pane can be traced back to the servers it was drawn from and the passages it rests on, and a session can be replayed. Traceability is the property that makes agent output usable in an investment process: a number or a claim a PM acts on has to be traceable, and a compliance function has to be able to review it.

The log is also how the Terminal improves. Optional opt-in usage telemetry, which is visible in the source and can be inspected by the user, feeds a fully automated development loop that enables Jaspers coding agents to improve the codebase seamlessly.

Open source and availability

Jaspers Terminal is free to download and use, and the source is public. The application, its connector framework, and the connectors we ship are open, so a user can read how a source is queried, modify a connector, or write a new one, and a vendor can publish a connector for their own data without our involvement. The Jaspers research engine behind Discover and Research is a hosted service that the Terminal connects to as one server among many; it is metered, and a user who connects only their own sources can run the Terminal without subscribing to the research engine.

The Terminal ships for macOS and Windows, updates itself, and runs entirely on the user's machine apart from the servers the user chooses to connect to. Concurrent multi-session execution across the pane grid is the component still under active development at the time of writing, and it will be delivered through the updater.

The download, the source repository, and the connector documentation will be published on the Jaspers website upon release. Connectors written by third parties are accepted into the repository under the same license as the application.