# Polaris

> Integrate the tools and skills catalog from the Polaris platform into DeepSeek Harness, and enforce the permitted tool policies declared in skills during the current DSH turn execution.

## Metadata

- Author: [@ZJU-REAL](https://github.com/ZJU-REAL)
- Repo: <https://github.com/ZJU-REAL/Polaris.git>
- GitHub: [ZJU-REAL/Polaris](https://github.com/ZJU-REAL/Polaris)
- Stars: 196
- Language: Python
- License: [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)
- Homepage: <https://zju-real.github.io/Polaris/>
- Topics: `ai-agents`, `ai-scientist`, `auto-research`, `dsh-plugin`, `polaris-agent`
- Forks: 26
- Open Issues: 6
- Last push: 2026-08-20T07:39:24.000Z
- Added: 2026-08-17T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:ZJU-REAL/Polaris/integrations/deepseek-harness
```

## Wiki

## One-Sentence Positioning
This is a connector plugin that integrates the Polaris platform into DeepSeek Harness (DSH). It pulls Polaris backend's MCP tool list into DSH on one side, and injects Polaris assistant skills into DSH as native skills (rather than MCP tools) on the other side, and enforces the "allowed-tools" policy declared by each skill into the current DSH turn.

## Core Capabilities
- Connect to Polaris `/mcp` through DSH's official MCP client, inject Polaris tools (like `search_papers`) into DSH tool directory with `mcp__polaris__*` namespace
- As a native skill provider, regularly pulls the Polaris skill directory and registers Polaris assistant skills into DSH's native skill system
- Registers `polaris_skill_resource` tool to read skill declaration attachment content on demand (only paths explicitly listed by the skill are readable)
- Based on Polaris skills loaded in the current turn, hides Polaris tools outside its `allowed-tools` whitelist at the tool layer, and performs guard interception on tools discovered later in the turn
- When multiple skills are loaded in the same turn, automatically takes the intersection of their allowed tools lists, only tightening rather than loosening
- When tokens expire (401/403) or permissions are downgraded, automatically clears cache and marks DSH skill discovery as invalid, achieving fail-close

## Technical Implementation
- **Language**: TypeScript (ESM, `tsconfig.json` builds to `dist/`)
- **Key dependencies**: `@deepseek-ai/dsh-mcp-client` (official MCP bridge), `@deepseek-ai/schemastery` (config schema), `zod` (runtime data structure validation), `@deepseek-ai/cordis` (host injection)
- **Architecture pattern**: Dual-adapter bundle. `cordis.patch.yml` inserts two services into the host at startup: `polaris-mcp` (via official MCP client) and `polaris-skills` (native provider from this plugin). The plugin then tracks turn state through Cordis hooks (`tools/post-execute`, `agent/pre-step`, `tools/change`, `agent/disposed`, `agent/error`, `agent/turn-stopping`)
- **Entry point**: `integrations/deepseek-harness/src/index.ts` (`apply(ctx, config)` is the plugin activation entry)

## Use Cases
Users who have deployed a Polaris instance and want DSH to both call Polaris's exposed MCP tools and leverage Polaris's assistant skills to uniformly manage team prompts and triggering rules. It treats skills as native first-class citizens in DSH, avoiding the misregistration issue where skills are misplaced as MCP tools; simultaneously, through the `allowed-tools` policy, individual skills can declare their own tool whitelist, preserving Polaris tools while preventing privilege escalation.

## Prerequisites & Compatibility

| Dependency | Minimum Version | Description |
|---|---|---|
| DeepSeek Harness | 0.1.0-rc.6 | Plugin `peerDependencies` declares `cordis`, `dsh-agent`, `dsh-session`, `dsh-skill`, `dsh-tools` all as `^0.1.0-rc.6` |
| Node.js | >=20 | `engines.node` field; required for local bundle building |
| Platform | Cross-platform | No `os` / `cpu` restrictions declared |
| Native modules | None | Dependencies are pure JS/TS packages, no `node-gyp` modules |
| Polaris backend | Database migration `8ff89f7fcdeb` | Otherwise `/api/integrations/deepseek-harness/v1/skills*` endpoints unavailable |

## Installation

```bash
dsh plugin --profile web add github:ZJU-REAL/Polaris/integrations/deepseek-harness
```

## Configuration Options

Environment variables are read by `cordis.patch.yml` when the plugin is injected, and the patch line also accepts same-name config field overrides.

| Config | Type | Description | Default |
|---|---|---|---|
| `POLARIS_BASE_URL` | Environment variable / string | Polaris service root address, automatically strips trailing slash and appends `/mcp` | `http://127.0.0.1:8000` |
| `POLARIS_DSH_TOKEN` | Environment variable / string | Integration token plaintext, created via `/api/integration-tokens`, scopes require at least `skills:read` and `mcp:read` | empty |
| `POLARIS_DSH_TOOL_PROFILE` | Environment variable / string | Backend MCP profile; `dsh-readonly-v1` is read-only, `dsh-full-v1` additionally exposes `remember` (and only when account has Buddy memory enabled) | `dsh-readonly-v1` |
| `baseUrl` | Field (override env) | Same as `POLARIS_BASE_URL`, used to bypass environment variables for direct passing | Required |
| `token` | Field (override env) | Same as `POLARIS_DSH_TOKEN`, marked as `secret` field by schemastery | Required |
| `serverName` | String | MCP namespace, must match official client row | `polaris` |
| `refreshIntervalMs` | Number, ≥1000 | Skill directory polling interval | `30000` |
| `requestTimeoutMs` | Number, ≥1 | Polaris single discovery request timeout | `10000` |
| `failOnStartupError` | Boolean | Whether to interrupt DSH startup if skill discovery fails at startup | `false` |
| `allowedToolsMode` | Enum | Skill `allowed-tools` policy enforcement strength: `enforce` hides and intercepts violating tools; `advisory` only logs warnings; `off` completely disables policy | `enforce` |
| `userSkillRank` | Number | DSH candidate ranking for user-scoped Polaris skills | `340` |
| `builtinSkillRank` | Number | DSH candidate ranking for builtin-scoped Polaris skills | `360` |

## FAQ

**Q: What environment variables must be set after installation?**

A: At minimum `POLARIS_BASE_URL` and `POLARIS_DSH_TOKEN`, otherwise the plugin will throw an error immediately during client construction due to empty token. If using `dsh-full-v1` profile, the backend account also needs Buddy memory enabled, otherwise the `remember` tool won't appear in the discovery list.

**Q: How do I grant permissions for the integration token?**

A: Use the current logged-in JWT to call `POST /api/integration-tokens`, select scopes. `skills:read` is used for skill discovery and reading, `mcp:read` is used for connecting to `/mcp`, `mcp:write` is used to open write tool profile. The token plaintext only appears once in the creation response; the Polaris backend only stores SHA-256 hash, so it must be recreated if lost. Created token scopes cannot be edited, only revoked and recreated.

**Q: How do I verify the plugin is active?**

A: Run `dsh --profile web --dump-config` before DSH profile startup; the config should show both `polaris-mcp` and `polaris-skills` lines; after startup, DSH's tool directory should contain tools like `mcp__polaris__search_papers`, and Polaris backend's `skill_load` won't appear as an MCP tool (it's carried by DSH's native `skill` tool).

**Q: How do I write `allowed-tools` in skills correctly?**

A: Must be Polaris original tool names (like `search_papers`), not DSH namespace forms like `mcp__polaris__search_papers`; when multiple Polaris skills load in the same turn, their allowed lists automatically take intersection, won't expand the tool set, nor restrict non-Polaris DSH tools; `allowed-tools: null` means no additional restrictions.

**Q: What happens when token is revoked or account is downgraded to read-only?**

A: Skill discovery encountering 401 or 403 will immediately clear cached skill directory and mark DSH discovery as invalid; if next request still doesn't recover, it will directly reject; after backend downgrades account to read-only, even if token declares write scope, it will be rejected on next request at `/mcp`, not just the browser session affected.

**Q: How to choose between the three `allowedToolsMode` modes?**

A: Default `enforce` hides violating Polaris tools from tool directory and synchronously intercepts newly discovered tools in the turn; `advisory` only logs without interception, suitable for troubleshooting before going live; `off` completely disables policy, turns off the entire policy controller, suitable for reducing event loop overhead when Polaris backend hasn't declared any policies.

## Difficulty Level
Advanced — requires preparing database migration and integration token on Polaris backend first, understanding the relationship between DSH profile, cordis patch and environment variables, and being able to distinguish between `enforce`/`advisory`/`off` three policy strengths to avoid misinterception.

## Known Issues & Limitations
- Polaris backend must apply migration `8ff89f7fcdeb`, otherwise skill-related endpoints are unavailable
- Integration token `scopes` cannot be edited after creation, can only be recreated via `DELETE /api/integration-tokens/{id}`; `serverName` must match official MCP client row, otherwise policy matching will fail
- Skill attachment paths reject empty segments, `.` and `..` segments on client side (`src/client.ts:84`), preventing undeclared path bypass validation to redirect requests
- When Polaris account is read-only, even if token declares `mcp:write`, it will be rejected on `/mcp`; the only write tool in `dsh-full-v1`, `remember`, only appears in discovery and call lists after account enables Buddy memory
- No TODO / FIXME / HACK comments in source code, no explicitly marked bugs currently identified

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [Polaris](https://deepseek-plugin.org/plugins/ZJU-REAL/Polaris/integrations/deepseek-harness)
Wiki generated by AI (model: `MiniMax-M2.5`)
