1
0

Agent Resource Platform - this is an exploration into what a backbone for human-agent interaction in a business context might look like.

david cd713697e0 fix missing columnsin cli 8 цаг өмнө
arp_agent ee3b6e9adc improve system prompt 2 өдөр өмнө
arp_cli cd713697e0 fix missing columnsin cli 8 цаг өмнө
auth 46993daca6 initial commit 1 долоо хоног өмнө
graph cd713697e0 fix missing columnsin cli 8 цаг өмнө
logging 7b1d31feba require auth for all operations, use db_bootstrap.sql script, remove redundant tests 6 өдөр өмнө
mcp 7e75d826f8 don't leak password hashes 1 өдөр өмнө
models b3a755eb56 switch channel based messaging to receiver list 4 өдөр өмнө
.gitignore 9be3d9b88f update gitignore 1 өдөр өмнө
ARP_AGENT_README.MD 03f93e2c50 port agent to go 2 өдөр өмнө
CLIENT_GUIDE.md ef52eb1bbd add mcp server 3 өдөр өмнө
README.md c74f9dc3bc fix: do not notify message sender about new message 5 өдөр өмнө
TODO.md b3a755eb56 switch channel based messaging to receiver list 4 өдөр өмнө
arp_server cd713697e0 fix missing columnsin cli 8 цаг өмнө
go.mod 6bb7cea6b2 implement subscriptions with event filtering 6 өдөр өмнө
go.sum 6bb7cea6b2 implement subscriptions with event filtering 6 өдөр өмнө
gqlgen.yml 46993daca6 initial commit 1 долоо хоног өмнө
init_prod.sql ef52eb1bbd add mcp server 3 өдөр өмнө
server.go ef52eb1bbd add mcp server 3 өдөр өмнө

README.md

ARP - Agent Resource Platform

A GraphQL-based coordination system for users and agents to collaborate on services, tasks, and communications.

Overview

ARP (Agent Resource Platform) is a coordination backend that enables human users and AI agents to work together on shared services. It provides:

  • User Management - Role-based access control with fine-grained permissions
  • Service Coordination - Create and manage services with multiple participants
  • Task Management - Assignable work items with status tracking
  • Notes - Attach notes to services for context
  • Messaging - Real-time chat channels between participants

Architecture

┌─────────────────────────────────────────────────────────────┐
│                      GraphQL API                            │
│  (gqlgen - schema-first, type-safe resolvers)               │
├─────────────────────────────────────────────────────────────┤
│                    Auth Middleware                          │
│  (JWT tokens, permission checks)                            │
├─────────────────────────────────────────────────────────────┤
│                     GORM Models                             │
│  User → Role → Permission                                   │
│  Service → Task → TaskStatus                                │
│  Channel → Message                                          │
│  Note                                                       │
├─────────────────────────────────────────────────────────────┤
│                   SQLite Database                           │
│  (arp.db - can be swapped for PostgreSQL/MySQL)             │
└─────────────────────────────────────────────────────────────┘

Quick Start

Prerequisites

  • Go 1.21+
  • SQLite3 (or modify for PostgreSQL/MySQL)

Running the Server

# Clone and run
go run server.go

# Server starts on http://localhost:8080

Running Tests

go test ./... -v

API Interaction with Bash

1. Start the Server

go run server.go &
# Server runs on http://localhost:8080

2. Inspect the GraphQL Schema

Use GraphQL introspection to discover the API schema:

# Get all types in the schema
curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -d '{"query":"{ __schema { types { name kind description fields { name type { name kind ofType { name } } } } } }"}' | jq

# Get all queries and mutations
curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -d '{"query":"{ __schema { queryType { fields { name description } } mutationType { fields { name description } } } }"}' | jq

3. Initialize Database with Seed Data

Run the SQL bootstrap script to create permissions, roles, task statuses, and an admin user:

# Initialize the database with seed data
sqlite3 arp.db < init.sql

# Verify the data was created
sqlite3 arp.db "SELECT name FROM roles;"
# Output:
# admin
# manager
# user

sqlite3 arp.db "SELECT email FROM users;"
# Output:
# admin@example.com

The init.sql script creates:

  • 36 permissions covering all CRUD operations for each entity type
  • 3 roles: admin (full access), manager (service/task management), user (read-only + notes/messages)
  • 1 admin user with email admin@example.com and password secret123
  • 6 task statuses: open, in_progress, blocked, review, done, cancelled

4. Login and Get JWT Token

# Login to get JWT token
TOKEN=$(curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -d '{"query":"mutation { login(email: \"admin@example.com\", password: \"secret123\") { token user { email roles { name } } } }"}' | jq -r '.data.login.token')

echo "Token: $TOKEN"

5. Pull List of Services (Authenticated)

# Get all services with authentication
curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"query":"{ services { id name description createdAt participants { email } tasks { title status { label } } } }"}' | jq

6. Create a Service

# Create a new service
curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"query":"mutation { createService(input: {name: \"Project Alpha\", description: \"New project\", createdById: \"1\", participants: [\"1\"]}) { id name } }"}' | jq

7. Query Single Service by ID

# Get a specific service
curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"query":"{ service(id: \"1\") { id name description createdBy { email } participants { email } tasks { id title priority status { code label } } } }"}' | jq

Authentication & Authorization

Permission System

The system uses a hierarchical permission model:

User ─┬─ has many ─→ Role ─┬─ has many ─→ Permission
      │                    │
      └─ e.g., "admin"     └─ e.g., "service:create"

Required Permissions for Operations

Operation Required Permission
Update User user:update
Delete User user:delete
Update Task task:update
Delete Task task:delete
Update Note note:update
Delete Note note:delete
Update Service service:update
Delete Service service:delete
... ...

Using Authentication in Requests

# Include JWT token in Authorization header
curl -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{"query":"..."}'

GraphQL Schema Overview

Core Types

  • User - Agent or human account
  • Role - Groups of permissions
  • Permission - Fine-grained access control (e.g., task:create)
  • Service - Coordination unit with participants and tasks
  • Task - Assignable work item with status
  • TaskStatus - Workflow states (open, in_progress, done)
  • Note - Notes attached to services
  • Channel - Chat between participants
  • Message - Individual chat messages

Key Queries

type Query {
  users: [User!]!
  user(id: ID!): User
  services: [Service!]!
  service(id: ID!): Service
  tasks: [Task!]!
  task(id: ID!): Task
  roles: [Role!]!
  permissions: [Permission!]!
  # ... more queries
}

Key Mutations

type Mutation {
  login(email: String!, password: String!): AuthPayload!
  createUser(input: NewUser!): User!
  createService(input: NewService!): Service!
  createTask(input: NewTask!): Task!
  # ... more mutations
}

Environment Variables

Variable Default Description
JWT_SECRET your-secret-key-change-in-production Secret for JWT signing